@@ -15,12 +15,13 @@ use tracing::{debug, instrument, trace};
1515
1616use crate :: infer:: InferCtxt ;
1717use crate :: traits;
18+
1819/// Returns the set of obligations needed to make `arg` well-formed.
1920/// If `arg` contains unresolved inference variables, this may include
2021/// further WF obligations. However, if `arg` IS an unresolved
2122/// inference variable, returns `None`, because we are not able to
22- /// make any progress at all. This is to prevent "livelock" where we
23- /// say "$ 0 is WF if $ 0 is WF".
23+ /// make any progress at all. This is to prevent cycles where we
24+ /// say "? 0 is WF if ? 0 is WF".
2425pub fn obligations < ' tcx > (
2526 infcx : & InferCtxt < ' tcx > ,
2627 param_env : ty:: ParamEnv < ' tcx > ,
@@ -29,14 +30,14 @@ pub fn obligations<'tcx>(
2930 arg : GenericArg < ' tcx > ,
3031 span : Span ,
3132) -> Option < PredicateObligations < ' tcx > > {
32- // Handle the "livelock " case (see comment above) by bailing out if necessary.
33+ // Handle the "cycle " case (see comment above) by bailing out if necessary.
3334 let arg = match arg. unpack ( ) {
3435 GenericArgKind :: Type ( ty) => {
3536 match ty. kind ( ) {
3637 ty:: Infer ( ty:: TyVar ( _) ) => {
3738 let resolved_ty = infcx. shallow_resolve ( ty) ;
3839 if resolved_ty == ty {
39- // No progress, bail out to prevent "livelock" .
40+ // No progress, bail out to prevent cycles .
4041 return None ;
4142 } else {
4243 resolved_ty
@@ -51,7 +52,7 @@ pub fn obligations<'tcx>(
5152 ty:: ConstKind :: Infer ( _) => {
5253 let resolved = infcx. shallow_resolve_const ( ct) ;
5354 if resolved == ct {
54- // No progress.
55+ // No progress, bail out to prevent cycles .
5556 return None ;
5657 } else {
5758 resolved
@@ -74,7 +75,7 @@ pub fn obligations<'tcx>(
7475 recursion_depth,
7576 item : None ,
7677 } ;
77- wf. compute ( arg) ;
78+ wf. add_wf_preds_for_generic_arg ( arg) ;
7879 debug ! ( "wf::obligations({:?}, body_id={:?}) = {:?}" , arg, body_id, wf. out) ;
7980
8081 let result = wf. normalize ( infcx) ;
@@ -97,7 +98,7 @@ pub fn unnormalized_obligations<'tcx>(
9798
9899 // However, if `arg` IS an unresolved inference variable, returns `None`,
99100 // because we are not able to make any progress at all. This is to prevent
100- // "livelock" where we say "$ 0 is WF if $ 0 is WF".
101+ // cycles where we say "? 0 is WF if ? 0 is WF".
101102 if arg. is_non_region_infer ( ) {
102103 return None ;
103104 }
@@ -115,7 +116,7 @@ pub fn unnormalized_obligations<'tcx>(
115116 recursion_depth : 0 ,
116117 item : None ,
117118 } ;
118- wf. compute ( arg) ;
119+ wf. add_wf_preds_for_generic_arg ( arg) ;
119120 Some ( wf. out )
120121}
121122
@@ -140,7 +141,7 @@ pub fn trait_obligations<'tcx>(
140141 recursion_depth : 0 ,
141142 item : Some ( item) ,
142143 } ;
143- wf. compute_trait_pred ( trait_pred, Elaborate :: All ) ;
144+ wf. add_wf_preds_for_trait_pred ( trait_pred, Elaborate :: All ) ;
144145 debug ! ( obligations = ?wf. out) ;
145146 wf. normalize ( infcx)
146147}
@@ -171,30 +172,30 @@ pub fn clause_obligations<'tcx>(
171172 // It's ok to skip the binder here because wf code is prepared for it
172173 match clause. kind ( ) . skip_binder ( ) {
173174 ty:: ClauseKind :: Trait ( t) => {
174- wf. compute_trait_pred ( t, Elaborate :: None ) ;
175+ wf. add_wf_preds_for_trait_pred ( t, Elaborate :: None ) ;
175176 }
176177 ty:: ClauseKind :: HostEffect ( ..) => {
177178 // Technically the well-formedness of this predicate is implied by
178179 // the corresponding trait predicate it should've been generated beside.
179180 }
180181 ty:: ClauseKind :: RegionOutlives ( ..) => { }
181182 ty:: ClauseKind :: TypeOutlives ( ty:: OutlivesPredicate ( ty, _reg) ) => {
182- wf. compute ( ty. into ( ) ) ;
183+ wf. add_wf_preds_for_generic_arg ( ty. into ( ) ) ;
183184 }
184185 ty:: ClauseKind :: Projection ( t) => {
185- wf. compute_alias_term ( t. projection_term ) ;
186- wf. compute ( t. term . into_arg ( ) ) ;
186+ wf. add_wf_preds_for_alias_term ( t. projection_term ) ;
187+ wf. add_wf_preds_for_generic_arg ( t. term . into_arg ( ) ) ;
187188 }
188189 ty:: ClauseKind :: ConstArgHasType ( ct, ty) => {
189- wf. compute ( ct. into ( ) ) ;
190- wf. compute ( ty. into ( ) ) ;
190+ wf. add_wf_preds_for_generic_arg ( ct. into ( ) ) ;
191+ wf. add_wf_preds_for_generic_arg ( ty. into ( ) ) ;
191192 }
192193 ty:: ClauseKind :: WellFormed ( arg) => {
193- wf. compute ( arg) ;
194+ wf. add_wf_preds_for_generic_arg ( arg) ;
194195 }
195196
196197 ty:: ClauseKind :: ConstEvaluatable ( ct) => {
197- wf. compute ( ct. into ( ) ) ;
198+ wf. add_wf_preds_for_generic_arg ( ct. into ( ) ) ;
198199 }
199200 }
200201
@@ -372,14 +373,18 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
372373 }
373374
374375 /// Pushes the obligations required for `trait_ref` to be WF into `self.out`.
375- fn compute_trait_pred ( & mut self , trait_pred : ty:: TraitPredicate < ' tcx > , elaborate : Elaborate ) {
376+ fn add_wf_preds_for_trait_pred (
377+ & mut self ,
378+ trait_pred : ty:: TraitPredicate < ' tcx > ,
379+ elaborate : Elaborate ,
380+ ) {
376381 let tcx = self . tcx ( ) ;
377382 let trait_ref = trait_pred. trait_ref ;
378383
379384 // Negative trait predicates don't require supertraits to hold, just
380385 // that their args are WF.
381386 if trait_pred. polarity == ty:: PredicatePolarity :: Negative {
382- self . compute_negative_trait_pred ( trait_ref) ;
387+ self . add_wf_preds_for_negative_trait_pred ( trait_ref) ;
383388 return ;
384389 }
385390
@@ -445,15 +450,15 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
445450
446451 // Compute the obligations that are required for `trait_ref` to be WF,
447452 // given that it is a *negative* trait predicate.
448- fn compute_negative_trait_pred ( & mut self , trait_ref : ty:: TraitRef < ' tcx > ) {
453+ fn add_wf_preds_for_negative_trait_pred ( & mut self , trait_ref : ty:: TraitRef < ' tcx > ) {
449454 for arg in trait_ref. args {
450- self . compute ( arg) ;
455+ self . add_wf_preds_for_generic_arg ( arg) ;
451456 }
452457 }
453458
454459 /// Pushes the obligations required for an alias (except inherent) to be WF
455460 /// into `self.out`.
456- fn compute_alias_term ( & mut self , data : ty:: AliasTerm < ' tcx > ) {
461+ fn add_wf_preds_for_alias_term ( & mut self , data : ty:: AliasTerm < ' tcx > ) {
457462 // A projection is well-formed if
458463 //
459464 // (a) its predicates hold (*)
@@ -478,13 +483,13 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
478483 let obligations = self . nominal_obligations ( data. def_id , data. args ) ;
479484 self . out . extend ( obligations) ;
480485
481- self . compute_projection_args ( data. args ) ;
486+ self . add_wf_preds_for_projection_args ( data. args ) ;
482487 }
483488
484489 /// Pushes the obligations required for an inherent alias to be WF
485490 /// into `self.out`.
486491 // FIXME(inherent_associated_types): Merge this function with `fn compute_alias`.
487- fn compute_inherent_projection ( & mut self , data : ty:: AliasTy < ' tcx > ) {
492+ fn add_wf_preds_for_inherent_projection ( & mut self , data : ty:: AliasTy < ' tcx > ) {
488493 // An inherent projection is well-formed if
489494 //
490495 // (a) its predicates hold (*)
@@ -511,7 +516,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
511516 data. args . visit_with ( self ) ;
512517 }
513518
514- fn compute_projection_args ( & mut self , args : GenericArgsRef < ' tcx > ) {
519+ fn add_wf_preds_for_projection_args ( & mut self , args : GenericArgsRef < ' tcx > ) {
515520 let tcx = self . tcx ( ) ;
516521 let cause = self . cause ( ObligationCauseCode :: WellFormed ( None ) ) ;
517522 let param_env = self . param_env ;
@@ -557,7 +562,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
557562
558563 /// Pushes all the predicates needed to validate that `ty` is WF into `out`.
559564 #[ instrument( level = "debug" , skip( self ) ) ]
560- fn compute ( & mut self , arg : GenericArg < ' tcx > ) {
565+ fn add_wf_preds_for_generic_arg ( & mut self , arg : GenericArg < ' tcx > ) {
561566 arg. visit_with ( self ) ;
562567 debug ! ( ?self . out) ;
563568 }
@@ -596,7 +601,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
596601 . collect ( )
597602 }
598603
599- fn from_object_ty (
604+ fn add_wf_preds_for_dyn_ty (
600605 & mut self ,
601606 ty : Ty < ' tcx > ,
602607 data : & ' tcx ty:: List < ty:: PolyExistentialPredicate < ' tcx > > ,
@@ -651,6 +656,13 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
651656 outlives,
652657 ) ) ;
653658 }
659+
660+ // We don't add any wf predicates corresponding to the trait ref's generic arguments
661+ // which allows code like this to compile:
662+ // ```rust
663+ // trait Trait<T: Sized> {}
664+ // fn foo(_: &dyn Trait<[u32]>) {}
665+ // ```
654666 }
655667 }
656668}
@@ -761,7 +773,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
761773 self . out . extend ( obligations) ;
762774 }
763775 ty:: Alias ( ty:: Inherent , data) => {
764- self . compute_inherent_projection ( data) ;
776+ self . add_wf_preds_for_inherent_projection ( data) ;
765777 return ; // Subtree handled by compute_inherent_projection.
766778 }
767779
@@ -895,7 +907,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
895907 //
896908 // Here, we defer WF checking due to higher-ranked
897909 // regions. This is perhaps not ideal.
898- self . from_object_ty ( t, data, r) ;
910+ self . add_wf_preds_for_dyn_ty ( t, data, r) ;
899911
900912 // FIXME(#27579) RFC also considers adding trait
901913 // obligations that don't refer to Self and
@@ -917,11 +929,11 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
917929 // 1. Check if they have been resolved, and if so proceed with
918930 // THAT type.
919931 // 2. If not, we've at least simplified things (e.g., we went
920- // from `Vec<$ 0>: WF` to `$ 0: WF`), so we can
932+ // from `Vec? 0>: WF` to `? 0: WF`), so we can
921933 // register a pending obligation and keep
922934 // moving. (Goal is that an "inductive hypothesis"
923935 // is satisfied to ensure termination.)
924- // See also the comment on `fn obligations`, describing "livelock"
936+ // See also the comment on `fn obligations`, describing cycle
925937 // prevention, which happens before this can be reached.
926938 ty:: Infer ( _) => {
927939 let cause = self . cause ( ObligationCauseCode :: WellFormed ( None ) ) ;
0 commit comments