Skip to content

Commit 67263f6

Browse files
committed
Elaborate predicates to also display transitive obligations
1 parent cb2fd6e commit 67263f6

File tree

2 files changed

+38
-19
lines changed

2 files changed

+38
-19
lines changed

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+26-19
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::{
@@ -672,25 +673,31 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
672673
// fn foo(&self) where Self: 'static {}
673674
// }
674675
// ```
675-
let mut predicates: Vec<Span> = tcx
676-
.predicates_of(def_id)
677-
.predicates
678-
.iter()
679-
.chain(tcx.predicates_of(parent).predicates.iter())
680-
.filter_map(|(pred, pred_span)| {
681-
if let Some(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(pred_ty, r))) =
682-
pred.kind().no_bound_vars()
683-
// Look for `'static` bounds
684-
&& r.kind() == ty::ReStatic
685-
// We only want bounds on `Self`
686-
&& self.infcx.can_eq(self.param_env, ty, pred_ty)
687-
{
688-
Some(*pred_span)
689-
} else {
690-
None
691-
}
692-
})
693-
.collect();
676+
let mut predicates: Vec<Span> = traits::elaborate(
677+
tcx,
678+
tcx.predicates_of(def_id).predicates.iter().map(|(p, sp)| (p.as_predicate(), *sp)),
679+
)
680+
.chain(traits::elaborate(
681+
tcx,
682+
tcx.predicates_of(parent).predicates.iter().map(|(p, sp)| (p.as_predicate(), *sp)),
683+
))
684+
.filter_map(|(pred, pred_span)| {
685+
if let ty::PredicateKind::Clause(clause) = pred.kind().skip_binder()
686+
&& let ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(pred_ty, r)) = clause
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+
|| matches!(
692+
pred_ty.kind(),
693+
ty::Param(name) if name.name.as_str() == "Self"))
694+
{
695+
Some(pred_span)
696+
} else {
697+
None
698+
}
699+
})
700+
.collect();
694701

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

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

+12
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)