diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2024-08-12 22:57:14 +0000 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2024-08-21 16:40:15 +0000 |
| commit | f5bae722be1f81f70d92e30cec1930f7cefc6313 (patch) | |
| tree | 42a4ddc047523fae41d3e1323d09750a86c5adaa /compiler/rustc_trait_selection | |
| parent | 4d5b3b196284aded6ae99d12bcf149ffdc8ef379 (diff) | |
| download | rust-f5bae722be1f81f70d92e30cec1930f7cefc6313.tar.gz rust-f5bae722be1f81f70d92e30cec1930f7cefc6313.zip | |
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.
Diffstat (limited to 'compiler/rustc_trait_selection')
3 files changed, 26 insertions, 6 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_relation.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_relation.rs index 9c772f42cca..f2a7da707b8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_relation.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_relation.rs @@ -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, .. }, diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs index 04e1be22a4d..600da730845 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note.rs @@ -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, diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index 877a8a23d7f..765237557d9 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -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, ); |
