@@ -168,6 +168,20 @@ pub fn predicate_obligations<'tcx>(
168
168
wf. normalize ( infcx)
169
169
}
170
170
171
+ /// Whether we should emit nested obligations containing `value`.
172
+ /// This is a hack to deal with higher ranked types as we require implications
173
+ /// in binders for a more correct implementation.
174
+ ///
175
+ /// `WF(for<'a> fn(&'a T))` would otherwise emit a `T: 'a` bound for `&'a T`
176
+ /// which would require `T: 'static`. What we actually want here is the type
177
+ /// `for<'a> where { T: 'a } fn(&'a T)`, at which point the `T: 'a` bound is
178
+ /// trivially implied from the `param_env`.
179
+ ///
180
+ /// This means that we WF bounds aren't always sufficiently checked for now.
181
+ fn emit_obligations_for < ' tcx , T : TypeVisitable < ' tcx > > ( value : T ) -> bool {
182
+ !value. has_escaping_bound_vars ( )
183
+ }
184
+
171
185
struct WfPredicates < ' tcx > {
172
186
tcx : TyCtxt < ' tcx > ,
173
187
param_env : ty:: ParamEnv < ' tcx > ,
@@ -280,7 +294,7 @@ impl<'tcx> WfPredicates<'tcx> {
280
294
let param_env = self . param_env ;
281
295
let mut obligations = Vec :: with_capacity ( self . out . len ( ) ) ;
282
296
for mut obligation in self . out {
283
- assert ! ( ! obligation. has_escaping_bound_vars ( ) ) ;
297
+ assert ! ( emit_obligations_for ( obligation. predicate ) ) ;
284
298
let mut selcx = traits:: SelectionContext :: new ( infcx) ;
285
299
// Don't normalize the whole obligation, the param env is either
286
300
// already normalized, or we're currently normalizing the
@@ -373,7 +387,7 @@ impl<'tcx> WfPredicates<'tcx> {
373
387
. filter ( |( _, arg) | {
374
388
matches ! ( arg. unpack( ) , GenericArgKind :: Type ( ..) | GenericArgKind :: Const ( ..) )
375
389
} )
376
- . filter ( |( _, arg) | !arg . has_escaping_bound_vars ( ) )
390
+ . filter ( |& ( _, arg) | emit_obligations_for ( arg ) )
377
391
. map ( |( i, arg) | {
378
392
let mut cause = traits:: ObligationCause :: misc ( self . span , self . body_id ) ;
379
393
// The first subst is the self ty - use the correct span for it.
@@ -433,7 +447,7 @@ impl<'tcx> WfPredicates<'tcx> {
433
447
. filter ( |arg| {
434
448
matches ! ( arg. unpack( ) , GenericArgKind :: Type ( ..) | GenericArgKind :: Const ( ..) )
435
449
} )
436
- . filter ( |arg| !arg . has_escaping_bound_vars ( ) )
450
+ . filter ( |& arg| emit_obligations_for ( arg ) )
437
451
. map ( |arg| {
438
452
traits:: Obligation :: with_depth (
439
453
cause. clone ( ) ,
@@ -446,7 +460,7 @@ impl<'tcx> WfPredicates<'tcx> {
446
460
}
447
461
448
462
fn require_sized ( & mut self , subty : Ty < ' tcx > , cause : traits:: ObligationCauseCode < ' tcx > ) {
449
- if !subty . has_escaping_bound_vars ( ) {
463
+ if emit_obligations_for ( subty ) {
450
464
let cause = self . cause ( cause) ;
451
465
let trait_ref = ty:: TraitRef {
452
466
def_id : self . tcx . require_lang_item ( LangItem :: Sized , None ) ,
@@ -582,7 +596,7 @@ impl<'tcx> WfPredicates<'tcx> {
582
596
583
597
ty:: Ref ( r, rty, _) => {
584
598
// WfReference
585
- if !r . has_escaping_bound_vars ( ) && !rty . has_escaping_bound_vars ( ) {
599
+ if emit_obligations_for ( r ) && emit_obligations_for ( rty ) {
586
600
let cause = self . cause ( traits:: ReferenceOutlivesReferent ( ty) ) ;
587
601
self . out . push ( traits:: Obligation :: with_depth (
588
602
cause,
@@ -755,7 +769,7 @@ impl<'tcx> WfPredicates<'tcx> {
755
769
}
756
770
traits:: Obligation :: with_depth ( cause, self . recursion_depth , self . param_env , pred)
757
771
} )
758
- . filter ( |pred| !pred . has_escaping_bound_vars ( ) )
772
+ . filter ( |obl| emit_obligations_for ( obl . predicate ) )
759
773
. collect ( )
760
774
}
761
775
@@ -812,7 +826,7 @@ impl<'tcx> WfPredicates<'tcx> {
812
826
//
813
827
// Note: in fact we only permit builtin traits, not `Bar<'d>`, I
814
828
// am looking forward to the future here.
815
- if !data . has_escaping_bound_vars ( ) && !region . has_escaping_bound_vars ( ) {
829
+ if emit_obligations_for ( data ) && emit_obligations_for ( region ) {
816
830
let implicit_bounds = object_region_bounds ( self . tcx , data) ;
817
831
818
832
let explicit_bound = region;
@@ -876,12 +890,12 @@ pub fn object_region_bounds<'tcx>(
876
890
/// Requires that trait definitions have been processed so that we can
877
891
/// elaborate predicates and walk supertraits.
878
892
#[ instrument( skip( tcx, predicates) , level = "debug" , ret) ]
879
- pub ( crate ) fn required_region_bounds < ' tcx > (
893
+ fn required_region_bounds < ' tcx > (
880
894
tcx : TyCtxt < ' tcx > ,
881
895
erased_self_ty : Ty < ' tcx > ,
882
896
predicates : impl Iterator < Item = ty:: Predicate < ' tcx > > ,
883
897
) -> Vec < ty:: Region < ' tcx > > {
884
- assert ! ( !erased_self_ty . has_escaping_bound_vars ( ) ) ;
898
+ assert ! ( emit_obligations_for ( erased_self_ty ) ) ;
885
899
886
900
traits:: elaborate_predicates ( tcx, predicates)
887
901
. filter_map ( |obligation| {
@@ -898,7 +912,7 @@ pub(crate) fn required_region_bounds<'tcx>(
898
912
| ty:: PredicateKind :: ConstEvaluatable ( ..)
899
913
| ty:: PredicateKind :: ConstEquate ( ..)
900
914
| ty:: PredicateKind :: TypeWellFormedFromEnv ( ..) => None ,
901
- ty:: PredicateKind :: TypeOutlives ( ty:: OutlivesPredicate ( ref t , ref r) ) => {
915
+ ty:: PredicateKind :: TypeOutlives ( ty:: OutlivesPredicate ( t , r) ) => {
902
916
// Search for a bound of the form `erased_self_ty
903
917
// : 'a`, but be wary of something like `for<'a>
904
918
// erased_self_ty : 'a` (we interpret a
@@ -908,11 +922,7 @@ pub(crate) fn required_region_bounds<'tcx>(
908
922
// it's kind of a moot point since you could never
909
923
// construct such an object, but this seems
910
924
// correct even if that code changes).
911
- if t == & erased_self_ty && !r. has_escaping_bound_vars ( ) {
912
- Some ( * r)
913
- } else {
914
- None
915
- }
925
+ if t == erased_self_ty && emit_obligations_for ( r) { Some ( r) } else { None }
916
926
}
917
927
}
918
928
} )
0 commit comments