Skip to content

Commit 73dc916

Browse files
committed
Auto merge of #160348 - JonathanBrouwer:rollup-rHpJo5w, r=JonathanBrouwer
Rollup of 8 pull requests Successful merges: - #160262 (Library lock file maintenance) - #158548 (Move `std::io::copy` to `alloc::io`) - #158814 (Produce an error when `#[inline]` and `#[rust_force_inline]` are used together) - #160025 (Fix an edge case with `StepBy::nth` on non-fused iterators) - #160271 (Resolver: Introduce `CmRef` which has a speclative borrow variant for `CmRefCell`) - #160281 (Fix(lib/fs/tests): Avoid permission denials when cleaning up TempDirs in `set_get_permissions_nofollows*`) - #160325 (tidy: Check `proc_macro_deps.rs` by reading it, not by including it) - #160334 (Add regression test for unused_allocation on boxed comparison)
2 parents b430378 + a8e864f commit 73dc916

25 files changed

Lines changed: 827 additions & 446 deletions

File tree

compiler/rustc_attr_parsing/src/attributes/inline.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
// FIXME(jdonszelmann): merge these two parsers and error when both attributes are present here.
2-
// note: need to model better how duplicate attr errors work when not using
3-
// SingleAttributeParser which is what we have two of here.
4-
51
use rustc_feature::AttributeStability;
62
use rustc_hir::attrs::{AttributeKind, InlineAttr};
3+
use rustc_hir::find_attr;
74
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
85

96
use super::prelude::*;
7+
use crate::session_diagnostics::InlineForceInlineConflict;
108

119
pub(crate) struct InlineParser;
1210

@@ -94,4 +92,16 @@ impl SingleAttributeParser for RustcForceInlineParser {
9492
cx.attr_span,
9593
))
9694
}
95+
96+
fn finalize_check(cx: &FinalizeCheckContext<'_, '_>, attr_span: Span) {
97+
let Some(inline_span) = find_attr!(cx.parsed_attrs, Inline(attr, span) if !matches!(attr, InlineAttr::Force { .. }) => span)
98+
else {
99+
return;
100+
};
101+
102+
cx.emit_err(InlineForceInlineConflict {
103+
inline_span: *inline_span,
104+
force_inline_span: attr_span,
105+
});
106+
}
97107
}

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ use rustc_target::spec::TargetTuple;
1313
use crate::AttributeTemplate;
1414
use crate::context::Suggestion;
1515

16+
#[derive(Diagnostic)]
17+
#[diag("`#[rustc_force_inline]` and `#[inline]` cannot be used together")]
18+
pub(crate) struct InlineForceInlineConflict {
19+
#[primary_span]
20+
pub force_inline_span: Span,
21+
#[label("the inline attribute is specified here")]
22+
pub inline_span: Span,
23+
}
24+
1625
#[derive(Diagnostic)]
1726
#[diag("`#[ffi_const]` function cannot be `#[ffi_pure]`", code = E0757)]
1827
pub(crate) struct BothFfiConstAndPure {

compiler/rustc_resolve/src/check_unused.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ impl Resolver<'_, '_> {
558558
let unused_imports = visitor.unused_imports;
559559
let mut check_redundant_imports = FxIndexSet::default();
560560
for module in &self.local_modules {
561-
for (_key, resolution) in self.resolutions(module.to_module()).borrow().iter() {
561+
for (_key, resolution) in self.resolutions(module.to_module()).iter() {
562562
if let Some(decl) = resolution.borrow().best_decl()
563563
&& let DeclKind::Import { import, .. } = decl.kind
564564
&& let ImportKind::Single { id, .. } = import.kind

compiler/rustc_resolve/src/diagnostics/impls.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1870,24 +1870,22 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
18701870
// If so, we have to disambiguate the potential import suggestions by making
18711871
// the paths *global* (i.e., by prefixing them with `::`).
18721872
let needs_disambiguation =
1873-
self.resolutions(parent_scope.module).borrow().iter().any(
1874-
|(key, name_resolution)| {
1875-
if key.ns == TypeNS
1876-
&& key.ident == *ident
1877-
&& let Some(decl) = name_resolution.borrow().best_decl()
1878-
{
1879-
match decl.res() {
1880-
// No disambiguation needed if the identically named item we
1881-
// found in scope actually refers to the crate in question.
1882-
Res::Def(_, def_id) => def_id != crate_def_id,
1883-
Res::PrimTy(_) => true,
1884-
_ => false,
1885-
}
1886-
} else {
1887-
false
1873+
self.resolutions(parent_scope.module).iter().any(|(key, name_resolution)| {
1874+
if key.ns == TypeNS
1875+
&& key.ident == *ident
1876+
&& let Some(decl) = name_resolution.borrow().best_decl()
1877+
{
1878+
match decl.res() {
1879+
// No disambiguation needed if the identically named item we
1880+
// found in scope actually refers to the crate in question.
1881+
Res::Def(_, def_id) => def_id != crate_def_id,
1882+
Res::PrimTy(_) => true,
1883+
_ => false,
18881884
}
1889-
},
1890-
);
1885+
} else {
1886+
false
1887+
}
1888+
});
18911889
let mut crate_path = ThinVec::new();
18921890
if needs_disambiguation {
18931891
crate_path.push(ast::PathSegment::path_root(rustc_span::DUMMY_SP));

compiler/rustc_resolve/src/effective_visibilities.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
125125
/// including their whole reexport chains.
126126
fn set_bindings_effective_visibilities(&mut self, module_id: LocalDefId) {
127127
let module = self.r.expect_module(module_id.to_def_id());
128-
for (_, name_resolution) in self.r.resolutions(module).borrow().iter() {
128+
for (_, name_resolution) in self.r.resolutions(module).iter() {
129129
let Some(decl) = name_resolution.borrow().best_decl() else {
130130
continue;
131131
};
@@ -309,7 +309,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
309309
) {
310310
if self.macro_reachable.insert((module_def_id, defining_mod)) {
311311
let module = self.r.expect_module(module_def_id.to_def_id());
312-
for (_, name_resolution) in self.r.resolutions(module).borrow().iter() {
312+
for (_, name_resolution) in self.r.resolutions(module).iter() {
313313
let Some(decl) = name_resolution.borrow().best_decl() else {
314314
continue;
315315
};

compiler/rustc_resolve/src/imports.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,7 +1002,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
10021002

10031003
pub(crate) fn lint_reexports(&mut self, exported_ambiguities: FxHashSet<Decl<'ra>>) {
10041004
for module in &self.local_modules {
1005-
for (key, resolution) in self.resolutions(module.to_module()).borrow().iter() {
1005+
for (key, resolution) in self.resolutions(module.to_module()).iter() {
10061006
let resolution = resolution.borrow();
10071007
let Some(binding) = resolution.best_decl() else { continue };
10081008

@@ -1481,7 +1481,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
14811481
let names = match module {
14821482
ModuleOrUniformRoot::Module(module) => {
14831483
self.resolutions(module)
1484-
.borrow()
14851484
.iter()
14861485
.filter_map(|(BindingKey { ident: i, .. }, resolution)| {
14871486
if i.name == ident.name {
@@ -1799,7 +1798,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
17991798
let import_bindings = match imported_module {
18001799
ModuleOrUniformRoot::Module(module) if module != import.parent_scope.module => self
18011800
.resolutions(module)
1802-
.borrow()
18031801
.iter()
18041802
.filter_map(|(key, resolution)| {
18051803
let res = resolution.borrow();

compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
190190
assoc_name: Symbol,
191191
) -> Option<DefId> {
192192
let module = self.r.get_module(trait_def_id)?;
193-
self.r.resolutions(module).borrow().iter().find_map(|(key, resolution)| {
193+
self.r.resolutions(module).iter().find_map(|(key, resolution)| {
194194
if key.ident.name != assoc_name {
195195
return None;
196196
}
@@ -648,7 +648,6 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
648648
&& self
649649
.r
650650
.resolutions(module)
651-
.borrow()
652651
.iter()
653652
.any(|(key, _r)| key.ident.name == following_seg.ident.name)
654653
} else {
@@ -1164,7 +1163,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
11641163

11651164
fn lookup_doc_alias_name(&mut self, path: &[Segment], ns: Namespace) -> Option<(DefId, Ident)> {
11661165
let find_doc_alias_name = |r: &mut Resolver<'ra, '_>, m: Module<'ra>, item_name: Symbol| {
1167-
for resolution in r.resolutions(m).borrow().values() {
1166+
for resolution in r.resolutions(m).values() {
11681167
let Some(did) =
11691168
resolution.borrow().best_decl().and_then(|binding| binding.res().opt_def_id())
11701169
else {
@@ -1904,7 +1903,6 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
19041903
let targets: Vec<_> = self
19051904
.r
19061905
.resolutions(module)
1907-
.borrow()
19081906
.iter()
19091907
.filter_map(|(key, resolution)| {
19101908
let resolution = resolution.borrow();
@@ -2767,7 +2765,6 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
27672765
let targets = self
27682766
.r
27692767
.resolutions(*module)
2770-
.borrow()
27712768
.iter()
27722769
.filter_map(|(key, res)| res.borrow().best_decl().map(|binding| (key, binding.res())))
27732770
.filter(|(_, res)| match (kind, res) {
@@ -2970,7 +2967,6 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
29702967
let module = self.r.expect_module(def_id);
29712968
self.r
29722969
.resolutions(module)
2973-
.borrow()
29742970
.iter()
29752971
.any(|(key, _)| key.ident.name == following_seg.ident.name)
29762972
}

compiler/rustc_resolve/src/lib.rs

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#![recursion_limit = "256"]
2222
// tidy-alphabetical-end
2323

24-
use std::cell::Ref;
24+
use std::cell::{Ref, RefMut};
2525
use std::collections::BTreeSet;
2626
use std::ops::ControlFlow;
2727
use std::sync::{Arc, OnceLock};
@@ -81,7 +81,7 @@ use crate::diagnostics::impls::{
8181
ImportSuggestion, LabelSuggestion, OnUnknownData, StructCtor, Suggestion,
8282
};
8383
use crate::imports::{ImportResolution, NameResolutionRef};
84-
use crate::ref_mut::{CmCell, CmRefCell};
84+
use crate::ref_mut::{CmCell, CmRef, CmRefCell};
8585

8686
mod build_reduced_graph;
8787
mod check_unused;
@@ -637,7 +637,7 @@ type ResolutionTable<'ra> = FxIndexMap<BindingKey, NameResolutionRef<'ra>>;
637637

638638
enum Resolutions<'ra> {
639639
Local(CmRefCell<ResolutionTable<'ra>>),
640-
Extern(OnceLock<CmRefCell<ResolutionTable<'ra>>>),
640+
Extern(OnceLock<ResolutionTable<'ra>>),
641641
}
642642

643643
impl<'ra> Resolutions<'ra> {
@@ -792,7 +792,7 @@ impl<'ra> Module<'ra> {
792792
resolver: &R,
793793
mut f: impl FnMut(&R, IdentKey, Span, Namespace, Decl<'ra>),
794794
) {
795-
for (key, name_resolution) in resolver.as_ref().resolutions(self).borrow().iter() {
795+
for (key, name_resolution) in resolver.as_ref().resolutions(self).iter() {
796796
let name_resolution = name_resolution.borrow();
797797
if let Some(decl) = name_resolution.best_decl() {
798798
f(resolver, key.ident, name_resolution.orig_ident_span, key.ns, decl);
@@ -805,7 +805,7 @@ impl<'ra> Module<'ra> {
805805
resolver: &mut R,
806806
mut f: impl FnMut(&mut R, IdentKey, Span, Namespace, Decl<'ra>),
807807
) {
808-
for (key, name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() {
808+
for (key, name_resolution) in resolver.as_mut().resolutions(self).iter() {
809809
let name_resolution = name_resolution.borrow();
810810
if let Some(decl) = name_resolution.best_decl() {
811811
f(resolver, key.ident, name_resolution.orig_ident_span, key.ns, decl);
@@ -2152,7 +2152,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
21522152
match (trait_module, assoc_item) {
21532153
(Some(trait_module), Some((name, ns))) => self
21542154
.resolutions(trait_module)
2155-
.borrow()
21562155
.iter()
21572156
.any(|(key, _name_resolution)| key.ns == ns && key.ident.name == name),
21582157
_ => true,
@@ -2177,14 +2176,28 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
21772176
self.tcx.hir_arena.alloc_slice(&import_ids)
21782177
}
21792178

2180-
fn resolutions(&self, module: Module<'ra>) -> &'ra CmRefCell<ResolutionTable<'ra>> {
2179+
fn resolutions(&self, module: Module<'ra>) -> CmRef<'ra, ResolutionTable<'ra>> {
21812180
match &module.0.0.lazy_resolutions {
2182-
Resolutions::Local(local_res) => local_res,
2181+
Resolutions::Local(local_res) => CmRef::Tracked(local_res.borrow()),
21832182
Resolutions::Extern(extern_res) => {
2184-
// as long as 1 thread is building this external table, all other threads will wait
2185-
extern_res.get_or_init(|| {
2186-
CmRefCell::new(self.build_reduced_graph_external(module.expect_extern()))
2187-
})
2183+
// It is fine to return a `CmRef::Untracked`, we never give out a `&mut`
2184+
// to an external table.
2185+
CmRef::Untracked(
2186+
// As long as 1 thread is building this external table, all other threads will wait.
2187+
extern_res
2188+
.get_or_init(|| self.build_reduced_graph_external(module.expect_extern())),
2189+
)
2190+
}
2191+
}
2192+
}
2193+
2194+
fn resolutions_mut(&self, module: Module<'ra>) -> RefMut<'ra, ResolutionTable<'ra>> {
2195+
match &module.0.0.lazy_resolutions {
2196+
Resolutions::Local(local_res) => local_res.borrow_mut(self),
2197+
Resolutions::Extern(_) => {
2198+
// We do not allow in place mutations of the external resolution table. In fact,
2199+
// we never attempt it.
2200+
unreachable!("Attempted to mutably borrow an extenral resolution table")
21882201
}
21892202
}
21902203
}
@@ -2194,7 +2207,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
21942207
module: Module<'ra>,
21952208
key: BindingKey,
21962209
) -> Option<Ref<'ra, NameResolution<'ra>>> {
2197-
self.resolutions(module).borrow().get(&key).map(|resolution| resolution.0.borrow())
2210+
self.resolutions(module).get(&key).map(|resolution| resolution.0.borrow())
21982211
}
21992212

22002213
#[track_caller]
@@ -2204,7 +2217,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
22042217
key: BindingKey,
22052218
orig_ident_span: Span,
22062219
) -> NameResolutionRef<'ra> {
2207-
*self.resolutions(module).borrow_mut(self).entry(key).or_insert_with(|| {
2220+
*self.resolutions_mut(module).entry(key).or_insert_with(|| {
22082221
self.arenas.alloc_name_resolution(NameResolution::new(orig_ident_span))
22092222
})
22102223
}
@@ -2915,6 +2928,24 @@ mod ref_mut {
29152928
}
29162929
}
29172930

2931+
pub(crate) enum CmRef<'b, T> {
2932+
/// A tracked borrow of a [`CmRefCell`]
2933+
Tracked(Ref<'b, T>),
2934+
/// An untracked or normal reference (not dynamically borrow-checked by `RefCell`)
2935+
Untracked(&'b T),
2936+
}
2937+
2938+
impl<'b, T> Deref for CmRef<'b, T> {
2939+
type Target = T;
2940+
2941+
fn deref(&self) -> &Self::Target {
2942+
match self {
2943+
CmRef::Tracked(r) => r,
2944+
CmRef::Untracked(r) => r,
2945+
}
2946+
}
2947+
}
2948+
29182949
/// A wrapper around a [`RefCell`] that only allows writes (mutable borrows) based on a condition in the resolver.
29192950
#[derive(Default)]
29202951
pub(crate) struct CmRefCell<T>(RefCell<T>);
@@ -2926,10 +2957,7 @@ mod ref_mut {
29262957

29272958
#[track_caller]
29282959
pub(crate) fn borrow_mut<'ra, 'tcx>(&self, r: &Resolver<'ra, 'tcx>) -> RefMut<'_, T> {
2929-
if r.assert_speculative {
2930-
panic!("not allowed to mutably borrow a `CmRefCell` during speculative resolution");
2931-
}
2932-
self.0.borrow_mut()
2960+
self.try_borrow_mut(r).unwrap()
29332961
}
29342962

29352963
#[track_caller]

0 commit comments

Comments
 (0)