Rework how we emit errors for unresolved object lifetimes
This commit is contained in:
parent
f167efad2f
commit
147bb17f51
3 changed files with 25 additions and 16 deletions
|
@ -392,7 +392,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
|
fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
|
||||||
if let RegionInferReason::BorrowedObjectLifetimeDefault = reason {
|
if let RegionInferReason::ObjectLifetimeDefault = reason {
|
||||||
let e = struct_span_code_err!(
|
let e = struct_span_code_err!(
|
||||||
self.dcx(),
|
self.dcx(),
|
||||||
span,
|
span,
|
||||||
|
|
|
@ -85,10 +85,9 @@ pub enum PredicateFilter {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum RegionInferReason<'a> {
|
pub enum RegionInferReason<'a> {
|
||||||
/// Lifetime on a trait object behind a reference.
|
/// Lifetime on a trait object that is spelled explicitly, e.g. `+ 'a` or `+ '_`.
|
||||||
/// This allows inferring information from the reference.
|
ExplicitObjectLifetime,
|
||||||
BorrowedObjectLifetimeDefault,
|
/// A trait object's lifetime when it is elided, e.g. `dyn Any`.
|
||||||
/// A trait object's lifetime.
|
|
||||||
ObjectLifetimeDefault,
|
ObjectLifetimeDefault,
|
||||||
/// Generic lifetime parameter
|
/// Generic lifetime parameter
|
||||||
Param(&'a ty::GenericParamDef),
|
Param(&'a ty::GenericParamDef),
|
||||||
|
|
|
@ -30,7 +30,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
hir_id: hir::HirId,
|
hir_id: hir::HirId,
|
||||||
hir_trait_bounds: &[(hir::PolyTraitRef<'tcx>, hir::TraitBoundModifier)],
|
hir_trait_bounds: &[(hir::PolyTraitRef<'tcx>, hir::TraitBoundModifier)],
|
||||||
lifetime: &hir::Lifetime,
|
lifetime: &hir::Lifetime,
|
||||||
borrowed: bool,
|
_borrowed: bool,
|
||||||
representation: DynKind,
|
representation: DynKind,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
@ -325,22 +325,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
v.dedup();
|
v.dedup();
|
||||||
let existential_predicates = tcx.mk_poly_existential_predicates(&v);
|
let existential_predicates = tcx.mk_poly_existential_predicates(&v);
|
||||||
|
|
||||||
// Use explicitly-specified region bound.
|
// Use explicitly-specified region bound, unless the bound is missing.
|
||||||
let region_bound = if !lifetime.is_elided() {
|
let region_bound = if !lifetime.is_elided() {
|
||||||
self.lower_lifetime(lifetime, RegionInferReason::ObjectLifetimeDefault)
|
self.lower_lifetime(lifetime, RegionInferReason::ExplicitObjectLifetime)
|
||||||
} else {
|
} else {
|
||||||
self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
|
self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
|
||||||
|
// Curiously, we prefer object lifetime default for `+ '_`...
|
||||||
if tcx.named_bound_var(lifetime.hir_id).is_some() {
|
if tcx.named_bound_var(lifetime.hir_id).is_some() {
|
||||||
self.lower_lifetime(lifetime, RegionInferReason::ObjectLifetimeDefault)
|
self.lower_lifetime(lifetime, RegionInferReason::ExplicitObjectLifetime)
|
||||||
} else {
|
} else {
|
||||||
self.re_infer(
|
let reason =
|
||||||
span,
|
if let hir::LifetimeName::ImplicitObjectLifetimeDefault = lifetime.res {
|
||||||
if borrowed {
|
if let hir::Node::Ty(hir::Ty {
|
||||||
RegionInferReason::ObjectLifetimeDefault
|
kind: hir::TyKind::Ref(parent_lifetime, _),
|
||||||
|
..
|
||||||
|
}) = tcx.parent_hir_node(hir_id)
|
||||||
|
&& tcx.named_bound_var(parent_lifetime.hir_id).is_none()
|
||||||
|
{
|
||||||
|
// Parent lifetime must have failed to resolve. Don't emit a redundant error.
|
||||||
|
RegionInferReason::ExplicitObjectLifetime
|
||||||
|
} else {
|
||||||
|
RegionInferReason::ObjectLifetimeDefault
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
RegionInferReason::BorrowedObjectLifetimeDefault
|
RegionInferReason::ExplicitObjectLifetime
|
||||||
},
|
};
|
||||||
)
|
self.re_infer(span, reason)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue