Handle anonymous lifetimes properly in diagnostics.

This commit is contained in:
Camille GILLOT 2022-05-13 19:08:57 +02:00
parent 7b86c6f21e
commit 3162b33ce5
3 changed files with 40 additions and 38 deletions

View File

@ -567,15 +567,17 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
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 { match lifetime.name {
hir::LifetimeName::Param(_) hir::LifetimeName::Param(hir::ParamName::Plain(_) | hir::ParamName::Error)
| hir::LifetimeName::Error | hir::LifetimeName::Error
| hir::LifetimeName::Static | hir::LifetimeName::Static => {
| hir::LifetimeName::Underscore => {
let lifetime_span = lifetime.span; let lifetime_span = lifetime.span;
Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span)) Some(RegionNameHighlight::MatchedAdtAndSegment(lifetime_span))
} }
hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Implicit => { hir::LifetimeName::Param(hir::ParamName::Fresh(_))
| hir::LifetimeName::ImplicitObjectLifetimeDefault
| hir::LifetimeName::Implicit
| hir::LifetimeName::Underscore => {
// In this case, the user left off the lifetime; so // In this case, the user left off the lifetime; so
// they wrote something like: // they wrote something like:
// //

View File

@ -161,45 +161,45 @@ fn msg_span_from_early_bound_and_free_regions<'tcx>(
{ {
sp = param.span; sp = param.span;
} }
let text = if br.name == kw::UnderscoreLifetime { let text = if br.has_name() {
format!("the anonymous lifetime as defined here")
} else {
format!("the lifetime `{}` as defined here", br.name) format!("the lifetime `{}` as defined here", br.name)
};
(text, sp)
}
ty::ReFree(ty::FreeRegion {
bound_region: ty::BoundRegionKind::BrNamed(_, name), ..
}) => {
let mut sp = sm.guess_head_span(tcx.def_span(scope));
if let Some(param) =
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name))
{
sp = param.span;
}
let text = if name == kw::UnderscoreLifetime {
format!("the anonymous lifetime as defined here")
} else { } else {
format!("the lifetime `{}` as defined here", name) format!("the anonymous lifetime as defined here")
}; };
(text, sp) (text, sp)
} }
ty::ReFree(ref fr) => match fr.bound_region { ty::ReFree(ref fr) => {
ty::BrAnon(idx) => { if !fr.bound_region.is_named()
if let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region) { && let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region)
("the anonymous lifetime defined here".to_string(), ty.span) {
} else { ("the anonymous lifetime defined here".to_string(), ty.span)
( } else {
match fr.bound_region {
ty::BoundRegionKind::BrNamed(_, name) => {
let mut sp = sm.guess_head_span(tcx.def_span(scope));
if let Some(param) =
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name))
{
sp = param.span;
}
let text = if name == kw::UnderscoreLifetime {
format!("the anonymous lifetime as defined here")
} else {
format!("the lifetime `{}` as defined here", name)
};
(text, sp)
}
ty::BrAnon(idx) => (
format!("the anonymous lifetime #{} defined here", idx + 1), format!("the anonymous lifetime #{} defined here", idx + 1),
tcx.def_span(scope), tcx.def_span(scope)
) ),
_ => (
format!("the lifetime `{}` as defined here", region),
sm.guess_head_span(tcx.def_span(scope)),
),
} }
} }
_ => ( }
format!("the lifetime `{}` as defined here", region),
sm.guess_head_span(tcx.def_span(scope)),
),
},
_ => bug!(), _ => bug!(),
} }
} }
@ -2555,7 +2555,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
ty::ReEarlyBound(ty::EarlyBoundRegion { name, .. }) ty::ReEarlyBound(ty::EarlyBoundRegion { name, .. })
| ty::ReFree(ty::FreeRegion { bound_region: ty::BrNamed(_, name), .. }), | ty::ReFree(ty::FreeRegion { bound_region: ty::BrNamed(_, name), .. }),
_, _,
) => { ) if name != kw::UnderscoreLifetime => {
// Does the required lifetime have a nice name we can print? // Does the required lifetime have a nice name we can print?
let mut err = struct_span_err!( let mut err = struct_span_err!(
self.tcx.sess, self.tcx.sess,

View File

@ -2,9 +2,9 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:48 --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:48
| |
LL | async fn f(self: Pin<&Self>) -> impl Clone { self } LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
| - ^^^^^^^^ | ----- ^^^^^^^^
| | | |
| hidden type `Pin<&Foo>` captures the anonymous lifetime as defined here | hidden type `Pin<&Foo>` captures the anonymous lifetime defined here
| |
help: to declare that the `impl Trait` captures `'_`, you can add an explicit `'_` lifetime bound help: to declare that the `impl Trait` captures `'_`, you can add an explicit `'_` lifetime bound
| |