mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-23 05:03:47 +00:00
Handle anonymous lifetimes properly in diagnostics.
This commit is contained in:
parent
7b86c6f21e
commit
3162b33ce5
@ -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:
|
||||||
//
|
//
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
|
|
|
||||||
|
Loading…
Reference in New Issue
Block a user