Separate lifetime ident from resolution in HIR.
This commit is contained in:
parent
d121aa3b55
commit
fb7d25e978
28 changed files with 177 additions and 273 deletions
|
@ -303,7 +303,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
|||
}
|
||||
|
||||
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>) {
|
||||
|
|
|
@ -1479,10 +1479,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}))
|
||||
}
|
||||
GenericParamKind::Lifetime => {
|
||||
let ident_span = self.lower_span(ident.span);
|
||||
let ident = self.lower_ident(ident);
|
||||
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 {
|
||||
lifetime,
|
||||
span,
|
||||
|
|
|
@ -1255,7 +1255,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
} else {
|
||||
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 }
|
||||
});
|
||||
let lifetime = self.lower_lifetime(®ion);
|
||||
|
@ -1546,15 +1546,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
let lifetimes =
|
||||
self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(|(_, lifetime)| {
|
||||
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 l = self.new_named_lifetime(lifetime.id, id, span, ident);
|
||||
let l = self.new_named_lifetime(lifetime.id, id, lifetime.ident);
|
||||
hir::GenericArg::Lifetime(l)
|
||||
}));
|
||||
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(
|
||||
|(_, lifetime, res)| {
|
||||
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(
|
||||
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 {
|
||||
let span = self.lower_span(l.ident.span);
|
||||
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))]
|
||||
fn new_named_lifetime_with_res(
|
||||
&mut self,
|
||||
id: NodeId,
|
||||
span: Span,
|
||||
ident: Ident,
|
||||
res: LifetimeRes,
|
||||
) -> &'hir hir::Lifetime {
|
||||
let name = match res {
|
||||
let res = match res {
|
||||
LifetimeRes::Param { param, .. } => {
|
||||
let p_name = ParamName::Plain(ident);
|
||||
let param = self.get_remapped_def_id(param);
|
||||
|
||||
hir::LifetimeName::Param(param, p_name)
|
||||
hir::LifetimeName::Param(param)
|
||||
}
|
||||
LifetimeRes::Fresh { param, .. } => {
|
||||
debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
|
||||
let param = self.local_def_id(param);
|
||||
|
||||
hir::LifetimeName::Param(param, ParamName::Fresh)
|
||||
hir::LifetimeName::Param(param)
|
||||
}
|
||||
LifetimeRes::Infer => hir::LifetimeName::Infer,
|
||||
LifetimeRes::Static => hir::LifetimeName::Static,
|
||||
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 {
|
||||
hir_id: self.lower_node_id(id),
|
||||
span: self.lower_span(span),
|
||||
name,
|
||||
ident: self.lower_ident(ident),
|
||||
res,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2140,11 +2122,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
&mut self,
|
||||
id: NodeId,
|
||||
new_id: NodeId,
|
||||
span: Span,
|
||||
ident: Ident,
|
||||
) -> &'hir hir::Lifetime {
|
||||
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>(
|
||||
|
@ -2556,8 +2537,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
fn elided_dyn_bound(&mut self, span: Span) -> &'hir hir::Lifetime {
|
||||
let r = hir::Lifetime {
|
||||
hir_id: self.next_id(),
|
||||
span: self.lower_span(span),
|
||||
name: hir::LifetimeName::ImplicitObjectLifetimeDefault,
|
||||
ident: Ident::new(kw::Empty, self.lower_span(span)),
|
||||
res: hir::LifetimeName::ImplicitObjectLifetimeDefault,
|
||||
};
|
||||
debug!("elided_dyn_bound: r={:?}", r);
|
||||
self.arena.alloc(r)
|
||||
|
|
|
@ -2509,7 +2509,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
if let hir::TyKind::Rptr(lifetime, _) = &fn_decl.inputs[index].kind {
|
||||
// With access to the lifetime, we can get
|
||||
// the span of it.
|
||||
arguments.push((*argument, lifetime.span));
|
||||
arguments.push((*argument, lifetime.ident.span));
|
||||
} else {
|
||||
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();
|
||||
if let hir::FnRetTy::Return(ty) = &fn_decl.output {
|
||||
if let hir::TyKind::Rptr(lifetime, _) = ty.kind {
|
||||
return_span = lifetime.span;
|
||||
return_span = lifetime.ident.span;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1211,7 +1211,7 @@ fn get_mut_span_in_struct_field<'tcx>(
|
|||
&& let hir::Node::Field(field) = node
|
||||
&& 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
|
||||
|
|
|
@ -576,30 +576,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
|||
let args = last_segment.args.as_ref()?;
|
||||
let lifetime =
|
||||
self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?;
|
||||
match lifetime.name {
|
||||
hir::LifetimeName::Param(_, hir::ParamName::Plain(_) | hir::ParamName::Error)
|
||||
| hir::LifetimeName::Error
|
||||
| hir::LifetimeName::Static => {
|
||||
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
|
||||
}
|
||||
if lifetime.is_anonymous() {
|
||||
None
|
||||
} else {
|
||||
Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime.ident.span))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ use std::fmt;
|
|||
#[derive(Debug, Copy, Clone, Encodable, HashStable_Generic)]
|
||||
pub struct Lifetime {
|
||||
pub hir_id: HirId,
|
||||
pub span: Span,
|
||||
pub ident: Ident,
|
||||
|
||||
/// Either "`'a`", referring to a named lifetime definition,
|
||||
/// or "``" (i.e., `kw::Empty`), for elision placeholders.
|
||||
|
@ -37,7 +37,7 @@ pub struct Lifetime {
|
|||
/// HIR lowering inserts these placeholders in type paths that
|
||||
/// refer to type definitions needing lifetime parameters,
|
||||
/// `&T` and `&mut T`, and trait objects without `... + 'a`.
|
||||
pub name: LifetimeName,
|
||||
pub res: LifetimeName,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Encodable, Hash, Copy)]
|
||||
|
@ -88,7 +88,7 @@ impl ParamName {
|
|||
#[derive(HashStable_Generic)]
|
||||
pub enum LifetimeName {
|
||||
/// User-given names or fresh (synthetic) names.
|
||||
Param(LocalDefId, ParamName),
|
||||
Param(LocalDefId),
|
||||
|
||||
/// Implicit lifetime in a context like `dyn Foo`. This is
|
||||
/// distinguished from implicit lifetimes elsewhere because the
|
||||
|
@ -116,25 +116,6 @@ pub enum 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 {
|
||||
match self {
|
||||
LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Infer => true,
|
||||
|
@ -146,34 +127,25 @@ impl LifetimeName {
|
|||
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 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.name.ident().fmt(f)
|
||||
self.ident.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Lifetime {
|
||||
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 {
|
||||
self.name.is_static()
|
||||
self.res == LifetimeName::Static
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,7 +239,7 @@ pub enum GenericArg<'hir> {
|
|||
impl GenericArg<'_> {
|
||||
pub fn span(&self) -> Span {
|
||||
match self {
|
||||
GenericArg::Lifetime(l) => l.span,
|
||||
GenericArg::Lifetime(l) => l.ident.span,
|
||||
GenericArg::Type(t) => t.span,
|
||||
GenericArg::Const(c) => c.span,
|
||||
GenericArg::Infer(i) => i.span,
|
||||
|
@ -284,7 +256,7 @@ impl GenericArg<'_> {
|
|||
}
|
||||
|
||||
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 {
|
||||
|
@ -446,7 +418,7 @@ impl GenericBound<'_> {
|
|||
match self {
|
||||
GenericBound::Trait(t, ..) => t.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.
|
||||
pub fn span_for_param_suggestion(&self) -> Option<Span> {
|
||||
if self.params.iter().any(|p| self.span.contains(p.span)) {
|
||||
|
@ -765,10 +750,7 @@ pub struct WhereRegionPredicate<'hir> {
|
|||
impl<'hir> WhereRegionPredicate<'hir> {
|
||||
/// Returns `true` if `param_def_id` matches the `lifetime` of this predicate.
|
||||
pub fn is_param_bound(&self, param_def_id: LocalDefId) -> bool {
|
||||
match self.lifetime.name {
|
||||
LifetimeName::Param(id, _) => id == param_def_id,
|
||||
_ => false,
|
||||
}
|
||||
self.lifetime.res == LifetimeName::Param(param_def_id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3453,7 +3435,7 @@ impl<'hir> Node<'hir> {
|
|||
| Node::Variant(Variant { ident, .. })
|
||||
| Node::Item(Item { 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::TypeBinding(b) => Some(b.ident),
|
||||
Node::Param(..)
|
||||
|
|
|
@ -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) {
|
||||
visitor.visit_id(lifetime.hir_id);
|
||||
match lifetime.name {
|
||||
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 => {}
|
||||
}
|
||||
visitor.visit_ident(lifetime.ident);
|
||||
}
|
||||
|
||||
pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath<'v>, id: HirId) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#![feature(associated_type_defaults)]
|
||||
#![feature(closure_track_caller)]
|
||||
#![feature(const_btree_len)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(never_type)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
|
|
@ -241,14 +241,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
|
||||
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");
|
||||
|
||||
// This indicates an illegal lifetime
|
||||
// elision. `resolve_lifetime` should have
|
||||
// reported an error in this case -- but if
|
||||
// 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
|
||||
// `re_error`, annoyingly, so use `'static`.
|
||||
|
@ -961,9 +961,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
}
|
||||
hir::GenericBound::Outlives(lifetime) => {
|
||||
let region = self.ast_region_to_region(lifetime, None);
|
||||
bounds
|
||||
.region_bounds
|
||||
.push((ty::Binder::bind_with_vars(region, bound_vars), lifetime.span));
|
||||
bounds.region_bounds.push((
|
||||
ty::Binder::bind_with_vars(region, bound_vars),
|
||||
lifetime.ident.span,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::LateBound(debruijn, _, _)) if debruijn < self.outer_index => {}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ use rustc_middle::hir::nested_filter;
|
|||
use rustc_middle::middle::resolve_lifetime::*;
|
||||
use rustc_middle::ty::{self, DefIdTree, TyCtxt, TypeSuperVisitable, TypeVisitor};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::Span;
|
||||
use std::fmt;
|
||||
|
||||
|
@ -595,7 +595,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
this.visit_poly_trait_ref(bound);
|
||||
}
|
||||
});
|
||||
match lifetime.name {
|
||||
match lifetime.res {
|
||||
LifetimeName::ImplicitObjectLifetimeDefault => {
|
||||
// If the user does not write *anything*, we
|
||||
// use the object lifetime defaulting
|
||||
|
@ -686,7 +686,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
|||
if !parent_id.is_owner() {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
lifetime.span,
|
||||
lifetime.ident.span,
|
||||
E0657,
|
||||
"`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)
|
||||
{
|
||||
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",
|
||||
);
|
||||
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))]
|
||||
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::Param(param_def_id, _) => {
|
||||
hir::LifetimeName::Param(param_def_id) => {
|
||||
self.resolve_lifetime_ref(param_def_id, 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);
|
||||
walk_list!(this, visit_param_bound, bounds);
|
||||
|
||||
if lifetime.name != hir::LifetimeName::Static {
|
||||
if lifetime.res != hir::LifetimeName::Static {
|
||||
for bound in bounds {
|
||||
let hir::GenericBound::Outlives(ref lt) = bound else {
|
||||
continue;
|
||||
};
|
||||
if lt.name != hir::LifetimeName::Static {
|
||||
if lt.res != hir::LifetimeName::Static {
|
||||
continue;
|
||||
}
|
||||
this.insert_lifetime(lt, Region::Static);
|
||||
this.tcx
|
||||
.sess
|
||||
.struct_span_warn(
|
||||
lifetime.span,
|
||||
lifetime.ident.span,
|
||||
&format!(
|
||||
"unnecessary lifetime parameter `{}`",
|
||||
lifetime.name.ident(),
|
||||
lifetime.ident,
|
||||
),
|
||||
)
|
||||
.help(&format!(
|
||||
"you can use the `'static` lifetime directly, in place of `{}`",
|
||||
lifetime.name.ident(),
|
||||
lifetime.ident,
|
||||
))
|
||||
.emit();
|
||||
}
|
||||
|
@ -1043,7 +1043,7 @@ fn object_lifetime_default<'tcx>(tcx: TyCtxt<'tcx>, param_def_id: DefId) -> Obje
|
|||
|
||||
for bound in bound.bounds {
|
||||
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 {
|
||||
Set1::Empty => ObjectLifetimeDefault::Empty,
|
||||
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::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
|
||||
// regular fns.
|
||||
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)
|
||||
&& !self.tcx.features().anonymous_lifetime_in_impl_trait
|
||||
{
|
||||
let mut diag = rustc_session::parse::feature_err(
|
||||
&self.tcx.sess.parse_sess,
|
||||
sym::anonymous_lifetime_in_impl_trait,
|
||||
lifetime_ref.span,
|
||||
lifetime_ref.ident.span,
|
||||
"anonymous lifetimes in `impl Trait` are unstable",
|
||||
);
|
||||
|
||||
match self.tcx.hir().get_generics(lifetime_ref.hir_id.owner.def_id) {
|
||||
Some(generics) => {
|
||||
if let 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() {
|
||||
Some(_) => {
|
||||
Some((self.tcx.sess.source_map().span_through_char(generics.span, '<').shrink_to_hi(), "'a, ".to_owned()))
|
||||
},
|
||||
None => Some((generics.span, "<'a>".to_owned()))
|
||||
};
|
||||
|
||||
let mut multi_sugg_vec = vec![(lifetime_ref.span.shrink_to_hi(), "'a ".to_owned())];
|
||||
|
||||
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.span_label(
|
||||
lifetime_ref.ident.span,
|
||||
"expected named lifetime parameter",
|
||||
);
|
||||
diag.multipart_suggestion(
|
||||
"consider introducing a named lifetime parameter",
|
||||
suggestions,
|
||||
rustc_errors::Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
|
||||
diag.emit();
|
||||
|
@ -1287,7 +1293,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
|||
where_bound_origin: Some(hir::PredicateOrigin::ImplTrait), ..
|
||||
} => {
|
||||
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",
|
||||
);
|
||||
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(
|
||||
lifetime_ref.span,
|
||||
lifetime_ref.ident.span,
|
||||
&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))]
|
||||
fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) {
|
||||
debug!(
|
||||
node = ?self.tcx.hir().node_to_string(lifetime_ref.hir_id),
|
||||
span = ?self.tcx.sess.source_map().span_to_diagnostic_string(lifetime_ref.span)
|
||||
);
|
||||
debug!(span = ?lifetime_ref.ident.span);
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -1852,7 +1855,7 @@ fn is_late_bound_map(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<&FxIndexSet<
|
|||
|
||||
impl<'v> Visitor<'v> for AllCollector {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -229,7 +229,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
|||
predicates.extend(region_pred.bounds.iter().map(|bound| {
|
||||
let (r2, span) = match bound {
|
||||
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!(),
|
||||
};
|
||||
|
|
|
@ -2159,7 +2159,7 @@ impl<'a> State<'a> {
|
|||
}
|
||||
|
||||
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<'_>) {
|
||||
|
|
|
@ -375,7 +375,7 @@ impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> {
|
|||
return false;
|
||||
};
|
||||
|
||||
if !lifetime_sub.name.is_anonymous() || !lifetime_sup.name.is_anonymous() {
|
||||
if !lifetime_sub.is_anonymous() || !lifetime_sup.is_anonymous() {
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -407,20 +407,20 @@ impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> {
|
|||
let suggestion_param_name =
|
||||
suggestion_param_name.map(|n| n.to_string()).unwrap_or_else(|| "'a".to_owned());
|
||||
|
||||
debug!(?lifetime_sup.span);
|
||||
debug!(?lifetime_sub.span);
|
||||
let make_suggestion = |span: rustc_span::Span| {
|
||||
if span.is_empty() {
|
||||
(span, format!("{}, ", suggestion_param_name))
|
||||
} else if let Ok("&") = self.tcx.sess.source_map().span_to_snippet(span).as_deref()
|
||||
{
|
||||
(span.shrink_to_hi(), format!("{} ", suggestion_param_name))
|
||||
debug!(?lifetime_sup.ident.span);
|
||||
debug!(?lifetime_sub.ident.span);
|
||||
let make_suggestion = |ident: Ident| {
|
||||
let sugg = if ident.name == kw::Empty {
|
||||
format!("{}, ", suggestion_param_name)
|
||||
} else if ident.name == kw::UnderscoreLifetime && ident.span.is_empty() {
|
||||
format!("{} ", suggestion_param_name)
|
||||
} else {
|
||||
(span, suggestion_param_name.clone())
|
||||
}
|
||||
suggestion_param_name.clone()
|
||||
};
|
||||
(ident.span, sugg)
|
||||
};
|
||||
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 {
|
||||
let new_param_suggestion = if let Some(first) =
|
||||
|
|
|
@ -314,10 +314,10 @@ pub fn suggest_new_region_bound(
|
|||
.iter()
|
||||
.filter_map(|arg| match arg {
|
||||
GenericBound::Outlives(Lifetime {
|
||||
name: LifetimeName::Static,
|
||||
span,
|
||||
res: LifetimeName::Static,
|
||||
ident,
|
||||
..
|
||||
}) => Some(*span),
|
||||
}) => Some(ident.span),
|
||||
_ => None,
|
||||
})
|
||||
.next()
|
||||
|
@ -342,10 +342,10 @@ pub fn suggest_new_region_bound(
|
|||
.bounds
|
||||
.iter()
|
||||
.filter_map(|arg| match arg {
|
||||
GenericBound::Outlives(Lifetime { name, span, .. })
|
||||
if name.ident().to_string() == lifetime_name =>
|
||||
GenericBound::Outlives(Lifetime { ident, .. })
|
||||
if ident.name.to_string() == lifetime_name =>
|
||||
{
|
||||
Some(*span)
|
||||
Some(ident.span)
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
|
@ -361,8 +361,8 @@ pub fn suggest_new_region_bound(
|
|||
);
|
||||
}
|
||||
}
|
||||
TyKind::TraitObject(_, lt, _) => match lt.name {
|
||||
LifetimeName::ImplicitObjectLifetimeDefault => {
|
||||
TyKind::TraitObject(_, lt, _) => {
|
||||
if let LifetimeName::ImplicitObjectLifetimeDefault = lt.res {
|
||||
err.span_suggestion_verbose(
|
||||
fn_return.span.shrink_to_hi(),
|
||||
&format!(
|
||||
|
@ -374,15 +374,14 @@ pub fn suggest_new_region_bound(
|
|||
&plus_lt,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
name if name.ident().to_string() != lifetime_name => {
|
||||
} else if lt.ident.name.to_string() != lifetime_name {
|
||||
// With this check we avoid suggesting redundant bounds. This
|
||||
// would happen if there are nested impl/dyn traits and only
|
||||
// one of them has the bound we'd suggest already there, like
|
||||
// in `impl Foo<X = dyn Bar> + '_`.
|
||||
if let Some(explicit_static) = &explicit_static {
|
||||
err.span_suggestion_verbose(
|
||||
lt.span,
|
||||
lt.ident.span,
|
||||
&format!("{} the trait object's {}", consider, explicit_static),
|
||||
&lifetime_name,
|
||||
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>) {
|
||||
if let TyKind::TraitObject(
|
||||
poly_trait_refs,
|
||||
Lifetime { name: LifetimeName::ImplicitObjectLifetimeDefault, .. },
|
||||
Lifetime { res: LifetimeName::ImplicitObjectLifetimeDefault, .. },
|
||||
_,
|
||||
) = t.kind
|
||||
{
|
||||
|
|
|
@ -272,11 +272,7 @@ fn gen_args(segment: &PathSegment<'_>) -> String {
|
|||
.args
|
||||
.iter()
|
||||
.filter_map(|arg| {
|
||||
if let GenericArg::Lifetime(lt) = arg {
|
||||
Some(lt.name.ident().to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
if let GenericArg::Lifetime(lt) = arg { Some(lt.ident.to_string()) } else { None }
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ fn gen_args(cx: &LateContext<'_>, segment: &PathSegment<'_>) -> String {
|
|||
.args
|
||||
.iter()
|
||||
.map(|arg| match arg {
|
||||
GenericArg::Lifetime(lt) => lt.name.ident().to_string(),
|
||||
GenericArg::Lifetime(lt) => lt.ident.to_string(),
|
||||
GenericArg::Type(ty) => {
|
||||
cx.tcx.sess.source_map().span_to_snippet(ty.span).unwrap_or_else(|_| "_".into())
|
||||
}
|
||||
|
|
|
@ -1058,7 +1058,7 @@ impl<'hir> Map<'hir> {
|
|||
Node::Arm(arm) => arm.span,
|
||||
Node::Block(block) => block.span,
|
||||
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::Infer(i) => i.span,
|
||||
Node::Local(local) => local.span,
|
||||
|
|
|
@ -397,7 +397,7 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
|
|||
hir::TyKind::TraitObject(
|
||||
_,
|
||||
hir::Lifetime {
|
||||
name:
|
||||
res:
|
||||
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> {
|
||||
fn visit_lifetime(&mut self, lt: &'v hir::Lifetime) {
|
||||
if let hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static =
|
||||
lt.name
|
||||
if let hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static = lt.res
|
||||
{
|
||||
self.0.push(lt.span);
|
||||
self.0.push(lt.ident.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ impl<'hir> Sig for hir::Ty<'hir> {
|
|||
}
|
||||
hir::TyKind::Rptr(ref lifetime, ref mt) => {
|
||||
let mut prefix = "&".to_owned();
|
||||
prefix.push_str(&lifetime.name.ident().to_string());
|
||||
prefix.push_str(&lifetime.ident.to_string());
|
||||
prefix.push(' ');
|
||||
if let hir::Mutability::Mut = mt.mutbl {
|
||||
prefix.push_str("mut ");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue