Separate lifetime ident from resolution in HIR.

This commit is contained in:
Camille GILLOT 2022-11-05 22:41:07 +00:00
parent d121aa3b55
commit fb7d25e978
28 changed files with 177 additions and 273 deletions

View file

@ -303,7 +303,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
} }
fn visit_lifetime(&mut self, lifetime: &'hir Lifetime) { fn visit_lifetime(&mut self, lifetime: &'hir Lifetime) {
self.insert(lifetime.span, lifetime.hir_id, Node::Lifetime(lifetime)); self.insert(lifetime.ident.span, lifetime.hir_id, Node::Lifetime(lifetime));
} }
fn visit_variant(&mut self, v: &'hir Variant<'hir>) { fn visit_variant(&mut self, v: &'hir Variant<'hir>) {

View file

@ -1479,10 +1479,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
})) }))
} }
GenericParamKind::Lifetime => { GenericParamKind::Lifetime => {
let ident_span = self.lower_span(ident.span);
let ident = self.lower_ident(ident); let ident = self.lower_ident(ident);
let lt_id = self.next_node_id(); let lt_id = self.next_node_id();
let lifetime = self.new_named_lifetime(id, lt_id, ident_span, ident); let lifetime = self.new_named_lifetime(id, lt_id, ident);
Some(hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { Some(hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
lifetime, lifetime,
span, span,

View file

@ -1255,7 +1255,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} else { } else {
self.next_node_id() self.next_node_id()
}; };
let span = self.tcx.sess.source_map().start_point(t.span); let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();
Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id } Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
}); });
let lifetime = self.lower_lifetime(&region); let lifetime = self.lower_lifetime(&region);
@ -1546,15 +1546,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let lifetimes = let lifetimes =
self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(|(_, lifetime)| { self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(|(_, lifetime)| {
let id = self.next_node_id(); let id = self.next_node_id();
let span = lifetime.ident.span; let l = self.new_named_lifetime(lifetime.id, id, lifetime.ident);
let ident = if lifetime.ident.name == kw::UnderscoreLifetime {
Ident::with_dummy_span(kw::UnderscoreLifetime)
} else {
lifetime.ident
};
let l = self.new_named_lifetime(lifetime.id, id, span, ident);
hir::GenericArg::Lifetime(l) hir::GenericArg::Lifetime(l)
})); }));
debug!(?lifetimes); debug!(?lifetimes);
@ -2014,18 +2006,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let generic_args = self.arena.alloc_from_iter(collected_lifetimes.into_iter().map( let generic_args = self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(
|(_, lifetime, res)| { |(_, lifetime, res)| {
let id = self.next_node_id(); let id = self.next_node_id();
let span = lifetime.ident.span;
let ident = if lifetime.ident.name == kw::UnderscoreLifetime {
Ident::with_dummy_span(kw::UnderscoreLifetime)
} else {
lifetime.ident
};
let res = res.unwrap_or( let res = res.unwrap_or(
self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error), self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error),
); );
hir::GenericArg::Lifetime(self.new_named_lifetime_with_res(id, span, ident, res)) hir::GenericArg::Lifetime(self.new_named_lifetime_with_res(id, lifetime.ident, res))
}, },
)); ));
@ -2095,43 +2079,41 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
fn lower_lifetime(&mut self, l: &Lifetime) -> &'hir hir::Lifetime { fn lower_lifetime(&mut self, l: &Lifetime) -> &'hir hir::Lifetime {
let span = self.lower_span(l.ident.span);
let ident = self.lower_ident(l.ident); let ident = self.lower_ident(l.ident);
self.new_named_lifetime(l.id, l.id, span, ident) self.new_named_lifetime(l.id, l.id, ident)
} }
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn new_named_lifetime_with_res( fn new_named_lifetime_with_res(
&mut self, &mut self,
id: NodeId, id: NodeId,
span: Span,
ident: Ident, ident: Ident,
res: LifetimeRes, res: LifetimeRes,
) -> &'hir hir::Lifetime { ) -> &'hir hir::Lifetime {
let name = match res { let res = match res {
LifetimeRes::Param { param, .. } => { LifetimeRes::Param { param, .. } => {
let p_name = ParamName::Plain(ident);
let param = self.get_remapped_def_id(param); let param = self.get_remapped_def_id(param);
hir::LifetimeName::Param(param)
hir::LifetimeName::Param(param, p_name)
} }
LifetimeRes::Fresh { param, .. } => { LifetimeRes::Fresh { param, .. } => {
debug_assert_eq!(ident.name, kw::UnderscoreLifetime); debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
let param = self.local_def_id(param); let param = self.local_def_id(param);
hir::LifetimeName::Param(param)
hir::LifetimeName::Param(param, ParamName::Fresh)
} }
LifetimeRes::Infer => hir::LifetimeName::Infer, LifetimeRes::Infer => hir::LifetimeName::Infer,
LifetimeRes::Static => hir::LifetimeName::Static, LifetimeRes::Static => hir::LifetimeName::Static,
LifetimeRes::Error => hir::LifetimeName::Error, LifetimeRes::Error => hir::LifetimeName::Error,
res => panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span), res => panic!(
"Unexpected lifetime resolution {:?} for {:?} at {:?}",
res, ident, ident.span
),
}; };
debug!(?name); debug!(?res);
self.arena.alloc(hir::Lifetime { self.arena.alloc(hir::Lifetime {
hir_id: self.lower_node_id(id), hir_id: self.lower_node_id(id),
span: self.lower_span(span), ident: self.lower_ident(ident),
name, res,
}) })
} }
@ -2140,11 +2122,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&mut self, &mut self,
id: NodeId, id: NodeId,
new_id: NodeId, new_id: NodeId,
span: Span,
ident: Ident, ident: Ident,
) -> &'hir hir::Lifetime { ) -> &'hir hir::Lifetime {
let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error); let res = self.resolver.get_lifetime_res(id).unwrap_or(LifetimeRes::Error);
self.new_named_lifetime_with_res(new_id, span, ident, res) self.new_named_lifetime_with_res(new_id, ident, res)
} }
fn lower_generic_params_mut<'s>( fn lower_generic_params_mut<'s>(
@ -2556,8 +2537,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime { fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
let r = hir::Lifetime { let r = hir::Lifetime {
hir_id: self.next_id(), hir_id: self.next_id(),
span: self.lower_span(span), ident: Ident::new(kw::Empty, self.lower_span(span)),
name: hir::LifetimeName::ImplicitObjectLifetimeDefault, res: hir::LifetimeName::ImplicitObjectLifetimeDefault,
}; };
debug!("elided_dyn_bound: r={:?}", r); debug!("elided_dyn_bound: r={:?}", r);
self.arena.alloc(r) self.arena.alloc(r)

View file

@ -2509,7 +2509,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let hir::TyKind::Rptr(lifetime, _) = &fn_decl.inputs[index].kind { if let hir::TyKind::Rptr(lifetime, _) = &fn_decl.inputs[index].kind {
// With access to the lifetime, we can get // With access to the lifetime, we can get
// the span of it. // the span of it.
arguments.push((*argument, lifetime.span)); arguments.push((*argument, lifetime.ident.span));
} else { } else {
bug!("ty type is a ref but hir type is not"); bug!("ty type is a ref but hir type is not");
} }
@ -2528,7 +2528,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let mut return_span = fn_decl.output.span(); let mut return_span = fn_decl.output.span();
if let hir::FnRetTy::Return(ty) = &fn_decl.output { if let hir::FnRetTy::Return(ty) = &fn_decl.output {
if let hir::TyKind::Rptr(lifetime, _) = ty.kind { if let hir::TyKind::Rptr(lifetime, _) = ty.kind {
return_span = lifetime.span; return_span = lifetime.ident.span;
} }
} }

View file

@ -1211,7 +1211,7 @@ fn get_mut_span_in_struct_field<'tcx>(
&& let hir::Node::Field(field) = node && let hir::Node::Field(field) = node
&& let hir::TyKind::Rptr(lt, hir::MutTy { mutbl: hir::Mutability::Not, ty }) = field.ty.kind && let hir::TyKind::Rptr(lt, hir::MutTy { mutbl: hir::Mutability::Not, ty }) = field.ty.kind
{ {
return Some(lt.span.between(ty.span)); return Some(lt.ident.span.between(ty.span));
} }
None None

View file

@ -576,30 +576,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let args = last_segment.args.as_ref()?; let args = last_segment.args.as_ref()?;
let lifetime = let lifetime =
self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?; self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?;
match lifetime.name { if lifetime.is_anonymous() {
hir::LifetimeName::Param(_, hir::ParamName::Plain(_) | hir::ParamName::Error) None
| hir::LifetimeName::Error } else {
| hir::LifetimeName::Static => { Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime.ident.span))
let lifetime_span = lifetime.span;
Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span))
}
hir::LifetimeName::Param(_, hir::ParamName::Fresh)
| hir::LifetimeName::ImplicitObjectLifetimeDefault
| hir::LifetimeName::Infer => {
// In this case, the user left off the lifetime; so
// they wrote something like:
//
// ```
// x: Foo<T>
// ```
//
// where the fully elaborated form is `Foo<'_, '1,
// T>`. We don't consider this a match; instead we let
// the "fully elaborated" type fallback above handle
// it.
None
}
} }
} }

