Skip to content

Commit bc34960

Browse files
committed
Introduce ModernIdent type to unify macro 2.0 hygiene handling
1. Added ModernIdent type. Wraps Ident and automatically calls normalize_to_macros_2_0() Used for "item hygiene" comparisons, ensuring type safety. 2. Unified identifier normalization. Replaced scattered ident.normalize_to_macros_2_0() calls with ModernIdent::new(ident) Signed-off-by: xizheyin <[email protected]>
1 parent 460259d commit bc34960

File tree

14 files changed

+157
-81
lines changed

14 files changed

+157
-81
lines changed

compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId;
77
use rustc_index::IndexVec;
88
use rustc_middle::traits::specialization_graph::OverlapMode;
99
use rustc_middle::ty::{self, TyCtxt};
10-
use rustc_span::{ErrorGuaranteed, Symbol};
10+
use rustc_span::{ErrorGuaranteed, ModernIdent, Symbol};
1111
use rustc_trait_selection::traits::{self, SkipLeakCheck};
1212
use smallvec::SmallVec;
1313
use tracing::debug;
@@ -65,8 +65,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
6565
fn compare_hygienically(&self, item1: ty::AssocItem, item2: ty::AssocItem) -> bool {
6666
// Symbols and namespace match, compare hygienically.
6767
item1.namespace() == item2.namespace()
68-
&& item1.ident(self.tcx).normalize_to_macros_2_0()
69-
== item2.ident(self.tcx).normalize_to_macros_2_0()
68+
&& ModernIdent::new(item1.ident(self.tcx)) == ModernIdent::new(item2.ident(self.tcx))
7069
}
7170

