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:
commit
696ea0627d
@ -10,8 +10,8 @@ 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, LifetimeParamKind, PolyTraitRef, PredicateOrigin, TraitFn,
|
||||||
TraitItemKind, Ty, TyKind, WherePredicate,
|
TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::hir::nested_filter as middle_nested_filter;
|
use rustc_middle::hir::nested_filter as middle_nested_filter;
|
||||||
@ -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<'_>) {
|
||||||
@ -601,7 +595,9 @@ fn report_extra_lifetimes<'tcx>(cx: &LateContext<'tcx>, func: &'tcx FnDecl<'_>,
|
|||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|par| match par.kind {
|
.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,
|
_ => None,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
@ -626,7 +622,9 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'
|
|||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|par| match par.kind {
|
.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,
|
_ => None,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
@ -653,7 +651,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.is_anonymous() && lifetime.ident.name != kw::StaticLifetime {
|
||||||
self.lifetimes_used_in_body = true;
|
self.lifetimes_used_in_body = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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 {
|
||||||
|
@ -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 => {},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user