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(),
|
span: Default::default(),
|
||||||
tokens: Default::default(),
|
tokens: Default::default(),
|
||||||
},
|
},
|
||||||
ident: Ident::empty(),
|
ident: Ident::dummy(),
|
||||||
kind: ItemKind::ExternCrate(None),
|
kind: ItemKind::ExternCrate(None),
|
||||||
tokens: Default::default(),
|
tokens: Default::default(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ use rustc_errors::{DiagCtxtHandle, Diagnostic};
|
||||||
use rustc_feature::Features;
|
use rustc_feature::Features;
|
||||||
use rustc_hir::{AttrArgs, AttrItem, AttrPath, Attribute, HashIgnoredAttrId};
|
use rustc_hir::{AttrArgs, AttrItem, AttrPath, Attribute, HashIgnoredAttrId};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::symbol::kw;
|
|
||||||
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
|
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
|
||||||
|
|
||||||
use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser};
|
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)",
|
"expr in place where literal is expected (builtin attr parsing)",
|
||||||
);
|
);
|
||||||
ast::MetaItemLit {
|
ast::MetaItemLit {
|
||||||
symbol: kw::Empty,
|
symbol: sym::dummy,
|
||||||
suffix: None,
|
suffix: None,
|
||||||
kind: ast::LitKind::Err(guar),
|
kind: ast::LitKind::Err(guar),
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
|
|
|
@ -12,7 +12,7 @@ use rustc_ast::{AttrArgs, DelimArgs, Expr, ExprKind, LitKind, MetaItemLit, Norma
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_errors::DiagCtxtHandle;
|
use rustc_errors::DiagCtxtHandle;
|
||||||
use rustc_hir::{self as hir, AttrPath};
|
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};
|
use rustc_span::{ErrorGuaranteed, Span, Symbol};
|
||||||
|
|
||||||
pub struct SegmentIterator<'a> {
|
pub struct SegmentIterator<'a> {
|
||||||
|
@ -360,7 +360,7 @@ fn expr_to_lit(dcx: DiagCtxtHandle<'_>, expr: &Expr, span: Span) -> MetaItemLit
|
||||||
span,
|
span,
|
||||||
"expr in place where literal is expected (builtin attr parsing)",
|
"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 =
|
let msg =
|
||||||
format!("expected identifier, found `{}`", pprust::token_to_string(token),);
|
format!("expected identifier, found `{}`", pprust::token_to_string(token),);
|
||||||
sess.dcx().span_err(token.span, msg);
|
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.
|
// There are no more tokens. Just return the `$` we already have.
|
||||||
|
|
|
@ -243,7 +243,7 @@ impl<'hir> PathSegment<'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn invalid() -> Self {
|
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> {
|
pub fn args(&self) -> &GenericArgs<'hir> {
|
||||||
|
|
|
@ -2266,7 +2266,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||||
&& !first.ident.is_path_segment_keyword() =>
|
&& !first.ident.is_path_segment_keyword() =>
|
||||||
{
|
{
|
||||||
// Insert a placeholder that's later replaced by `self`/`super`/etc.
|
// 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,
|
_ => return None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,15 @@ symbols! {
|
||||||
// Special reserved identifiers used internally for elided lifetimes,
|
// Special reserved identifiers used internally for elided lifetimes,
|
||||||
// unnamed method parameters, crate root module, error recovery etc.
|
// unnamed method parameters, crate root module, error recovery etc.
|
||||||
// Matching predicates: `is_any_keyword`, `is_special`/`is_reserved`
|
// 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: "",
|
Empty: "",
|
||||||
PathRoot: "{{root}}",
|
PathRoot: "{{root}}",
|
||||||
DollarCrate: "$crate",
|
DollarCrate: "$crate",
|
||||||
|
@ -834,6 +843,7 @@ symbols! {
|
||||||
drop_types_in_const,
|
drop_types_in_const,
|
||||||
dropck_eyepatch,
|
dropck_eyepatch,
|
||||||
dropck_parametricity,
|
dropck_parametricity,
|
||||||
|
dummy: "<!dummy!>", // use this instead of `kw::Empty` for symbols that won't be used
|
||||||
dummy_cgu_name,
|
dummy_cgu_name,
|
||||||
dylib,
|
dylib,
|
||||||
dyn_compatible_for_dispatch,
|
dyn_compatible_for_dispatch,
|
||||||
|
@ -2305,11 +2315,23 @@ impl Ident {
|
||||||
Ident::new(name, DUMMY_SP)
|
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]
|
#[inline]
|
||||||
pub fn empty() -> Ident {
|
pub fn empty() -> Ident {
|
||||||
Ident::with_dummy_span(kw::Empty)
|
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.
|
/// Maps a string to an identifier with a dummy span.
|
||||||
pub fn from_str(string: &str) -> Ident {
|
pub fn from_str(string: &str) -> Ident {
|
||||||
Ident::with_dummy_span(Symbol::intern(string))
|
Ident::with_dummy_span(Symbol::intern(string))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue