Skip to content

Commit 147bb17

Browse files
Rework how we emit errors for unresolved object lifetimes
1 parent f167efa commit 147bb17

File tree

3 files changed

+25
-16
lines changed

3 files changed

+25
-16
lines changed

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
392392
}
393393

394394
fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
395-
if let RegionInferReason::BorrowedObjectLifetimeDefault = reason {
395+
if let RegionInferReason::ObjectLifetimeDefault = reason {
396396
let e = struct_span_code_err!(
397397
self.dcx(),
398398
span,

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,9 @@ pub enum PredicateFilter {
8585

8686
#[derive(Debug)]
8787
pub enum RegionInferReason<'a> {
88-
/// Lifetime on a trait object behind a reference.
89-
/// This allows inferring information from the reference.
90-
BorrowedObjectLifetimeDefault,
91-
/// A trait object's lifetime.
88+
/// Lifetime on a trait object that is spelled explicitly, e.g. `+ 'a` or `+ '_`.
89+
ExplicitObjectLifetime,
90+
/// A trait object's lifetime when it is elided, e.g. `dyn Any`.
9291
ObjectLifetimeDefault,
9392
/// Generic lifetime parameter
9493
Param(&'a ty::GenericParamDef),

compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
3030
hir_id: hir::HirId,
3131
hir_trait_bounds: &[(hir::PolyTraitRef<'tcx>, hir::TraitBoundModifier)],
3232
lifetime: &hir::Lifetime,
33-
borrowed: bool,
33+
_borrowed: bool,
3434
representation: DynKind,
3535
) -> Ty<'tcx> {
3636
let tcx = self.tcx();
@@ -325,22 +325,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
325325
v.dedup();
326326
let existential_predicates = tcx.mk_poly_existential_predicates(&v);
327327

328-
// Use explicitly-specified region bound.
328+
// Use explicitly-specified region bound, unless the bound is missing.
329329
let region_bound = if !lifetime.is_elided() {
330-
self.lower_lifetime(lifetime, RegionInferReason::ObjectLifetimeDefault)
330+
self.lower_lifetime(lifetime, RegionInferReason::ExplicitObjectLifetime)
331331
} else {
332332
self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
333+
// Curiously, we prefer object lifetime default for `+ '_`...
333334
if tcx.named_bound_var(lifetime.hir_id).is_some() {
334-
self.lower_lifetime(lifetime, RegionInferReason::ObjectLifetimeDefault)
335+
self.lower_lifetime(lifetime, RegionInferReason::ExplicitObjectLifetime)
335336
} else {
336-
self.re_infer(
337-
span,
338-
if borrowed {
339-
RegionInferReason::ObjectLifetimeDefault
337+
let reason =
338+
if let hir::LifetimeName::ImplicitObjectLifetimeDefault = lifetime.res {
339+
if let hir::Node::Ty(hir::Ty {
340+
kind: hir::TyKind::Ref(parent_lifetime, _),
341+
..
342+
}) = tcx.parent_hir_node(hir_id)
343+
&& tcx.named_bound_var(parent_lifetime.hir_id).is_none()
344+
{
345+
// Parent lifetime must have failed to resolve. Don't emit a redundant error.
346+
RegionInferReason::ExplicitObjectLifetime
347+
} else {
348+
RegionInferReason::ObjectLifetimeDefault
349+
}
340350
} else {
341-
RegionInferReason::BorrowedObjectLifetimeDefault
342-
},
343-
)
351+
RegionInferReason::ExplicitObjectLifetime
352+
};
353+
self.re_infer(span, reason)
344354
}
345355
})
346356
};

0 commit comments

Comments
 (0)