Skip to content

Commit d05b341

Browse files
committed
Elaborate predicates to also display transitive obligations
1 parent 5734935 commit d05b341

File tree

2 files changed

+38
-19
lines changed

2 files changed

+38
-19
lines changed

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use rustc_middle::traits::ObligationCauseCode;
2525
use rustc_middle::ty::{self, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeVisitor};
2626
use rustc_span::symbol::{kw, Ident};
2727
use rustc_span::Span;
28+
use rustc_trait_selection::traits;
2829

2930
use crate::borrowck_errors;
3031
use crate::session_diagnostics::{
@@ -676,25 +677,31 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
676677
// fn foo(&self) where Self: 'static {}
677678
// }
678679
// ```
679-
let mut predicates: Vec<Span> = tcx
680-
.predicates_of(def_id)
681-
.predicates
682-
.iter()
683-
.chain(tcx.predicates_of(parent).predicates.iter())
684-
.filter_map(|(pred, pred_span)| {
685-
if let Some(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(pred_ty, r))) =
686-
pred.kind().no_bound_vars()
687-
// Look for `'static` bounds
688-
&& r.kind() == ty::ReStatic
689-
// We only want bounds on `Self`
690-
&& self.infcx.can_eq(self.param_env, ty, pred_ty)
691-
{
692-
Some(*pred_span)
693-
} else {
694-
None
695-
}
696-
})
697-
.collect();
680+
let mut predicates: Vec<Span> = traits::elaborate(
681+
tcx,
682+
tcx.predicates_of(def_id).predicates.iter().map(|(p, sp)| (p.as_predicate(), *sp)),
683+
)
684+
.chain(traits::elaborate(
685+
tcx,
686+
tcx.predicates_of(parent).predicates.iter().map(|(p, sp)| (p.as_predicate(), *sp)),
687+
))
688+
.filter_map(|(pred, pred_span)| {
689+
if let ty::PredicateKind::Clause(clause) = pred.kind().skip_binder()
690+
&& let ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(pred_ty, r)) = clause
691+
// Look for `'static` bounds
692+
&& r.kind() == ty::ReStatic
693+
// We only want bounds on `Self`
694+
&& (self.infcx.can_eq(self.param_env, ty, pred_ty)
695+
|| matches!(
696+
pred_ty.kind(),
697+
ty::Param(name) if name.name.as_str() == "Self"))
698+
{
699+
Some(pred_span)
700+
} else {
701+
None
702+
}
703+
})
704+
.collect();
698705

699706
// Look at the receiver for `&'static self`, which introduces a `'static` obligation.
700707
// ```

tests/ui/lifetimes/static-impl-obligation.stderr

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ LL | val.use_self()
2828
| |
2929
| `val` escapes the function body here
3030
| argument requires that `'a` must outlive `'static`
31+
|
32+
note: the `impl` on `dyn t::ObjectTrait` has a `'static` lifetime requirement
33+
--> $DIR/static-impl-obligation.rs:216:47
34+
|
35+
LL | fn use_self(&self) -> &() where Self: 'static { panic!() }
36+
| ^^^^^^^
3137

3238
error[E0521]: borrowed data escapes outside of function
3339
--> $DIR/static-impl-obligation.rs:243:9
@@ -41,6 +47,12 @@ LL | val.use_self()
4147
| |
4248
| `val` escapes the function body here
4349
| argument requires that `'a` must outlive `'static`
50+
|
51+
note: the `impl` on `dyn u::ObjectTrait` has a `'static` lifetime requirement
52+
--> $DIR/static-impl-obligation.rs:234:47
53+
|
54+
LL | fn use_self(&self) -> &() where Self: 'static { panic!() }
55+
| ^^^^^^^
4456

4557
error[E0521]: borrowed data escapes outside of function
4658
--> $DIR/static-impl-obligation.rs:261:9

0 commit comments

Comments
 (0)