View file

@ -29,7 +29,7 @@ use std::fmt;
#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)] #[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)]
pub struct Lifetime { pub struct Lifetime {
pub hir_id: HirId, pub hir_id: HirId,
pub span: Span, pub ident: Ident,
/// Either "`'a`", referring to a named lifetime definition, /// Either "`'a`", referring to a named lifetime definition,
/// or "``" (i.e., `kw::Empty`), for elision placeholders. /// or "``" (i.e., `kw::Empty`), for elision placeholders.
@ -37,7 +37,7 @@ pub struct Lifetime {
/// HIR lowering inserts these placeholders in type paths that /// HIR lowering inserts these placeholders in type paths that
/// refer to type definitions needing lifetime parameters, /// refer to type definitions needing lifetime parameters,
/// `&T` and `&mut T`, and trait objects without `... + 'a`. /// `&T` and `&mut T`, and trait objects without `... + 'a`.
pub name: LifetimeName, pub res: LifetimeName,
} }
#[derive(Debug, Clone, PartialEq, Eq, Encodable, Hash, Copy)] #[derive(Debug, Clone, PartialEq, Eq, Encodable, Hash, Copy)]
@ -88,7 +88,7 @@ impl ParamName {
#[derive(HashStable_Generic)] #[derive(HashStable_Generic)]
pub enum LifetimeName { pub enum LifetimeName {
/// User-given names or fresh (synthetic) names. /// User-given names or fresh (synthetic) names.
Param(LocalDefId, ParamName), Param(LocalDefId),
/// Implicit lifetime in a context like `dyn Foo`. This is /// Implicit lifetime in a context like `dyn Foo`. This is
/// distinguished from implicit lifetimes elsewhere because the /// distinguished from implicit lifetimes elsewhere because the
@ -116,25 +116,6 @@ pub enum LifetimeName {
} }
impl LifetimeName { impl LifetimeName {
pub fn ident(&self) -> Ident {
match *self {
LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Error => Ident::empty(),
LifetimeName::Infer => Ident::with_dummy_span(kw::UnderscoreLifetime),
LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime),
LifetimeName::Param(_, param_name) => param_name.ident(),
}
}
pub fn is_anonymous(&self) -> bool {
match *self {
LifetimeName::ImplicitObjectLifetimeDefault
| LifetimeName::Infer
| LifetimeName::Param(_, ParamName::Fresh)
| LifetimeName::Error => true,
LifetimeName::Static | LifetimeName::Param(..) => false,
}
}
pub fn is_elided(&self) -> bool { pub fn is_elided(&self) -> bool {
match self { match self {
LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Infer => true, LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Infer => true,
@ -146,34 +127,25 @@ impl LifetimeName {
LifetimeName::Error | LifetimeName::Param(..) | LifetimeName::Static => false, LifetimeName::Error | LifetimeName::Param(..) | LifetimeName::Static => false,
} }
} }
fn is_static(&self) -> bool {
self == &LifetimeName::Static
}
pub fn normalize_to_macros_2_0(&self) -> LifetimeName {
match *self {
LifetimeName::Param(def_id, param_name) => {
LifetimeName::Param(def_id, param_name.normalize_to_macros_2_0())
}
lifetime_name => lifetime_name,
}
}
} }
impl fmt::Display for Lifetime { impl fmt::Display for Lifetime {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.name.ident().fmt(f) self.ident.fmt(f)
} }
} }
impl Lifetime { impl Lifetime {
pub fn is_elided(&self) -> bool { pub fn is_elided(&self) -> bool {
self.name.is_elided() self.res.is_elided()
}
pub fn is_anonymous(&self) -> bool {
self.ident.name == kw::Empty || self.ident.name == kw::UnderscoreLifetime
} }
pub fn is_static(&self) -> bool { pub fn is_static(&self) -> bool {
self.name.is_static() self.res == LifetimeName::Static
} }
} }
@ -267,7 +239,7 @@ pub enum GenericArg<'hir> {
impl GenericArg<'_> { impl GenericArg<'_> {
pub fn span(&self) -> Span { pub fn span(&self) -> Span {
match self { match self {
GenericArg::Lifetime(l) => l.span, GenericArg::Lifetime(l) => l.ident.span,
GenericArg::Type(t) => t.span, GenericArg::Type(t) => t.span,
GenericArg::Const(c) => c.span, GenericArg::Const(c) => c.span,
GenericArg::Infer(i) => i.span, GenericArg::Infer(i) => i.span,
@ -284,7 +256,7 @@ impl GenericArg<'_> {
} }
pub fn is_synthetic(&self) -> bool { pub fn is_synthetic(&self) -> bool {
matches!(self, GenericArg::Lifetime(lifetime) if lifetime.name.ident() == Ident::empty()) matches!(self, GenericArg::Lifetime(lifetime) if lifetime.ident == Ident::empty())
} }
pub fn descr(&self) -> &'static str { pub fn descr(&self) -> &'static str {
@ -446,7 +418,7 @@ impl GenericBound<'_> {
match self { match self {
GenericBound::Trait(t, ..) => t.span, GenericBound::Trait(t, ..) => t.span,
GenericBound::LangItemTrait(_, span, ..) => *span, GenericBound::LangItemTrait(_, span, ..) => *span,
GenericBound::Outlives(l) => l.span, GenericBound::Outlives(l) => l.ident.span,
} }
} }
} }
@ -559,6 +531,19 @@ impl<'hir> Generics<'hir> {
} }
} }
/// If there are generic parameters, return where to introduce a new one.
pub fn span_for_lifetime_suggestion(&self) -> Option<Span> {
if let Some(first) = self.params.first()
&& self.span.contains(first.span)
{
// `fn foo<A>(t: impl Trait)`
// ^ suggest `'a, ` here
Some(first.span.shrink_to_lo())
} else {
None
}
}
/// If there are generic parameters, return where to introduce a new one. /// If there are generic parameters, return where to introduce a new one.
pub fn span_for_param_suggestion(&self) -> Option<Span> { pub fn span_for_param_suggestion(&self) -> Option<Span> {
if self.params.iter().any(|p| self.span.contains(p.span)) { if self.params.iter().any(|p| self.span.contains(p.span)) {
@ -765,10 +750,7 @@ pub struct WhereRegionPredicate<'hir> {
impl<'hir> WhereRegionPredicate<'hir> { impl<'hir> WhereRegionPredicate<'hir> {
/// Returns `true` if `param_def_id` matches the `lifetime` of this predicate. /// Returns `true` if `param_def_id` matches the `lifetime` of this predicate.
pub fn is_param_bound(&self, param_def_id: LocalDefId) -> bool { pub fn is_param_bound(&self, param_def_id: LocalDefId) -> bool {
match self.lifetime.name { self.lifetime.res == LifetimeName::Param(param_def_id)
LifetimeName::Param(id, _) => id == param_def_id,
_ => false,
}
} }
} }
@ -3453,7 +3435,7 @@ impl<'hir> Node<'hir> {
| Node::Variant(Variant { ident, .. }) | Node::Variant(Variant { ident, .. })
| Node::Item(Item { ident, .. }) | Node::Item(Item { ident, .. })
| Node::PathSegment(PathSegment { ident, .. }) => Some(*ident), | Node::PathSegment(PathSegment { ident, .. }) => Some(*ident),
Node::Lifetime(lt) => Some(lt.name.ident()), Node::Lifetime(lt) => Some(lt.ident),
Node::GenericParam(p) => Some(p.name.ident()), Node::GenericParam(p) => Some(p.name.ident()),
Node::TypeBinding(b) => Some(b.ident), Node::TypeBinding(b) => Some(b.ident),
Node::Param(..) Node::Param(..)

View file

@ -1109,17 +1109,7 @@ pub fn walk_generic_arg<'v, V: Visitor<'v>>(visitor: &mut V, generic_arg: &'v Ge
pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) { pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) {
visitor.visit_id(lifetime.hir_id); visitor.visit_id(lifetime.hir_id);
match lifetime.name { visitor.visit_ident(lifetime.ident);
LifetimeName::Param(_, ParamName::Plain(ident)) => {
visitor.visit_ident(ident);
}
LifetimeName::Param(_, ParamName::Fresh)
| LifetimeName::Param(_, ParamName::Error)
| LifetimeName::Static
| LifetimeName::Error
| LifetimeName::ImplicitObjectLifetimeDefault
| LifetimeName::Infer => {}
}
} }
pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath<'v>, id: HirId) { pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath<'v>, id: HirId) {

View file

@ -5,6 +5,7 @@
#![feature(associated_type_defaults)] #![feature(associated_type_defaults)]
#![feature(closure_track_caller)] #![feature(closure_track_caller)]
#![feature(const_btree_len)] #![feature(const_btree_len)]
#![feature(let_chains)]
#![feature(min_specialization)] #![feature(min_specialization)]
#![feature(never_type)] #![feature(never_type)]
#![feature(rustc_attrs)] #![feature(rustc_attrs)]

View file

@ -241,14 +241,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
} }
None => { None => {
self.re_infer(def, lifetime.span).unwrap_or_else(|| { self.re_infer(def, lifetime.ident.span).unwrap_or_else(|| {
debug!(?lifetime, "unelided lifetime in signature"); debug!(?lifetime, "unelided lifetime in signature");
// This indicates an illegal lifetime // This indicates an illegal lifetime
// elision. `resolve_lifetime` should have // elision. `resolve_lifetime` should have
// reported an error in this case -- but if // reported an error in this case -- but if
// not, let's error out. // not, let's error out.
tcx.sess.delay_span_bug(lifetime.span, "unelided lifetime in signature"); tcx.sess.delay_span_bug(lifetime.ident.span, "unelided lifetime in signature");
// Supply some dummy value. We don't have an // Supply some dummy value. We don't have an
// `re_error`, annoyingly, so use `'static`. // `re_error`, annoyingly, so use `'static`.
@ -961,9 +961,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
} }
hir::GenericBound::Outlives(lifetime) => { hir::GenericBound::Outlives(lifetime) => {
let region = self.ast_region_to_region(lifetime, None); let region = self.ast_region_to_region(lifetime, None);
bounds bounds.region_bounds.push((
.region_bounds ty::Binder::bind_with_vars(region, bound_vars),
.push((ty::Binder::bind_with_vars(region, bound_vars), lifetime.span)); lifetime.ident.span,
));
} }
} }
} }

View file

@ -398,7 +398,7 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
Some(rl::Region::Static | rl::Region::EarlyBound(..)) => {} Some(rl::Region::Static | rl::Region::EarlyBound(..)) => {}
Some(rl::Region::LateBound(debruijn, _, _)) if debruijn < self.outer_index => {} Some(rl::Region::LateBound(debruijn, _, _)) if debruijn < self.outer_index => {}
Some(rl::Region::LateBound(..) | rl::Region::Free(..)) | None => { Some(rl::Region::LateBound(..) | rl::Region::Free(..)) | None => {
self.has_late_bound_regions = Some(lt.span); self.has_late_bound_regions = Some(lt.ident.span);
} }
} }
} }

View file

@ -19,7 +19,7 @@ use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_lifetime::*; use rustc_middle::middle::resolve_lifetime::*;
use rustc_middle::ty::{self, DefIdTree, TyCtxt, TypeSuperVisitable, TypeVisitor}; use rustc_middle::ty::{self, DefIdTree, TyCtxt, TypeSuperVisitable, TypeVisitor};
use rustc_span::def_id::DefId; use rustc_span::def_id::DefId;
use rustc_span::symbol::{sym, Ident}; use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span; use rustc_span::Span;
use std::fmt; use std::fmt;
@ -595,7 +595,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
this.visit_poly_trait_ref(bound); this.visit_poly_trait_ref(bound);
} }
}); });
match lifetime.name { match lifetime.res {
LifetimeName::ImplicitObjectLifetimeDefault => { LifetimeName::ImplicitObjectLifetimeDefault => {
// If the user does not write *anything*, we // If the user does not write *anything*, we
// use the object lifetime defaulting // use the object lifetime defaulting
@ -686,7 +686,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
if !parent_id.is_owner() { if !parent_id.is_owner() {
struct_span_err!( struct_span_err!(
self.tcx.sess, self.tcx.sess,
lifetime.span, lifetime.ident.span,
E0657, E0657,
"`impl Trait` can only capture lifetimes bound at the fn or impl level" "`impl Trait` can only capture lifetimes bound at the fn or impl level"
) )
@ -698,7 +698,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
}) = self.tcx.hir().get(parent_id) }) = self.tcx.hir().get(parent_id)
{ {
let mut err = self.tcx.sess.struct_span_err( let mut err = self.tcx.sess.struct_span_err(
lifetime.span, lifetime.ident.span,
"higher kinded lifetime bounds on nested opaque types are not supported yet", "higher kinded lifetime bounds on nested opaque types are not supported yet",
); );
err.span_note(self.tcx.def_span(def_id), "lifetime declared here"); err.span_note(self.tcx.def_span(def_id), "lifetime declared here");
@ -802,9 +802,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) { fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
match lifetime_ref.name { match lifetime_ref.res {
hir::LifetimeName::Static => self.insert_lifetime(lifetime_ref, Region::Static), hir::LifetimeName::Static => self.insert_lifetime(lifetime_ref, Region::Static),
hir::LifetimeName::Param(param_def_id, _) => { hir::LifetimeName::Param(param_def_id) => {
self.resolve_lifetime_ref(param_def_id, lifetime_ref) self.resolve_lifetime_ref(param_def_id, lifetime_ref)
} }
// If we've already reported an error, just ignore `lifetime_ref`. // If we've already reported an error, just ignore `lifetime_ref`.
@ -912,27 +912,27 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
this.visit_lifetime(lifetime); this.visit_lifetime(lifetime);
walk_list!(this, visit_param_bound, bounds); walk_list!(this, visit_param_bound, bounds);
if lifetime.name != hir::LifetimeName::Static { if lifetime.res != hir::LifetimeName::Static {
for bound in bounds { for bound in bounds {
let hir::GenericBound::Outlives(ref lt) = bound else { let hir::GenericBound::Outlives(ref lt) = bound else {
continue; continue;
}; };
if lt.name != hir::LifetimeName::Static { if lt.res != hir::LifetimeName::Static {
continue; continue;
} }
this.insert_lifetime(lt, Region::Static); this.insert_lifetime(lt, Region::Static);
this.tcx this.tcx
.sess .sess
.struct_span_warn( .struct_span_warn(
lifetime.span, lifetime.ident.span,
&format!( &format!(
"unnecessary lifetime parameter `{}`", "unnecessary lifetime parameter `{}`",
lifetime.name.ident(), lifetime.ident,
), ),
) )
.help(&format!( .help(&format!(
"you can use the `'static` lifetime directly, in place of `{}`", "you can use the `'static` lifetime directly, in place of `{}`",
lifetime.name.ident(), lifetime.ident,
)) ))
.emit(); .emit();
} }
@ -1043,7 +1043,7 @@ fn object_lifetime_default<'tcx>(tcx: TyCtxt<'tcx>, param_def_id: DefId) -> Obje
for bound in bound.bounds { for bound in bound.bounds {
if let hir::GenericBound::Outlives(ref lifetime) = *bound { if let hir::GenericBound::Outlives(ref lifetime) = *bound {
set.insert(lifetime.name.normalize_to_macros_2_0()); set.insert(lifetime.res);
} }
} }
} }
@ -1051,7 +1051,7 @@ fn object_lifetime_default<'tcx>(tcx: TyCtxt<'tcx>, param_def_id: DefId) -> Obje
match set { match set {
Set1::Empty => ObjectLifetimeDefault::Empty, Set1::Empty => ObjectLifetimeDefault::Empty,
Set1::One(hir::LifetimeName::Static) => ObjectLifetimeDefault::Static, Set1::One(hir::LifetimeName::Static) => ObjectLifetimeDefault::Static,
Set1::One(hir::LifetimeName::Param(param_def_id, _)) => { Set1::One(hir::LifetimeName::Param(param_def_id)) => {
ObjectLifetimeDefault::Param(param_def_id.to_def_id()) ObjectLifetimeDefault::Param(param_def_id.to_def_id())
} }
_ => ObjectLifetimeDefault::Ambiguous, _ => ObjectLifetimeDefault::Ambiguous,
@ -1195,42 +1195,48 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
// Fresh lifetimes in APIT used to be allowed in async fns and forbidden in // Fresh lifetimes in APIT used to be allowed in async fns and forbidden in
// regular fns. // regular fns.
if let Some(hir::PredicateOrigin::ImplTrait) = where_bound_origin if let Some(hir::PredicateOrigin::ImplTrait) = where_bound_origin
&& let hir::LifetimeName::Param(_, hir::ParamName::Fresh) = lifetime_ref.name && let hir::LifetimeName::Param(_) = lifetime_ref.res
&& lifetime_ref.is_anonymous()
&& let hir::IsAsync::NotAsync = self.tcx.asyncness(lifetime_ref.hir_id.owner.def_id) && let hir::IsAsync::NotAsync = self.tcx.asyncness(lifetime_ref.hir_id.owner.def_id)
&& !self.tcx.features().anonymous_lifetime_in_impl_trait && !self.tcx.features().anonymous_lifetime_in_impl_trait
{ {
let mut diag = rustc_session::parse::feature_err( let mut diag = rustc_session::parse::feature_err(
&self.tcx.sess.parse_sess, &self.tcx.sess.parse_sess,
sym::anonymous_lifetime_in_impl_trait, sym::anonymous_lifetime_in_impl_trait,
lifetime_ref.span, lifetime_ref.ident.span,
"anonymous lifetimes in `impl Trait` are unstable", "anonymous lifetimes in `impl Trait` are unstable",
); );
match self.tcx.hir().get_generics(lifetime_ref.hir_id.owner.def_id) { if let Some(generics) =
Some(generics) => { self.tcx.hir().get_generics(lifetime_ref.hir_id.owner.def_id)
{
let new_param_sugg = if let Some(span) =
generics.span_for_lifetime_suggestion()
{
(span, "'a, ".to_owned())
} else {
(generics.span, "<'a>".to_owned())
};
let new_param_sugg_tuple; let lifetime_sugg = match lifetime_ref.ident.name {
kw::Empty => "'a, ".to_owned(),
kw::UnderscoreLifetime => "'a ".to_owned(),
_ => "'a ".to_owned(),
};
let suggestions = vec![
(lifetime_ref.ident.span.shrink_to_hi(), lifetime_sugg),
new_param_sugg,
];
new_param_sugg_tuple = match generics.span_for_param_suggestion() { diag.span_label(
Some(_) => { lifetime_ref.ident.span,
Some((self.tcx.sess.source_map().span_through_char(generics.span, '<').shrink_to_hi(), "'a, ".to_owned())) "expected named lifetime parameter",
}, );
None => Some((generics.span, "<'a>".to_owned())) diag.multipart_suggestion(
}; "consider introducing a named lifetime parameter",
suggestions,
let mut multi_sugg_vec = vec![(lifetime_ref.span.shrink_to_hi(), "'a ".to_owned())]; rustc_errors::Applicability::MaybeIncorrect,
);
if let Some(new_tuple) = new_param_sugg_tuple{
multi_sugg_vec.push(new_tuple);
}
diag.span_label(lifetime_ref.span, "expected named lifetime parameter");
diag.multipart_suggestion("consider introducing a named lifetime parameter",
multi_sugg_vec,
rustc_errors::Applicability::MaybeIncorrect);
},
None => { }
} }
diag.emit(); diag.emit();
@ -1287,7 +1293,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
where_bound_origin: Some(hir::PredicateOrigin::ImplTrait), .. where_bound_origin: Some(hir::PredicateOrigin::ImplTrait), ..
} => { } => {
let mut err = self.tcx.sess.struct_span_err( let mut err = self.tcx.sess.struct_span_err(
lifetime_ref.span, lifetime_ref.ident.span,
"`impl Trait` can only mention lifetimes bound at the fn or impl level", "`impl Trait` can only mention lifetimes bound at the fn or impl level",
); );
err.span_note(self.tcx.def_span(region_def_id), "lifetime declared here"); err.span_note(self.tcx.def_span(region_def_id), "lifetime declared here");
@ -1307,7 +1313,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
} }
self.tcx.sess.delay_span_bug( self.tcx.sess.delay_span_bug(
lifetime_ref.span, lifetime_ref.ident.span,
&format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,), &format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
); );
} }
@ -1625,10 +1631,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) { fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) {
debug!( debug!(span = ?lifetime_ref.ident.span);
node = ?self.tcx.hir().node_to_string(lifetime_ref.hir_id),
span = ?self.tcx.sess.source_map().span_to_diagnostic_string(lifetime_ref.span)
);
self.map.defs.insert(lifetime_ref.hir_id, def); self.map.defs.insert(lifetime_ref.hir_id, def);
} }
@ -1839,7 +1842,7 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<
} }
fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) { fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
if let hir::LifetimeName::Param(def_id, _) = lifetime_ref.name { if let hir::LifetimeName::Param(def_id) = lifetime_ref.res {
self.regions.insert(def_id); self.regions.insert(def_id);
} }
} }
@ -1852,7 +1855,7 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<
impl<'v> Visitor<'v> for AllCollector { impl<'v> Visitor<'v> for AllCollector {
fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) { fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) {
if let hir::LifetimeName::Param(def_id, _) = lifetime_ref.name { if let hir::LifetimeName::Param(def_id) = lifetime_ref.res {
self.regions.insert(def_id); self.regions.insert(def_id);
} }
} }