7271
fn check_for_duplicate_items_in_impl(&self, impl_: DefId) -> Result<(), ErrorGuaranteed> {
@@ -78,7 +77,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
7877
let span = self.tcx.def_span(impl_item.def_id);
7978
let ident = impl_item.ident(self.tcx);
8079

81-
let norm_ident = ident.normalize_to_macros_2_0();
80+
let norm_ident = ModernIdent::new(ident);
8281
match seen_items.entry(norm_ident) {
8382
IndexEntry::Occupied(entry) => {
8483
let former = entry.get();
@@ -117,7 +116,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
117116
.find(|&&item2| self.compare_hygienically(item1, item2));
118117

119118
if let Some(item2) = collision {
120-
let name = item1.ident(self.tcx).normalize_to_macros_2_0();
119+
let name = ModernIdent::new(item1.ident(self.tcx));
121120
let mut err = struct_span_code_err!(
122121
self.tcx.dcx(),
123122
self.tcx.def_span(item1.def_id),

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use rustc_middle::ty::{
4545
use rustc_middle::{bug, span_bug};
4646
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
4747
use rustc_session::parse::feature_err;
48-
use rustc_span::{DUMMY_SP, Ident, Span, kw, sym};
48+
use rustc_span::{DUMMY_SP, Ident, ModernIdent, Span, kw, sym};
4949
use rustc_trait_selection::infer::InferCtxtExt;
5050
use rustc_trait_selection::traits::wf::object_region_bounds;
5151
use rustc_trait_selection::traits::{self, FulfillmentError};
@@ -1545,7 +1545,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
15451545
let item = tcx
15461546
.associated_items(scope)
15471547
.filter_by_name_unhygienic(ident.name)
1548-
.find(|i| i.as_tag() == assoc_tag && i.ident(tcx).normalize_to_macros_2_0() == ident)?;
1548+
.find(|i| i.as_tag() == assoc_tag && ModernIdent::new(i.ident(tcx)) == ident)?;
15491549

15501550
Some((*item, def_scope))
15511551
}

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use rustc_session::parse::feature_err;
3333
use rustc_span::edit_distance::find_best_match_for_name;
3434
use rustc_span::hygiene::DesugaringKind;
3535
use rustc_span::source_map::Spanned;
36-
use rustc_span::{Ident, Span, Symbol, kw, sym};
36+
use rustc_span::{Ident, ModernIdent, Span, Symbol, kw, sym};
3737
use rustc_trait_selection::infer::InferCtxtExt;
3838
use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt};
3939
use tracing::{debug, instrument, trace};
@@ -2035,7 +2035,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20352035
let mut remaining_fields = variant
20362036
.fields
20372037
.iter_enumerated()
2038-
.map(|(i, field)| (field.ident(tcx).normalize_to_macros_2_0(), (i, field)))
2038+
.map(|(i, field)| (ModernIdent::new(field.ident(tcx)), (i, field)))
20392039
.collect::<UnordMap<_, _>>();
20402040

20412041
let mut seen_fields = FxHashMap::default();
@@ -2072,7 +2072,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20722072
self.dcx().emit_err(FieldMultiplySpecifiedInInitializer {
20732073
span: field.ident.span,
20742074
prev_span: *prev_span,
2075-
ident,
2075+
ident: ident.0,
20762076
})
20772077
} else {
20782078
self.report_unknown_field(
@@ -2388,7 +2388,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23882388
adt_ty: Ty<'tcx>,
23892389
span: Span,
23902390
full_span: Span,
2391-
remaining_fields: UnordMap<Ident, (FieldIdx, &ty::FieldDef)>,
2391+
remaining_fields: UnordMap<ModernIdent, (FieldIdx, &ty::FieldDef)>,
23922392
variant: &'tcx ty::VariantDef,
23932393
hir_fields: &'tcx [hir::ExprField<'tcx>],
23942394
args: GenericArgsRef<'tcx>,
@@ -2818,15 +2818,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
28182818
fn find_adt_field(
28192819
&self,
28202820
base_def: ty::AdtDef<'tcx>,
2821-
ident: Ident,
2821+
ident: ModernIdent,
28222822
) -> Option<(FieldIdx, &'tcx ty::FieldDef)> {
28232823
// No way to find a field in an enum.
28242824
if base_def.is_enum() {
28252825
return None;
28262826
}
28272827

28282828
for (field_idx, field) in base_def.non_enum_variant().fields.iter_enumerated() {
2829-
if field.ident(self.tcx).normalize_to_macros_2_0() == ident {
2829+
if ModernIdent::new(field.ident(self.tcx)) == ident {
28302830
// We found the field we wanted.
28312831
return Some((field_idx, field));
28322832
}
@@ -3449,10 +3449,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
34493449
matches: &impl Fn(&ty::FieldDef, Ty<'tcx>) -> bool,
34503450
candidate_field: &ty::FieldDef,
34513451
subst: GenericArgsRef<'tcx>,
3452-
mut field_path: Vec<Ident>,
3452+
mut field_path: Vec<ModernIdent>,
34533453
mod_id: DefId,
34543454
hir_id: HirId,
3455-
) -> Option<Vec<Ident>> {
3455+
) -> Option<Vec<ModernIdent>> {
34563456
debug!(
34573457
"check_for_nested_field_satisfying(span: {:?}, candidate_field: {:?}, field_path: {:?}",
34583458
span, candidate_field, field_path
@@ -3463,7 +3463,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
34633463
// up to a depth of three
34643464
None
34653465
} else {
3466-
field_path.push(candidate_field.ident(self.tcx).normalize_to_macros_2_0());
3466+
field_path.push(ModernIdent::new(candidate_field.ident(self.tcx)));
34673467
let field_ty = candidate_field.ty(self.tcx, subst);
34683468
if matches(candidate_field, field_ty) {
34693469
return Some(field_path);
@@ -3860,10 +3860,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38603860
let Some((index, variant)) = container_def
38613861
.variants()
38623862
.iter_enumerated()
3863-
.find(|(_, v)| v.ident(self.tcx).normalize_to_macros_2_0() == ident)
3863+
.find(|(_, v)| ModernIdent::new(v.ident(self.tcx)) == ident)
38643864
else {
38653865
self.dcx()
3866-
.create_err(NoVariantNamed { span: ident.span, ident, ty: container })
3866+
.create_err(NoVariantNamed {
3867+
span: ident.span,
3868+
ident: ident.0,
3869+
ty: container,
3870+
})
38673871
.with_span_label(field.span, "variant not found")
38683872
.emit_unless_delay(container.references_error());
38693873
break;
@@ -3886,13 +3890,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38863890
let Some((subindex, field)) = variant
38873891
.fields
38883892
.iter_enumerated()
3889-
.find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == subident)
3893+
.find(|(_, f)| ModernIdent::new(f.ident(self.tcx)) == subident)
38903894
else {
38913895
self.dcx()
38923896
.create_err(NoFieldOnVariant {
38933897
span: ident.span,
38943898
container,
3895-
ident,
3899+
ident: ident.0,
38963900
field: subfield,
38973901
enum_span: field.span,
38983902
field_span: subident.span,
@@ -3918,7 +3922,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
39183922
if field.vis.is_accessible_from(sub_def_scope, self.tcx) {
39193923
self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None);
39203924
} else {
3921-
self.private_field_err(ident, container_def.did()).emit();
3925+
self.private_field_err(ident.0, container_def.did()).emit();
39223926
}
39233927

39243928
// Save the index of all fields regardless of their visibility in case
@@ -3936,7 +3940,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
39363940
let fields = &container_def.non_enum_variant().fields;
39373941
if let Some((index, field)) = fields
39383942
.iter_enumerated()
3939-
.find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == ident)
3943+
.find(|(_, f)| ModernIdent::new(f.ident(self.tcx)) == ident)
39403944
{
39413945
let field_ty = self.field_ty(expr.span, field, args);
39423946

@@ -3953,7 +3957,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
39533957
if field.vis.is_accessible_from(def_scope, self.tcx) {
39543958
self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None);
39553959
} else {
3956-
self.private_field_err(ident, container_def.did()).emit();
3960+
self.private_field_err(ident.0, container_def.did()).emit();
39573961
}
39583962

39593963
// Save the index of all fields regardless of their visibility in case

compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
515515
for expr_field in expr_fields {
516516
// Look for the ExprField that matches the field, using the
517517
// same rules that check_expr_struct uses for macro hygiene.
518-
if self.tcx.adjust_ident(expr_field.ident, variant_def_id) == field.ident(self.tcx)
518+
if self.tcx.adjust_ident(expr_field.ident, variant_def_id).0
519+
== field.ident(self.tcx)
519520
{
520521
return Some((
521522
expr_field.expr,

compiler/rustc_hir_typeck/src/pat.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use rustc_session::parse::feature_err;
2525
use rustc_span::edit_distance::find_best_match_for_name;
2626
use rustc_span::edition::Edition;
2727
use rustc_span::source_map::Spanned;
28-
use rustc_span::{BytePos, DUMMY_SP, Ident, Span, kw, sym};
28+
use rustc_span::{BytePos, DUMMY_SP, Ident, ModernIdent, Span, kw, sym};
2929
use rustc_trait_selection::infer::InferCtxtExt;
3030
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode};
3131
use tracing::{debug, instrument, trace};
@@ -1907,7 +1907,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19071907
let field_map = variant
19081908
.fields
19091909
.iter_enumerated()
1910-
.map(|(i, field)| (field.ident(self.tcx).normalize_to_macros_2_0(), (i, field)))
1910+
.map(|(i, field)| (ModernIdent::new(field.ident(self.tcx)), (i, field)))
19111911
.collect::<FxHashMap<_, _>>();
19121912

19131913
// Keep track of which fields have already appeared in the pattern.
@@ -1947,7 +1947,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19471947
let mut unmentioned_fields = variant
19481948
.fields
19491949
.iter()
1950-
.map(|field| (field, field.ident(self.tcx).normalize_to_macros_2_0()))
1950+
.map(|field| (field, ModernIdent::new(field.ident(self.tcx))))
19511951
.filter(|(_, ident)| !used_fields.contains_key(ident))
19521952
.collect::<Vec<_>>();
19531953

@@ -2115,7 +2115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21152115
&self,
21162116
kind_name: &str,
21172117
inexistent_fields: &[&hir::PatField<'tcx>],
2118-
unmentioned_fields: &mut Vec<(&'tcx ty::FieldDef, Ident)>,
2118+
unmentioned_fields: &mut Vec<(&'tcx ty::FieldDef, ModernIdent)>,
21192119
pat: &'tcx Pat<'tcx>,
21202120
variant: &ty::VariantDef,
21212121
args: ty::GenericArgsRef<'tcx>,
@@ -2351,10 +2351,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23512351
fn lint_non_exhaustive_omitted_patterns(
23522352
&self,
23532353
pat: &Pat<'_>,
2354-
unmentioned_fields: &[(&ty::FieldDef, Ident)],
2354+
unmentioned_fields: &[(&ty::FieldDef, ModernIdent)],
23552355
ty: Ty<'tcx>,
23562356
) {
2357-
fn joined_uncovered_patterns(witnesses: &[&Ident]) -> String {
2357+
fn joined_uncovered_patterns(witnesses: &[&ModernIdent]) -> String {
23582358
const LIMIT: usize = 3;
23592359
match witnesses {
23602360
[] => {
@@ -2402,7 +2402,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24022402
fn error_unmentioned_fields(
24032403
&self,
24042404
pat: &Pat<'_>,
2405-
unmentioned_fields: &[(&ty::FieldDef, Ident)],
2405+
unmentioned_fields: &[(&ty::FieldDef, ModernIdent)],
24062406
have_inaccessible_fields: bool,
24072407
fields: &'tcx [hir::PatField<'tcx>],
24082408
) -> Diag<'a> {

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ use rustc_serialize::{Decodable, Encodable};
4949
use rustc_session::lint::LintBuffer;
5050
pub use rustc_session::lint::RegisteredTools;
5151
use rustc_span::hygiene::MacroKind;
52-
use rustc_span::{DUMMY_SP, ExpnId, ExpnKind, Ident, Span, Symbol, kw, sym};
52+
use rustc_span::{DUMMY_SP, ExpnId, ExpnKind, Ident, ModernIdent, Span, Symbol, kw, sym};
5353
pub use rustc_type_ir::data_structures::{DelayedMap, DelayedSet};
5454
pub use rustc_type_ir::fast_reject::DeepRejectCtxt;
5555
#[allow(
@@ -2061,21 +2061,19 @@ impl<'tcx> TyCtxt<'tcx> {
20612061
.hygienic_eq(def_ident.span.ctxt(), self.expn_that_defined(def_parent_def_id))
20622062
}
20632063

2064-
pub fn adjust_ident(self, mut ident: Ident, scope: DefId) -> Ident {
2065-
ident.span.normalize_to_macros_2_0_and_adjust(self.expn_that_defined(scope));
2066-
ident
2064+
pub fn adjust_ident(self, ident: Ident, scope: DefId) -> ModernIdent {
2065+
ModernIdent::new_and_adjust(ident, self.expn_that_defined(scope)).0
20672066
}
20682067

20692068
// FIXME(vincenzopalazzo): move the HirId to a LocalDefId
20702069
pub fn adjust_ident_and_get_scope(
20712070
self,
2072-
mut ident: Ident,
2071+
ident: Ident,
20732072
scope: DefId,
20742073
block: hir::HirId,
2075-
) -> (Ident, DefId) {
2076-
let scope = ident
2077-
.span
2078-
.normalize_to_macros_2_0_and_adjust(self.expn_that_defined(scope))
2074+
) -> (ModernIdent, DefId) {
2075+
let (ident, expnid) = ModernIdent::new_and_adjust(ident, self.expn_that_defined(scope));
2076+
let scope = expnid
20792077
.and_then(|actual_expansion| actual_expansion.expn_data().parent_module)
20802078
.unwrap_or_else(|| self.parent_module(block).to_def_id());
20812079
(ident, scope)

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use rustc_middle::bug;
2424
use rustc_middle::metadata::ModChild;
2525
use rustc_middle::ty::{Feed, Visibility};
2626
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind};
27-
use rustc_span::{Ident, Span, Symbol, kw, sym};
27+
use rustc_span::{Ident, ModernIdent, Span, Symbol, kw, sym};
2828
use tracing::debug;
2929

3030
use crate::Namespace::{MacroNS, TypeNS, ValueNS};
@@ -933,8 +933,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
933933
self.r.potentially_unused_imports.push(import);
934934
let imported_binding = self.r.import(binding, import);
935935
if parent == self.r.graph_root {
936-
let ident = ident.normalize_to_macros_2_0();
937-
if let Some(entry) = self.r.extern_prelude.get(&ident)
936+
let ident = ModernIdent::new(ident);
937+
if let Some(entry) = self.r.extern_prelude.get(&ident.0)
938938
&& expansion != LocalExpnId::ROOT
939939
&& orig_name.is_some()
940940
&& !entry.is_import()
@@ -951,7 +951,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
951951
let entry = self
952952
.r
953953
.extern_prelude
954-
.entry(ident)
954+
.entry(ident.0)
955955
.or_insert(ExternPreludeEntry { binding: None, introduced_by_item: true });
956956
if orig_name.is_some() {
957957
entry.introduced_by_item = true;
@@ -1216,7 +1216,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
12161216
self.r.local_macro_def_scopes.insert(def_id, parent_scope.module);
12171217

12181218
if macro_rules {
1219-
let ident = ident.normalize_to_macros_2_0();
1219+
let ident = ModernIdent::new(ident);
12201220
self.r.macro_names.insert(ident);
12211221
let is_macro_export = ast::attr::contains_name(&item.attrs, sym::macro_export);
12221222
let vis = if is_macro_export {
@@ -1243,17 +1243,17 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
12431243
});
12441244
self.r.import_use_map.insert(import, Used::Other);
12451245
let import_binding = self.r.import(binding, import);
1246-
self.r.define_binding(self.r.graph_root, ident, MacroNS, import_binding);
1246+
self.r.define_binding(self.r.graph_root, ident.0, MacroNS, import_binding);
12471247
} else {
12481248
self.r.check_reserved_macro_name(ident, res);
1249-
self.insert_unused_macro(ident, def_id, item.id);
1249+
self.insert_unused_macro(ident.0, def_id, item.id);
12501250
}
12511251
self.r.feed_visibility(feed, vis);
12521252
let scope = self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Binding(
12531253
self.r.arenas.alloc_macro_rules_binding(MacroRulesBinding {
12541254
parent_macro_rules_scope: parent_scope.macro_rules,
12551255
binding,
1256-
ident,
1256+
ident: ident.0,
12571257
}),
12581258
));
12591259
self.r.macro_rules_scopes.insert(def_id, scope);

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1441,7 +1441,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
14411441
self.resolutions(parent_scope.module).borrow().iter().any(
14421442
|(key, name_resolution)| {
14431443
if key.ns == TypeNS
1444-
&& key.ident == ident
1444+
&& key.ident.0 == ident
14451445
&& let Some(binding) = name_resolution.borrow().best_binding()
14461446
{
14471447
match binding.res() {

0 commit comments

Comments
 (0)