diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2025-03-04 17:10:55 +1100 |
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2025-03-12 09:35:11 +1100 |
| commit | 0b2d7062c47fa385ff83e20dc53b13c8c5ba4616 (patch) | |
| tree | 4bc279d596a743d5ea5d9defb03616783b67663d | |
| parent | fe04460f6fdc32c0783ca7cab6a0fb73ed254100 (diff) | |
| download | rust-0b2d7062c47fa385ff83e20dc53b13c8c5ba4616.tar.gz rust-0b2d7062c47fa385ff83e20dc53b13c8c5ba4616.zip | |
Introduce `sym::dummy` and `Ident::dummy`.
The idea is to identify cases of symbols/identifiers that are not expected to be used. There isn't a perfectly sharp line between "dummy" and "not dummy", but I think it's useful nonetheless.
| -rw-r--r-- | compiler/rustc_ast/src/mut_visit.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_attr_parsing/src/context.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_attr_parsing/src/parser.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/mbe/quoted.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/hir.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 22 |
7 files changed, 29 insertions, 8 deletions
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index e4396a50a15..fc31912283a 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1948,7 +1948,7 @@ impl DummyAstNode for Item { span: Default::default(), tokens: Default::default(), }, - ident: Ident::empty(), + ident: Ident::dummy(), kind: ItemKind::ExternCrate(None), tokens: Default::default(), } diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 0e6b0bab082..35541bb04bd 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -9,7 +9,6 @@ use rustc_errors::{DiagCtxtHandle, Diagnostic}; use rustc_feature::Features; use rustc_hir::{AttrArgs, AttrItem, AttrPath, Attribute, HashIgnoredAttrId}; use rustc_session::Session; -use rustc_span::symbol::kw; use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser}; @@ -338,7 +337,7 @@ impl<'sess> AttributeParser<'sess> { "expr in place where literal is expected (builtin attr parsing)", ); ast::MetaItemLit { - symbol: kw::Empty, + symbol: sym::dummy, suffix: None, kind: ast::LitKind::Err(guar), span: DUMMY_SP, diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index f0cce26f4e2..a8a1460591c 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -12,7 +12,7 @@ use rustc_ast::{AttrArgs, DelimArgs, Expr, ExprKind, LitKind, MetaItemLit, Norma use rustc_ast_pretty::pprust; use rustc_errors::DiagCtxtHandle; use rustc_hir::{self as hir, AttrPath}; -use rustc_span::symbol::{Ident, kw}; +use rustc_span::symbol::{Ident, kw, sym}; use rustc_span::{ErrorGuaranteed, Span, Symbol}; pub struct SegmentIterator<'a> { @@ -360,7 +360,7 @@ fn expr_to_lit(dcx: DiagCtxtHandle<'_>, expr: &Expr, span: Span) -> MetaItemLit span, "expr in place where literal is expected (builtin attr parsing)", ); - MetaItemLit { symbol: kw::Empty, suffix: None, kind: LitKind::Err(guar), span } + MetaItemLit { symbol: sym::dummy, suffix: None, kind: LitKind::Err(guar), span } } } diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index 8cb001391c5..0ea53627fe7 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -274,7 +274,7 @@ fn parse_tree<'a>( let msg = format!("expected identifier, found `{}`", pprust::token_to_string(token),); sess.dcx().span_err(token.span, msg); - TokenTree::MetaVar(token.span, Ident::empty()) + TokenTree::MetaVar(token.span, Ident::dummy()) } // There are no more tokens. Just return the `$` we already have. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 53f0194091c..4ec7aff7286 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -243,7 +243,7 @@ impl<'hir> PathSegment<'hir> { } pub fn invalid() -> Self { - Self::new(Ident::empty(), HirId::INVALID, Res::Err) + Self::new(Ident::dummy(), HirId::INVALID, Res::Err) } pub fn args(&self) -> &GenericArgs<'hir> { diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index e3405c89b79..88d1126de1a 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2266,7 +2266,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && !first.ident.is_path_segment_keyword() => { // Insert a placeholder that's later replaced by `self`/`super`/etc. - path.insert(0, Segment::from_ident(Ident::empty())); + path.insert(0, Segment::from_ident(Ident::dummy())); } _ => return None, } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 718f23d761f..8a8bec35d81 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -33,6 +33,15 @@ symbols! { // Special reserved identifiers used internally for elided lifetimes, // unnamed method parameters, crate root module, error recovery etc. // Matching predicates: `is_any_keyword`, `is_special`/`is_reserved` + // + // Notes about `kw::Empty`: + // - Its use can blur the lines between "empty symbol" and "no symbol". + // Using `Option<Symbol>` is preferable, where possible, because that + // is unambiguous. + // - For dummy symbols that are never used and absolutely must be + // present, it's better to use `sym::dummy` than `kw::Empty`, because + // it's clearer that it's intended as a dummy value, and more likely + // to be detected if it accidentally does get used. Empty: "", PathRoot: "{{root}}", DollarCrate: "$crate", @@ -834,6 +843,7 @@ symbols! { drop_types_in_const, dropck_eyepatch, dropck_parametricity, + dummy: "<!dummy!>", // use this instead of `kw::Empty` for symbols that won't be used dummy_cgu_name, dylib, dyn_compatible_for_dispatch, @@ -2305,11 +2315,23 @@ impl Ident { Ident::new(name, DUMMY_SP) } + /// This is best avoided, because it blurs the lines between "empty + /// identifier" and "no identifier". Using `Option<Ident>` is preferable, + /// where possible, because that is unambiguous. #[inline] pub fn empty() -> Ident { Ident::with_dummy_span(kw::Empty) } + // For dummy identifiers that are never used and absolutely must be + // present, it's better to use `Ident::dummy` than `Ident::Empty`, because + // it's clearer that it's intended as a dummy value, and more likely to be + // detected if it accidentally does get used. + #[inline] + pub fn dummy() -> Ident { + Ident::with_dummy_span(sym::dummy) + } + /// Maps a string to an identifier with a dummy span. pub fn from_str(string: &str) -> Ident { Ident::with_dummy_span(Symbol::intern(string)) |