View file

@ -229,7 +229,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
predicates.extend(region_pred.bounds.iter().map(|bound| { predicates.extend(region_pred.bounds.iter().map(|bound| {
let (r2, span) = match bound { let (r2, span) = match bound {
hir::GenericBound::Outlives(lt) => { hir::GenericBound::Outlives(lt) => {
(<dyn AstConv<'_>>::ast_region_to_region(&icx, lt, None), lt.span) (<dyn AstConv<'_>>::ast_region_to_region(&icx, lt, None), lt.ident.span)
} }
_ => bug!(), _ => bug!(),
}; };

View file

@ -2159,7 +2159,7 @@ impl<'a> State<'a> {
} }
pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) { pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) {
self.print_ident(lifetime.name.ident()) self.print_ident(lifetime.ident)
} }
pub fn print_where_clause(&mut self, generics: &hir::Generics<'_>) { pub fn print_where_clause(&mut self, generics: &hir::Generics<'_>) {

View file

@ -375,7 +375,7 @@ impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> {
return false; return false;
}; };
if !lifetime_sub.name.is_anonymous() || !lifetime_sup.name.is_anonymous() { if !lifetime_sub.is_anonymous() || !lifetime_sup.is_anonymous() {
return false; return false;
}; };
@ -407,20 +407,20 @@ impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> {
let suggestion_param_name = let suggestion_param_name =
suggestion_param_name.map(|n| n.to_string()).unwrap_or_else(|| "'a".to_owned()); suggestion_param_name.map(|n| n.to_string()).unwrap_or_else(|| "'a".to_owned());
debug!(?lifetime_sup.span); debug!(?lifetime_sup.ident.span);
debug!(?lifetime_sub.span); debug!(?lifetime_sub.ident.span);
let make_suggestion = |span: rustc_span::Span| { let make_suggestion = |ident: Ident| {
if span.is_empty() { let sugg = if ident.name == kw::Empty {
(span, format!("{}, ", suggestion_param_name)) format!("{}, ", suggestion_param_name)
} else if let Ok("&") = self.tcx.sess.source_map().span_to_snippet(span).as_deref() } else if ident.name == kw::UnderscoreLifetime && ident.span.is_empty() {
{ format!("{} ", suggestion_param_name)
(span.shrink_to_hi(), format!("{} ", suggestion_param_name))
} else { } else {
(span, suggestion_param_name.clone()) suggestion_param_name.clone()
} };
(ident.span, sugg)
}; };
let mut suggestions = let mut suggestions =
vec![make_suggestion(lifetime_sub.span), make_suggestion(lifetime_sup.span)]; vec![make_suggestion(lifetime_sub.ident), make_suggestion(lifetime_sup.ident)];
if introduce_new { if introduce_new {
let new_param_suggestion = if let Some(first) = let new_param_suggestion = if let Some(first) =

View file

@ -314,10 +314,10 @@ pub fn suggest_new_region_bound(
.iter() .iter()
.filter_map(|arg| match arg { .filter_map(|arg| match arg {
GenericBound::Outlives(Lifetime { GenericBound::Outlives(Lifetime {
name: LifetimeName::Static, res: LifetimeName::Static,
span, ident,
.. ..
}) => Some(*span), }) => Some(ident.span),
_ => None, _ => None,
}) })
.next() .next()
@ -342,10 +342,10 @@ pub fn suggest_new_region_bound(
.bounds .bounds
.iter() .iter()
.filter_map(|arg| match arg { .filter_map(|arg| match arg {
GenericBound::Outlives(Lifetime { name, span, .. }) GenericBound::Outlives(Lifetime { ident, .. })
if name.ident().to_string() == lifetime_name => if ident.name.to_string() == lifetime_name =>
{ {
Some(*span) Some(ident.span)
} }
_ => None, _ => None,
}) })
@ -361,8 +361,8 @@ pub fn suggest_new_region_bound(
); );
} }
} }
TyKind::TraitObject(_, lt, _) => match lt.name { TyKind::TraitObject(_, lt, _) => {
LifetimeName::ImplicitObjectLifetimeDefault => { if let LifetimeName::ImplicitObjectLifetimeDefault = lt.res {
err.span_suggestion_verbose( err.span_suggestion_verbose(
fn_return.span.shrink_to_hi(), fn_return.span.shrink_to_hi(),
&format!( &format!(
@ -374,15 +374,14 @@ pub fn suggest_new_region_bound(
&plus_lt, &plus_lt,
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
); );
} } else if lt.ident.name.to_string() != lifetime_name {
name if name.ident().to_string() != lifetime_name => {
// With this check we avoid suggesting redundant bounds. This // With this check we avoid suggesting redundant bounds. This
// would happen if there are nested impl/dyn traits and only // would happen if there are nested impl/dyn traits and only
// one of them has the bound we'd suggest already there, like // one of them has the bound we'd suggest already there, like
// in `impl Foo<X = dyn Bar> + '_`. // in `impl Foo<X = dyn Bar> + '_`.
if let Some(explicit_static) = &explicit_static { if let Some(explicit_static) = &explicit_static {
err.span_suggestion_verbose( err.span_suggestion_verbose(
lt.span, lt.ident.span,
&format!("{} the trait object's {}", consider, explicit_static), &format!("{} the trait object's {}", consider, explicit_static),
&lifetime_name, &lifetime_name,
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
@ -397,8 +396,7 @@ pub fn suggest_new_region_bound(
); );
} }
} }
_ => {} }
},
_ => {} _ => {}
} }
} }
@ -561,7 +559,7 @@ impl<'a, 'tcx> Visitor<'tcx> for HirTraitObjectVisitor<'a> {
fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) { fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) {
if let TyKind::TraitObject( if let TyKind::TraitObject(
poly_trait_refs, poly_trait_refs,
Lifetime { name: LifetimeName::ImplicitObjectLifetimeDefault, .. }, Lifetime { res: LifetimeName::ImplicitObjectLifetimeDefault, .. },
_, _,
) = t.kind ) = t.kind
{ {

View file

@ -272,11 +272,7 @@ fn gen_args(segment: &PathSegment<'_>) -> String {
.args .args
.iter() .iter()
.filter_map(|arg| { .filter_map(|arg| {
if let GenericArg::Lifetime(lt) = arg { if let GenericArg::Lifetime(lt) = arg { Some(lt.ident.to_string()) } else { None }
Some(lt.name.ident().to_string())
} else {
None
}
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();

View file

@ -78,7 +78,7 @@ fn gen_args(cx: &LateContext<'_>, segment: &PathSegment<'_>) -> String {
.args .args
.iter() .iter()
.map(|arg| match arg { .map(|arg| match arg {
GenericArg::Lifetime(lt) => lt.name.ident().to_string(), GenericArg::Lifetime(lt) => lt.ident.to_string(),
GenericArg::Type(ty) => { GenericArg::Type(ty) => {
cx.tcx.sess.source_map().span_to_snippet(ty.span).unwrap_or_else(|_| "_".into()) cx.tcx.sess.source_map().span_to_snippet(ty.span).unwrap_or_else(|_| "_".into())
} }

View file

@ -1058,7 +1058,7 @@ impl<'hir> Map<'hir> {
Node::Arm(arm) => arm.span, Node::Arm(arm) => arm.span,
Node::Block(block) => block.span, Node::Block(block) => block.span,
Node::Ctor(..) => self.span_with_body(self.get_parent_node(hir_id)), Node::Ctor(..) => self.span_with_body(self.get_parent_node(hir_id)),
Node::Lifetime(lifetime) => lifetime.span, Node::Lifetime(lifetime) => lifetime.ident.span,
Node::GenericParam(param) => param.span, Node::GenericParam(param) => param.span,
Node::Infer(i) => i.span, Node::Infer(i) => i.span,
Node::Local(local) => local.span, Node::Local(local) => local.span,

View file

@ -397,7 +397,7 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
hir::TyKind::TraitObject( hir::TyKind::TraitObject(
_, _,
hir::Lifetime { hir::Lifetime {
name: res:
hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static, hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static,
.. ..
}, },
@ -421,10 +421,9 @@ pub struct StaticLifetimeVisitor<'tcx>(pub Vec<Span>, pub crate::hir::map::Map<'
impl<'v> hir::intravisit::Visitor<'v> for StaticLifetimeVisitor<'v> { impl<'v> hir::intravisit::Visitor<'v> for StaticLifetimeVisitor<'v> {
fn visit_lifetime(&mut self, lt: &'v hir::Lifetime) { fn visit_lifetime(&mut self, lt: &'v hir::Lifetime) {
if let hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static = if let hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static = lt.res
lt.name
{ {
self.0.push(lt.span); self.0.push(lt.ident.span);
} }
} }
} }

View file

@ -167,7 +167,7 @@ impl<'hir> Sig for hir::Ty<'hir> {
} }
hir::TyKind::Rptr(ref lifetime, ref mt) => { hir::TyKind::Rptr(ref lifetime, ref mt) => {
let mut prefix = "&".to_owned(); let mut prefix = "&".to_owned();
prefix.push_str(&lifetime.name.ident().to_string()); prefix.push_str(&lifetime.ident.to_string());
prefix.push(' '); prefix.push(' ');
if let hir::Mutability::Mut = mt.mutbl { if let hir::Mutability::Mut = mt.mutbl {
prefix.push_str("mut "); prefix.push_str("mut ");

View file

@ -208,7 +208,7 @@ fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) ->
return lt; return lt;
} }
} }
Lifetime(lifetime.name.ident().name) Lifetime(lifetime.ident.name)
} }
pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg, cx: &mut DocContext<'tcx>) -> Constant { pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg, cx: &mut DocContext<'tcx>) -> Constant {
@ -1524,16 +1524,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
TyKind::Never => Primitive(PrimitiveType::Never), TyKind::Never => Primitive(PrimitiveType::Never),
TyKind::Ptr(ref m) => RawPointer(m.mutbl, Box::new(clean_ty(m.ty, cx))), TyKind::Ptr(ref m) => RawPointer(m.mutbl, Box::new(clean_ty(m.ty, cx))),
TyKind::Rptr(ref l, ref m) => { TyKind::Rptr(ref l, ref m) => {
// There are two times a `Fresh` lifetime can be created: let lifetime = if l.is_anonymous() { None } else { Some(clean_lifetime(*l, cx)) };
// 1. For `&'_ x`, written by the user. This corresponds to `lower_lifetime` in `rustc_ast_lowering`.
// 2. For `&x` as a parameter to an `async fn`. This corresponds to `elided_ref_lifetime in `rustc_ast_lowering`.
// See #59286 for more information.
// Ideally we would only hide the `'_` for case 2., but I don't know a way to distinguish it.
// Turning `fn f(&'_ self)` into `fn f(&self)` isn't the worst thing in the world, though;
// there's no case where it could cause the function to fail to compile.
let elided =
l.is_elided() || matches!(l.name, LifetimeName::Param(_, ParamName::Fresh));
let lifetime = if elided { None } else { Some(clean_lifetime(*l, cx)) };
BorrowedRef { lifetime, mutability: m.mutbl, type_: Box::new(clean_ty(m.ty, cx)) } BorrowedRef { lifetime, mutability: m.mutbl, type_: Box::new(clean_ty(m.ty, cx)) }
} }
TyKind::Slice(ty) => Slice(Box::new(clean_ty(ty, cx))), TyKind::Slice(ty) => Slice(Box::new(clean_ty(ty, cx))),

View file

@ -119,7 +119,7 @@ hir-stats HIR STATS
hir-stats Name Accumulated Size Count Item Size hir-stats Name Accumulated Size Count Item Size
hir-stats ---------------------------------------------------------------- hir-stats ----------------------------------------------------------------
hir-stats ForeignItemRef 24 ( 0.3%) 1 24 hir-stats ForeignItemRef 24 ( 0.3%) 1 24
hir-stats Lifetime 32 ( 0.3%) 1 32 hir-stats Lifetime 24 ( 0.3%) 1 24
hir-stats Mod 32 ( 0.3%) 1 32 hir-stats Mod 32 ( 0.3%) 1 32
hir-stats ExprField 40 ( 0.4%) 1 40 hir-stats ExprField 40 ( 0.4%) 1 40
hir-stats TraitItemRef 56 ( 0.6%) 2 28 hir-stats TraitItemRef 56 ( 0.6%) 2 28
@ -152,7 +152,7 @@ hir-stats - Struct 72 ( 0.8%) 1
hir-stats - Binding 216 ( 2.4%) 3 hir-stats - Binding 216 ( 2.4%) 3
hir-stats GenericParam 400 ( 4.4%) 5 80 hir-stats GenericParam 400 ( 4.4%) 5 80
hir-stats Generics 560 ( 6.1%) 10 56 hir-stats Generics 560 ( 6.1%) 10 56
hir-stats Ty 720 ( 7.8%) 15 48 hir-stats Ty 720 ( 7.9%) 15 48
hir-stats - Ptr 48 ( 0.5%) 1 hir-stats - Ptr 48 ( 0.5%) 1
hir-stats - Rptr 48 ( 0.5%) 1 hir-stats - Rptr 48 ( 0.5%) 1
hir-stats - Path 624 ( 6.8%) 13 hir-stats - Path 624 ( 6.8%) 13
@ -171,8 +171,8 @@ hir-stats - ForeignMod 80 ( 0.9%) 1
hir-stats - Impl 80 ( 0.9%) 1 hir-stats - Impl 80 ( 0.9%) 1
hir-stats - Fn 160 ( 1.7%) 2 hir-stats - Fn 160 ( 1.7%) 2
hir-stats - Use 400 ( 4.4%) 5 hir-stats - Use 400 ( 4.4%) 5
hir-stats Path 1_280 (13.9%) 32 40 hir-stats Path 1_280 (14.0%) 32 40
hir-stats PathSegment 1_920 (20.9%) 40 48 hir-stats PathSegment 1_920 (20.9%) 40 48
hir-stats ---------------------------------------------------------------- hir-stats ----------------------------------------------------------------
hir-stats Total 9_176 hir-stats Total 9_168
hir-stats hir-stats

View file

@ -10,7 +10,7 @@ use rustc_hir::lang_items;
use rustc_hir::FnRetTy::Return; use rustc_hir::FnRetTy::Return;
use rustc_hir::{ use rustc_hir::{
BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl, ImplItem, BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl, ImplItem,
ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, ParamName, PolyTraitRef, PredicateOrigin, TraitFn, TraitItem, ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, PolyTraitRef, PredicateOrigin, TraitFn, TraitItem,
TraitItemKind, Ty, TyKind, WherePredicate, TraitItemKind, Ty, TyKind, WherePredicate,
}; };
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
@ -180,7 +180,7 @@ fn check_fn_inner<'tcx>(
_ => None, _ => None,
}); });
for bound in lifetimes { for bound in lifetimes {
if bound.name != LifetimeName::Static && !bound.is_elided() { if !bound.is_static() && !bound.is_elided() {
return; return;
} }
} }
@ -414,17 +414,13 @@ impl<'a, 'tcx> RefVisitor<'a, 'tcx> {
fn record(&mut self, lifetime: &Option<Lifetime>) { fn record(&mut self, lifetime: &Option<Lifetime>) {
if let Some(ref lt) = *lifetime { if let Some(ref lt) = *lifetime {
if lt.name == LifetimeName::Static { if lt.is_static() {
self.lts.push(RefLt::Static); self.lts.push(RefLt::Static);
} else if let LifetimeName::Param(_, ParamName::Fresh) = lt.name { } else if lt.is_anonymous() {
// Fresh lifetimes generated should be ignored. // Fresh lifetimes generated should be ignored.
self.lts.push(RefLt::Unnamed); self.lts.push(RefLt::Unnamed);
} else if lt.is_elided() { } else if let LifetimeName::Param(def_id) = lt.res {
self.lts.push(RefLt::Unnamed);
} else if let LifetimeName::Param(def_id, _) = lt.name {
self.lts.push(RefLt::Named(def_id)); self.lts.push(RefLt::Named(def_id));
} else {
self.lts.push(RefLt::Unnamed);
} }
} else { } else {
self.lts.push(RefLt::Unnamed); self.lts.push(RefLt::Unnamed);
@ -472,7 +468,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
walk_item(self, item); walk_item(self, item);
self.lts.truncate(len); self.lts.truncate(len);
self.lts.extend(bounds.iter().filter_map(|bound| match bound { self.lts.extend(bounds.iter().filter_map(|bound| match bound {
GenericArg::Lifetime(l) => Some(if let LifetimeName::Param(def_id, _) = l.name { GenericArg::Lifetime(l) => Some(if let LifetimeName::Param(def_id) = l.res {
RefLt::Named(def_id) RefLt::Named(def_id)
} else { } else {
RefLt::Unnamed RefLt::Unnamed
@ -498,10 +494,8 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
} }
fn visit_generic_arg(&mut self, generic_arg: &'tcx GenericArg<'tcx>) { fn visit_generic_arg(&mut self, generic_arg: &'tcx GenericArg<'tcx>) {
if let GenericArg::Lifetime(l) = generic_arg if let GenericArg::Lifetime(l) = generic_arg && let LifetimeName::Param(def_id) = l.res {
&& let LifetimeName::Param(def_id, _) = l.name self.lifetime_generic_arg_spans.entry(def_id).or_insert(l.ident.span);
{
self.lifetime_generic_arg_spans.entry(def_id).or_insert(l.span);
} }
// Replace with `walk_generic_arg` if/when https://github.com/rust-lang/rust/pull/103692 lands. // Replace with `walk_generic_arg` if/when https://github.com/rust-lang/rust/pull/103692 lands.
// walk_generic_arg(self, generic_arg); // walk_generic_arg(self, generic_arg);
@ -577,7 +571,7 @@ where
// for lifetimes as parameters of generics // for lifetimes as parameters of generics
fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) { fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {
self.map.remove(&lifetime.name.ident().name); self.map.remove(&lifetime.ident.name);
} }
fn visit_generic_param(&mut self, param: &'tcx GenericParam<'_>) { fn visit_generic_param(&mut self, param: &'tcx GenericParam<'_>) {
@ -653,7 +647,7 @@ struct BodyLifetimeChecker {
impl<'tcx> Visitor<'tcx> for BodyLifetimeChecker { impl<'tcx> Visitor<'tcx> for BodyLifetimeChecker {
// for lifetimes as parameters of generics // for lifetimes as parameters of generics
fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) { fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {
if lifetime.name.ident().name != kw::UnderscoreLifetime && lifetime.name.ident().name != kw::StaticLifetime { if lifetime.ident.name != kw::UnderscoreLifetime && lifetime.ident.name != kw::StaticLifetime {
self.lifetimes_used_in_body = true; self.lifetimes_used_in_body = true;
} }
} }

View file

@ -118,7 +118,7 @@ fn future_trait_ref<'tcx>(
.iter() .iter()
.filter_map(|bound| { .filter_map(|bound| {
if let GenericArg::Lifetime(lt) = bound { if let GenericArg::Lifetime(lt) = bound {
Some(lt.name) Some(lt.res)
} else { } else {
None None
} }
@ -153,7 +153,7 @@ fn captures_all_lifetimes(inputs: &[Ty<'_>], output_lifetimes: &[LifetimeName])
.iter() .iter()
.filter_map(|ty| { .filter_map(|ty| {
if let TyKind::Rptr(lt, _) = ty.kind { if let TyKind::Rptr(lt, _) = ty.kind {
Some(lt.name) Some(lt.res)
} else { } else {
None None
} }

View file

@ -12,8 +12,8 @@ use rustc_hir::hir_id::HirIdMap;
use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{ use rustc_hir::{
self as hir, AnonConst, BinOpKind, BindingAnnotation, Body, Expr, ExprKind, FnRetTy, FnSig, GenericArg, self as hir, AnonConst, BinOpKind, BindingAnnotation, Body, Expr, ExprKind, FnRetTy, FnSig, GenericArg,
ImplItemKind, ItemKind, Lifetime, LifetimeName, Mutability, Node, Param, ParamName, PatKind, QPath, TraitFn, ImplItemKind, ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, TraitFn, TraitItem, TraitItemKind,
TraitItem, TraitItemKind, TyKind, Unsafety, TyKind, Unsafety,
}; };
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_infer::traits::{Obligation, ObligationCause};
@ -343,21 +343,16 @@ impl PtrArg<'_> {
} }
struct RefPrefix { struct RefPrefix {
lt: LifetimeName, lt: Lifetime,
mutability: Mutability, mutability: Mutability,
} }
impl fmt::Display for RefPrefix { impl fmt::Display for RefPrefix {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use fmt::Write; use fmt::Write;
f.write_char('&')?; f.write_char('&')?;
match self.lt { if !self.lt.is_anonymous() {
LifetimeName::Param(_, ParamName::Plain(name)) => { self.lt.ident.fmt(f)?;
name.fmt(f)?; f.write_char(' ')?;
f.write_char(' ')?;
},
LifetimeName::Infer => f.write_str("'_ ")?,
LifetimeName::Static => f.write_str("'static ")?,
_ => (),
} }
f.write_str(self.mutability.prefix_str()) f.write_str(self.mutability.prefix_str())
} }
@ -495,7 +490,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
ty_name: name.ident.name, ty_name: name.ident.name,
method_renames, method_renames,
ref_prefix: RefPrefix { ref_prefix: RefPrefix {
lt: lt.name, lt: lt.clone(),
mutability, mutability,
}, },
deref_ty, deref_ty,

View file

@ -31,10 +31,10 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
return false; return false;
} }
let ltopt = if lt.name.is_anonymous() { let ltopt = if lt.is_anonymous() {
String::new() String::new()
} else { } else {
format!("{} ", lt.name.ident().as_str()) format!("{} ", lt.ident.as_str())
}; };
if mut_ty.mutbl == Mutability::Mut { if mut_ty.mutbl == Mutability::Mut {

View file

@ -7,7 +7,7 @@ use rustc_hir::def::Res;
use rustc_hir::HirIdMap; use rustc_hir::HirIdMap;
use rustc_hir::{ use rustc_hir::{
ArrayLen, BinOpKind, BindingAnnotation, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg, ArrayLen, BinOpKind, BindingAnnotation, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg,
GenericArgs, Guard, HirId, InlineAsmOperand, Let, Lifetime, LifetimeName, ParamName, Pat, PatField, PatKind, Path, GenericArgs, Guard, HirId, InlineAsmOperand, Let, Lifetime, LifetimeName, Pat, PatField, PatKind, Path,
PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding, PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding,
}; };
use rustc_lexer::{tokenize, TokenKind}; use rustc_lexer::{tokenize, TokenKind};
@ -337,7 +337,7 @@ impl HirEqInterExpr<'_, '_, '_> {
} }
fn eq_lifetime(left: &Lifetime, right: &Lifetime) -> bool { fn eq_lifetime(left: &Lifetime, right: &Lifetime) -> bool {
left.name == right.name left.res == right.res
} }
fn eq_pat_field(&mut self, left: &PatField<'_>, right: &PatField<'_>) -> bool { fn eq_pat_field(&mut self, left: &PatField<'_>, right: &PatField<'_>) -> bool {
@ -925,16 +925,10 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
} }
pub fn hash_lifetime(&mut self, lifetime: &Lifetime) { pub fn hash_lifetime(&mut self, lifetime: &Lifetime) {
std::mem::discriminant(&lifetime.name).hash(&mut self.s); lifetime.ident.name.hash(&mut self.s);
if let LifetimeName::Param(param_id, ref name) = lifetime.name { std::mem::discriminant(&lifetime.res).hash(&mut self.s);
std::mem::discriminant(name).hash(&mut self.s); if let LifetimeName::Param(param_id) = lifetime.res {
param_id.hash(&mut self.s); param_id.hash(&mut self.s);
match name {
ParamName::Plain(ref ident) => {
ident.name.hash(&mut self.s);
},
ParamName::Fresh | ParamName::Error => {},
}
} }
} }