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.
This commit is contained in:
parent
fe04460f6f
commit
0b2d7062c4
7 changed files with 29 additions and 8 deletions
|
@ -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(),
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue