Modernize diagnostic for indeterminate trait object lifetime bounds

This commit is contained in:
León Orell Valerian Liehr 2026-01-29 21:13:09 +01:00
parent 38c71295e8
commit dc24aae43e
No known key found for this signature in database
GPG key ID: D17A07215F68E713
11 changed files with 63 additions and 27 deletions

View file

@ -22,9 +22,7 @@ use rustc_abi::{ExternAbi, Size};
use rustc_ast::Recovered;
use rustc_data_structures::assert_matches;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_errors::{
Applicability, Diag, DiagCtxtHandle, E0228, ErrorGuaranteed, StashKey, struct_span_code_err,
};
use rustc_errors::{Applicability, Diag, DiagCtxtHandle, E0228, ErrorGuaranteed, StashKey};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
@ -316,16 +314,24 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
}
fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
if let RegionInferReason::ObjectLifetimeDefault = reason {
let e = struct_span_code_err!(
self.dcx(),
span,
E0228,
"the lifetime bound for this object type cannot be deduced \
from context; please supply an explicit bound"
)
.emit();
ty::Region::new_error(self.tcx(), e)
if let RegionInferReason::ObjectLifetimeDefault(sugg_sp) = reason {
// FIXME: Account for trailing plus `dyn Trait+`, the need of parens in
// `*const dyn Trait` and `Fn() -> *const dyn Trait`.
let guar = self
.dcx()
.struct_span_err(
span,
"cannot deduce the lifetime bound for this trait object type from context",
)
.with_code(E0228)
.with_span_suggestion_verbose(
sugg_sp,
"please supply an explicit bound",
" + /* 'a */",
Applicability::HasPlaceholders,
)
.emit();
ty::Region::new_error(self.tcx(), guar)
} else {
// This indicates an illegal lifetime in a non-assoc-trait position
ty::Region::new_error_with_message(self.tcx(), span, "unelided lifetime in signature")

View file

@ -460,7 +460,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// Parent lifetime must have failed to resolve. Don't emit a redundant error.
RegionInferReason::ExplicitObjectLifetime
} else {
RegionInferReason::ObjectLifetimeDefault
RegionInferReason::ObjectLifetimeDefault(span.shrink_to_hi())
}
} else {
RegionInferReason::ExplicitObjectLifetime

View file

@ -105,7 +105,7 @@ pub enum RegionInferReason<'a> {
/// Lifetime on a trait object that is spelled explicitly, e.g. `+ 'a` or `+ '_`.
ExplicitObjectLifetime,
/// A trait object's lifetime when it is elided, e.g. `dyn Any`.
ObjectLifetimeDefault,
ObjectLifetimeDefault(Span),
/// Generic lifetime parameter
Param(&'a ty::GenericParamDef),
RegionPredicate,

View file

@ -21,11 +21,11 @@ struct Ref2<'a,'b:'a,T:'a+'b+?Sized> {
}
fn a<'a,'b>(t: Ref2<'a,'b, dyn Test>) {
//~^ ERROR lifetime bound for this object type cannot be deduced from context
//~^ ERROR cannot deduce the lifetime bound for this trait object type
}
fn b(t: Ref2<dyn Test>) {
//~^ ERROR lifetime bound for this object type cannot be deduced from context
//~^ ERROR cannot deduce the lifetime bound for this trait object type
}
fn c(t: Ref2<&dyn Test>) {
@ -41,7 +41,7 @@ fn e(t: Ref2<Ref0<dyn Test>>) {
}
fn f(t: &Ref2<dyn Test>) {
//~^ ERROR lifetime bound for this object type cannot be deduced from context
//~^ ERROR cannot deduce the lifetime bound for this trait object type
}
fn main() {

View file

@ -1,20 +1,35 @@
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
error[E0228]: cannot deduce the lifetime bound for this trait object type from context
--> $DIR/object-lifetime-default-ambiguous.rs:23:28
|
LL | fn a<'a,'b>(t: Ref2<'a,'b, dyn Test>) {
| ^^^^^^^^
|
help: please supply an explicit bound
|
LL | fn a<'a,'b>(t: Ref2<'a,'b, dyn Test + /* 'a */>) {
| ++++++++++
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
error[E0228]: cannot deduce the lifetime bound for this trait object type from context
--> $DIR/object-lifetime-default-ambiguous.rs:27:14
|
LL | fn b(t: Ref2<dyn Test>) {
| ^^^^^^^^
|
help: please supply an explicit bound
|
LL | fn b(t: Ref2<dyn Test + /* 'a */>) {
| ++++++++++
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
error[E0228]: cannot deduce the lifetime bound for this trait object type from context
--> $DIR/object-lifetime-default-ambiguous.rs:43:15
|
LL | fn f(t: &Ref2<dyn Test>) {
| ^^^^^^^^
|
help: please supply an explicit bound
|
LL | fn f(t: &Ref2<dyn Test + /* 'a */>) {
| ++++++++++
error: aborting due to 3 previous errors

View file

@ -18,7 +18,7 @@ fn is_static<T>(_: T) where T: 'static { }
// Here, we should default to `dyn Bar + 'static`, but the current
// code forces us into a conservative, hacky path.
fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar> { &() }
//~^ ERROR please supply an explicit bound
//~^ ERROR cannot deduce the lifetime bound for this trait object type
fn main() {
let s = format!("foo");

View file

@ -1,8 +1,13 @@
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
error[E0228]: cannot deduce the lifetime bound for this trait object type from context
--> $DIR/object-lifetime-default-dyn-binding-nonstatic1.rs:20:50
|
LL | fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar> { &() }
| ^^^^^^^
|
help: please supply an explicit bound
|
LL | fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar + /* 'a */> { &() }
| ++++++++++
error: aborting due to 1 previous error

View file

@ -18,7 +18,7 @@ fn is_static<T>(_: T) where T: 'static { }
// Here, we default to `dyn Bar + 'a`. Or, we *should*, but the
// current code forces us into a conservative, hacky path.
fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar> { &() }
//~^ ERROR please supply an explicit bound
//~^ ERROR cannot deduce the lifetime bound for this trait object type
fn main() {
let s = format!("foo");

View file

@ -1,8 +1,13 @@
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
error[E0228]: cannot deduce the lifetime bound for this trait object type from context
--> $DIR/object-lifetime-default-dyn-binding-nonstatic2.rs:20:50
|
LL | fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar> { &() }
| ^^^^^^^
|
help: please supply an explicit bound
|
LL | fn bar<'a>(x: &'a str) -> &'a dyn Foo<'a, Item = dyn Bar + /* 'a */> { &() }
| ++++++++++
error: aborting due to 1 previous error

View file

@ -14,7 +14,7 @@ fn is_static<T>(_: T) where T: 'static { }
// Here, we should default to `dyn Bar + 'static`, but the current
// code forces us into a conservative, hacky path.
fn bar(x: &str) -> &dyn Foo<Item = dyn Bar> { &() }
//~^ ERROR please supply an explicit bound
//~^ ERROR cannot deduce the lifetime bound for this trait object type
fn main() {
let s = format!("foo");

View file

@ -1,8 +1,13 @@
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
error[E0228]: cannot deduce the lifetime bound for this trait object type from context
--> $DIR/object-lifetime-default-dyn-binding-nonstatic3.rs:16:36
|
LL | fn bar(x: &str) -> &dyn Foo<Item = dyn Bar> { &() }
| ^^^^^^^
|
help: please supply an explicit bound
|
LL | fn bar(x: &str) -> &dyn Foo<Item = dyn Bar + /* 'a */> { &() }
| ++++++++++
error: aborting due to 1 previous error