Auto merge of #104048 - cjgillot:split-lifetime, r=compiler-errors

Separate lifetime ident from lifetime resolution in HIR

Drive-by: change how suggested generic args are computed.
Fixes https://github.com/rust-lang/rust/issues/103815

I recommend reviewing commit-by-commit.
This commit is contained in:
bors 2022-11-27 14:30:19 +00:00
commit 696ea0627d
5 changed files with 33 additions and 46 deletions

View File

@ -10,8 +10,8 @@
use rustc_hir::FnRetTy::Return;
use rustc_hir::{
BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl, ImplItem,
ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, ParamName, PolyTraitRef, PredicateOrigin, TraitFn, TraitItem,
TraitItemKind, Ty, TyKind, WherePredicate,
ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, PolyTraitRef, PredicateOrigin, TraitFn,
TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter as middle_nested_filter;
@ -180,7 +180,7 @@ fn check_fn_inner<'tcx>(
_ => None,
});
for bound in lifetimes {
if bound.name != LifetimeName::Static && !bound.is_elided() {
if !bound.is_static() && !bound.is_elided() {
return;
}
}
@ -414,17 +414,13 @@ fn new(cx: &'a LateContext<'tcx>) -> Self {
fn record(&mut self, lifetime: &Option<Lifetime>) {
if let Some(ref lt) = *lifetime {
if lt.name == LifetimeName::Static {
if lt.is_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.
self.lts.push(RefLt::Unnamed);
} else if lt.is_elided() {
self.lts.push(RefLt::Unnamed);
} else if let LifetimeName::Param(def_id, _) = lt.name {
} else if let LifetimeName::Param(def_id) = lt.res {
self.lts.push(RefLt::Named(def_id));
} else {
self.lts.push(RefLt::Unnamed);
}
} else {
self.lts.push(RefLt::Unnamed);
@ -472,7 +468,7 @@ fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
walk_item(self, item);
self.lts.truncate(len);
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)
} else {
RefLt::Unnamed
@ -498,10 +494,8 @@ fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
}
fn visit_generic_arg(&mut self, generic_arg: &'tcx GenericArg<'tcx>) {
if let GenericArg::Lifetime(l) = generic_arg
&& let LifetimeName::Param(def_id, _) = l.name
{
self.lifetime_generic_arg_spans.entry(def_id).or_insert(l.span);
if let GenericArg::Lifetime(l) = generic_arg && let LifetimeName::Param(def_id) = l.res {
self.lifetime_generic_arg_spans.entry(def_id).or_insert(l.ident.span);
}
// Replace with `walk_generic_arg` if/when https://github.com/rust-lang/rust/pull/103692 lands.
// walk_generic_arg(self, generic_arg);
@ -577,7 +571,7 @@ impl<'cx, 'tcx, F> Visitor<'tcx> for LifetimeChecker<'cx, 'tcx, F>
// for lifetimes as parameters of generics
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<'_>) {
@ -601,7 +595,9 @@ fn report_extra_lifetimes<'tcx>(cx: &LateContext<'tcx>, func: &'tcx FnDecl<'_>,
.params
.iter()
.filter_map(|par| match par.kind {
GenericParamKind::Lifetime { .. } => Some((par.name.ident().name, par.span)),
GenericParamKind::Lifetime {
kind: LifetimeParamKind::Explicit,
} => Some((par.name.ident().name, par.span)),
_ => None,
})
.collect();
@ -626,7 +622,9 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'
.params
.iter()
.filter_map(|par| match par.kind {
GenericParamKind::Lifetime { .. } => Some((par.name.ident().name, par.span)),
GenericParamKind::Lifetime {
kind: LifetimeParamKind::Explicit,
} => Some((par.name.ident().name, par.span)),
_ => None,
})
.collect();
@ -653,7 +651,7 @@ struct BodyLifetimeChecker {
impl<'tcx> Visitor<'tcx> for BodyLifetimeChecker {
// for lifetimes as parameters of generics
fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {
if lifetime.name.ident().name != kw::UnderscoreLifetime && lifetime.name.ident().name != kw::StaticLifetime {
if !lifetime.is_anonymous() && lifetime.ident.name != kw::StaticLifetime {
self.lifetimes_used_in_body = true;
}
}

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@
use rustc_hir::HirIdMap;
use rustc_hir::{
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,
};
use rustc_lexer::{tokenize, TokenKind};
@ -337,7 +337,7 @@ fn eq_generic_arg(&mut self, left: &GenericArg<'_>, right: &GenericArg<'_>) -> b
}
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 {
@ -925,16 +925,10 @@ pub fn hash_guard(&mut self, g: &Guard<'_>) {
}
pub fn hash_lifetime(&mut self, lifetime: &Lifetime) {
std::mem::discriminant(&lifetime.name).hash(&mut self.s);
if let LifetimeName::Param(param_id, ref name) = lifetime.name {
std::mem::discriminant(name).hash(&mut self.s);
lifetime.ident.name.hash(&mut self.s);
std::mem::discriminant(&lifetime.res).hash(&mut self.s);
if let LifetimeName::Param(param_id) = lifetime.res {
param_id.hash(&mut self.s);
match name {
ParamName::Plain(ref ident) => {
ident.name.hash(&mut self.s);
},
ParamName::Fresh | ParamName::Error => {},
}
}
}