Skip to content

Commit 117cdf3

Browse files
committed
Auto merge of #64469 - matthewjasper:increase-hygiene-use, r=petrochenkov
Cleanup handling of hygiene for built-in macros This makes most identifiers generated by built-in macros use def-site hygiene, not only the ones that previously used gensyms. * `ExtCtxt::ident_of` now takes a `Span` and is preferred to `Ident::{from_str, from_str_and_span}` * Remove `Span::with_legacy_ctxt` * `assert` now uses call-site hygiene because it needs to resolve `panic` unhygienically. * `concat_idents` now uses call-site hygiene because it wouldn't be very useful with def-site hygiene. * everything else is moved to def-site hygiene r? @petrochenkov
2 parents 8bf776d + 8ab67c8 commit 117cdf3

31 files changed

+161
-153
lines changed

src/librustc/hir/lowering.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,7 @@ impl<'a> LoweringContext<'a> {
13161316
ImplTraitContext::Universal(in_band_ty_params),
13171317
);
13181318
// Set the name to `impl Bound1 + Bound2`.
1319-
let ident = Ident::from_str(&pprust::ty_to_string(t)).with_span_pos(span);
1319+
let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
13201320
in_band_ty_params.push(hir::GenericParam {
13211321
hir_id: self.lower_node_id(def_node_id),
13221322
name: ParamName::Plain(ident),

src/librustc_lint/unused.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -618,24 +618,19 @@ impl UnusedImportBraces {
618618
}
619619

620620
// Trigger the lint if the nested item is a non-self single item
621-
let node_ident;
622-
match items[0].0.kind {
621+
let node_name = match items[0].0.kind {
623622
ast::UseTreeKind::Simple(rename, ..) => {
624623
let orig_ident = items[0].0.prefix.segments.last().unwrap().ident;
625624
if orig_ident.name == kw::SelfLower {
626625
return;
627626
}
628-
node_ident = rename.unwrap_or(orig_ident);
627+
rename.unwrap_or(orig_ident).name
629628
}
630-
ast::UseTreeKind::Glob => {
631-
node_ident = ast::Ident::from_str("*");
632-
}
633-
ast::UseTreeKind::Nested(_) => {
634-
return;
635-
}
636-
}
629+
ast::UseTreeKind::Glob => Symbol::intern("*"),
630+
ast::UseTreeKind::Nested(_) => return,
631+
};
637632

638-
let msg = format!("braces around {} is unnecessary", node_ident.name);
633+
let msg = format!("braces around {} is unnecessary", node_name);
639634
cx.span_lint(UNUSED_IMPORT_BRACES, item.span, &msg);
640635
}
641636
}

src/librustc_metadata/cstore_impl.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,8 @@ impl cstore::CStore {
444444
.insert(local_span, (name.to_string(), data.get_span(id.index, sess)));
445445

446446
LoadedMacro::MacroDef(ast::Item {
447-
ident: ast::Ident::from_str(&name.as_str()),
447+
// FIXME: cross-crate hygiene
448+
ident: ast::Ident::with_dummy_span(name.as_symbol()),
448449
id: ast::DUMMY_NODE_ID,
449450
span: local_span,
450451
attrs: attrs.iter().cloned().collect(),

src/librustc_resolve/lib.rs

+16-18
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use rustc_metadata::cstore::CStore;
4040
use syntax::ext::hygiene::{ExpnId, Transparency, SyntaxContext};
4141
use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy};
4242
use syntax::ext::base::{SyntaxExtension, MacroKind, SpecialDerives};
43-
use syntax::symbol::{Symbol, kw, sym};
43+
use syntax::symbol::{kw, sym};
4444

4545
use syntax::visit::{self, Visitor};
4646
use syntax::attr;
@@ -241,7 +241,7 @@ impl Segment {
241241

242242
fn names_to_string(segments: &[Segment]) -> String {
243243
names_to_string(&segments.iter()
244-
.map(|seg| seg.ident)
244+
.map(|seg| seg.ident.name)
245245
.collect::<Vec<_>>())
246246
}
247247
}
@@ -951,7 +951,7 @@ pub struct Resolver<'a> {
951951
struct_constructors: DefIdMap<(Res, ty::Visibility)>,
952952

953953
/// Features enabled for this crate.
954-
active_features: FxHashSet<Symbol>,
954+
active_features: FxHashSet<Name>,
955955

956956
/// Stores enum visibilities to properly build a reduced graph
957957
/// when visiting the correspondent variants.
@@ -1018,8 +1018,8 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
10181018
fn resolve_str_path(
10191019
&mut self,
10201020
span: Span,
1021-
crate_root: Option<Symbol>,
1022-
components: &[Symbol],
1021+
crate_root: Option<Name>,
1022+
components: &[Name],
10231023
ns: Namespace,
10241024
) -> (ast::Path, Res) {
10251025
let root = if crate_root.is_some() {
@@ -2555,7 +2555,7 @@ impl<'a> Resolver<'a> {
25552555
fn add_suggestion_for_rename_of_use(
25562556
&self,
25572557
err: &mut DiagnosticBuilder<'_>,
2558-
name: Symbol,
2558+
name: Name,
25592559
directive: &ImportDirective<'_>,
25602560
binding_span: Span,
25612561
) {
@@ -2770,38 +2770,37 @@ impl<'a> Resolver<'a> {
27702770
}
27712771
}
27722772

2773-
fn names_to_string(idents: &[Ident]) -> String {
2773+
fn names_to_string(names: &[Name]) -> String {
27742774
let mut result = String::new();
2775-
for (i, ident) in idents.iter()
2776-
.filter(|ident| ident.name != kw::PathRoot)
2775+
for (i, name) in names.iter()
2776+
.filter(|name| **name != kw::PathRoot)
27772777
.enumerate() {
27782778
if i > 0 {
27792779
result.push_str("::");
27802780
}
2781-
result.push_str(&ident.as_str());
2781+
result.push_str(&name.as_str());
27822782
}
27832783
result
27842784
}
27852785

27862786
fn path_names_to_string(path: &Path) -> String {
27872787
names_to_string(&path.segments.iter()
2788-
.map(|seg| seg.ident)
2788+
.map(|seg| seg.ident.name)
27892789
.collect::<Vec<_>>())
27902790
}
27912791

27922792
/// A somewhat inefficient routine to obtain the name of a module.
27932793
fn module_to_string(module: Module<'_>) -> Option<String> {
27942794
let mut names = Vec::new();
27952795

2796-
fn collect_mod(names: &mut Vec<Ident>, module: Module<'_>) {
2796+
fn collect_mod(names: &mut Vec<Name>, module: Module<'_>) {
27972797
if let ModuleKind::Def(.., name) = module.kind {
27982798
if let Some(parent) = module.parent {
2799-
names.push(Ident::with_dummy_span(name));
2799+
names.push(name);
28002800
collect_mod(names, parent);
28012801
}
28022802
} else {
2803-
// danger, shouldn't be ident?
2804-
names.push(Ident::from_str("<opaque>"));
2803+
names.push(Name::intern("<opaque>"));
28052804
collect_mod(names, module.parent.unwrap());
28062805
}
28072806
}
@@ -2810,9 +2809,8 @@ fn module_to_string(module: Module<'_>) -> Option<String> {
28102809
if names.is_empty() {
28112810
return None;
28122811
}
2813-
Some(names_to_string(&names.into_iter()
2814-
.rev()
2815-
.collect::<Vec<_>>()))
2812+
names.reverse();
2813+
Some(names_to_string(&names))
28162814
}
28172815

28182816
#[derive(Copy, Clone, Debug)]

src/librustc_resolve/resolve_imports.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1433,15 +1433,17 @@ fn import_path_to_string(names: &[Ident],
14331433
let global = !names.is_empty() && names[0].name == kw::PathRoot;
14341434
if let Some(pos) = pos {
14351435
let names = if global { &names[1..pos + 1] } else { &names[..pos + 1] };
1436-
names_to_string(names)
1436+
names_to_string(&names.iter().map(|ident| ident.name).collect::<Vec<_>>())
14371437
} else {
14381438
let names = if global { &names[1..] } else { names };
14391439
if names.is_empty() {
14401440
import_directive_subclass_to_string(subclass)
14411441
} else {
1442-
format!("{}::{}",
1443-
names_to_string(names),
1444-
import_directive_subclass_to_string(subclass))
1442+
format!(
1443+
"{}::{}",
1444+
names_to_string(&names.iter().map(|ident| ident.name).collect::<Vec<_>>()),
1445+
import_directive_subclass_to_string(subclass),
1446+
)
14451447
}
14461448
}
14471449
}

src/libsyntax/ext/base.rs

+2-9
Original file line numberDiff line numberDiff line change
@@ -977,13 +977,6 @@ impl<'a> ExtCtxt<'a> {
977977
span.with_call_site_ctxt(self.current_expansion.id)
978978
}
979979

980-
/// Span with a context reproducing `macro_rules` hygiene (hygienic locals, unhygienic items).
981-
/// FIXME: This should be eventually replaced either with `with_def_site_ctxt` (preferably),
982-
/// or with `with_call_site_ctxt` (where necessary).
983-
pub fn with_legacy_ctxt(&self, span: Span) -> Span {
984-
span.with_legacy_ctxt(self.current_expansion.id)
985-
}
986-
987980
/// Returns span for the macro which originally caused the current expansion to happen.
988981
///
989982
/// Stops backtracing at include! boundary.
@@ -1081,8 +1074,8 @@ impl<'a> ExtCtxt<'a> {
10811074
pub fn set_trace_macros(&mut self, x: bool) {
10821075
self.ecfg.trace_mac = x
10831076
}
1084-
pub fn ident_of(&self, st: &str) -> ast::Ident {
1085-
ast::Ident::from_str(st)
1077+
pub fn ident_of(&self, st: &str, sp: Span) -> ast::Ident {
1078+
ast::Ident::from_str_and_span(st, sp)
10861079
}
10871080
pub fn std_path(&self, components: &[Symbol]) -> Vec<ast::Ident> {
10881081
let def_site = self.with_def_site_ctxt(DUMMY_SP);

src/libsyntax/ext/build.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ impl<'a> ExtCtxt<'a> {
363363
self.expr(sp, ast::ExprKind::Field(expr, ident.with_span_pos(sp)))
364364
}
365365
pub fn expr_tup_field_access(&self, sp: Span, expr: P<ast::Expr>, idx: usize) -> P<ast::Expr> {
366-
let ident = Ident::from_str(&idx.to_string()).with_span_pos(sp);
366+
let ident = Ident::new(sym::integer(idx), sp);
367367
self.expr(sp, ast::ExprKind::Field(expr, ident))
368368
}
369369
pub fn expr_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> {
@@ -525,7 +525,7 @@ impl<'a> ExtCtxt<'a> {
525525
let err = self.std_path(&[sym::result, sym::Result, sym::Err]);
526526
let err_path = self.path_global(sp, err);
527527

528-
let binding_variable = self.ident_of("__try_var");
528+
let binding_variable = self.ident_of("__try_var", sp);
529529
let binding_pat = self.pat_ident(sp, binding_variable);
530530
let binding_expr = self.expr_ident(sp, binding_variable);
531531

src/libsyntax/parse/parser/item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1256,7 +1256,7 @@ impl<'a> Parser<'a> {
12561256
for part in idents {
12571257
fixed_name.push_str(&format!("_{}", part.name));
12581258
}
1259-
ident = Ident::from_str(&fixed_name).with_span_pos(fixed_name_sp);
1259+
ident = Ident::from_str_and_span(&fixed_name, fixed_name_sp);
12601260

12611261
self.struct_span_err(fixed_name_sp, error_msg)
12621262
.span_label(fixed_name_sp, "dash-separated idents are not valid")

src/libsyntax_ext/asm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
6262
MacEager::expr(P(ast::Expr {
6363
id: ast::DUMMY_NODE_ID,
6464
node: ast::ExprKind::InlineAsm(P(inline_asm)),
65-
span: cx.with_legacy_ctxt(sp),
65+
span: cx.with_def_site_ctxt(sp),
6666
attrs: ThinVec::new(),
6767
}))
6868
}

src/libsyntax_ext/assert.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ pub fn expand_assert<'cx>(
2323
}
2424
};
2525

26-
let sp = cx.with_legacy_ctxt(sp);
26+
// `core::panic` and `std::panic` are different macros, so we use call-site
27+
// context to pick up whichever is currently in scope.
28+
let sp = cx.with_call_site_ctxt(sp);
2729
let panic_call = Mac {
2830
path: Path::from_ident(Ident::new(sym::panic, sp)),
2931
tts: custom_message.unwrap_or_else(|| {

src/libsyntax_ext/cfg.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub fn expand_cfg(
1616
sp: Span,
1717
tts: TokenStream,
1818
) -> Box<dyn base::MacResult + 'static> {
19-
let sp = cx.with_legacy_ctxt(sp);
19+
let sp = cx.with_def_site_ctxt(sp);
2020

2121
match parse_cfg(cx, sp, tts) {
2222
Ok(cfg) => {

src/libsyntax_ext/concat.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,6 @@ pub fn expand_concat(
5959
} else if has_errors {
6060
return DummyResult::any(sp);
6161
}
62-
let sp = cx.with_legacy_ctxt(sp);
62+
let sp = cx.with_def_site_ctxt(sp);
6363
base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
6464
}

src/libsyntax_ext/concat_idents.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub fn expand_concat_idents<'cx>(cx: &'cx mut ExtCtxt<'_>,
3939
}
4040
}
4141

42-
let ident = ast::Ident::new(Symbol::intern(&res_str), cx.with_legacy_ctxt(sp));
42+
let ident = ast::Ident::new(Symbol::intern(&res_str), cx.with_call_site_ctxt(sp));
4343

4444
struct ConcatIdentsResult { ident: ast::Ident }
4545

src/libsyntax_ext/deriving/cmp/partial_ord.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ pub fn some_ordering_collapsed(
109109
GtOp => "gt",
110110
GeOp => "ge",
111111
};
112-
cx.expr_method_call(span, lft, ast::Ident::from_str_and_span(op_str, span), vec![rgt])
112+
cx.expr_method_call(span, lft, cx.ident_of(op_str, span), vec![rgt])
113113
}
114114

115115
pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {

src/libsyntax_ext/deriving/debug.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
6262
// We want to make sure we have the ctxt set so that we can use unstable methods
6363
let span = cx.with_def_site_ctxt(span);
6464
let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
65-
let builder = Ident::from_str_and_span("debug_trait_builder", span);
65+
let builder = cx.ident_of("debug_trait_builder", span);
6666
let builder_expr = cx.expr_ident(span, builder.clone());
6767

6868
let fmt = substr.nonself_args[0].clone();
@@ -72,7 +72,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
7272
ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => {
7373
// tuple struct/"normal" variant
7474
let expr =
75-
cx.expr_method_call(span, fmt, Ident::from_str("debug_tuple"), vec![name]);
75+
cx.expr_method_call(span, fmt, cx.ident_of("debug_tuple", span), vec![name]);
7676
stmts.push(cx.stmt_let(span, true, builder, expr));
7777

7878
for field in fields {
@@ -93,7 +93,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
9393
ast::VariantData::Struct(..) => {
9494
// normal struct/struct variant
9595
let expr =
96-
cx.expr_method_call(span, fmt, Ident::from_str("debug_struct"), vec![name]);
96+
cx.expr_method_call(span, fmt, cx.ident_of("debug_struct", span), vec![name]);
9797
stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr));
9898

9999
for field in fields {
@@ -113,7 +113,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
113113
}
114114
}
115115

116-
let expr = cx.expr_method_call(span, builder_expr, Ident::from_str("finish"), vec![]);
116+
let expr = cx.expr_method_call(span, builder_expr, cx.ident_of("finish", span), vec![]);
117117

118118
stmts.push(cx.stmt_expr(expr));
119119
let block = cx.block(span, stmts);

src/libsyntax_ext/deriving/decodable.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,14 @@ fn decodable_substructure(cx: &mut ExtCtxt<'_>,
6666
krate: &str)
6767
-> P<Expr> {
6868
let decoder = substr.nonself_args[0].clone();
69-
let recurse = vec![cx.ident_of(krate), cx.ident_of("Decodable"), cx.ident_of("decode")];
69+
let recurse = vec![
70+
cx.ident_of(krate, trait_span),
71+
cx.ident_of("Decodable", trait_span),
72+
cx.ident_of("decode", trait_span),
73+
];
7074
let exprdecode = cx.expr_path(cx.path_global(trait_span, recurse));
7175
// throw an underscore in front to suppress unused variable warnings
72-
let blkarg = cx.ident_of("_d");
76+
let blkarg = cx.ident_of("_d", trait_span);
7377
let blkdecoder = cx.expr_ident(trait_span, blkarg);
7478

7579
return match *substr.fields {
@@ -78,7 +82,7 @@ fn decodable_substructure(cx: &mut ExtCtxt<'_>,
7882
Unnamed(ref fields, _) => fields.len(),
7983
Named(ref fields) => fields.len(),
8084
};
81-
let read_struct_field = cx.ident_of("read_struct_field");
85+
let read_struct_field = cx.ident_of("read_struct_field", trait_span);
8286

8387
let path = cx.path_ident(trait_span, substr.type_ident);
8488
let result =
@@ -94,17 +98,17 @@ fn decodable_substructure(cx: &mut ExtCtxt<'_>,
9498
let result = cx.expr_ok(trait_span, result);
9599
cx.expr_method_call(trait_span,
96100
decoder,
97-
cx.ident_of("read_struct"),
101+
cx.ident_of("read_struct", trait_span),
98102
vec![cx.expr_str(trait_span, substr.type_ident.name),
99103
cx.expr_usize(trait_span, nfields),
100104
cx.lambda1(trait_span, result, blkarg)])
101105
}
102106
StaticEnum(_, ref fields) => {
103-
let variant = cx.ident_of("i");
107+
let variant = cx.ident_of("i", trait_span);
104108

105109
let mut arms = Vec::with_capacity(fields.len() + 1);
106110
let mut variants = Vec::with_capacity(fields.len());
107-
let rvariant_arg = cx.ident_of("read_enum_variant_arg");
111+
let rvariant_arg = cx.ident_of("read_enum_variant_arg", trait_span);
108112

109113
for (i, &(ident, v_span, ref parts)) in fields.iter().enumerate() {
110114
variants.push(cx.expr_str(v_span, ident.name));
@@ -132,11 +136,11 @@ fn decodable_substructure(cx: &mut ExtCtxt<'_>,
132136
let variant_vec = cx.expr_addr_of(trait_span, variant_vec);
133137
let result = cx.expr_method_call(trait_span,
134138
blkdecoder,
135-
cx.ident_of("read_enum_variant"),
139+
cx.ident_of("read_enum_variant", trait_span),
136140
vec![variant_vec, lambda]);
137141
cx.expr_method_call(trait_span,
138142
decoder,
139-
cx.ident_of("read_enum"),
143+
cx.ident_of("read_enum", trait_span),
140144
vec![cx.expr_str(trait_span, substr.type_ident.name),
141145
cx.lambda1(trait_span, result, blkarg)])
142146
}

0 commit comments

Comments
 (0)