Skip to content

Commit 59e0fac

Browse files
committed
Elaborate predicates to also display transitive obligations
1 parent dcdcafb commit 59e0fac

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

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

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)