Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::edition::Edition;
use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::{SourceMap, Spanned};
use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol, SyntaxContext, kw, sym};
use rustc_span::{BytePos, Ident, Span, Symbol, SyntaxContext, kw, sym};
use thin_vec::{ThinVec, thin_vec};
use tracing::{debug, instrument};

Expand All @@ -41,6 +41,7 @@ use crate::errors::{
ExplicitUnsafeTraits, MacroDefinedLater, MacroRulesNot, MacroSuggMovePosition,
MaybeMissingMacroRulesName,
};
use crate::hygiene::Macros20NormalizedSyntaxContext;
use crate::imports::{Import, ImportKind};
use crate::late::{DiagMetadata, PatternSource, Rib};
use crate::{
Expand Down Expand Up @@ -1163,11 +1164,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
suggestions: &mut Vec<TypoSuggestion>,
scope_set: ScopeSet<'ra>,
ps: &ParentScope<'ra>,
ctxt: SyntaxContext,
sp: Span,
filter_fn: &impl Fn(Res) -> bool,
) {
let ctxt = DUMMY_SP.with_ctxt(ctxt);
self.cm().visit_scopes(scope_set, ps, ctxt, None, |this, scope, use_prelude, _| {
let ctxt = Macros20NormalizedSyntaxContext::new(sp.ctxt());
self.cm().visit_scopes(scope_set, ps, ctxt, sp, None, |this, scope, use_prelude, _| {
match scope {
Scope::DeriveHelpers(expn_id) => {
let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
Expand Down Expand Up @@ -1269,8 +1270,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
filter_fn: &impl Fn(Res) -> bool,
) -> Option<TypoSuggestion> {
let mut suggestions = Vec::new();
let ctxt = ident.span.ctxt();
self.add_scope_set_candidates(&mut suggestions, scope_set, parent_scope, ctxt, filter_fn);
self.add_scope_set_candidates(
&mut suggestions,
scope_set,
parent_scope,
ident.span,
filter_fn,
);

// Make sure error reporting is deterministic.
suggestions.sort_by(|a, b| a.candidate.as_str().cmp(b.candidate.as_str()));
Expand Down
140 changes: 68 additions & 72 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
mut self: CmResolver<'r, 'ra, 'tcx>,
scope_set: ScopeSet<'ra>,
parent_scope: &ParentScope<'ra>,
// Location of the span is not significant, but pass a `Span` instead of `SyntaxContext`
// to avoid extracting and re-packaging the syntax context unnecessarily.
orig_ctxt: Span,
mut ctxt: Macros20NormalizedSyntaxContext,
orig_ident_span: Span,
derive_fallback_lint_id: Option<NodeId>,
mut visitor: impl FnMut(
CmResolver<'_, 'ra, 'tcx>,
Expand Down Expand Up @@ -128,7 +127,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
TypeNS | ValueNS => Scope::ModuleNonGlobs(module, None),
MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
};
let mut ctxt = Macros20NormalizedSyntaxContext::new(orig_ctxt.ctxt());
let mut use_prelude = !module.no_implicit_prelude;

loop {
Expand All @@ -153,7 +151,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
true
}
Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..) => true,
Scope::MacroUsePrelude => use_prelude || orig_ctxt.edition().is_rust_2015(),
Scope::MacroUsePrelude => use_prelude || orig_ident_span.is_rust_2015(),
Scope::BuiltinAttrs => true,
Scope::ExternPreludeItems | Scope::ExternPreludeFlags => {
use_prelude || module_and_extern_prelude || extern_prelude
Expand Down Expand Up @@ -396,9 +394,30 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
finalize: Option<Finalize>,
ignore_decl: Option<Decl<'ra>>,
ignore_import: Option<Import<'ra>>,
) -> Result<Decl<'ra>, Determinacy> {
self.resolve_ident_in_scope_set_inner(
IdentKey::new(orig_ident),
orig_ident.span,
scope_set,
parent_scope,
finalize,
ignore_decl,
ignore_import,
)
}

fn resolve_ident_in_scope_set_inner<'r>(
self: CmResolver<'r, 'ra, 'tcx>,
ident: IdentKey,
orig_ident_span: Span,
scope_set: ScopeSet<'ra>,
parent_scope: &ParentScope<'ra>,
finalize: Option<Finalize>,
ignore_decl: Option<Decl<'ra>>,
ignore_import: Option<Import<'ra>>,
) -> Result<Decl<'ra>, Determinacy> {
// Make sure `self`, `super` etc produce an error when passed to here.
if !matches!(scope_set, ScopeSet::Module(..)) && orig_ident.is_path_segment_keyword() {
if !matches!(scope_set, ScopeSet::Module(..)) && ident.name.is_path_segment_keyword() {
return Err(Determinacy::Determined);
}

Expand Down Expand Up @@ -432,13 +451,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let break_result = self.visit_scopes(
scope_set,
parent_scope,
orig_ident.span,
ident.ctxt,
orig_ident_span,
derive_fallback_lint_id,
|mut this, scope, use_prelude, ctxt| {
let ident = IdentKey { name: orig_ident.name, ctxt };
let ident = IdentKey { name: ident.name, ctxt };
let res = match this.reborrow().resolve_ident_in_scope(
ident,
orig_ident.span,
orig_ident_span,
ns,
scope,
use_prelude,
Expand Down Expand Up @@ -472,7 +492,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if let Some(&(innermost_decl, _)) = innermost_results.first() {
// Found another solution, if the first one was "weak", report an error.
if this.get_mut().maybe_push_ambiguity(
orig_ident,
ident,
orig_ident_span,
ns,
scope_set,
parent_scope,
Expand Down Expand Up @@ -695,8 +716,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Scope::StdLibPrelude => {
let mut result = Err(Determinacy::Determined);
if let Some(prelude) = self.prelude
&& let Ok(decl) = self.reborrow().resolve_ident_in_scope_set(
ident.orig(orig_ident_span.with_ctxt(*ident.ctxt)),
&& let Ok(decl) = self.reborrow().resolve_ident_in_scope_set_inner(
ident,
orig_ident_span,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and the other call to resolve_ident_in_scope_set_inner are the point of the PR.
First, here we avoid a span packing/unpacking on a good path, and second we pass a span that is actually original, rather than "slightly less massaged".

ScopeSet::Module(ns, prelude),
parent_scope,
None,
Expand Down Expand Up @@ -749,7 +771,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {

fn maybe_push_ambiguity(
&mut self,
orig_ident: Ident,
ident: IdentKey,
orig_ident_span: Span,
ns: Namespace,
scope_set: ScopeSet<'ra>,
parent_scope: &ParentScope<'ra>,
Expand All @@ -775,7 +798,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} else if innermost_res == derive_helper_compat {
Some(AmbiguityKind::DeriveHelper)
} else if res == derive_helper_compat && innermost_res != derive_helper {
span_bug!(orig_ident.span, "impossible inner resolution kind")
span_bug!(orig_ident_span, "impossible inner resolution kind")
} else if matches!(innermost_scope, Scope::MacroRules(_))
&& matches!(scope, Scope::ModuleNonGlobs(..) | Scope::ModuleGlobs(..))
&& !self.disambiguate_macro_rules_vs_modularized(innermost_decl, decl)
Expand All @@ -790,7 +813,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// we visit all macro_rules scopes (e.g. textual scope macros)
// before we visit any modules (e.g. path-based scope macros)
span_bug!(
orig_ident.span,
orig_ident_span,
"ambiguous scoped macro resolutions with path-based \
scope resolution as first candidate"
)
Expand Down Expand Up @@ -839,8 +862,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
} else {
// Turn ambiguity errors for core vs std panic into warnings.
// FIXME: Remove with lang team approval.
let is_issue_147319_hack = orig_ident.span.edition() <= Edition::Edition2024
&& matches!(orig_ident.name, sym::panic)
let is_issue_147319_hack = orig_ident_span.edition() <= Edition::Edition2024
&& matches!(ident.name, sym::panic)
&& matches!(scope, Scope::StdLibPrelude)
&& matches!(innermost_scope, Scope::ModuleGlobs(_, _))
&& ((self.is_specific_builtin_macro(res, sym::std_panic)
Expand All @@ -852,7 +875,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {

self.ambiguity_errors.push(AmbiguityError {
kind,
ident: orig_ident,
ident: ident.orig(orig_ident_span),
b1: innermost_decl,
b2: decl,
scope1: innermost_scope,
Expand Down Expand Up @@ -880,46 +903,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {

#[instrument(level = "debug", skip(self))]
pub(crate) fn resolve_ident_in_module<'r>(
self: CmResolver<'r, 'ra, 'tcx>,
module: ModuleOrUniformRoot<'ra>,
mut ident: Ident,
ns: Namespace,
parent_scope: &ParentScope<'ra>,
finalize: Option<Finalize>,
ignore_decl: Option<Decl<'ra>>,
ignore_import: Option<Import<'ra>>,
) -> Result<Decl<'ra>, Determinacy> {
let tmp_parent_scope;
let mut adjusted_parent_scope = parent_scope;
match module {
ModuleOrUniformRoot::Module(m) => {
if let Some(def) = ident.span.normalize_to_macros_2_0_and_adjust(m.expansion) {
tmp_parent_scope =
ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
adjusted_parent_scope = &tmp_parent_scope;
}
}
ModuleOrUniformRoot::ExternPrelude => {
ident.span.normalize_to_macros_2_0_and_adjust(ExpnId::root());
}
ModuleOrUniformRoot::ModuleAndExternPrelude(..) | ModuleOrUniformRoot::CurrentScope => {
// No adjustments
}
}
self.resolve_ident_in_virt_module_unadjusted(
module,
ident,
ns,
adjusted_parent_scope,
finalize,
ignore_decl,
ignore_import,
)
}

/// Attempts to resolve `ident` in namespace `ns` of `module`.
#[instrument(level = "debug", skip(self))]
fn resolve_ident_in_virt_module_unadjusted<'r>(
self: CmResolver<'r, 'ra, 'tcx>,
module: ModuleOrUniformRoot<'ra>,
ident: Ident,
Expand All @@ -930,14 +913,22 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ignore_import: Option<Import<'ra>>,
) -> Result<Decl<'ra>, Determinacy> {
match module {
ModuleOrUniformRoot::Module(module) => self.resolve_ident_in_scope_set(
ident,
ScopeSet::Module(ns, module),
parent_scope,
finalize,
ignore_decl,
ignore_import,
),
ModuleOrUniformRoot::Module(module) => {
let (ident_key, def) = IdentKey::new_adjusted(ident, module.expansion);
let adjusted_parent_scope = match def {
Some(def) => ParentScope { module: self.expn_def_scope(def), ..*parent_scope },
None => *parent_scope,
};
self.resolve_ident_in_scope_set_inner(
ident_key,
ident.span,
ScopeSet::Module(ns, module),
&adjusted_parent_scope,
finalize,
ignore_decl,
ignore_import,
)
}
ModuleOrUniformRoot::ModuleAndExternPrelude(module) => self.resolve_ident_in_scope_set(
ident,
ScopeSet::ModuleAndExternPrelude(ns, module),
Expand All @@ -950,8 +941,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if ns != TypeNS {
Err(Determined)
} else {
self.resolve_ident_in_scope_set(
ident,
self.resolve_ident_in_scope_set_inner(
IdentKey::new_adjusted(ident, ExpnId::root()).0,
ident.span,
ScopeSet::ExternPrelude,
parent_scope,
finalize,
Expand Down Expand Up @@ -1145,8 +1137,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None => return Err(ControlFlow::Continue(Undetermined)),
};
let tmp_parent_scope;
let (mut adjusted_parent_scope, mut ctxt) = (parent_scope, *ident.ctxt);
match ctxt.glob_adjust(module.expansion, glob_import.span) {
let (mut adjusted_parent_scope, mut adjusted_ident) = (parent_scope, ident);
match adjusted_ident
.ctxt
.update_unchecked(|ctxt| ctxt.glob_adjust(module.expansion, glob_import.span))
{
Some(Some(def)) => {
tmp_parent_scope =
ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
Expand All @@ -1155,8 +1150,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Some(None) => {}
None => continue,
};
let result = self.reborrow().resolve_ident_in_scope_set(
ident.orig(orig_ident_span.with_ctxt(ctxt)),
let result = self.reborrow().resolve_ident_in_scope_set_inner(
adjusted_ident,
orig_ident_span,
ScopeSet::Module(ns, module),
adjusted_parent_scope,
None,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2677,7 +2677,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
&mut names,
ScopeSet::All(ns),
parent_scope,
ctxt,
segment.ident.span.with_ctxt(ctxt),
filter_fn,
);
break;
Expand Down
22 changes: 19 additions & 3 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,12 @@ impl IdentKey {
IdentKey { name: ident.name, ctxt: Macros20NormalizedSyntaxContext::new(ident.span.ctxt()) }
}

#[inline]
fn new_adjusted(ident: Ident, expn_id: ExpnId) -> (IdentKey, Option<ExpnId>) {
let (ctxt, def) = Macros20NormalizedSyntaxContext::new_adjusted(ident.span.ctxt(), expn_id);
(IdentKey { name: ident.name, ctxt }, def)
}

#[inline]
fn with_root_ctxt(name: Symbol) -> Self {
let ctxt = Macros20NormalizedSyntaxContext::new_unchecked(SyntaxContext::root());
Expand Down Expand Up @@ -1923,7 +1929,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
&mut self,
current_trait: Option<Module<'ra>>,
parent_scope: &ParentScope<'ra>,
ctxt: Span,
sp: Span,
assoc_item: Option<(Symbol, Namespace)>,
) -> Vec<TraitCandidate> {
let mut found_traits = Vec::new();
Expand All @@ -1940,7 +1946,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}

let scope_set = ScopeSet::All(TypeNS);
self.cm().visit_scopes(scope_set, parent_scope, ctxt, None, |mut this, scope, _, _| {
let ctxt = Macros20NormalizedSyntaxContext::new(sp.ctxt());
self.cm().visit_scopes(scope_set, parent_scope, ctxt, sp, None, |mut this, scope, _, _| {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.cm().visit_scopes(scope_set, parent_scope, ctxt, sp, None, |mut this, scope, _, _| {
self.cm().visit_scopes(scope_set, parent_scope, ctxt, orig_ident_span, None, |mut this, scope, _, _| {

Using something longer here messes up the closure's formatting.

match scope {
Scope::ModuleNonGlobs(module, _) => {
this.get_mut().traits_in_module(module, assoc_item, &mut found_traits);
Expand Down Expand Up @@ -2723,7 +2730,7 @@ mod ref_mut {
}

mod hygiene {
use rustc_span::SyntaxContext;
use rustc_span::{ExpnId, SyntaxContext};

/// A newtype around `SyntaxContext` that can only keep contexts produced by
/// [SyntaxContext::normalize_to_macros_2_0].
Expand All @@ -2736,6 +2743,15 @@ mod hygiene {
Macros20NormalizedSyntaxContext(ctxt.normalize_to_macros_2_0())
}

#[inline]
pub(crate) fn new_adjusted(
mut ctxt: SyntaxContext,
expn_id: ExpnId,
) -> (Macros20NormalizedSyntaxContext, Option<ExpnId>) {
let def = ctxt.normalize_to_macros_2_0_and_adjust(expn_id);
(Macros20NormalizedSyntaxContext(ctxt), def)
}

#[inline]
pub(crate) fn new_unchecked(ctxt: SyntaxContext) -> Macros20NormalizedSyntaxContext {
debug_assert_eq!(ctxt, ctxt.normalize_to_macros_2_0());
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_span/src/hygiene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,7 @@ impl SyntaxContext {

/// Like `SyntaxContext::adjust`, but also normalizes `self` to macros 2.0.
#[inline]
pub(crate) fn normalize_to_macros_2_0_and_adjust(&mut self, expn_id: ExpnId) -> Option<ExpnId> {
pub fn normalize_to_macros_2_0_and_adjust(&mut self, expn_id: ExpnId) -> Option<ExpnId> {
HygieneData::with(|data| {
*self = data.normalize_to_macros_2_0(*self);
data.adjust(self, expn_id)
Expand Down
Loading