@@ -58,15 +58,8 @@ pub fn obligations<'tcx>(
58
58
GenericArgKind :: Lifetime ( ..) => return Some ( Vec :: new ( ) ) ,
59
59
} ;
60
60
61
- let mut wf = WfPredicates {
62
- tcx : infcx. tcx ,
63
- param_env,
64
- body_id,
65
- span,
66
- out : vec ! [ ] ,
67
- recursion_depth,
68
- item : None ,
69
- } ;
61
+ let mut wf =
62
+ WfPredicates { infcx, param_env, body_id, span, out : vec ! [ ] , recursion_depth, item : None } ;
70
63
wf. compute ( arg) ;
71
64
debug ! ( "wf::obligations({:?}, body_id={:?}) = {:?}" , arg, body_id, wf. out) ;
72
65
@@ -91,7 +84,7 @@ pub fn unnormalized_obligations<'tcx>(
91
84
debug_assert_eq ! ( arg, infcx. resolve_vars_if_possible( arg) ) ;
92
85
93
86
let mut wf = WfPredicates {
94
- tcx : infcx. tcx ,
87
+ infcx,
95
88
param_env,
96
89
body_id : CRATE_DEF_ID ,
97
90
span : DUMMY_SP ,
@@ -116,7 +109,7 @@ pub fn trait_obligations<'tcx>(
116
109
item : & ' tcx hir:: Item < ' tcx > ,
117
110
) -> Vec < traits:: PredicateObligation < ' tcx > > {
118
111
let mut wf = WfPredicates {
119
- tcx : infcx. tcx ,
112
+ infcx,
120
113
param_env,
121
114
body_id,
122
115
span,
@@ -138,7 +131,7 @@ pub fn predicate_obligations<'tcx>(
138
131
span : Span ,
139
132
) -> Vec < traits:: PredicateObligation < ' tcx > > {
140
133
let mut wf = WfPredicates {
141
- tcx : infcx. tcx ,
134
+ infcx,
142
135
param_env,
143
136
body_id,
144
137
span,
@@ -190,8 +183,8 @@ pub fn predicate_obligations<'tcx>(
190
183
wf. normalize ( infcx)
191
184
}
192
185
193
- struct WfPredicates < ' tcx > {
194
- tcx : TyCtxt < ' tcx > ,
186
+ struct WfPredicates < ' a , ' tcx > {
187
+ infcx : & ' a InferCtxt < ' tcx > ,
195
188
param_env : ty:: ParamEnv < ' tcx > ,
196
189
body_id : LocalDefId ,
197
190
span : Span ,
@@ -290,9 +283,9 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
290
283
}
291
284
}
292
285
293
- impl < ' tcx > WfPredicates < ' tcx > {
286
+ impl < ' a , ' tcx > WfPredicates < ' a , ' tcx > {
294
287
fn tcx ( & self ) -> TyCtxt < ' tcx > {
295
- self . tcx
288
+ self . infcx . tcx
296
289
}
297
290
298
291
fn cause ( & self , code : traits:: ObligationCauseCode < ' tcx > ) -> traits:: ObligationCause < ' tcx > {
@@ -325,7 +318,7 @@ impl<'tcx> WfPredicates<'tcx> {
325
318
326
319
/// Pushes the obligations required for `trait_ref` to be WF into `self.out`.
327
320
fn compute_trait_pred ( & mut self , trait_pred : & ty:: TraitPredicate < ' tcx > , elaborate : Elaborate ) {
328
- let tcx = self . tcx ;
321
+ let tcx = self . tcx ( ) ;
329
322
let trait_ref = & trait_pred. trait_ref ;
330
323
331
324
// Negative trait predicates don't require supertraits to hold, just
@@ -369,7 +362,6 @@ impl<'tcx> WfPredicates<'tcx> {
369
362
self . out . extend ( obligations) ;
370
363
}
371
364
372
- let tcx = self . tcx ( ) ;
373
365
self . out . extend (
374
366
trait_ref
375
367
. substs
@@ -436,13 +428,45 @@ impl<'tcx> WfPredicates<'tcx> {
436
428
let obligations = self . nominal_obligations_without_const ( data. def_id , data. substs ) ;
437
429
self . out . extend ( obligations) ;
438
430
431
+ self . compute_projection_substs ( data. substs ) ;
432
+ }
433
+
434
+ fn compute_inherent_projection ( & mut self , data : ty:: AliasTy < ' tcx > ) {
435
+ // An inherent projection is well-formed if
436
+ //
437
+ // (a) its predicates hold (*)
438
+ // (b) its substs are wf
439
+ //
440
+ // (*) The predicates of an inherent associated type include the
441
+ // predicates of the impl that it's contained in.
442
+
443
+ if !data. self_ty ( ) . has_escaping_bound_vars ( ) {
444
+ // FIXME(inherent_associated_types): Should this happen inside of a snapshot?
445
+ // FIXME(inherent_associated_types): This is incompatible with the new solver and lazy norm!
446
+ let substs = traits:: project:: compute_inherent_assoc_ty_substs (
447
+ & mut traits:: SelectionContext :: new ( self . infcx ) ,
448
+ self . param_env ,
449
+ data,
450
+ self . cause ( traits:: WellFormed ( None ) ) ,
451
+ self . recursion_depth ,
452
+ & mut self . out ,
453
+ ) ;
454
+ // Inherent projection types do not require const predicates.
455
+ let obligations = self . nominal_obligations_without_const ( data. def_id , substs) ;
456
+ self . out . extend ( obligations) ;
457
+ }
458
+
459
+ self . compute_projection_substs ( data. substs ) ;
460
+ }
461
+
462
+ fn compute_projection_substs ( & mut self , substs : SubstsRef < ' tcx > ) {
439
463
let tcx = self . tcx ( ) ;
440
464
let cause = self . cause ( traits:: WellFormed ( None ) ) ;
441
465
let param_env = self . param_env ;
442
466
let depth = self . recursion_depth ;
443
467
444
468
self . out . extend (
445
- data . substs
469
+ substs
446
470
. iter ( )
447
471
. filter ( |arg| {
448
472
matches ! ( arg. unpack( ) , GenericArgKind :: Type ( ..) | GenericArgKind :: Const ( ..) )
@@ -464,9 +488,9 @@ impl<'tcx> WfPredicates<'tcx> {
464
488
if !subty. has_escaping_bound_vars ( ) {
465
489
let cause = self . cause ( cause) ;
466
490
let trait_ref =
467
- ty:: TraitRef :: from_lang_item ( self . tcx , LangItem :: Sized , cause. span , [ subty] ) ;
491
+ ty:: TraitRef :: from_lang_item ( self . tcx ( ) , LangItem :: Sized , cause. span , [ subty] ) ;
468
492
self . out . push ( traits:: Obligation :: with_depth (
469
- self . tcx ,
493
+ self . tcx ( ) ,
470
494
cause,
471
495
self . recursion_depth ,
472
496
self . param_env ,
@@ -605,8 +629,9 @@ impl<'tcx> WfPredicates<'tcx> {
605
629
walker. skip_current_subtree ( ) ; // Subtree handled by compute_projection.
606
630
self . compute_projection ( data) ;
607
631
}
608
- ty:: Alias ( ty:: Inherent , _) => {
609
- // WF if their substs are WF.
632
+ ty:: Alias ( ty:: Inherent , data) => {
633
+ walker. skip_current_subtree ( ) ; // Subtree handled by compute_inherent_projection.
634
+ self . compute_inherent_projection ( data) ;
610
635
}
611
636
612
637
ty:: Adt ( def, substs) => {
@@ -700,7 +725,7 @@ impl<'tcx> WfPredicates<'tcx> {
700
725
// All of the requirements on type parameters
701
726
// have already been checked for `impl Trait` in
702
727
// return position. We do need to check type-alias-impl-trait though.
703
- if self . tcx . is_type_alias_impl_trait ( def_id) {
728
+ if self . tcx ( ) . is_type_alias_impl_trait ( def_id) {
704
729
let obligations = self . nominal_obligations ( def_id, substs) ;
705
730
self . out . extend ( obligations) ;
706
731
}
@@ -770,15 +795,15 @@ impl<'tcx> WfPredicates<'tcx> {
770
795
substs : SubstsRef < ' tcx > ,
771
796
remap_constness : bool ,
772
797
) -> Vec < traits:: PredicateObligation < ' tcx > > {
773
- let predicates = self . tcx . predicates_of ( def_id) ;
798
+ let predicates = self . tcx ( ) . predicates_of ( def_id) ;
774
799
let mut origins = vec ! [ def_id; predicates. predicates. len( ) ] ;
775
800
let mut head = predicates;
776
801
while let Some ( parent) = head. parent {
777
- head = self . tcx . predicates_of ( parent) ;
802
+ head = self . tcx ( ) . predicates_of ( parent) ;
778
803
origins. extend ( iter:: repeat ( parent) . take ( head. predicates . len ( ) ) ) ;
779
804
}
780
805
781
- let predicates = predicates. instantiate ( self . tcx , substs) ;
806
+ let predicates = predicates. instantiate ( self . tcx ( ) , substs) ;
782
807
trace ! ( "{:#?}" , predicates) ;
783
808
debug_assert_eq ! ( predicates. predicates. len( ) , origins. len( ) ) ;
784
809
@@ -791,10 +816,10 @@ impl<'tcx> WfPredicates<'tcx> {
791
816
} ;
792
817
let cause = self . cause ( code) ;
793
818
if remap_constness {
794
- pred = pred. without_const ( self . tcx ) ;
819
+ pred = pred. without_const ( self . tcx ( ) ) ;
795
820
}
796
821
traits:: Obligation :: with_depth (
797
- self . tcx ,
822
+ self . tcx ( ) ,
798
823
cause,
799
824
self . recursion_depth ,
800
825
self . param_env ,
@@ -859,7 +884,7 @@ impl<'tcx> WfPredicates<'tcx> {
859
884
// Note: in fact we only permit builtin traits, not `Bar<'d>`, I
860
885
// am looking forward to the future here.
861
886
if !data. has_escaping_bound_vars ( ) && !region. has_escaping_bound_vars ( ) {
862
- let implicit_bounds = object_region_bounds ( self . tcx , data) ;
887
+ let implicit_bounds = object_region_bounds ( self . tcx ( ) , data) ;
863
888
864
889
let explicit_bound = region;
865
890
@@ -869,7 +894,7 @@ impl<'tcx> WfPredicates<'tcx> {
869
894
let outlives =
870
895
ty:: Binder :: dummy ( ty:: OutlivesPredicate ( explicit_bound, implicit_bound) ) ;
871
896
self . out . push ( traits:: Obligation :: with_depth (
872
- self . tcx ,
897
+ self . tcx ( ) ,
873
898
cause,
874
899
self . recursion_depth ,
875
900
self . param_env ,
0 commit comments