Point at explicit 'static obligations on a trait

Given `trait Any: 'static` and a `struct` with a `Box<dyn Any + 'a>` field, point at the `'static` bound in `Any` to explain why `'a: 'static`.

```
error[E0478]: lifetime bound not satisfied
   --> f202.rs:2:12
    |
2   |     value: Box<dyn std::any::Any + 'a>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
note: lifetime parameter instantiated with the lifetime `'a` as defined here
   --> f202.rs:1:14
    |
1   | struct Hello<'a> {
    |              ^^
note: but lifetime parameter must outlive the static lifetime
   --> /home/gh-estebank/rust/library/core/src/any.rs:113:16
    |
113 | pub trait Any: 'static {
    |                ^^^^^^^
```

Partially address #33652.
This commit is contained in:
Esteban Küber 2024-08-12 22:57:14 +00:00
parent 4d5b3b1962
commit f5bae722be
8 changed files with 80 additions and 11 deletions

View file

@ -11,7 +11,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
pub(super) fn try_report_placeholder_relation(&self) -> Option<Diag<'tcx>> {
match &self.error {
Some(RegionResolutionError::ConcreteFailure(
SubregionOrigin::RelateRegionParamBound(span),
SubregionOrigin::RelateRegionParamBound(span, _),
Region(Interned(
RePlaceholder(ty::Placeholder {
bound: ty::BoundRegion { kind: sub_name, .. },

View file

@ -52,7 +52,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
.add_to_diag(err);
}
}
infer::RelateRegionParamBound(span) => {
infer::RelateRegionParamBound(span, _) => {
RegionOriginNote::Plain { span, msg: fluent::infer_relate_region_param_bound }
.add_to_diag(err);
}
@ -199,7 +199,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
note,
})
}
infer::RelateRegionParamBound(span) => {
infer::RelateRegionParamBound(span, _) => {
let param_instantiated = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,

View file

@ -257,7 +257,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
.add_to_diag(err);
}
}
infer::RelateRegionParamBound(span) => {
infer::RelateRegionParamBound(span, _) => {
RegionOriginNote::Plain {
span,
msg: fluent::trait_selection_relate_region_param_bound,
@ -410,7 +410,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
note,
})
}
infer::RelateRegionParamBound(span) => {
infer::RelateRegionParamBound(span, ty) => {
let param_instantiated = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,
@ -419,11 +419,31 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
note_and_explain::PrefixKind::LfParamInstantiatedWith,
note_and_explain::SuffixKind::Empty,
);
let mut alt_span = None;
if let Some(ty) = ty
&& sub.is_static()
&& let ty::Dynamic(preds, _, ty::DynKind::Dyn) = ty.kind()
&& let Some(def_id) = preds.principal_def_id()
{
for (clause, span) in
self.tcx.predicates_of(def_id).instantiate_identity(self.tcx)
{
if let ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(a, b)) =
clause.kind().skip_binder()
&& let ty::Param(param) = a.kind()
&& param.name == kw::SelfUpper
&& b.is_static()
{
// Point at explicit `'static` bound on the trait (`trait T: 'static`).
alt_span = Some(span);
}
}
}
let param_must_outlive = note_and_explain::RegionExplanation::new(
self.tcx,
generic_param_scope,
sub,
None,
alt_span,
note_and_explain::PrefixKind::LfParamMustOutlive,
note_and_explain::SuffixKind::Empty,
);