Skip to content

Commit 26d451f

Browse files
committed
Auto merge of #80782 - petrochenkov:viscopes, r=matthewjasper
resolve: Scope visiting doesn't need an `Ident` Resolution scope visitor (`fn visit_scopes`) currently takes an `Ident` parameter, but it doesn't need a full identifier, or even its span, it only needs the `SyntaxContext` part. The `SyntaxContext` part is necessary because scope visitor has to jump to macro definition sites, so it has to be directed by macro expansion information somehow. I think it's clearer to pass only the necessary part. Yes, usually visiting happens as a part of an identifier resolution, but in cases like collecting traits in scope (#80765) or collecting typo suggestions that's not the case. r? `@matthewjasper`
2 parents c97f11a + 3ff866e commit 26d451f

File tree

6 files changed

+90
-57
lines changed

6 files changed

+90
-57
lines changed

compiler/rustc_resolve/src/diagnostics.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,8 @@ impl<'a> Resolver<'a> {
611611
filter_fn: &impl Fn(Res) -> bool,
612612
) -> Option<TypoSuggestion> {
613613
let mut suggestions = Vec::new();
614-
self.visit_scopes(scope_set, parent_scope, ident, |this, scope, use_prelude, _| {
614+
let ctxt = ident.span.ctxt();
615+
self.visit_scopes(scope_set, parent_scope, ctxt, |this, scope, use_prelude, _| {
615616
match scope {
616617
Scope::DeriveHelpers(expn_id) => {
617618
let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);

compiler/rustc_resolve/src/late.rs

+47-35
Original file line numberDiff line numberDiff line change
@@ -268,52 +268,60 @@ impl<'a> PathSource<'a> {
268268

269269
crate fn is_expected(self, res: Res) -> bool {
270270
match self {
271-
PathSource::Type => matches!(res, Res::Def(
271+
PathSource::Type => matches!(
272+
res,
273+
Res::Def(
272274
DefKind::Struct
273-
| DefKind::Union
274-
| DefKind::Enum
275-
| DefKind::Trait
276-
| DefKind::TraitAlias
277-
| DefKind::TyAlias
278-
| DefKind::AssocTy
279-
| DefKind::TyParam
280-
| DefKind::OpaqueTy
281-
| DefKind::ForeignTy,
275+
| DefKind::Union
276+
| DefKind::Enum
277+
| DefKind::Trait
278+
| DefKind::TraitAlias
279+
| DefKind::TyAlias
280+
| DefKind::AssocTy
281+
| DefKind::TyParam
282+
| DefKind::OpaqueTy
283+
| DefKind::ForeignTy,
282284
_,
283-
)
284-
| Res::PrimTy(..)
285-
| Res::SelfTy(..)),
285+
) | Res::PrimTy(..)
286+
| Res::SelfTy(..)
287+
),
286288
PathSource::Trait(AliasPossibility::No) => matches!(res, Res::Def(DefKind::Trait, _)),
287289
PathSource::Trait(AliasPossibility::Maybe) => {
288290
matches!(res, Res::Def(DefKind::Trait | DefKind::TraitAlias, _))
289291
}
290-
PathSource::Expr(..) => matches!(res, Res::Def(
292+
PathSource::Expr(..) => matches!(
293+
res,
294+
Res::Def(
291295
DefKind::Ctor(_, CtorKind::Const | CtorKind::Fn)
292-
| DefKind::Const
293-
| DefKind::Static
294-
| DefKind::Fn
295-
| DefKind::AssocFn
296-
| DefKind::AssocConst
297-
| DefKind::ConstParam,
296+
| DefKind::Const
297+
| DefKind::Static
298+
| DefKind::Fn
299+
| DefKind::AssocFn
300+
| DefKind::AssocConst
301+
| DefKind::ConstParam,
298302
_,
299-
)
300-
| Res::Local(..)
301-
| Res::SelfCtor(..)),
302-
PathSource::Pat => matches!(res, Res::Def(
303+
) | Res::Local(..)
304+
| Res::SelfCtor(..)
305+
),
306+
PathSource::Pat => matches!(
307+
res,
308+
Res::Def(
303309
DefKind::Ctor(_, CtorKind::Const) | DefKind::Const | DefKind::AssocConst,
304310
_,
305-
)
306-
| Res::SelfCtor(..)),
311+
) | Res::SelfCtor(..)
312+
),
307313
PathSource::TupleStruct(..) => res.expected_in_tuple_struct_pat(),
308-
PathSource::Struct => matches!(res, Res::Def(
314+
PathSource::Struct => matches!(
315+
res,
316+
Res::Def(
309317
DefKind::Struct
310-
| DefKind::Union
311-
| DefKind::Variant
312-
| DefKind::TyAlias
313-
| DefKind::AssocTy,
318+
| DefKind::Union
319+
| DefKind::Variant
320+
| DefKind::TyAlias
321+
| DefKind::AssocTy,
314322
_,
315-
)
316-
| Res::SelfTy(..)),
323+
) | Res::SelfTy(..)
324+
),
317325
PathSource::TraitItem(ns) => match res {
318326
Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) if ns == ValueNS => true,
319327
Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true,
@@ -2415,8 +2423,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
24152423
&mut found_traits,
24162424
&self.parent_scope,
24172425
);
2418-
search_module =
2419-
unwrap_or!(self.r.hygienic_lexical_parent(search_module, &mut ident.span), break);
2426+
let mut span_data = ident.span.data();
2427+
search_module = unwrap_or!(
2428+
self.r.hygienic_lexical_parent(search_module, &mut span_data.ctxt),
2429+
break
2430+
);
2431+
ident.span = span_data.span();
24202432
}
24212433

24222434
if let Some(prelude) = self.r.prelude {

compiler/rustc_resolve/src/lib.rs

+29-18
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ use rustc_middle::{bug, span_bug};
5050
use rustc_session::lint;
5151
use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
5252
use rustc_session::Session;
53+
use rustc_span::edition::Edition;
5354
use rustc_span::hygiene::{ExpnId, ExpnKind, MacroKind, SyntaxContext, Transparency};
5455
use rustc_span::source_map::Spanned;
5556
use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -763,10 +764,13 @@ impl<'a> NameBinding<'a> {
763764
}
764765

765766
fn is_variant(&self) -> bool {
766-
matches!(self.kind, NameBindingKind::Res(
767+
matches!(
768+
self.kind,
769+
NameBindingKind::Res(
767770
Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Variant, ..), _),
768771
_,
769-
))
772+
)
773+
)
770774
}
771775

772776
fn is_extern_crate(&self) -> bool {
@@ -1630,8 +1634,13 @@ impl<'a> Resolver<'a> {
16301634
&mut self,
16311635
scope_set: ScopeSet,
16321636
parent_scope: &ParentScope<'a>,
1633-
ident: Ident,
1634-
mut visitor: impl FnMut(&mut Self, Scope<'a>, /*use_prelude*/ bool, Ident) -> Option<T>,
1637+
ctxt: SyntaxContext,
1638+
mut visitor: impl FnMut(
1639+
&mut Self,
1640+
Scope<'a>,
1641+
/*use_prelude*/ bool,
1642+
SyntaxContext,
1643+
) -> Option<T>,
16351644
) -> Option<T> {
16361645
// General principles:
16371646
// 1. Not controlled (user-defined) names should have higher priority than controlled names
@@ -1674,7 +1683,7 @@ impl<'a> Resolver<'a> {
16741683
// 4c. Standard library prelude (de-facto closed, controlled).
16751684
// 6. Language prelude: builtin attributes (closed, controlled).
16761685

1677-
let rust_2015 = ident.span.rust_2015();
1686+
let rust_2015 = ctxt.edition() == Edition::Edition2015;
16781687
let (ns, macro_kind, is_absolute_path) = match scope_set {
16791688
ScopeSet::All(ns, _) => (ns, None, false),
16801689
ScopeSet::AbsolutePath(ns) => (ns, None, true),
@@ -1687,7 +1696,7 @@ impl<'a> Resolver<'a> {
16871696
TypeNS | ValueNS => Scope::Module(module),
16881697
MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
16891698
};
1690-
let mut ident = ident.normalize_to_macros_2_0();
1699+
let mut ctxt = ctxt.normalize_to_macros_2_0();
16911700
let mut use_prelude = !module.no_implicit_prelude;
16921701

16931702
loop {
@@ -1723,7 +1732,7 @@ impl<'a> Resolver<'a> {
17231732
};
17241733

17251734
if visit {
1726-
if let break_result @ Some(..) = visitor(self, scope, use_prelude, ident) {
1735+
if let break_result @ Some(..) = visitor(self, scope, use_prelude, ctxt) {
17271736
return break_result;
17281737
}
17291738
}
@@ -1753,17 +1762,17 @@ impl<'a> Resolver<'a> {
17531762
},
17541763
Scope::CrateRoot => match ns {
17551764
TypeNS => {
1756-
ident.span.adjust(ExpnId::root());
1765+
ctxt.adjust(ExpnId::root());
17571766
Scope::ExternPrelude
17581767
}
17591768
ValueNS | MacroNS => break,
17601769
},
17611770
Scope::Module(module) => {
17621771
use_prelude = !module.no_implicit_prelude;
1763-
match self.hygienic_lexical_parent(module, &mut ident.span) {
1772+
match self.hygienic_lexical_parent(module, &mut ctxt) {
17641773
Some(parent_module) => Scope::Module(parent_module),
17651774
None => {
1766-
ident.span.adjust(ExpnId::root());
1775+
ctxt.adjust(ExpnId::root());
17671776
match ns {
17681777
TypeNS => Scope::ExternPrelude,
17691778
ValueNS => Scope::StdLibPrelude,
@@ -1888,16 +1897,18 @@ impl<'a> Resolver<'a> {
18881897
ident = normalized_ident;
18891898
let mut poisoned = None;
18901899
loop {
1900+
let mut span_data = ident.span.data();
18911901
let opt_module = if let Some(node_id) = record_used_id {
18921902
self.hygienic_lexical_parent_with_compatibility_fallback(
18931903
module,
1894-
&mut ident.span,
1904+
&mut span_data.ctxt,
18951905
node_id,
18961906
&mut poisoned,
18971907
)
18981908
} else {
1899-
self.hygienic_lexical_parent(module, &mut ident.span)
1909+
self.hygienic_lexical_parent(module, &mut span_data.ctxt)
19001910
};
1911+
ident.span = span_data.span();
19011912
module = unwrap_or!(opt_module, break);
19021913
let adjusted_parent_scope = &ParentScope { module, ..*parent_scope };
19031914
let result = self.resolve_ident_in_module_unadjusted(
@@ -1971,10 +1982,10 @@ impl<'a> Resolver<'a> {
19711982
fn hygienic_lexical_parent(
19721983
&mut self,
19731984
module: Module<'a>,
1974-
span: &mut Span,
1985+
ctxt: &mut SyntaxContext,
19751986
) -> Option<Module<'a>> {
1976-
if !module.expansion.outer_expn_is_descendant_of(span.ctxt()) {
1977-
return Some(self.macro_def_scope(span.remove_mark()));
1987+
if !module.expansion.outer_expn_is_descendant_of(*ctxt) {
1988+
return Some(self.macro_def_scope(ctxt.remove_mark()));
19781989
}
19791990

19801991
if let ModuleKind::Block(..) = module.kind {
@@ -1987,11 +1998,11 @@ impl<'a> Resolver<'a> {
19871998
fn hygienic_lexical_parent_with_compatibility_fallback(
19881999
&mut self,
19892000
module: Module<'a>,
1990-
span: &mut Span,
2001+
ctxt: &mut SyntaxContext,
19912002
node_id: NodeId,
19922003
poisoned: &mut Option<NodeId>,
19932004
) -> Option<Module<'a>> {
1994-
if let module @ Some(..) = self.hygienic_lexical_parent(module, span) {
2005+
if let module @ Some(..) = self.hygienic_lexical_parent(module, ctxt) {
19952006
return module;
19962007
}
19972008

@@ -2016,7 +2027,7 @@ impl<'a> Resolver<'a> {
20162027
let ext = self.get_macro_by_def_id(def_id);
20172028
if ext.builtin_name.is_none()
20182029
&& ext.macro_kind() == MacroKind::Derive
2019-
&& parent.expansion.outer_expn_is_descendant_of(span.ctxt())
2030+
&& parent.expansion.outer_expn_is_descendant_of(*ctxt)
20202031
{
20212032
*poisoned = Some(node_id);
20222033
return module.parent;

compiler/rustc_resolve/src/macros.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -618,8 +618,9 @@ impl<'a> Resolver<'a> {
618618
let break_result = self.visit_scopes(
619619
scope_set,
620620
parent_scope,
621-
orig_ident,
622-
|this, scope, use_prelude, ident| {
621+
orig_ident.span.ctxt(),
622+
|this, scope, use_prelude, ctxt| {
623+
let ident = Ident::new(orig_ident.name, orig_ident.span.with_ctxt(ctxt));
623624
let ok = |res, span, arenas| {
624625
Ok((
625626
(res, ty::Visibility::Public, span, ExpnId::root()).to_name_binding(arenas),

compiler/rustc_span/src/hygiene.rs

+4
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,10 @@ impl SyntaxContext {
622622
pub fn dollar_crate_name(self) -> Symbol {
623623
HygieneData::with(|data| data.syntax_context_data[self.0 as usize].dollar_crate_name)
624624
}
625+
626+
pub fn edition(self) -> Edition {
627+
self.outer_expn_data().edition
628+
}
625629
}
626630

627631
impl fmt::Debug for SyntaxContext {

compiler/rustc_span/src/lib.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,10 @@ pub struct SpanData {
300300
}
301301

302302
impl SpanData {
303+
#[inline]
304+
pub fn span(&self) -> Span {
305+
Span::new(self.lo, self.hi, self.ctxt)
306+
}
303307
#[inline]
304308
pub fn with_lo(&self, lo: BytePos) -> Span {
305309
Span::new(lo, self.hi, self.ctxt)
@@ -468,7 +472,7 @@ impl Span {
468472

469473
/// Edition of the crate from which this span came.
470474
pub fn edition(self) -> edition::Edition {
471-
self.ctxt().outer_expn_data().edition
475+
self.ctxt().edition()
472476
}
473477

474478
#[inline]

0 commit comments

Comments
 (0)