// that collisions are ok here and this shouldn't
// really show up for end-user.
let str_name = match hir_name {
- ParamName::Plain(ident) => name.as_interned_str(),
+ ParamName::Plain(ident) => ident.as_interned_str(),
ParamName::Fresh(_) => keywords::UnderscoreLifetime.name().as_interned_str(),
};
self.resolver.definitions().create_def_with_parent(
parent_id.index,
def_node_id,
- DefPathData::LifetimeDef(str_name),
+ DefPathData::LifetimeParam(str_name),
DefIndexAddressSpace::High,
Mark::root(),
span,
return;
}
- let hir_name = ParamName::Plain(name);
+ let hir_name = ParamName::Plain(ident);
if self.lifetimes_to_define.iter()
- .any(|(_, lt_name)| *lt_name.modern() == hir_name.modern()) {
+ .any(|(_, lt_name)| lt_name.modern() == hir_name.modern()) {
return;
}
let ident = Ident::from_str(&pprust::ty_to_string(t)).with_span_pos(span);
self.in_band_ty_params.push(hir::GenericParam {
id: def_node_id,
- ident: ParamName::Plain(ident),
+ name: ParamName::Plain(ident),
pure_wrt_drop: false,
attrs: hir_vec![],
bounds: hir_bounds,
+ span,
kind: hir::GenericParamKind::Type {
default: None,
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
let name = match name {
hir::LifetimeName::Underscore => {
- hir::ParamName::Plain(keywords::UnderscoreLifetime.name())
+ hir::ParamName::Plain(keywords::UnderscoreLifetime.ident())
}
hir::LifetimeName::Param(param_name) => param_name,
_ => bug!("expected LifetimeName::Param or ParamName::Plain"),
let future_params = P(hir::GenericArgs {
args: hir_vec![],
bindings: hir_vec![hir::TypeBinding {
- name: Symbol::intern(FN_OUTPUT_NAME),
+ ident: Ident::from_str(FN_OUTPUT_NAME),
ty: output_ty,
id: this.next_id().node_id,
span,
fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
let span = l.ident.span;
- match self.lower_ident(l.ident) {
+ match l.ident {
ident if ident.name == keywords::StaticLifetime.name() =>
self.new_named_lifetime(l.id, span, hir::LifetimeName::Static),
ident if ident.name == keywords::UnderscoreLifetime.name() =>
let lt = self.lower_lifetime(&Lifetime { id: param.id, ident: param.ident });
let param_name = match lt.name {
hir::LifetimeName::Param(param_name) => param_name,
- _ => hir::ParamName::Plain(lt.name.name()),
+ _ => hir::ParamName::Plain(lt.name.ident()),
};
let param = hir::GenericParam {
id: lt.id,
param
}
GenericParamKind::Type { ref default, .. } => {
- let mut name = self.lower_ident(param.ident);
-
// Don't expose `Self` (recovered "keyword used as ident" parse error).
// `rustc::ty` expects `Self` to be only used for a trait's `Self`.
// Instead, use gensym("Self") to create a distinct name that looks the same.
- if name == keywords::SelfType.name() {
- name = Symbol::gensym("Self");
- }
+ let ident = if param.ident.name == keywords::SelfType.name() {
+ param.ident.gensym()
+ } else {
+ param.ident
+ };
let add_bounds = add_bounds.get(¶m.id).map_or(&[][..], |x| &x);
if !add_bounds.is_empty() {
hir::GenericParam {
id: self.lower_node_id(param.id).node_id,
- name: hir::ParamName::Plain(name),
- span: param.ident.span,
+ name: hir::ParamName::Plain(ident),
pure_wrt_drop: attr::contains_name(¶m.attrs, "may_dangle"),
attrs: self.lower_attrs(¶m.attrs),
bounds,
+ span: ident.span,
kind: hir::GenericParamKind::Type {
default: default.as_ref().map(|x| {
self.lower_ty(x, ImplTraitContext::Disallowed)
let e2 = self.lower_expr(e2);
let ty_path = P(self.std_path(span, &["ops", "RangeInclusive"], None, false));
let ty = P(self.ty_path(id, span, hir::QPath::Resolved(None, ty_path)));
- let new_seg = P(hir::PathSegment::from_name(Ident::from_str("new")));
+ let new_seg = P(hir::PathSegment::from_ident(Ident::from_str("new")));
let new_path = hir::QPath::TypeRelative(ty, new_seg);
let new = P(self.expr(span, hir::ExprPath(new_path), ThinVec::new()));
hir::ExprCall(new, hir_vec![e1, e2])
NodeItem(&Item { node: ItemTrait(..), .. }) => {
keywords::SelfType.name()
}
- NodeGenericParam(param) => param.name.ident(),
+ NodeGenericParam(param) => param.name.ident().name,
_ => bug!("ty_param_name: {} not a type parameter", self.node_to_string(id)),
}
}
NodeField(f) => f.ident.name,
NodeLifetime(lt) => lt.name.ident().name,
NodeGenericParam(param) => param.name.ident().name,
- NodeBinding(&Pat { node: PatKind::Binding(_,_,l,_), .. }) => l.node,
+ NodeBinding(&Pat { node: PatKind::Binding(_,_,l,_), .. }) => l.name,
NodeStructCtor(_) => self.name(self.get_parent(id)),
_ => bug!("no name for {}", self.node_to_string(id))
}
Some(EntryBlock(_, _, block)) => block.span,
Some(EntryStructCtor(_, _, _)) => self.expect_item(self.get_parent(id)).span,
Some(EntryLifetime(_, _, lifetime)) => lifetime.span,
- Some(EntryGenericParam(_, _, param)) => param.ident.span,
+ Some(EntryGenericParam(_, _, param)) => param.span,
Some(EntryVisibility(_, _, &Visibility::Restricted { ref path, .. })) => path.span,
Some(EntryVisibility(_, _, v)) => bug!("unexpected Visibility {:?}", v),
Some(EntryLocal(_, _, local)) => local.span,
#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)]
pub enum ParamName {
/// Some user-given name like `T` or `'x`.
- Plain(Name),
+ Plain(Ident),
/// Synthetic name generated when user elided a lifetime in an impl header,
/// e.g. the lifetimes in cases like these:
}
impl ParamName {
- pub fn name(&self) -> Name {
+ pub fn ident(&self) -> Ident {
+ match *self {
+ ParamName::Plain(ident) => ident,
+ ParamName::Fresh(_) => keywords::UnderscoreLifetime.ident(),
+ }
+ }
+
+ pub fn modern(&self) -> ParamName {
match *self {
- ParamName::Plain(name) => name,
- ParamName::Fresh(_) => keywords::UnderscoreLifetime.name(),
+ ParamName::Plain(ident) => ParamName::Plain(ident.modern()),
+ param_name => param_name,
}
}
}
pub fn ident(&self) -> Ident {
match *self {
LifetimeName::Implicit => keywords::Invalid.ident(),
- LifetimeName::Fresh(_) | LifetimeName::Underscore =>
- keywords::UnderscoreLifetime.ident(),
+ LifetimeName::Underscore => keywords::UnderscoreLifetime.ident(),
LifetimeName::Static => keywords::StaticLifetime.ident(),
- LifetimeName::Ident(ident) => ident,
+ LifetimeName::Param(param_name) => param_name.ident(),
}
}
pub fn is_elided(&self) -> bool {
- use self::LifetimeName::*;
match self {
- Implicit | Underscore => true,
+ LifetimeName::Implicit | LifetimeName::Underscore => true,
// It might seem surprising that `Fresh(_)` counts as
// *not* elided -- but this is because, as far as the code
// in the compiler is concerned -- `Fresh(_)` variants act
// equivalently to "some fresh name". They correspond to
// early-bound regions on an impl, in other words.
- Param(_) | Static => false,
+ LifetimeName::Param(_) | LifetimeName::Static => false,
}
}
pub fn modern(&self) -> LifetimeName {
match *self {
- LifetimeName::Ident(ident) => LifetimeName::Ident(ident.modern()),
+ LifetimeName::Param(param_name) => LifetimeName::Param(param_name.modern()),
lifetime_name => lifetime_name,
}
}
pub name: ParamName,
pub attrs: HirVec<Attribute>,
pub bounds: GenericBounds,
+ pub span: Span,
pub pure_wrt_drop: bool,
pub kind: GenericParamKind,
}
pub fn print_generic_param(&mut self, param: &GenericParam) -> io::Result<()> {
- self.print_name(param.name.name())?;
+ self.print_ident(param.name.ident())?;
match param.kind {
GenericParamKind::Lifetime { .. } => {
let mut sep = ":";
}
pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) -> io::Result<()> {
- self.print_name(lifetime.name.name())
+ self.print_ident(lifetime.name.ident())
}
pub fn print_where_clause(&mut self, where_clause: &hir::WhereClause) -> io::Result<()> {
pure_wrt_drop,
attrs,
bounds,
+ span,
kind
});
GenericParamKind::Lifetime { .. } => {
let (name, reg) = Region::early(&self.tcx.hir, &mut index, ¶m);
if let hir::ParamName::Plain(param_name) = name {
- if param_name == keywords::UnderscoreLifetime.name() {
+ if param_name.name == keywords::UnderscoreLifetime.name() {
// Pick the elided lifetime "definition" if one exists
// and use it to make an elision scope.
elision = Some(reg);
ref lifetimes, s, ..
} => {
// FIXME (#24278): non-hygienic comparison
- if let Some(def) = lifetimes.get(&hir::LifetimeName::Ident(label.modern())) {
+ if let Some(def) = lifetimes.get(&hir::ParamName::Plain(label.modern())) {
let node_id = tcx.hir.as_local_node_id(def.id().unwrap()).unwrap();
signal_shadowing_problem(
debug!("node id first={:?}", node_id);
if let Some((id, span, name)) = match self.tcx.hir.get(node_id) {
hir::map::NodeLifetime(hir_lifetime) => {
- Some((hir_lifetime.id, hir_lifetime.span, hir_lifetime.name.name()))
+ Some((hir_lifetime.id, hir_lifetime.span, hir_lifetime.name.ident()))
}
hir::map::NodeGenericParam(param) => {
- Some((param.id, param.span, param.name.name()))
+ Some((param.id, param.span, param.name.ident()))
}
_ => None,
} {
let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
if let Some((id, span, name)) = match self.tcx.hir.get(node_id) {
hir::map::NodeLifetime(hir_lifetime) => {
- Some((hir_lifetime.id, hir_lifetime.span, hir_lifetime.name.name()))
+ Some((hir_lifetime.id, hir_lifetime.span, hir_lifetime.name.ident()))
}
hir::map::NodeGenericParam(param) => {
- Some((param.id, param.span, param.name.name()))
+ Some((param.id, param.span, param.name.ident()))
}
_ => None,
} {
}).collect();
for (i, (lifetime_i, lifetime_i_name)) in lifetimes.iter().enumerate() {
if let hir::ParamName::Plain(_) = lifetime_i_name {
- let name = lifetime_i_name.name();
+ let name = lifetime_i_name.ident().name;
if name == keywords::UnderscoreLifetime.name() ||
name == keywords::StaticLifetime.name() {
let mut err = struct_span_err!(
lifetime_i.span,
E0262,
"invalid lifetime parameter name: `{}`",
- lifetime
+ lifetime_i.name.ident(),
);
err.span_label(
lifetime_i.span,
lifetime_j.span,
E0263,
"lifetime name `{}` declared twice in the same scope",
- lifetime_j.name.name()
+ lifetime_j.name.ident()
).span_label(lifetime_j.span, "declared twice")
.span_label(lifetime_i.span, "previous declaration here")
.emit();
lifetime_i.span.to(lt.span),
&format!(
"unnecessary lifetime parameter `{}`",
- lifetime_i.name.name(),
+ lifetime_i.name.ident(),
),
).help(&format!(
"you can use the `'static` lifetime directly, in place \
of `{}`",
- lifetime_i.name.name(),
+ lifetime_i.name.ident(),
)).emit();
}
hir::LifetimeName::Param(_)
}
debug!("insert_late_bound_lifetimes: lifetime {:?} with id {:?} is late-bound",
- param.name.name(),
+ param.name.ident(),
param.id);
let inserted = map.late_bound.insert(param.id);
err.span_suggestion_with_applicability(
p.span,
"to match on the variant, qualify the path",
- format!("{}::{}", ty_path, name.node),
+ format!("{}::{}", ty_path, ident),
Applicability::MachineApplicable
);
err.emit();
args: Option<P<hir::GenericArgs>>,
is_value: bool
) -> hir::Path {
- let mut segments = iter::once(keywords::CrateRoot.name())
+ let mut segments = iter::once(keywords::CrateRoot.ident())
.chain(
crate_root.into_iter()
.chain(components.iter().cloned())
- .map(Symbol::intern)
- ).map(hir::PathSegment::from_name).collect::<Vec<_>>();
+ .map(Ident::from_str)
+ ).map(hir::PathSegment::from_ident).collect::<Vec<_>>();
if let Some(args) = args {
- let name = segments.last().unwrap().name;
+ let ident = segments.last().unwrap().ident;
*segments.last_mut().unwrap() = hir::PathSegment {
- name,
+ ident,
args: Some(args),
infer_types: true,
};
// ... except when we try to 'break rust;'.
// ICE this expression in particular (see #43162).
if let hir::ExprPath(hir::QPath::Resolved(_, ref path)) = e.node {
- if path.segments.len() == 1 && path.segments[0].name == "rust" {
+ if path.segments.len() == 1 && path.segments[0].ident.name == "rust" {
fatally_break_rust(self.tcx.sess);
}
}
match param.kind {
ty::GenericParamDefKind::Lifetime => {
let name = if param.name == "" {
- hir::ParamName::Plain(keywords::StaticLifetime.name())
+ hir::ParamName::Plain(keywords::StaticLifetime.ident())
} else {
hir::ParamName::Plain(ast::Ident::from_interned_str(param.name))
};
hir::GenericBound::Outlives(lt) => lt,
_ => panic!(),
});
- let name = bounds.next().unwrap().name.name();
- let mut s = format!("{}: {}", self.name.name(), name);
+ let name = bounds.next().unwrap().name.ident();
+ let mut s = format!("{}: {}", self.name.ident(), name);
for bound in bounds {
- s.push_str(&format!(" + {}", bound.name.name()));
+ s.push_str(&format!(" + {}", bound.name.ident()));
}
s
} else {
- self.name.name().to_string()
+ self.name.ident().to_string()
};
(name, GenericParamDefKind::Lifetime)
}
hir::GenericParamKind::Type { ref default, synthetic, .. } => {
- (self.name.name().clean(cx), GenericParamDefKind::Type {
+ (self.name.ident().name.clean(cx), GenericParamDefKind::Type {
did: cx.tcx.hir.local_def_id(self.id),
bounds: self.bounds.clean(cx),
default: default.clean(cx),
Ident::new(Symbol::intern(self.as_str().trim_left_matches('\'')), self.span)
}
+ /// "Normalize" ident for use in comparisons using "item hygiene".
+ /// Identifiers with same string value become same if they came from the same "modern" macro
+ /// (e.g. `macro` item, but not `macro_rules` item) and stay different if they came from
+ /// different "modern" macros.
+ /// Technically, this operation strips all non-opaque marks from ident's syntactic context.
pub fn modern(self) -> Ident {
Ident::new(self.name, self.span.modern())
}