Auto merge of #151550 - petrochenkov:packhyg2, r=nnethercote

resolve: Replace `Macros20NormalizedIdent` with `IdentKey`

This is a continuation of https://github.com/rust-lang/rust/pull/150741 and https://github.com/rust-lang/rust/pull/150982 based on the ideas from https://github.com/rust-lang/rust/pull/151491#issuecomment-3784421866.

Before this PR `Macros20NormalizedIdent` was used as a key in various "identifier -> its resolution" maps in `rustc_resolve`.
`Macros20NormalizedIdent` is a newtype around `Ident` in which `SyntaxContext` (packed inside `Span`) is guaranteed to be normalized using `normalize_to_macros_2_0`.
This type is also used in a number of functions looking up identifiers in those maps.
`Macros20NormalizedIdent` still contains span locations, which are useless and ignored during hash map lookups and comparisons due to `Ident`'s special `PartialEq` and `Hash` impls.

This PR replaces `Macros20NormalizedIdent` with a new type called `IdentKey`, which contains only a symbol and a normalized unpacked syntax context. (E.g. `IdentKey` == `Macros20NormalizedIdent` minus span locations.)
So we avoid keeping additional data and doing some syntax context packing/unpacking.

Along with `IdentKey` you can often see `orig_ident_span: Span` being passed around.
This is an unnormalized span of the original `Ident` from which `IdentKey` was obtained.
It is not used in map keys, but it is used in a number of other scenarios:
- diagnostics
- edition checks
- `allow_unstable` checks

This is because `normalize_to_macros_2_0` normalization is lossy and the normalized spans / syntax contexts no longer contain parts of macro backtraces, while the original span contains everything.
This commit is contained in:
bors 2026-01-28 18:31:51 +00:00
commit de6d33c033
19 changed files with 495 additions and 411 deletions

View file

@ -26,7 +26,7 @@ use rustc_middle::metadata::{ModChild, Reexport};
use rustc_middle::ty::{Feed, Visibility};
use rustc_middle::{bug, span_bug};
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind};
use rustc_span::{Ident, Macros20NormalizedIdent, Span, Symbol, kw, sym};
use rustc_span::{Ident, Span, Symbol, kw, sym};
use thin_vec::ThinVec;
use tracing::debug;
@ -36,9 +36,9 @@ use crate::imports::{ImportData, ImportKind};
use crate::macros::{MacroRulesDecl, MacroRulesScope, MacroRulesScopeRef};
use crate::ref_mut::CmCell;
use crate::{
BindingKey, Decl, DeclData, DeclKind, ExternPreludeEntry, Finalize, MacroData, Module,
ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, ResolutionError, Resolver, Segment,
Used, VisResolutionError, errors,
BindingKey, Decl, DeclData, DeclKind, ExternPreludeEntry, Finalize, IdentKey, MacroData,
Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, ResolutionError, Resolver,
Segment, Used, VisResolutionError, errors,
};
type Res = def::Res<NodeId>;
@ -48,12 +48,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
/// and report an error in case of a collision.
pub(crate) fn plant_decl_into_local_module(
&mut self,
ident: Macros20NormalizedIdent,
ident: IdentKey,
orig_ident_span: Span,
ns: Namespace,
decl: Decl<'ra>,
) {
if let Err(old_decl) = self.try_plant_decl_into_local_module(ident, ns, decl, false) {
self.report_conflict(ident.0, ns, old_decl, decl);
if let Err(old_decl) =
self.try_plant_decl_into_local_module(ident, orig_ident_span, ns, decl, false)
{
self.report_conflict(ident, ns, old_decl, decl);
}
}
@ -61,7 +64,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
fn define_local(
&mut self,
parent: Module<'ra>,
ident: Ident,
orig_ident: Ident,
ns: Namespace,
res: Res,
vis: Visibility,
@ -69,15 +72,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
expn_id: LocalExpnId,
) {
let decl = self.arenas.new_def_decl(res, vis.to_def_id(), span, expn_id, Some(parent));
let ident = Macros20NormalizedIdent::new(ident);
self.plant_decl_into_local_module(ident, ns, decl);
let ident = IdentKey::new(orig_ident);
self.plant_decl_into_local_module(ident, orig_ident.span, ns, decl);
}
/// Create a name definitinon from the given components, and put it into the extern module.
fn define_extern(
&self,
parent: Module<'ra>,
ident: Macros20NormalizedIdent,
ident: IdentKey,
orig_ident_span: Span,
ns: Namespace,
child_index: usize,
res: Res,
@ -102,7 +106,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let key =
BindingKey::new_disambiguated(ident, ns, || (child_index + 1).try_into().unwrap()); // 0 indicates no underscore
if self
.resolution_or_default(parent, key)
.resolution_or_default(parent, key, orig_ident_span)
.borrow_mut_unchecked()
.non_glob_decl
.replace(decl)
@ -279,8 +283,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
.unwrap_or_else(|| res.def_id()),
)
};
let ModChild { ident, res, vis, ref reexport_chain } = *child;
let ident = Macros20NormalizedIdent::new(ident);
let ModChild { ident: orig_ident, res, vis, ref reexport_chain } = *child;
let ident = IdentKey::new(orig_ident);
let span = child_span(self, reexport_chain, res);
let res = res.expect_non_local();
let expansion = parent_scope.expansion;
@ -293,7 +297,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// Record primary definitions.
let define_extern = |ns| {
self.define_extern(parent, ident, ns, child_index, res, vis, span, expansion, ambig)
self.define_extern(
parent,
ident,
orig_ident.span,
ns,
child_index,
res,
vis,
span,
expansion,
ambig,
)
};
match res {
Res::Def(
@ -533,8 +548,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
if target.name != kw::Underscore {
self.r.per_ns(|this, ns| {
if !type_ns_only || ns == TypeNS {
let key = BindingKey::new(Macros20NormalizedIdent::new(target), ns);
this.resolution_or_default(current_module, key)
let key = BindingKey::new(IdentKey::new(target), ns);
this.resolution_or_default(current_module, key, target.span)
.borrow_mut(this)
.single_imports
.insert(import);
@ -974,7 +989,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
&mut self,
orig_name: Option<Symbol>,
item: &Item,
ident: Ident,
orig_ident: Ident,
local_def_id: LocalDefId,
vis: Visibility,
) {
@ -983,7 +998,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
let parent = parent_scope.module;
let expansion = parent_scope.expansion;
let (used, module, decl) = if orig_name.is_none() && ident.name == kw::SelfLower {
let (used, module, decl) = if orig_name.is_none() && orig_ident.name == kw::SelfLower {
self.r.dcx().emit_err(errors::ExternCrateSelfRequiresRenaming { span: sp });
return;
} else if orig_name == Some(kw::SelfLower) {
@ -1008,7 +1023,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
})
.unwrap_or((true, None, self.r.dummy_decl));
let import = self.r.arenas.alloc_import(ImportData {
kind: ImportKind::ExternCrate { source: orig_name, target: ident, id: item.id },
kind: ImportKind::ExternCrate { source: orig_name, target: orig_ident, id: item.id },
root_id: item.id,
parent_scope,
imported_module: CmCell::new(module),
@ -1026,7 +1041,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
}
self.r.potentially_unused_imports.push(import);
let import_decl = self.r.new_import_decl(decl, import);
let ident = Macros20NormalizedIdent::new(ident);
let ident = IdentKey::new(orig_ident);
if ident.name != kw::Underscore && parent == self.r.graph_root {
// FIXME: this error is technically unnecessary now when extern prelude is split into
// two scopes, remove it with lang team approval.
@ -1045,20 +1060,20 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
Entry::Occupied(mut occupied) => {
let entry = occupied.get_mut();
if entry.item_decl.is_some() {
let msg = format!("extern crate `{ident}` already in extern prelude");
let msg = format!("extern crate `{orig_ident}` already in extern prelude");
self.r.tcx.dcx().span_delayed_bug(item.span, msg);
} else {
entry.item_decl = Some((import_decl, orig_name.is_some()));
entry.item_decl = Some((import_decl, orig_ident.span, orig_name.is_some()));
}
entry
}
Entry::Vacant(vacant) => vacant.insert(ExternPreludeEntry {
item_decl: Some((import_decl, true)),
item_decl: Some((import_decl, orig_ident.span, true)),
flag_decl: None,
}),
};
}
self.r.plant_decl_into_local_module(ident, TypeNS, import_decl);
self.r.plant_decl_into_local_module(ident, orig_ident.span, TypeNS, import_decl);
}
/// Constructs the reduced graph for one foreign item.
@ -1159,7 +1174,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
if let Some(span) = import_all {
let import = macro_use_import(self, span, false);
self.r.potentially_unused_imports.push(import);
module.for_each_child_mut(self, |this, ident, ns, binding| {
module.for_each_child_mut(self, |this, ident, _, ns, binding| {
if ns == MacroNS {
let import =
if this.r.is_accessible_from(binding.vis(), this.parent_scope.module) {
@ -1270,7 +1285,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
let expansion = parent_scope.expansion;
let feed = self.r.feed(item.id);
let def_id = feed.key();
let (res, ident, span, macro_rules) = match &item.kind {
let (res, orig_ident, span, macro_rules) = match &item.kind {
ItemKind::MacroDef(ident, def) => {
(self.res(def_id), *ident, item.span, def.macro_rules)
}
@ -1293,8 +1308,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
self.r.local_macro_def_scopes.insert(def_id, parent_scope.module);
if macro_rules {
let ident = Macros20NormalizedIdent::new(ident);
self.r.macro_names.insert(ident.0);
let ident = IdentKey::new(orig_ident);
self.r.macro_names.insert(ident);
let is_macro_export = ast::attr::contains_name(&item.attrs, sym::macro_export);
let vis = if is_macro_export {
Visibility::Public
@ -1326,10 +1341,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
});
self.r.import_use_map.insert(import, Used::Other);
let import_decl = self.r.new_import_decl(decl, import);
self.r.plant_decl_into_local_module(ident, MacroNS, import_decl);
self.r.plant_decl_into_local_module(ident, orig_ident.span, MacroNS, import_decl);
} else {
self.r.check_reserved_macro_name(ident.0, res);
self.insert_unused_macro(ident.0, def_id, item.id);
self.r.check_reserved_macro_name(ident.name, orig_ident.span, res);
self.insert_unused_macro(orig_ident, def_id, item.id);
}
self.r.feed_visibility(feed, vis);
let scope = self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Def(
@ -1337,6 +1352,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
parent_macro_rules_scope: parent_scope.macro_rules,
decl,
ident,
orig_ident_span: orig_ident.span,
}),
));
self.r.macro_rules_scopes.insert(def_id, scope);
@ -1352,9 +1368,9 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
_ => self.resolve_visibility(&item.vis),
};
if !vis.is_public() {
self.insert_unused_macro(ident, def_id, item.id);
self.insert_unused_macro(orig_ident, def_id, item.id);
}
self.r.define_local(module, ident, MacroNS, res, vis, span, expansion);
self.r.define_local(module, orig_ident, MacroNS, res, vis, span, expansion);
self.r.feed_visibility(feed, vis);
self.parent_scope.macro_rules
}
@ -1496,7 +1512,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
{
// Don't add underscore names, they cannot be looked up anyway.
let impl_def_id = self.r.tcx.local_parent(local_def_id);
let key = BindingKey::new(Macros20NormalizedIdent::new(ident), ns);
let key = BindingKey::new(IdentKey::new(ident), ns);
self.r.impl_binding_keys.entry(impl_def_id).or_default().insert(key);
}

View file

@ -33,10 +33,10 @@ use rustc_session::lint::BuiltinLintDiag;
use rustc_session::lint::builtin::{
MACRO_USE_EXTERN_CRATE, UNUSED_EXTERN_CRATES, UNUSED_IMPORTS, UNUSED_QUALIFICATIONS,
};
use rustc_span::{DUMMY_SP, Ident, Macros20NormalizedIdent, Span, kw};
use rustc_span::{DUMMY_SP, Ident, Span, kw};
use crate::imports::{Import, ImportKind};
use crate::{DeclKind, LateDecl, Resolver, module_to_string};
use crate::{DeclKind, IdentKey, LateDecl, Resolver, module_to_string};
struct UnusedImport {
use_tree: ast::UseTree,
@ -203,7 +203,7 @@ impl<'a, 'ra, 'tcx> UnusedImportCheckVisitor<'a, 'ra, 'tcx> {
if self
.r
.extern_prelude
.get(&Macros20NormalizedIdent::new(extern_crate.ident))
.get(&IdentKey::new(extern_crate.ident))
.is_none_or(|entry| entry.introduced_by_item())
{
continue;

View file

@ -32,9 +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, Macros20NormalizedIdent, Span, Symbol, SyntaxContext, kw, sym,
};
use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol, SyntaxContext, kw, sym};
use thin_vec::{ThinVec, thin_vec};
use tracing::{debug, instrument};
@ -47,10 +45,10 @@ use crate::imports::{Import, ImportKind};
use crate::late::{DiagMetadata, PatternSource, Rib};
use crate::{
AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingError, BindingKey, Decl, DeclKind,
Finalize, ForwardGenericParamBanReason, HasGenericParams, LateDecl, MacroRulesScope, Module,
ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, ResolutionError,
Resolver, Scope, ScopeSet, Segment, UseError, Used, VisResolutionError, errors as errs,
path_names_to_string,
Finalize, ForwardGenericParamBanReason, HasGenericParams, IdentKey, LateDecl, MacroRulesScope,
Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError,
ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used, VisResolutionError,
errors as errs, path_names_to_string,
};
type Res = def::Res<ast::NodeId>;
@ -81,24 +79,14 @@ pub(crate) struct TypoSuggestion {
}
impl TypoSuggestion {
pub(crate) fn typo_from_ident(ident: Ident, res: Res) -> TypoSuggestion {
Self {
candidate: ident.name,
span: Some(ident.span),
res,
target: SuggestionTarget::SimilarlyNamed,
}
pub(crate) fn new(candidate: Symbol, span: Span, res: Res) -> TypoSuggestion {
Self { candidate, span: Some(span), res, target: SuggestionTarget::SimilarlyNamed }
}
pub(crate) fn typo_from_name(candidate: Symbol, res: Res) -> TypoSuggestion {
Self { candidate, span: None, res, target: SuggestionTarget::SimilarlyNamed }
}
pub(crate) fn single_item_from_ident(ident: Ident, res: Res) -> TypoSuggestion {
Self {
candidate: ident.name,
span: Some(ident.span),
res,
target: SuggestionTarget::SingleItem,
}
pub(crate) fn single_item(candidate: Symbol, span: Span, res: Res) -> TypoSuggestion {
Self { candidate, span: Some(span), res, target: SuggestionTarget::SingleItem }
}
}
@ -212,7 +200,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
pub(crate) fn report_conflict(
&mut self,
ident: Ident,
ident: IdentKey,
ns: Namespace,
old_binding: Decl<'ra>,
new_binding: Decl<'ra>,
@ -324,10 +312,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// Check if the target of the use for both bindings is the same.
let duplicate = new_binding.res().opt_def_id() == old_binding.res().opt_def_id();
let has_dummy_span = new_binding.span.is_dummy() || old_binding.span.is_dummy();
let from_item = self
.extern_prelude
.get(&Macros20NormalizedIdent::new(ident))
.is_none_or(|entry| entry.introduced_by_item());
let from_item =
self.extern_prelude.get(&ident).is_none_or(|entry| entry.introduced_by_item());
// Only suggest removing an import if both bindings are to the same def, if both spans
// aren't dummy spans. Further, if both bindings are imports, then the ident must have
// been introduced by an item.
@ -531,10 +517,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
filter_fn: &impl Fn(Res) -> bool,
ctxt: Option<SyntaxContext>,
) {
module.for_each_child(self, |_this, ident, _ns, binding| {
module.for_each_child(self, |_this, ident, orig_ident_span, _ns, binding| {
let res = binding.res();
if filter_fn(res) && ctxt.is_none_or(|ctxt| ctxt == ident.span.ctxt()) {
names.push(TypoSuggestion::typo_from_ident(ident.0, res));
if filter_fn(res) && ctxt.is_none_or(|ctxt| ctxt == *ident.ctxt) {
names.push(TypoSuggestion::new(ident.name, orig_ident_span, res));
}
});
}
@ -1187,11 +1173,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
if filter_fn(res) {
suggestions.extend(
this.helper_attrs
.get(&expn_id)
.into_iter()
.flatten()
.map(|(ident, _)| TypoSuggestion::typo_from_ident(ident.0, res)),
this.helper_attrs.get(&expn_id).into_iter().flatten().map(
|&(ident, orig_ident_span, _)| {
TypoSuggestion::new(ident.name, orig_ident_span, res)
},
),
);
}
}
@ -1202,8 +1188,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if let MacroRulesScope::Def(macro_rules_def) = macro_rules_scope.get() {
let res = macro_rules_def.decl.res();
if filter_fn(res) {
suggestions
.push(TypoSuggestion::typo_from_ident(macro_rules_def.ident.0, res))
suggestions.push(TypoSuggestion::new(
macro_rules_def.ident.name,
macro_rules_def.orig_ident_span,
res,
))
}
}
}
@ -1233,9 +1222,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
Scope::ExternPreludeItems => {
// Add idents from both item and flag scopes.
suggestions.extend(this.extern_prelude.keys().filter_map(|ident| {
suggestions.extend(this.extern_prelude.iter().filter_map(|(ident, entry)| {
let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id());
filter_fn(res).then_some(TypoSuggestion::typo_from_ident(ident.0, res))
filter_fn(res).then_some(TypoSuggestion::new(ident.name, entry.span(), res))
}));
}
Scope::ExternPreludeFlags => {}
@ -1244,7 +1233,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
suggestions.extend(
this.registered_tools
.iter()
.map(|ident| TypoSuggestion::typo_from_ident(*ident, res)),
.map(|ident| TypoSuggestion::new(ident.name, ident.span, res)),
);
}
Scope::StdLibPrelude => {
@ -1329,7 +1318,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
{
let in_module_is_extern = !in_module.def_id().is_local();
in_module.for_each_child(self, |this, ident, ns, name_binding| {
in_module.for_each_child(self, |this, ident, orig_ident_span, ns, name_binding| {
// Avoid non-importable candidates.
if name_binding.is_assoc_item()
&& !this.tcx.features().import_trait_associated_functions()
@ -1382,7 +1371,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if ident.name == lookup_ident.name
&& ns == namespace
&& in_module != parent_scope.module
&& !ident.span.normalize_to_macros_2_0().from_expansion()
&& ident.ctxt.is_root()
&& filter_fn(res)
{
// create the path
@ -1395,7 +1384,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
};
segms.append(&mut path_segments.clone());
segms.push(ast::PathSegment::from_ident(ident.0));
segms.push(ast::PathSegment::from_ident(ident.orig(orig_ident_span)));
let path = Path { span: name_binding.span, segments: segms, tokens: None };
if child_accessible
@ -1468,7 +1457,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if let Some(def_id) = name_binding.res().module_like_def_id() {
// form the path
let mut path_segments = path_segments.clone();
path_segments.push(ast::PathSegment::from_ident(ident.0));
path_segments.push(ast::PathSegment::from_ident(ident.orig(orig_ident_span)));
let alias_import = if let DeclKind::Import { import, .. } = name_binding.kind
&& let ImportKind::ExternCrate { source: Some(_), .. } = import.kind
@ -1557,8 +1546,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
);
if lookup_ident.span.at_least_rust_2018() {
for &ident in self.extern_prelude.keys() {
if ident.span.from_expansion() {
for (ident, entry) in &self.extern_prelude {
if entry.span().from_expansion() {
// Idents are adjusted to the root context before being
// resolved in the extern prelude, so reporting this to the
// user is no help. This skips the injected
@ -1582,7 +1571,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
self.resolutions(parent_scope.module).borrow().iter().any(
|(key, name_resolution)| {
if key.ns == TypeNS
&& key.ident == ident
&& key.ident == *ident
&& let Some(decl) = name_resolution.borrow().best_decl()
{
match decl.res() {
@ -1601,7 +1590,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if needs_disambiguation {
crate_path.push(ast::PathSegment::path_root(rustc_span::DUMMY_SP));
}
crate_path.push(ast::PathSegment::from_ident(ident.0));
crate_path.push(ast::PathSegment::from_ident(ident.orig(entry.span())));
suggestions.extend(self.lookup_import_candidates_from_module(
lookup_ident,
@ -1777,7 +1766,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
return;
}
if self.macro_names.contains(&ident.normalize_to_macros_2_0()) {
if self.macro_names.contains(&IdentKey::new(ident)) {
err.subdiagnostic(AddedMacroUse);
return;
}
@ -2007,8 +1996,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
matches!(scope2, Scope::ExternPreludeFlags)
&& self
.extern_prelude
.get(&Macros20NormalizedIdent::new(ident))
.is_some_and(|entry| entry.item_decl.map(|(b, _)| b) == Some(b1))
.get(&IdentKey::new(ident))
.is_some_and(|entry| entry.item_decl.map(|(b, ..)| b) == Some(b1))
};
let (b1, b2, scope1, scope2, swapped) = if b2.span.is_dummy() && !b1.span.is_dummy() {
// We have to print the span-less alternative first, otherwise formatting looks bad.
@ -2914,7 +2903,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
return None;
}
let binding_key = BindingKey::new(Macros20NormalizedIdent::new(ident), MacroNS);
let binding_key = BindingKey::new(IdentKey::new(ident), MacroNS);
let binding = self.resolution(crate_module, binding_key)?.binding()?;
let Res::Def(DefKind::Macro(kinds), _) = binding.res() else {
return None;

View file

@ -601,7 +601,7 @@ pub(crate) struct ProcMacroDeriveResolutionFallback {
#[label]
pub span: Span,
pub ns_descr: &'static str,
pub ident: Ident,
pub ident: Symbol,
}
#[derive(LintDiagnostic)]
@ -1151,7 +1151,7 @@ pub(crate) struct CannotUseThroughAnImport {
pub(crate) struct NameReservedInAttributeNamespace {
#[primary_span]
pub(crate) span: Span,
pub(crate) ident: Ident,
pub(crate) ident: Symbol,
}
#[derive(Diagnostic)]

View file

@ -10,11 +10,12 @@ use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK;
use rustc_session::parse::feature_err;
use rustc_span::edition::Edition;
use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext};
use rustc_span::{Ident, Macros20NormalizedIdent, Span, kw, sym};
use rustc_span::{Ident, Span, kw, sym};
use smallvec::SmallVec;
use tracing::{debug, instrument};
use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
use crate::hygiene::Macros20NormalizedSyntaxContext;
use crate::imports::{Import, NameResolution};
use crate::late::{
ConstantHasGenerics, DiagMetadata, NoConstantGenericsReason, PathSource, Rib, RibKind,
@ -22,7 +23,7 @@ use crate::late::{
use crate::macros::{MacroRulesScope, sub_namespace_match};
use crate::{
AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingKey, CmResolver, Decl, DeclKind,
Determinacy, Finalize, ImportKind, LateDecl, Module, ModuleKind, ModuleOrUniformRoot,
Determinacy, Finalize, IdentKey, ImportKind, LateDecl, Module, ModuleKind, ModuleOrUniformRoot,
ParentScope, PathResult, PrivacyError, Res, ResolutionError, Resolver, Scope, ScopeSet,
Segment, Stage, Used, errors,
};
@ -61,7 +62,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
CmResolver<'_, 'ra, 'tcx>,
Scope<'ra>,
UsePrelude,
Span,
Macros20NormalizedSyntaxContext,
) -> ControlFlow<T>,
) -> Option<T> {
// General principles:
@ -127,7 +128,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
TypeNS | ValueNS => Scope::ModuleNonGlobs(module, None),
MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
};
let mut ctxt = orig_ctxt.normalize_to_macros_2_0();
let mut ctxt = Macros20NormalizedSyntaxContext::new(orig_ctxt.ctxt());
let mut use_prelude = !module.no_implicit_prelude;
loop {
@ -198,7 +199,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Scope::ModuleGlobs(..) if module_only => break,
Scope::ModuleGlobs(..) if module_and_extern_prelude => match ns {
TypeNS => {
ctxt.adjust(ExpnId::root());
ctxt.update_unchecked(|ctxt| ctxt.adjust(ExpnId::root()));
Scope::ExternPreludeItems
}
ValueNS | MacroNS => break,
@ -210,7 +211,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Scope::ModuleNonGlobs(parent_module, lint_id.or(prev_lint_id))
}
None => {
ctxt.adjust(ExpnId::root());
ctxt.update_unchecked(|ctxt| ctxt.adjust(ExpnId::root()));
match ns {
TypeNS => Scope::ExternPreludeItems,
ValueNS => Scope::StdLibPrelude,
@ -240,12 +241,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
fn hygienic_lexical_parent(
&self,
module: Module<'ra>,
span: &mut Span,
ctxt: &mut Macros20NormalizedSyntaxContext,
derive_fallback_lint_id: Option<NodeId>,
) -> Option<(Module<'ra>, Option<NodeId>)> {
let ctxt = span.ctxt();
if !module.expansion.outer_expn_is_descendant_of(ctxt) {
return Some((self.expn_def_scope(span.remove_mark()), None));
if !module.expansion.outer_expn_is_descendant_of(**ctxt) {
let expn_id = ctxt.update_unchecked(|ctxt| ctxt.remove_mark());
return Some((self.expn_def_scope(expn_id), None));
}
if let ModuleKind::Block = module.kind {
@ -275,7 +276,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let ext = &self.get_macro_by_def_id(def_id).ext;
if ext.builtin_name.is_none()
&& ext.macro_kinds() == MacroKinds::DERIVE
&& parent.expansion.outer_expn_is_descendant_of(ctxt)
&& parent.expansion.outer_expn_is_descendant_of(**ctxt)
{
return Some((parent, derive_fallback_lint_id));
}
@ -439,11 +440,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
orig_ident.span,
derive_fallback_lint_id,
|mut this, scope, use_prelude, ctxt| {
let ident = Ident::new(orig_ident.name, ctxt);
// The passed `ctxt` is already normalized, so avoid expensive double normalization.
let ident = Macros20NormalizedIdent(ident);
let ident = IdentKey { name: orig_ident.name, ctxt };
let res = match this.reborrow().resolve_ident_in_scope(
ident,
orig_ident.span,
ns,
scope,
use_prelude,
@ -515,7 +515,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
fn resolve_ident_in_scope<'r>(
mut self: CmResolver<'r, 'ra, 'tcx>,
ident: Macros20NormalizedIdent,
ident: IdentKey,
orig_ident_span: Span,
ns: Namespace,
scope: Scope<'ra>,
use_prelude: UsePrelude,
@ -531,7 +532,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if let Some(decl) = self
.helper_attrs
.get(&expn_id)
.and_then(|attrs| attrs.iter().rfind(|(i, _)| ident == *i).map(|(_, d)| *d))
.and_then(|attrs| attrs.iter().rfind(|(i, ..)| ident == *i).map(|(.., d)| *d))
{
Ok(decl)
} else {
@ -587,6 +588,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let decl = self.reborrow().resolve_ident_in_module_non_globs_unadjusted(
module,
ident,
orig_ident_span,
ns,
adjusted_parent_scope,
if matches!(scope_set, ScopeSet::Module(..)) {
@ -604,11 +606,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
self.get_mut().lint_buffer.buffer_lint(
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
lint_id,
ident.span,
orig_ident_span,
errors::ProcMacroDeriveResolutionFallback {
span: ident.span,
span: orig_ident_span,
ns_descr: ns.descr(),
ident: ident.0,
ident: ident.name,
},
);
}
@ -637,6 +639,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let binding = self.reborrow().resolve_ident_in_module_globs_unadjusted(
module,
ident,
orig_ident_span,
ns,
adjusted_parent_scope,
if matches!(scope_set, ScopeSet::Module(..)) {
@ -654,11 +657,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
self.get_mut().lint_buffer.buffer_lint(
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
lint_id,
ident.span,
orig_ident_span,
errors::ProcMacroDeriveResolutionFallback {
span: ident.span,
span: orig_ident_span,
ns_descr: ns.descr(),
ident: ident.0,
ident: ident.name,
},
);
}
@ -683,7 +686,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None => Err(Determinacy::Determined),
},
Scope::ExternPreludeItems => {
match self.reborrow().extern_prelude_get_item(ident, finalize.is_some()) {
match self.reborrow().extern_prelude_get_item(
ident,
orig_ident_span,
finalize.is_some(),
) {
Some(decl) => Ok(decl),
None => Err(Determinacy::determined(
self.graph_root.unexpanded_invocations.borrow().is_empty(),
@ -691,7 +698,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
}
Scope::ExternPreludeFlags => {
match self.extern_prelude_get_flag(ident, finalize.is_some()) {
match self.extern_prelude_get_flag(ident, orig_ident_span, finalize.is_some()) {
Some(decl) => Ok(decl),
None => Err(Determinacy::Determined),
}
@ -704,7 +711,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let mut result = Err(Determinacy::Determined);
if let Some(prelude) = self.prelude
&& let Ok(decl) = self.reborrow().resolve_ident_in_scope_set(
ident.0,
ident.orig(orig_ident_span.with_ctxt(*ident.ctxt)),
ScopeSet::Module(ns, prelude),
parent_scope,
None,
@ -723,26 +730,26 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Some(decl) => {
if matches!(ident.name, sym::f16)
&& !self.tcx.features().f16()
&& !ident.span.allows_unstable(sym::f16)
&& !orig_ident_span.allows_unstable(sym::f16)
&& finalize.is_some()
{
feature_err(
self.tcx.sess,
sym::f16,
ident.span,
orig_ident_span,
"the type `f16` is unstable",
)
.emit();
}
if matches!(ident.name, sym::f128)
&& !self.tcx.features().f128()
&& !ident.span.allows_unstable(sym::f128)
&& !orig_ident_span.allows_unstable(sym::f128)
&& finalize.is_some()
{
feature_err(
self.tcx.sess,
sym::f128,
ident.span,
orig_ident_span,
"the type `f128` is unstable",
)
.emit();
@ -1001,7 +1008,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
fn resolve_ident_in_module_non_globs_unadjusted<'r>(
mut self: CmResolver<'r, 'ra, 'tcx>,
module: Module<'ra>,
ident: Macros20NormalizedIdent,
ident: IdentKey,
orig_ident_span: Span,
ns: Namespace,
parent_scope: &ParentScope<'ra>,
shadowing: Shadowing,
@ -1016,7 +1024,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// doesn't need to be mutable. It will fail when there is a cycle of imports, and without
// the exclusive access infinite recursion will crash the compiler with stack overflow.
let resolution = &*self
.resolution_or_default(module, key)
.resolution_or_default(module, key, orig_ident_span)
.try_borrow_mut_unchecked()
.map_err(|_| ControlFlow::Continue(Determined))?;
@ -1024,7 +1032,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if let Some(finalize) = finalize {
return self.get_mut().finalize_module_binding(
ident.0,
ident,
orig_ident_span,
binding,
parent_scope,
module,
@ -1064,7 +1073,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
fn resolve_ident_in_module_globs_unadjusted<'r>(
mut self: CmResolver<'r, 'ra, 'tcx>,
module: Module<'ra>,
ident: Macros20NormalizedIdent,
ident: IdentKey,
orig_ident_span: Span,
ns: Namespace,
parent_scope: &ParentScope<'ra>,
shadowing: Shadowing,
@ -1077,7 +1087,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// doesn't need to be mutable. It will fail when there is a cycle of imports, and without
// the exclusive access infinite recursion will crash the compiler with stack overflow.
let resolution = &*self
.resolution_or_default(module, key)
.resolution_or_default(module, key, orig_ident_span)
.try_borrow_mut_unchecked()
.map_err(|_| ControlFlow::Continue(Determined))?;
@ -1085,7 +1095,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if let Some(finalize) = finalize {
return self.get_mut().finalize_module_binding(
ident.0,
ident,
orig_ident_span,
binding,
parent_scope,
module,
@ -1154,8 +1165,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None => return Err(ControlFlow::Continue(Undetermined)),
};
let tmp_parent_scope;
let (mut adjusted_parent_scope, mut ident) = (parent_scope, ident);
match ident.0.span.glob_adjust(module.expansion, glob_import.span) {
let (mut adjusted_parent_scope, mut ctxt) = (parent_scope, *ident.ctxt);
match ctxt.glob_adjust(module.expansion, glob_import.span) {
Some(Some(def)) => {
tmp_parent_scope =
ParentScope { module: self.expn_def_scope(def), ..*parent_scope };
@ -1165,7 +1176,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
None => continue,
};
let result = self.reborrow().resolve_ident_in_scope_set(
ident.0,
ident.orig(orig_ident_span.with_ctxt(ctxt)),
ScopeSet::Module(ns, module),
adjusted_parent_scope,
None,
@ -1191,7 +1202,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
fn finalize_module_binding(
&mut self,
ident: Ident,
ident: IdentKey,
orig_ident_span: Span,
binding: Option<Decl<'ra>>,
parent_scope: &ParentScope<'ra>,
module: Module<'ra>,
@ -1204,6 +1216,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
return Err(ControlFlow::Continue(Determined));
};
let ident = ident.orig(orig_ident_span);
if !self.is_accessible_from(binding.vis(), parent_scope.module) {
if report_private {
self.privacy_errors.push(PrivacyError {

View file

@ -20,7 +20,7 @@ use rustc_session::lint::builtin::{
use rustc_session::parse::feature_err;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::hygiene::LocalExpnId;
use rustc_span::{Ident, Macros20NormalizedIdent, Span, Symbol, kw, sym};
use rustc_span::{Ident, Span, Symbol, kw, sym};
use tracing::debug;
use crate::Namespace::{self, *};
@ -33,8 +33,8 @@ use crate::errors::{
use crate::ref_mut::CmCell;
use crate::{
AmbiguityError, BindingKey, CmResolver, Decl, DeclData, DeclKind, Determinacy, Finalize,
ImportSuggestion, Module, ModuleOrUniformRoot, ParentScope, PathResult, PerNS, ResolutionError,
Resolver, ScopeSet, Segment, Used, module_to_string, names_to_string,
IdentKey, ImportSuggestion, Module, ModuleOrUniformRoot, ParentScope, PathResult, PerNS,
ResolutionError, Resolver, ScopeSet, Segment, Used, module_to_string, names_to_string,
};
type Res = def::Res<NodeId>;
@ -239,18 +239,23 @@ impl<'ra> ImportData<'ra> {
}
/// Records information about the resolution of a name in a namespace of a module.
#[derive(Clone, Default, Debug)]
#[derive(Clone, Debug)]
pub(crate) struct NameResolution<'ra> {
/// Single imports that may define the name in the namespace.
/// Imports are arena-allocated, so it's ok to use pointers as keys.
pub single_imports: FxIndexSet<Import<'ra>>,
/// The non-glob declaration for this name, if it is known to exist.
pub non_glob_decl: Option<Decl<'ra>>,
pub non_glob_decl: Option<Decl<'ra>> = None,
/// The glob declaration for this name, if it is known to exist.
pub glob_decl: Option<Decl<'ra>>,
pub glob_decl: Option<Decl<'ra>> = None,
pub orig_ident_span: Span,
}
impl<'ra> NameResolution<'ra> {
pub(crate) fn new(orig_ident_span: Span) -> Self {
NameResolution { single_imports: FxIndexSet::default(), orig_ident_span, .. }
}
/// Returns the binding for the name if it is known or None if it not known.
pub(crate) fn binding(&self) -> Option<Decl<'ra>> {
self.best_decl().and_then(|binding| {
@ -417,14 +422,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
/// and return existing declaration if there is a collision.
pub(crate) fn try_plant_decl_into_local_module(
&mut self,
ident: Macros20NormalizedIdent,
ident: IdentKey,
orig_ident_span: Span,
ns: Namespace,
decl: Decl<'ra>,
warn_ambiguity: bool,
) -> Result<(), Decl<'ra>> {
let module = decl.parent_module.unwrap();
let res = decl.res();
self.check_reserved_macro_name(ident.0, res);
self.check_reserved_macro_name(ident.name, orig_ident_span, res);
// Even if underscore names cannot be looked up, we still need to add them to modules,
// because they can be fetched by glob imports from those modules, and bring traits
// into scope both directly and through glob imports.
@ -432,46 +438,52 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
module.underscore_disambiguator.update_unchecked(|d| d + 1);
module.underscore_disambiguator.get()
});
self.update_local_resolution(module, key, warn_ambiguity, |this, resolution| {
if let Some(old_decl) = resolution.best_decl() {
assert_ne!(decl, old_decl);
assert!(!decl.warn_ambiguity.get());
if res == Res::Err && old_decl.res() != Res::Err {
// Do not override real declarations with `Res::Err`s from error recovery.
return Ok(());
}
match (old_decl.is_glob_import(), decl.is_glob_import()) {
(true, true) => {
resolution.glob_decl =
Some(this.select_glob_decl(old_decl, decl, warn_ambiguity));
self.update_local_resolution(
module,
key,
orig_ident_span,
warn_ambiguity,
|this, resolution| {
if let Some(old_decl) = resolution.best_decl() {
assert_ne!(decl, old_decl);
assert!(!decl.warn_ambiguity.get());
if res == Res::Err && old_decl.res() != Res::Err {
// Do not override real declarations with `Res::Err`s from error recovery.
return Ok(());
}
(old_glob @ true, false) | (old_glob @ false, true) => {
let (glob_decl, non_glob_decl) =
if old_glob { (old_decl, decl) } else { (decl, old_decl) };
resolution.non_glob_decl = Some(non_glob_decl);
if let Some(old_glob_decl) = resolution.glob_decl
&& old_glob_decl != glob_decl
{
match (old_decl.is_glob_import(), decl.is_glob_import()) {
(true, true) => {
resolution.glob_decl =
Some(this.select_glob_decl(old_glob_decl, glob_decl, false));
} else {
resolution.glob_decl = Some(glob_decl);
Some(this.select_glob_decl(old_decl, decl, warn_ambiguity));
}
(old_glob @ true, false) | (old_glob @ false, true) => {
let (glob_decl, non_glob_decl) =
if old_glob { (old_decl, decl) } else { (decl, old_decl) };
resolution.non_glob_decl = Some(non_glob_decl);
if let Some(old_glob_decl) = resolution.glob_decl
&& old_glob_decl != glob_decl
{
resolution.glob_decl =
Some(this.select_glob_decl(old_glob_decl, glob_decl, false));
} else {
resolution.glob_decl = Some(glob_decl);
}
}
(false, false) => {
return Err(old_decl);
}
}
(false, false) => {
return Err(old_decl);
} else {
if decl.is_glob_import() {
resolution.glob_decl = Some(decl);
} else {
resolution.non_glob_decl = Some(decl);
}
}
} else {
if decl.is_glob_import() {
resolution.glob_decl = Some(decl);
} else {
resolution.non_glob_decl = Some(decl);
}
}
Ok(())
})
Ok(())
},
)
}
// Use `f` to mutate the resolution of the name in the module.
@ -480,6 +492,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
&mut self,
module: Module<'ra>,
key: BindingKey,
orig_ident_span: Span,
warn_ambiguity: bool,
f: F,
) -> T
@ -489,7 +502,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
// during which the resolution might end up getting re-defined via a glob cycle.
let (binding, t, warn_ambiguity) = {
let resolution = &mut *self.resolution_or_default(module, key).borrow_mut_unchecked();
let resolution = &mut *self
.resolution_or_default(module, key, orig_ident_span)
.borrow_mut_unchecked();
let old_decl = resolution.binding();
let t = f(self, resolution);
@ -510,7 +525,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// Define or update `binding` in `module`s glob importers.
for import in glob_importers.iter() {
let mut ident = key.ident;
let scope = match ident.0.span.reverse_glob_adjust(module.expansion, import.span) {
let scope = match ident
.ctxt
.update_unchecked(|ctxt| ctxt.reverse_glob_adjust(module.expansion, import.span))
{
Some(Some(def)) => self.expn_def_scope(def),
Some(None) => import.parent_scope.module,
None => continue,
@ -519,6 +537,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let import_decl = self.new_import_decl(binding, *import);
let _ = self.try_plant_decl_into_local_module(
ident,
orig_ident_span,
key.ns,
import_decl,
warn_ambiguity,
@ -540,14 +559,26 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let dummy_decl = self.new_import_decl(dummy_decl, import);
self.per_ns(|this, ns| {
let module = import.parent_scope.module;
let ident = Macros20NormalizedIdent::new(target);
let _ = this.try_plant_decl_into_local_module(ident, ns, dummy_decl, false);
let ident = IdentKey::new(target);
let _ = this.try_plant_decl_into_local_module(
ident,
target.span,
ns,
dummy_decl,
false,
);
// Don't remove underscores from `single_imports`, they were never added.
if target.name != kw::Underscore {
let key = BindingKey::new(ident, ns);
this.update_local_resolution(module, key, false, |_, resolution| {
resolution.single_imports.swap_remove(&import);
})
this.update_local_resolution(
module,
key,
target.span,
false,
|_, resolution| {
resolution.single_imports.swap_remove(&import);
},
)
}
});
self.record_use(target, dummy_decl, Used::Other);
@ -687,7 +718,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
import.root_id,
import.root_span,
BuiltinLintDiag::AmbiguousGlobReexports {
name: key.ident.to_string(),
name: key.ident.name.to_string(),
namespace: key.ns.descr().to_string(),
first_reexport_span: import.root_span,
duplicate_reexport_span: amb_binding.span,
@ -922,7 +953,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// We need the `target`, `source` can be extracted.
let import_decl = this.new_import_decl(binding, import);
this.get_mut_unchecked().plant_decl_into_local_module(
Macros20NormalizedIdent::new(target),
IdentKey::new(target),
target.span,
ns,
import_decl,
);
@ -931,10 +963,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
Err(Determinacy::Determined) => {
// Don't remove underscores from `single_imports`, they were never added.
if target.name != kw::Underscore {
let key = BindingKey::new(Macros20NormalizedIdent::new(target), ns);
let key = BindingKey::new(IdentKey::new(target), ns);
this.get_mut_unchecked().update_local_resolution(
parent,
key,
target.span,
false,
|_, resolution| {
resolution.single_imports.swap_remove(&import);
@ -1531,15 +1564,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
.borrow()
.iter()
.filter_map(|(key, resolution)| {
resolution.borrow().binding().map(|binding| (*key, binding))
let resolution = resolution.borrow();
resolution.binding().map(|binding| (*key, binding, resolution.orig_ident_span))
})
.collect::<Vec<_>>();
for (mut key, binding) in bindings {
let scope = match key.ident.0.span.reverse_glob_adjust(module.expansion, import.span) {
Some(Some(def)) => self.expn_def_scope(def),
Some(None) => import.parent_scope.module,
None => continue,
};
for (mut key, binding, orig_ident_span) in bindings {
let scope =
match key.ident.ctxt.update_unchecked(|ctxt| {
ctxt.reverse_glob_adjust(module.expansion, import.span)
}) {
Some(Some(def)) => self.expn_def_scope(def),
Some(None) => import.parent_scope.module,
None => continue,
};
if self.is_accessible_from(binding.vis(), scope) {
let import_decl = self.new_import_decl(binding, import);
let warn_ambiguity = self
@ -1548,6 +1585,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
.is_some_and(|binding| binding.warn_ambiguity_recursive());
let _ = self.try_plant_decl_into_local_module(
key.ident,
orig_ident_span,
key.ns,
import_decl,
warn_ambiguity,
@ -1575,19 +1613,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let mut children = Vec::new();
let mut ambig_children = Vec::new();
module.for_each_child(self, |this, ident, _, binding| {
module.for_each_child(self, |this, ident, orig_ident_span, _, binding| {
let res = binding.res().expect_non_local();
if res != def::Res::Err {
let child = |reexport_chain| ModChild {
ident: ident.0,
res,
vis: binding.vis(),
reexport_chain,
};
let ident = ident.orig(orig_ident_span);
let child =
|reexport_chain| ModChild { ident, res, vis: binding.vis(), reexport_chain };
if let Some((ambig_binding1, ambig_binding2)) = binding.descent_to_ambiguity() {
let main = child(ambig_binding1.reexport_chain(this));
let second = ModChild {
ident: ident.0,
ident,
res: ambig_binding2.res().expect_non_local(),
vis: ambig_binding2.vis(),
reexport_chain: ambig_binding2.reexport_chain(this),

View file

@ -37,15 +37,15 @@ use rustc_session::config::{CrateType, ResolveDocLinks};
use rustc_session::lint;
use rustc_session::parse::feature_err;
use rustc_span::source_map::{Spanned, respan};
use rustc_span::{BytePos, DUMMY_SP, Ident, Macros20NormalizedIdent, Span, Symbol, kw, sym};
use rustc_span::{BytePos, DUMMY_SP, Ident, Span, Symbol, kw, sym};
use smallvec::{SmallVec, smallvec};
use thin_vec::ThinVec;
use tracing::{debug, instrument, trace};
use crate::{
BindingError, BindingKey, Decl, Finalize, LateDecl, Module, ModuleOrUniformRoot, ParentScope,
PathResult, ResolutionError, Resolver, Segment, Stage, TyCtxt, UseError, Used, errors,
path_names_to_string, rustdoc,
BindingError, BindingKey, Decl, Finalize, IdentKey, LateDecl, Module, ModuleOrUniformRoot,
ParentScope, PathResult, ResolutionError, Resolver, Segment, Stage, TyCtxt, UseError, Used,
errors, path_names_to_string, rustdoc,
};
mod diagnostics;
@ -3650,7 +3650,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
return;
};
ident.span.normalize_to_macros_2_0_and_adjust(module.expansion);
let key = BindingKey::new(Macros20NormalizedIdent::new(ident), ns);
let key = BindingKey::new(IdentKey::new(ident), ns);
let mut decl = self.r.resolution(module, key).and_then(|r| r.best_decl());
debug!(?decl);
if decl.is_none() {
@ -3661,7 +3661,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
TypeNS => ValueNS,
_ => ns,
};
let key = BindingKey::new(Macros20NormalizedIdent::new(ident), ns);
let key = BindingKey::new(IdentKey::new(ident), ns);
decl = self.r.resolution(module, key).and_then(|r| r.best_decl());
debug!(?decl);
}

View file

@ -1620,22 +1620,24 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
if let PathResult::Module(ModuleOrUniformRoot::Module(module)) =
self.resolve_path(mod_path, None, None, *source)
{
let targets: Vec<_> =
self.r
.resolutions(module)
.borrow()
.iter()
.filter_map(|(key, resolution)| {
resolution.borrow().best_decl().map(|binding| binding.res()).and_then(
|res| if filter_fn(res) { Some((*key, res)) } else { None },
)
let targets: Vec<_> = self
.r
.resolutions(module)
.borrow()
.iter()
.filter_map(|(key, resolution)| {
let resolution = resolution.borrow();
resolution.best_decl().map(|binding| binding.res()).and_then(|res| {
if filter_fn(res) {
Some((key.ident.name, resolution.orig_ident_span, res))
} else {
None
}
})
.collect();
if let [target] = targets.as_slice() {
return Some(TypoSuggestion::single_item_from_ident(
target.0.ident.0,
target.1,
));
})
.collect();
if let &[(name, orig_ident_span, res)] = targets.as_slice() {
return Some(TypoSuggestion::single_item(name, orig_ident_span, res));
}
}
}
@ -2662,7 +2664,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
// Locals and type parameters
for (ident, &res) in &rib.bindings {
if filter_fn(res) && ident.span.ctxt() == rib_ctxt {
names.push(TypoSuggestion::typo_from_ident(*ident, res));
names.push(TypoSuggestion::new(ident.name, ident.span, res));
}
}
@ -2824,7 +2826,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
break;
}
in_module.for_each_child(self.r, |r, ident, _, name_binding| {
in_module.for_each_child(self.r, |r, ident, orig_ident_span, _, name_binding| {
// abort if the module is already found or if name_binding is private external
if result.is_some() || !name_binding.vis().is_visible_locally() {
return;
@ -2832,7 +2834,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
if let Some(module_def_id) = name_binding.res().module_like_def_id() {
// form the path
let mut path_segments = path_segments.clone();
path_segments.push(ast::PathSegment::from_ident(ident.0));
path_segments.push(ast::PathSegment::from_ident(ident.orig(orig_ident_span)));
let doc_visible = doc_visible
&& (module_def_id.is_local() || !r.tcx.is_doc_hidden(module_def_id));
if module_def_id == def_id {
@ -2868,10 +2870,10 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
fn collect_enum_ctors(&self, def_id: DefId) -> Option<Vec<(Path, DefId, CtorKind)>> {
self.find_module(def_id).map(|(enum_module, enum_import_suggestion)| {
let mut variants = Vec::new();
enum_module.for_each_child(self.r, |_, ident, _, name_binding| {
enum_module.for_each_child(self.r, |_, ident, orig_ident_span, _, name_binding| {
if let Res::Def(DefKind::Ctor(CtorOf::Variant, kind), def_id) = name_binding.res() {
let mut segms = enum_import_suggestion.path.segments.clone();
segms.push(ast::PathSegment::from_ident(ident.0));
segms.push(ast::PathSegment::from_ident(ident.orig(orig_ident_span)));
let path = Path { span: name_binding.span, segments: segms, tokens: None };
variants.push((path, def_id, kind));
}

View file

@ -33,6 +33,7 @@ use std::sync::Arc;
use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
use effective_visibilities::EffectiveVisibilitiesVisitor;
use errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
use hygiene::Macros20NormalizedSyntaxContext;
use imports::{Import, ImportData, ImportKind, NameResolution, PendingDecl};
use late::{
ForwardGenericParamBanReason, HasGenericParams, PathSource, PatternSource,
@ -75,7 +76,7 @@ use rustc_query_system::ich::StableHashingContext;
use rustc_session::config::CrateType;
use rustc_session::lint::builtin::PRIVATE_MACRO_USE;
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency};
use rustc_span::{DUMMY_SP, Ident, Macros20NormalizedIdent, Span, Symbol, kw, sym};
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
use smallvec::{SmallVec, smallvec};
use tracing::debug;
@ -552,6 +553,40 @@ impl ModuleKind {
}
}
/// Combination of a symbol and its macros 2.0 normalized hygiene context.
/// Used as a key in various kinds of name containers, including modules (as a part of slightly
/// larger `BindingKey`) and preludes.
///
/// Often passed around together with `orig_ident_span: Span`, which is an unnormalized span
/// of the original `Ident` from which `IdentKey` was obtained. This span is not used in map keys,
/// but used in a number of other scenarios - diagnostics, edition checks, `allow_unstable` checks
/// and similar. This is required because macros 2.0 normalization is lossy and the normalized
/// spans / syntax contexts no longer contain parts of macro backtraces, while the original span
/// contains everything.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
struct IdentKey {
name: Symbol,
ctxt: Macros20NormalizedSyntaxContext,
}
impl IdentKey {
#[inline]
fn new(ident: Ident) -> IdentKey {
IdentKey { name: ident.name, ctxt: Macros20NormalizedSyntaxContext::new(ident.span.ctxt()) }
}
#[inline]
fn with_root_ctxt(name: Symbol) -> Self {
let ctxt = Macros20NormalizedSyntaxContext::new_unchecked(SyntaxContext::root());
IdentKey { name, ctxt }
}
#[inline]
fn orig(self, orig_ident_span: Span) -> Ident {
Ident::new(self.name, orig_ident_span)
}
}
/// A key that identifies a binding in a given `Module`.
///
/// Multiple bindings in the same module can have the same key (in a valid
@ -560,7 +595,7 @@ impl ModuleKind {
struct BindingKey {
/// The identifier for the binding, always the `normalize_to_macros_2_0` version of the
/// identifier.
ident: Macros20NormalizedIdent,
ident: IdentKey,
ns: Namespace,
/// When we add an underscore binding (with ident `_`) to some module, this field has
/// a non-zero value that uniquely identifies this binding in that module.
@ -571,12 +606,12 @@ struct BindingKey {
}
impl BindingKey {
fn new(ident: Macros20NormalizedIdent, ns: Namespace) -> Self {
fn new(ident: IdentKey, ns: Namespace) -> Self {
BindingKey { ident, ns, disambiguator: 0 }
}
fn new_disambiguated(
ident: Macros20NormalizedIdent,
ident: IdentKey,
ns: Namespace,
disambiguator: impl FnOnce() -> u32,
) -> BindingKey {
@ -623,16 +658,7 @@ struct ModuleData<'ra> {
/// Used to memoize the traits in this module for faster searches through all traits in scope.
traits: CmRefCell<
Option<
Box<
[(
Macros20NormalizedIdent,
Decl<'ra>,
Option<Module<'ra>>,
bool, /* lint ambiguous */
)],
>,
>,
Option<Box<[(Symbol, Decl<'ra>, Option<Module<'ra>>, bool /* lint ambiguous */)]>>,
>,
/// Span of the module itself. Used for error reporting.
@ -699,11 +725,12 @@ impl<'ra> Module<'ra> {
fn for_each_child<'tcx, R: AsRef<Resolver<'ra, 'tcx>>>(
self,
resolver: &R,
mut f: impl FnMut(&R, Macros20NormalizedIdent, Namespace, Decl<'ra>),
mut f: impl FnMut(&R, IdentKey, Span, Namespace, Decl<'ra>),
) {
for (key, name_resolution) in resolver.as_ref().resolutions(self).borrow().iter() {
if let Some(decl) = name_resolution.borrow().best_decl() {
f(resolver, key.ident, key.ns, decl);
let name_resolution = name_resolution.borrow();
if let Some(decl) = name_resolution.best_decl() {
f(resolver, key.ident, name_resolution.orig_ident_span, key.ns, decl);
}
}
}
@ -711,11 +738,12 @@ impl<'ra> Module<'ra> {
fn for_each_child_mut<'tcx, R: AsMut<Resolver<'ra, 'tcx>>>(
self,
resolver: &mut R,
mut f: impl FnMut(&mut R, Macros20NormalizedIdent, Namespace, Decl<'ra>),
mut f: impl FnMut(&mut R, IdentKey, Span, Namespace, Decl<'ra>),
) {
for (key, name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() {
if let Some(decl) = name_resolution.borrow().best_decl() {
f(resolver, key.ident, key.ns, decl);
let name_resolution = name_resolution.borrow();
if let Some(decl) = name_resolution.best_decl() {
f(resolver, key.ident, name_resolution.orig_ident_span, key.ns, decl);
}
}
}
@ -725,13 +753,13 @@ impl<'ra> Module<'ra> {
let mut traits = self.traits.borrow_mut(resolver.as_ref());
if traits.is_none() {
let mut collected_traits = Vec::new();
self.for_each_child(resolver, |r, name, ns, binding| {
self.for_each_child(resolver, |r, ident, _, ns, binding| {
if ns != TypeNS {
return;
}
if let Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) = binding.res() {
collected_traits.push((
name,
ident.name,
binding,
r.as_ref().get_module(def_id),
binding.is_ambiguity_recursive(),
@ -1081,14 +1109,14 @@ struct ExternPreludeEntry<'ra> {
/// Name declaration from an `extern crate` item.
/// The boolean flag is true is `item_decl` is non-redundant, happens either when
/// `flag_decl` is `None`, or when `extern crate` introducing `item_decl` used renaming.
item_decl: Option<(Decl<'ra>, /* introduced by item */ bool)>,
item_decl: Option<(Decl<'ra>, Span, /* introduced by item */ bool)>,
/// Name declaration from an `--extern` flag, lazily populated on first use.
flag_decl: Option<CacheCell<(PendingDecl<'ra>, /* finalized */ bool)>>,
}
impl ExternPreludeEntry<'_> {
fn introduced_by_item(&self) -> bool {
matches!(self.item_decl, Some((_, true)))
matches!(self.item_decl, Some((.., true)))
}
fn flag() -> Self {
@ -1097,11 +1125,18 @@ impl ExternPreludeEntry<'_> {
flag_decl: Some(CacheCell::new((PendingDecl::Pending, false))),
}
}
fn span(&self) -> Span {
match self.item_decl {
Some((_, span, _)) => span,
None => DUMMY_SP,
}
}
}
struct DeriveData {
resolutions: Vec<DeriveResolution>,
helper_attrs: Vec<(usize, Macros20NormalizedIdent)>,
helper_attrs: Vec<(usize, IdentKey, Span)>,
has_derive_copy: bool,
}
@ -1137,7 +1172,7 @@ pub struct Resolver<'ra, 'tcx> {
assert_speculative: bool,
prelude: Option<Module<'ra>> = None,
extern_prelude: FxIndexMap<Macros20NormalizedIdent, ExternPreludeEntry<'ra>>,
extern_prelude: FxIndexMap<IdentKey, ExternPreludeEntry<'ra>>,
/// N.B., this is used only for better diagnostics, not name resolution itself.
field_names: LocalDefIdMap<Vec<Ident>> = Default::default(),
@ -1228,8 +1263,8 @@ pub struct Resolver<'ra, 'tcx> {
dummy_decl: Decl<'ra>,
builtin_type_decls: FxHashMap<Symbol, Decl<'ra>>,
builtin_attr_decls: FxHashMap<Symbol, Decl<'ra>>,
registered_tool_decls: FxHashMap<Ident, Decl<'ra>>,
macro_names: FxHashSet<Ident> = default::fx_hash_set(),
registered_tool_decls: FxHashMap<IdentKey, Decl<'ra>>,
macro_names: FxHashSet<IdentKey> = default::fx_hash_set(),
builtin_macros: FxHashMap<Symbol, SyntaxExtensionKind> = default::fx_hash_map(),
registered_tools: &'tcx RegisteredTools,
macro_use_prelude: FxIndexMap<Symbol, Decl<'ra>>,
@ -1265,7 +1300,7 @@ pub struct Resolver<'ra, 'tcx> {
/// `macro_rules` scopes produced by `macro_rules` item definitions.
macro_rules_scopes: FxHashMap<LocalDefId, MacroRulesScopeRef<'ra>> = default::fx_hash_map(),
/// Helper attributes that are in scope for the given expansion.
helper_attrs: FxHashMap<LocalExpnId, Vec<(Macros20NormalizedIdent, Decl<'ra>)>> = default::fx_hash_map(),
helper_attrs: FxHashMap<LocalExpnId, Vec<(IdentKey, Span, Decl<'ra>)>> = default::fx_hash_map(),
/// Ready or in-progress results of resolving paths inside the `#[derive(...)]` attribute
/// with the given `ExpnId`.
derive_data: FxHashMap<LocalExpnId, DeriveData> = default::fx_hash_map(),
@ -1409,8 +1444,11 @@ impl<'ra> ResolverArenas<'ra> {
fn alloc_import(&'ra self, import: ImportData<'ra>) -> Import<'ra> {
Interned::new_unchecked(self.imports.alloc(import))
}
fn alloc_name_resolution(&'ra self) -> &'ra CmRefCell<NameResolution<'ra>> {
self.name_resolutions.alloc(Default::default())
fn alloc_name_resolution(
&'ra self,
orig_ident_span: Span,
) -> &'ra CmRefCell<NameResolution<'ra>> {
self.name_resolutions.alloc(CmRefCell::new(NameResolution::new(orig_ident_span)))
}
fn alloc_macro_rules_scope(&'ra self, scope: MacroRulesScope<'ra>) -> MacroRulesScopeRef<'ra> {
self.dropless.alloc(CacheCell::new(scope))
@ -1580,7 +1618,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
&& let name = Symbol::intern(name)
&& name.can_be_raw()
{
let ident = Macros20NormalizedIdent::with_dummy_span(name);
let ident = IdentKey::with_root_ctxt(name);
Some((ident, ExternPreludeEntry::flag()))
} else {
None
@ -1589,10 +1627,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
.collect();
if !attr::contains_name(attrs, sym::no_core) {
let ident = Macros20NormalizedIdent::with_dummy_span(sym::core);
let ident = IdentKey::with_root_ctxt(sym::core);
extern_prelude.insert(ident, ExternPreludeEntry::flag());
if !attr::contains_name(attrs, sym::no_std) {
let ident = Macros20NormalizedIdent::with_dummy_span(sym::std);
let ident = IdentKey::with_root_ctxt(sym::std);
extern_prelude.insert(ident, ExternPreludeEntry::flag());
}
}
@ -1637,10 +1675,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
.collect(),
registered_tool_decls: registered_tools
.iter()
.map(|ident| {
.map(|&ident| {
let res = Res::ToolMod;
let decl = arenas.new_pub_def_decl(res, ident.span, LocalExpnId::ROOT);
(*ident, decl)
(IdentKey::new(ident), decl)
})
.collect(),
registered_tools,
@ -1940,7 +1978,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
{
if self.trait_may_have_item(trait_module, assoc_item) {
let def_id = trait_binding.res().def_id();
let import_ids = self.find_transitive_imports(&trait_binding.kind, trait_name.0);
let import_ids = self.find_transitive_imports(&trait_binding.kind, trait_name);
found_traits.push(TraitCandidate { def_id, import_ids, lint_ambiguous });
}
}
@ -1969,7 +2007,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
fn find_transitive_imports(
&mut self,
mut kind: &DeclKind<'_>,
trait_name: Ident,
trait_name: Symbol,
) -> SmallVec<[LocalDefId; 1]> {
let mut import_ids = smallvec![];
while let DeclKind::Import { import, source_decl, .. } = kind {
@ -2004,11 +2042,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
&self,
module: Module<'ra>,
key: BindingKey,
orig_ident_span: Span,
) -> &'ra CmRefCell<NameResolution<'ra>> {
self.resolutions(module)
.borrow_mut_unchecked()
.entry(key)
.or_insert_with(|| self.arenas.alloc_name_resolution())
.or_insert_with(|| self.arenas.alloc_name_resolution(orig_ident_span))
}
/// Test if AmbiguityError ambi is any identical to any one inside ambiguity_errors
@ -2082,8 +2121,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// Avoid marking `extern crate` items that refer to a name from extern prelude,
// but not introduce it, as used if they are accessed from lexical scope.
if used == Used::Scope
&& let Some(entry) = self.extern_prelude.get(&Macros20NormalizedIdent::new(ident))
&& entry.item_decl == Some((used_decl, false))
&& let Some(entry) = self.extern_prelude.get(&IdentKey::new(ident))
&& let Some((item_decl, _, false)) = entry.item_decl
&& item_decl == used_decl
{
return;
}
@ -2094,7 +2134,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if let Some(id) = import.id() {
self.used_imports.insert(id);
}
self.add_to_glob_map(import, ident);
self.add_to_glob_map(import, ident.name);
self.record_use_inner(
ident,
source_decl,
@ -2105,10 +2145,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
#[inline]
fn add_to_glob_map(&mut self, import: Import<'_>, ident: Ident) {
fn add_to_glob_map(&mut self, import: Import<'_>, name: Symbol) {
if let ImportKind::Glob { id, .. } = import.kind {
let def_id = self.local_def_id(id);
self.glob_map.entry(def_id).or_default().insert(ident.name);
self.glob_map.entry(def_id).or_default().insert(name);
}
}
@ -2230,13 +2270,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
fn extern_prelude_get_item<'r>(
mut self: CmResolver<'r, 'ra, 'tcx>,
ident: Macros20NormalizedIdent,
ident: IdentKey,
orig_ident_span: Span,
finalize: bool,
) -> Option<Decl<'ra>> {
let entry = self.extern_prelude.get(&ident);
entry.and_then(|entry| entry.item_decl).map(|(decl, _)| {
entry.and_then(|entry| entry.item_decl).map(|(decl, ..)| {
if finalize {
self.get_mut().record_use(ident.0, decl, Used::Scope);
self.get_mut().record_use(ident.orig(orig_ident_span), decl, Used::Scope);
}
decl
})
@ -2244,7 +2285,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
fn extern_prelude_get_flag(
&self,
ident: Macros20NormalizedIdent,
ident: IdentKey,
orig_ident_span: Span,
finalize: bool,
) -> Option<Decl<'ra>> {
let entry = self.extern_prelude.get(&ident);
@ -2253,14 +2295,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
let decl = match pending_decl {
PendingDecl::Ready(decl) => {
if finalize && !finalized {
self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span);
self.cstore_mut().process_path_extern(
self.tcx,
ident.name,
orig_ident_span,
);
}
decl
}
PendingDecl::Pending => {
debug_assert!(!finalized);
let crate_id = if finalize {
self.cstore_mut().process_path_extern(self.tcx, ident.name, ident.span)
self.cstore_mut().process_path_extern(self.tcx, ident.name, orig_ident_span)
} else {
self.cstore_mut().maybe_process_path_extern(self.tcx, ident.name)
};
@ -2675,3 +2721,40 @@ mod ref_mut {
}
}
}
mod hygiene {
use rustc_span::SyntaxContext;
/// A newtype around `SyntaxContext` that can only keep contexts produced by
/// [SyntaxContext::normalize_to_macros_2_0].
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub(crate) struct Macros20NormalizedSyntaxContext(SyntaxContext);
impl Macros20NormalizedSyntaxContext {
#[inline]
pub(crate) fn new(ctxt: SyntaxContext) -> Macros20NormalizedSyntaxContext {
Macros20NormalizedSyntaxContext(ctxt.normalize_to_macros_2_0())
}
#[inline]
pub(crate) fn new_unchecked(ctxt: SyntaxContext) -> Macros20NormalizedSyntaxContext {
debug_assert_eq!(ctxt, ctxt.normalize_to_macros_2_0());
Macros20NormalizedSyntaxContext(ctxt)
}
/// The passed closure must preserve the context's normalized-ness.
#[inline]
pub(crate) fn update_unchecked<R>(&mut self, f: impl FnOnce(&mut SyntaxContext) -> R) -> R {
let ret = f(&mut self.0);
debug_assert_eq!(self.0, self.0.normalize_to_macros_2_0());
ret
}
}
impl std::ops::Deref for Macros20NormalizedSyntaxContext {
type Target = SyntaxContext;
fn deref(&self) -> &Self::Target {
&self.0
}
}
}

View file

@ -29,16 +29,17 @@ use rustc_session::parse::feature_err;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::edition::Edition;
use rustc_span::hygiene::{self, AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind};
use rustc_span::{DUMMY_SP, Ident, Macros20NormalizedIdent, Span, Symbol, kw, sym};
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
use crate::Namespace::*;
use crate::errors::{
self, AddAsNonDerive, CannotDetermineMacroResolution, CannotFindIdentInThisScope,
MacroExpectedFound, RemoveSurroundingDerive,
};
use crate::hygiene::Macros20NormalizedSyntaxContext;
use crate::imports::Import;
use crate::{
BindingKey, CacheCell, CmResolver, Decl, DeclKind, DeriveData, Determinacy, Finalize,
BindingKey, CacheCell, CmResolver, Decl, DeclKind, DeriveData, Determinacy, Finalize, IdentKey,
InvocationParent, MacroData, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult,
ResolutionError, Resolver, ScopeSet, Segment, Used,
};
@ -52,7 +53,8 @@ pub(crate) struct MacroRulesDecl<'ra> {
pub(crate) decl: Decl<'ra>,
/// `macro_rules` scope into which the `macro_rules` item was planted.
pub(crate) parent_macro_rules_scope: MacroRulesScopeRef<'ra>,
pub(crate) ident: Macros20NormalizedIdent,
pub(crate) ident: IdentKey,
pub(crate) orig_ident_span: Span,
}
/// The scope introduced by a `macro_rules!` macro.
@ -412,9 +414,12 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
Ok((Some(ext), _)) => {
if !ext.helper_attrs.is_empty() {
let span = resolution.path.segments.last().unwrap().ident.span;
entry.helper_attrs.extend(ext.helper_attrs.iter().map(|name| {
(i, Macros20NormalizedIdent::new(Ident::new(*name, span)))
}));
let ctxt = Macros20NormalizedSyntaxContext::new(span.ctxt());
entry.helper_attrs.extend(
ext.helper_attrs
.iter()
.map(|&name| (i, IdentKey { name, ctxt }, span)),
);
}
entry.has_derive_copy |= ext.builtin_name == Some(sym::Copy);
ext
@ -430,13 +435,14 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
}
}
// Sort helpers in a stable way independent from the derive resolution order.
entry.helper_attrs.sort_by_key(|(i, _)| *i);
entry.helper_attrs.sort_by_key(|(i, ..)| *i);
let helper_attrs = entry
.helper_attrs
.iter()
.map(|(_, ident)| {
.map(|&(_, ident, orig_ident_span)| {
let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
(*ident, self.arenas.new_pub_def_decl(res, ident.span, expn_id))
let decl = self.arenas.new_pub_def_decl(res, orig_ident_span, expn_id);
(ident, orig_ident_span, decl)
})
.collect();
self.helper_attrs.insert(expn_id, helper_attrs);
@ -532,14 +538,14 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
}
let mut idents = Vec::new();
target_trait.for_each_child(self, |this, ident, ns, _binding| {
target_trait.for_each_child(self, |this, ident, orig_ident_span, ns, _binding| {
// FIXME: Adjust hygiene for idents from globs, like for glob imports.
if let Some(overriding_keys) = this.impl_binding_keys.get(&impl_def_id)
&& overriding_keys.contains(&BindingKey::new(ident, ns))
{
// The name is overridden, do not produce it from the glob delegation.
} else {
idents.push((ident.0, None));
idents.push((ident.orig(orig_ident_span), None));
}
});
Ok(idents)
@ -1145,14 +1151,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
}
pub(crate) fn check_reserved_macro_name(&self, ident: Ident, res: Res) {
pub(crate) fn check_reserved_macro_name(&self, name: Symbol, span: Span, res: Res) {
// Reserve some names that are not quite covered by the general check
// performed on `Resolver::builtin_attrs`.
if ident.name == sym::cfg || ident.name == sym::cfg_attr {
if name == sym::cfg || name == sym::cfg_attr {
let macro_kinds = self.get_macro(res).map(|macro_data| macro_data.ext.macro_kinds());
if macro_kinds.is_some() && sub_namespace_match(macro_kinds, Some(MacroKind::Attr)) {
self.dcx()
.emit_err(errors::NameReservedInAttributeNamespace { span: ident.span, ident });
self.dcx().emit_err(errors::NameReservedInAttributeNamespace { span, ident: name });
}
}
}

View file

@ -837,11 +837,7 @@ impl SyntaxContext {
/// ```
/// This returns `None` if the context cannot be glob-adjusted.
/// Otherwise, it returns the scope to use when privacy checking (see `adjust` for details).
pub(crate) fn glob_adjust(
&mut self,
expn_id: ExpnId,
glob_span: Span,
) -> Option<Option<ExpnId>> {
pub fn glob_adjust(&mut self, expn_id: ExpnId, glob_span: Span) -> Option<Option<ExpnId>> {
HygieneData::with(|data| {
let mut scope = None;
let mut glob_ctxt = data.normalize_to_macros_2_0(glob_span.ctxt());
@ -865,7 +861,7 @@ impl SyntaxContext {
/// assert!(self.glob_adjust(expansion, glob_ctxt) == Some(privacy_checking_scope));
/// }
/// ```
pub(crate) fn reverse_glob_adjust(
pub fn reverse_glob_adjust(
&mut self,
expn_id: ExpnId,
glob_span: Span,

View file

@ -63,8 +63,7 @@ pub use span_encoding::{DUMMY_SP, Span};
pub mod symbol;
pub use symbol::{
ByteSymbol, Ident, MacroRulesNormalizedIdent, Macros20NormalizedIdent, STDLIB_STABLE_CRATES,
Symbol, kw, sym,
ByteSymbol, Ident, MacroRulesNormalizedIdent, STDLIB_STABLE_CRATES, Symbol, kw, sym,
};
mod analyze_source_file;
@ -1312,30 +1311,6 @@ impl Span {
mark
}
#[inline]
pub fn glob_adjust(&mut self, expn_id: ExpnId, glob_span: Span) -> Option<Option<ExpnId>> {
let mut mark = None;
*self = self.map_ctxt(|mut ctxt| {
mark = ctxt.glob_adjust(expn_id, glob_span);
ctxt
});
mark
}
#[inline]
pub fn reverse_glob_adjust(
&mut self,
expn_id: ExpnId,
glob_span: Span,
) -> Option<Option<ExpnId>> {
let mut mark = None;
*self = self.map_ctxt(|mut ctxt| {
mark = ctxt.reverse_glob_adjust(expn_id, glob_span);
ctxt
});
mark
}
#[inline]
pub fn normalize_to_macros_2_0(self) -> Span {
self.map_ctxt(|ctxt| ctxt.normalize_to_macros_2_0())

View file

@ -3,7 +3,6 @@
//! type, and vice versa.
use std::hash::{Hash, Hasher};
use std::ops::Deref;
use std::{fmt, str};
use rustc_arena::DroplessArena;
@ -2753,7 +2752,7 @@ impl fmt::Display for IdentPrinter {
}
}
/// An newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
/// A newtype around `Ident` that calls [Ident::normalize_to_macro_rules] on
/// construction for "local variable hygiene" comparisons.
///
/// Use this type when you need to compare identifiers according to macro_rules hygiene.
@ -2780,48 +2779,6 @@ impl fmt::Display for MacroRulesNormalizedIdent {
}
}
/// An newtype around `Ident` that calls [Ident::normalize_to_macros_2_0] on
/// construction for "item hygiene" comparisons.
///
/// Identifiers with same string value become same if they came from the same macro 2.0 macro
/// (e.g., `macro` item, but not `macro_rules` item) and stay different if they came from
/// different macro 2.0 macros.
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct Macros20NormalizedIdent(pub Ident);
impl Macros20NormalizedIdent {
#[inline]
pub fn new(ident: Ident) -> Self {
Macros20NormalizedIdent(ident.normalize_to_macros_2_0())
}
// dummy_span does not need to be normalized, so we can use `Ident` directly
pub fn with_dummy_span(name: Symbol) -> Self {
Macros20NormalizedIdent(Ident::with_dummy_span(name))
}
}
impl fmt::Debug for Macros20NormalizedIdent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)
}
}
impl fmt::Display for Macros20NormalizedIdent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
/// By impl Deref, we can access the wrapped Ident as if it were a normal Ident
/// such as `norm_ident.name` instead of `norm_ident.0.name`.
impl Deref for Macros20NormalizedIdent {
type Target = Ident;
fn deref(&self) -> &Self::Target {
&self.0
}
}
/// An interned UTF-8 string.
///
/// Internally, a `Symbol` is implemented as an index, and all operations

View file

@ -1,13 +1,11 @@
error[E0422]: cannot find struct, variant or union type `MyStruct` in this scope
--> $DIR/cross-crate-name-hiding-2.rs:13:13
|
LL | my_struct!(define);
| ------------------ you might have meant to refer to this struct
...
LL | let x = MyStruct {};
| ^^^^^^^^ not found in this scope
|
::: $DIR/auxiliary/use_by_macro.rs:7:24
|
LL | pub struct MyStruct;
| -------- you might have meant to refer to this struct
error: aborting due to 1 previous error

View file

@ -15,6 +15,11 @@ error: unused macro definition: `m`
|
LL | macro_rules! m {
| ^
...
LL | create_macro!();
| --------------- in this macro invocation
|
= note: this error originates in the macro `create_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
error: unused macro definition: `unused`
--> $DIR/unused-macros.rs:26:18

View file

@ -57,54 +57,54 @@ PRINT-ATTR INPUT (DISPLAY): struct B(identity! ($crate :: S));
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",
span: $DIR/auxiliary/dollar-crate-external.rs:21:5: 21:11 (#11),
span: $DIR/auxiliary/dollar-crate-external.rs:21:5: 21:11 (#12),
},
Ident {
ident: "B",
span: $DIR/auxiliary/dollar-crate-external.rs:21:12: 21:13 (#11),
span: $DIR/auxiliary/dollar-crate-external.rs:21:12: 21:13 (#12),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "identity",
span: $DIR/auxiliary/dollar-crate-external.rs:21:14: 21:22 (#11),
span: $DIR/auxiliary/dollar-crate-external.rs:21:14: 21:22 (#12),
},
Punct {
ch: '!',
spacing: Alone,
span: $DIR/auxiliary/dollar-crate-external.rs:21:22: 21:23 (#11),
span: $DIR/auxiliary/dollar-crate-external.rs:21:22: 21:23 (#12),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "$crate",
span: $DIR/auxiliary/dollar-crate-external.rs:21:24: 21:30 (#11),
span: $DIR/auxiliary/dollar-crate-external.rs:21:24: 21:30 (#12),
},
Punct {
ch: ':',
spacing: Joint,
span: $DIR/auxiliary/dollar-crate-external.rs:21:30: 21:31 (#11),
span: $DIR/auxiliary/dollar-crate-external.rs:21:30: 21:31 (#12),
},
Punct {
ch: ':',
spacing: Alone,
span: $DIR/auxiliary/dollar-crate-external.rs:21:31: 21:32 (#11),
span: $DIR/auxiliary/dollar-crate-external.rs:21:31: 21:32 (#12),
},
Ident {
ident: "S",
span: $DIR/auxiliary/dollar-crate-external.rs:21:32: 21:33 (#11),
span: $DIR/auxiliary/dollar-crate-external.rs:21:32: 21:33 (#12),
},
],
span: $DIR/auxiliary/dollar-crate-external.rs:21:23: 21:34 (#11),
span: $DIR/auxiliary/dollar-crate-external.rs:21:23: 21:34 (#12),
},
],
span: $DIR/auxiliary/dollar-crate-external.rs:21:13: 21:35 (#11),
span: $DIR/auxiliary/dollar-crate-external.rs:21:13: 21:35 (#12),
},
Punct {
ch: ';',
spacing: Alone,
span: $DIR/auxiliary/dollar-crate-external.rs:21:35: 21:36 (#11),
span: $DIR/auxiliary/dollar-crate-external.rs:21:35: 21:36 (#12),
},
]

View file

@ -122,119 +122,119 @@ PRINT-BANG INPUT (DISPLAY): struct M($crate :: S);
PRINT-BANG INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",
span: $DIR/auxiliary/dollar-crate-external.rs:7:13: 7:19 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:7:13: 7:19 (#15),
},
Ident {
ident: "M",
span: $DIR/auxiliary/dollar-crate-external.rs:7:20: 7:21 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:7:20: 7:21 (#15),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "$crate",
span: $DIR/auxiliary/dollar-crate-external.rs:7:22: 7:28 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:7:22: 7:28 (#15),
},
Punct {
ch: ':',
spacing: Joint,
span: $DIR/auxiliary/dollar-crate-external.rs:7:28: 7:29 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:7:28: 7:29 (#15),
},
Punct {
ch: ':',
spacing: Alone,
span: $DIR/auxiliary/dollar-crate-external.rs:7:29: 7:30 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:7:29: 7:30 (#15),
},
Ident {
ident: "S",
span: $DIR/auxiliary/dollar-crate-external.rs:7:30: 7:31 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:7:30: 7:31 (#15),
},
],
span: $DIR/auxiliary/dollar-crate-external.rs:7:21: 7:32 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:7:21: 7:32 (#15),
},
Punct {
ch: ';',
spacing: Alone,
span: $DIR/auxiliary/dollar-crate-external.rs:7:32: 7:33 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:7:32: 7:33 (#15),
},
]
PRINT-ATTR INPUT (DISPLAY): struct A($crate :: S);
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",
span: $DIR/auxiliary/dollar-crate-external.rs:11:9: 11:15 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:11:9: 11:15 (#15),
},
Ident {
ident: "A",
span: $DIR/auxiliary/dollar-crate-external.rs:11:16: 11:17 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:11:16: 11:17 (#15),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "$crate",
span: $DIR/auxiliary/dollar-crate-external.rs:11:18: 11:24 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:11:18: 11:24 (#15),
},
Punct {
ch: ':',
spacing: Joint,
span: $DIR/auxiliary/dollar-crate-external.rs:11:24: 11:25 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:11:24: 11:25 (#15),
},
Punct {
ch: ':',
spacing: Alone,
span: $DIR/auxiliary/dollar-crate-external.rs:11:25: 11:26 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:11:25: 11:26 (#15),
},
Ident {
ident: "S",
span: $DIR/auxiliary/dollar-crate-external.rs:11:26: 11:27 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:11:26: 11:27 (#15),
},
],
span: $DIR/auxiliary/dollar-crate-external.rs:11:17: 11:28 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:11:17: 11:28 (#15),
},
Punct {
ch: ';',
spacing: Alone,
span: $DIR/auxiliary/dollar-crate-external.rs:11:28: 11:29 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:11:28: 11:29 (#15),
},
]
PRINT-DERIVE INPUT (DISPLAY): struct D($crate :: S);
PRINT-DERIVE INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",
span: $DIR/auxiliary/dollar-crate-external.rs:14:9: 14:15 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:14:9: 14:15 (#15),
},
Ident {
ident: "D",
span: $DIR/auxiliary/dollar-crate-external.rs:14:16: 14:17 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:14:16: 14:17 (#15),
},
Group {
delimiter: Parenthesis,
stream: TokenStream [
Ident {
ident: "$crate",
span: $DIR/auxiliary/dollar-crate-external.rs:14:18: 14:24 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:14:18: 14:24 (#15),
},
Punct {
ch: ':',
spacing: Joint,
span: $DIR/auxiliary/dollar-crate-external.rs:14:24: 14:25 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:14:24: 14:25 (#15),
},
Punct {
ch: ':',
spacing: Alone,
span: $DIR/auxiliary/dollar-crate-external.rs:14:25: 14:26 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:14:25: 14:26 (#15),
},
Ident {
ident: "S",
span: $DIR/auxiliary/dollar-crate-external.rs:14:26: 14:27 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:14:26: 14:27 (#15),
},
],
span: $DIR/auxiliary/dollar-crate-external.rs:14:17: 14:28 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:14:17: 14:28 (#15),
},
Punct {
ch: ';',
spacing: Alone,
span: $DIR/auxiliary/dollar-crate-external.rs:14:28: 14:29 (#14),
span: $DIR/auxiliary/dollar-crate-external.rs:14:28: 14:29 (#15),
},
]

View file

@ -47,6 +47,7 @@ LL | #[derive(generate_mod::CheckDerive)]
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
= note: `#[deny(proc_macro_derive_resolution_fallback)]` (part of `#[deny(future_incompatible)]`) on by default
= note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot find type `OuterDerive` in this scope
--> $DIR/generate-mod.rs:18:10
@ -56,6 +57,7 @@ LL | #[derive(generate_mod::CheckDerive)]
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
= note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot find type `FromOutside` in this scope
--> $DIR/generate-mod.rs:25:14
@ -65,6 +67,7 @@ LL | #[derive(generate_mod::CheckDerive)]
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
= note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot find type `OuterDerive` in this scope
--> $DIR/generate-mod.rs:25:14
@ -74,6 +77,7 @@ LL | #[derive(generate_mod::CheckDerive)]
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
= note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 8 previous errors
@ -88,6 +92,7 @@ LL | #[derive(generate_mod::CheckDerive)]
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
= note: `#[deny(proc_macro_derive_resolution_fallback)]` (part of `#[deny(future_incompatible)]`) on by default
= note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info)
Future breakage diagnostic:
error: cannot find type `OuterDerive` in this scope
@ -99,6 +104,7 @@ LL | #[derive(generate_mod::CheckDerive)]
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
= note: `#[deny(proc_macro_derive_resolution_fallback)]` (part of `#[deny(future_incompatible)]`) on by default
= note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info)
Future breakage diagnostic:
error: cannot find type `FromOutside` in this scope
@ -110,6 +116,7 @@ LL | #[derive(generate_mod::CheckDerive)]
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
= note: `#[deny(proc_macro_derive_resolution_fallback)]` (part of `#[deny(future_incompatible)]`) on by default
= note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info)
Future breakage diagnostic:
error: cannot find type `OuterDerive` in this scope
@ -121,6 +128,7 @@ LL | #[derive(generate_mod::CheckDerive)]
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
= note: `#[deny(proc_macro_derive_resolution_fallback)]` (part of `#[deny(future_incompatible)]`) on by default
= note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info)
Future breakage diagnostic:
warning: cannot find type `FromOutside` in this scope
@ -131,6 +139,7 @@ LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
= note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info)
Future breakage diagnostic:
warning: cannot find type `OuterDeriveLint` in this scope
@ -141,4 +150,5 @@ LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
= note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -2,45 +2,45 @@ PRINT-BANG INPUT (DISPLAY): FirstStruct
PRINT-BANG INPUT (DEBUG): TokenStream [
Ident {
ident: "FirstStruct",
span: $DIR/auxiliary/nested-macro-rules.rs:16:14: 16:25 (#6),
span: $DIR/auxiliary/nested-macro-rules.rs:16:14: 16:25 (#7),
},
]
PRINT-ATTR INPUT (DISPLAY): struct FirstAttrStruct {}
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",
span: $DIR/auxiliary/nested-macro-rules.rs:10:32: 10:38 (#5),
span: $DIR/auxiliary/nested-macro-rules.rs:10:32: 10:38 (#6),
},
Ident {
ident: "FirstAttrStruct",
span: $DIR/auxiliary/nested-macro-rules.rs:16:27: 16:42 (#6),
span: $DIR/auxiliary/nested-macro-rules.rs:16:27: 16:42 (#7),
},
Group {
delimiter: Brace,
stream: TokenStream [],
span: $DIR/auxiliary/nested-macro-rules.rs:10:57: 10:59 (#5),
span: $DIR/auxiliary/nested-macro-rules.rs:10:57: 10:59 (#6),
},
]
PRINT-BANG INPUT (DISPLAY): SecondStruct
PRINT-BANG INPUT (DEBUG): TokenStream [
Ident {
ident: "SecondStruct",
span: $DIR/nested-macro-rules.rs:23:38: 23:50 (#15),
span: $DIR/nested-macro-rules.rs:23:38: 23:50 (#16),
},
]
PRINT-ATTR INPUT (DISPLAY): struct SecondAttrStruct {}
PRINT-ATTR INPUT (DEBUG): TokenStream [
Ident {
ident: "struct",
span: $DIR/auxiliary/nested-macro-rules.rs:10:32: 10:38 (#14),
span: $DIR/auxiliary/nested-macro-rules.rs:10:32: 10:38 (#15),
},
Ident {
ident: "SecondAttrStruct",
span: $DIR/nested-macro-rules.rs:23:52: 23:68 (#15),
span: $DIR/nested-macro-rules.rs:23:52: 23:68 (#16),
},
Group {
delimiter: Brace,
stream: TokenStream [],
span: $DIR/auxiliary/nested-macro-rules.rs:10:57: 10:59 (#14),
span: $DIR/auxiliary/nested-macro-rules.rs:10:57: 10:59 (#15),
},
]