1+ //! Core logic responsible for determining what it means for various type system 
2+ //! primitives to be "well formed". Actually checking whether these primitives are 
3+ //! well formed is performed elsewhere (e.g. during type checking or item well formedness 
4+ //! checking). 
5+ 
16use  std:: iter; 
27
38use  rustc_hir as  hir; 
@@ -15,12 +20,13 @@ use tracing::{debug, instrument, trace};
1520
1621use  crate :: infer:: InferCtxt ; 
1722use  crate :: traits; 
23+ 
1824/// Returns the set of obligations needed to make `arg` well-formed. 
1925/// If `arg` contains unresolved inference variables, this may include 
2026/// further WF obligations. However, if `arg` IS an unresolved 
2127/// 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". 
28+ /// make any progress at all. This is to prevent cycles  where we 
29+ /// say "? 0 is WF if ? 0 is WF". 
2430pub  fn  obligations < ' tcx > ( 
2531    infcx :  & InferCtxt < ' tcx > , 
2632    param_env :  ty:: ParamEnv < ' tcx > , 
@@ -29,14 +35,14 @@ pub fn obligations<'tcx>(
2935    arg :  GenericArg < ' tcx > , 
3036    span :  Span , 
3137)  -> Option < PredicateObligations < ' tcx > >  { 
32-     // Handle the "livelock " case (see comment above) by bailing out if necessary. 
38+     // Handle the "cycle " case (see comment above) by bailing out if necessary. 
3339    let  arg = match  arg. unpack ( )  { 
3440        GenericArgKind :: Type ( ty)  => { 
3541            match  ty. kind ( )  { 
3642                ty:: Infer ( ty:: TyVar ( _) )  => { 
3743                    let  resolved_ty = infcx. shallow_resolve ( ty) ; 
3844                    if  resolved_ty == ty { 
39-                         // No progress, bail out to prevent "livelock" . 
45+                         // No progress, bail out to prevent cycles . 
4046                        return  None ; 
4147                    }  else  { 
4248                        resolved_ty
@@ -51,7 +57,7 @@ pub fn obligations<'tcx>(
5157                ty:: ConstKind :: Infer ( _)  => { 
5258                    let  resolved = infcx. shallow_resolve_const ( ct) ; 
5359                    if  resolved == ct { 
54-                         // No progress. 
60+                         // No progress, bail out to prevent cycles . 
5561                        return  None ; 
5662                    }  else  { 
5763                        resolved
@@ -74,7 +80,7 @@ pub fn obligations<'tcx>(
7480        recursion_depth, 
7581        item :  None , 
7682    } ; 
77-     wf. compute ( arg) ; 
83+     wf. add_wf_preds_for_generic_arg ( arg) ; 
7884    debug ! ( "wf::obligations({:?}, body_id={:?}) = {:?}" ,  arg,  body_id,  wf. out) ; 
7985
8086    let  result = wf. normalize ( infcx) ; 
@@ -97,7 +103,7 @@ pub fn unnormalized_obligations<'tcx>(
97103
98104    // However, if `arg` IS an unresolved inference variable, returns `None`, 
99105    // 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". 
106+     // cycles  where we say "? 0 is WF if ? 0 is WF". 
101107    if  arg. is_non_region_infer ( )  { 
102108        return  None ; 
103109    } 
@@ -115,7 +121,7 @@ pub fn unnormalized_obligations<'tcx>(
115121        recursion_depth :  0 , 
116122        item :  None , 
117123    } ; 
118-     wf. compute ( arg) ; 
124+     wf. add_wf_preds_for_generic_arg ( arg) ; 
119125    Some ( wf. out ) 
120126} 
121127
@@ -140,7 +146,7 @@ pub fn trait_obligations<'tcx>(
140146        recursion_depth :  0 , 
141147        item :  Some ( item) , 
142148    } ; 
143-     wf. compute_trait_pred ( trait_pred,  Elaborate :: All ) ; 
149+     wf. add_wf_preds_for_trait_pred ( trait_pred,  Elaborate :: All ) ; 
144150    debug ! ( obligations = ?wf. out) ; 
145151    wf. normalize ( infcx) 
146152} 
@@ -171,30 +177,30 @@ pub fn clause_obligations<'tcx>(
171177    // It's ok to skip the binder here because wf code is prepared for it 
172178    match  clause. kind ( ) . skip_binder ( )  { 
173179        ty:: ClauseKind :: Trait ( t)  => { 
174-             wf. compute_trait_pred ( t,  Elaborate :: None ) ; 
180+             wf. add_wf_preds_for_trait_pred ( t,  Elaborate :: None ) ; 
175181        } 
176182        ty:: ClauseKind :: HostEffect ( ..)  => { 
177183            // Technically the well-formedness of this predicate is implied by 
178184            // the corresponding trait predicate it should've been generated beside. 
179185        } 
180186        ty:: ClauseKind :: RegionOutlives ( ..)  => { } 
181187        ty:: ClauseKind :: TypeOutlives ( ty:: OutlivesPredicate ( ty,  _reg) )  => { 
182-             wf. compute ( ty. into ( ) ) ; 
188+             wf. add_wf_preds_for_generic_arg ( ty. into ( ) ) ; 
183189        } 
184190        ty:: ClauseKind :: Projection ( t)  => { 
185-             wf. compute_alias_term ( t. projection_term ) ; 
186-             wf. compute ( t. term . into_arg ( ) ) ; 
191+             wf. add_wf_preds_for_alias_term ( t. projection_term ) ; 
192+             wf. add_wf_preds_for_generic_arg ( t. term . into_arg ( ) ) ; 
187193        } 
188194        ty:: ClauseKind :: ConstArgHasType ( ct,  ty)  => { 
189-             wf. compute ( ct. into ( ) ) ; 
190-             wf. compute ( ty. into ( ) ) ; 
195+             wf. add_wf_preds_for_generic_arg ( ct. into ( ) ) ; 
196+             wf. add_wf_preds_for_generic_arg ( ty. into ( ) ) ; 
191197        } 
192198        ty:: ClauseKind :: WellFormed ( arg)  => { 
193-             wf. compute ( arg) ; 
199+             wf. add_wf_preds_for_generic_arg ( arg) ; 
194200        } 
195201
196202        ty:: ClauseKind :: ConstEvaluatable ( ct)  => { 
197-             wf. compute ( ct. into ( ) ) ; 
203+             wf. add_wf_preds_for_generic_arg ( ct. into ( ) ) ; 
198204        } 
199205    } 
200206
@@ -372,14 +378,18 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
372378    } 
373379
374380    /// 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 )  { 
381+      fn  add_wf_preds_for_trait_pred ( 
382+         & mut  self , 
383+         trait_pred :  ty:: TraitPredicate < ' tcx > , 
384+         elaborate :  Elaborate , 
385+     )  { 
376386        let  tcx = self . tcx ( ) ; 
377387        let  trait_ref = trait_pred. trait_ref ; 
378388
379389        // Negative trait predicates don't require supertraits to hold, just 
380390        // that their args are WF. 
381391        if  trait_pred. polarity  == ty:: PredicatePolarity :: Negative  { 
382-             self . compute_negative_trait_pred ( trait_ref) ; 
392+             self . add_wf_preds_for_negative_trait_pred ( trait_ref) ; 
383393            return ; 
384394        } 
385395
@@ -445,15 +455,15 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
445455
446456    // Compute the obligations that are required for `trait_ref` to be WF, 
447457    // given that it is a *negative* trait predicate. 
448-     fn  compute_negative_trait_pred ( & mut  self ,  trait_ref :  ty:: TraitRef < ' tcx > )  { 
458+     fn  add_wf_preds_for_negative_trait_pred ( & mut  self ,  trait_ref :  ty:: TraitRef < ' tcx > )  { 
449459        for  arg in  trait_ref. args  { 
450-             self . compute ( arg) ; 
460+             self . add_wf_preds_for_generic_arg ( arg) ; 
451461        } 
452462    } 
453463
454464    /// Pushes the obligations required for an alias (except inherent) to be WF 
455465     /// into `self.out`. 
456-      fn  compute_alias_term ( & mut  self ,  data :  ty:: AliasTerm < ' tcx > )  { 
466+      fn  add_wf_preds_for_alias_term ( & mut  self ,  data :  ty:: AliasTerm < ' tcx > )  { 
457467        // A projection is well-formed if 
458468        // 
459469        // (a) its predicates hold (*) 
@@ -478,13 +488,13 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
478488        let  obligations = self . nominal_obligations ( data. def_id ,  data. args ) ; 
479489        self . out . extend ( obligations) ; 
480490
481-         self . compute_projection_args ( data. args ) ; 
491+         self . add_wf_preds_for_projection_args ( data. args ) ; 
482492    } 
483493
484494    /// Pushes the obligations required for an inherent alias to be WF 
485495     /// into `self.out`. 
486496     // FIXME(inherent_associated_types): Merge this function with `fn compute_alias`. 
487-     fn  compute_inherent_projection ( & mut  self ,  data :  ty:: AliasTy < ' tcx > )  { 
497+     fn  add_wf_preds_for_inherent_projection ( & mut  self ,  data :  ty:: AliasTy < ' tcx > )  { 
488498        // An inherent projection is well-formed if 
489499        // 
490500        // (a) its predicates hold (*) 
@@ -511,7 +521,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
511521        data. args . visit_with ( self ) ; 
512522    } 
513523
514-     fn  compute_projection_args ( & mut  self ,  args :  GenericArgsRef < ' tcx > )  { 
524+     fn  add_wf_preds_for_projection_args ( & mut  self ,  args :  GenericArgsRef < ' tcx > )  { 
515525        let  tcx = self . tcx ( ) ; 
516526        let  cause = self . cause ( ObligationCauseCode :: WellFormed ( None ) ) ; 
517527        let  param_env = self . param_env ; 
@@ -557,7 +567,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
557567
558568    /// Pushes all the predicates needed to validate that `ty` is WF into `out`. 
559569     #[ instrument( level = "debug" ,  skip( self ) ) ]  
560-     fn  compute ( & mut  self ,  arg :  GenericArg < ' tcx > )  { 
570+     fn  add_wf_preds_for_generic_arg ( & mut  self ,  arg :  GenericArg < ' tcx > )  { 
561571        arg. visit_with ( self ) ; 
562572        debug ! ( ?self . out) ; 
563573    } 
@@ -596,7 +606,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
596606            . collect ( ) 
597607    } 
598608
599-     fn  from_object_ty ( 
609+     fn  add_wf_preds_for_dyn_ty ( 
600610        & mut  self , 
601611        ty :  Ty < ' tcx > , 
602612        data :  & ' tcx  ty:: List < ty:: PolyExistentialPredicate < ' tcx > > , 
@@ -651,6 +661,13 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
651661                    outlives, 
652662                ) ) ; 
653663            } 
664+ 
665+             // We don't add any wf predicates corresponding to the trait ref's generic arguments 
666+             // which allows code like this to compile: 
667+             // ```rust 
668+             // trait Trait<T: Sized> {} 
669+             // fn foo(_: &dyn Trait<[u32]>) {} 
670+             // ``` 
654671        } 
655672    } 
656673} 
@@ -761,7 +778,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
761778                self . out . extend ( obligations) ; 
762779            } 
763780            ty:: Alias ( ty:: Inherent ,  data)  => { 
764-                 self . compute_inherent_projection ( data) ; 
781+                 self . add_wf_preds_for_inherent_projection ( data) ; 
765782                return ;  // Subtree handled by compute_inherent_projection. 
766783            } 
767784
@@ -895,7 +912,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
895912                // 
896913                // Here, we defer WF checking due to higher-ranked 
897914                // regions. This is perhaps not ideal. 
898-                 self . from_object_ty ( t,  data,  r) ; 
915+                 self . add_wf_preds_for_dyn_ty ( t,  data,  r) ; 
899916
900917                // FIXME(#27579) RFC also considers adding trait 
901918                // obligations that don't refer to Self and 
@@ -917,11 +934,11 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
917934            // 1. Check if they have been resolved, and if so proceed with 
918935            //    THAT type. 
919936            // 2. If not, we've at least simplified things (e.g., we went 
920-             //    from `Vec<$ 0>: WF` to `$ 0: WF`), so we can 
937+             //    from `Vec? 0>: WF` to `? 0: WF`), so we can 
921938            //    register a pending obligation and keep 
922939            //    moving. (Goal is that an "inductive hypothesis" 
923940            //    is satisfied to ensure termination.) 
924-             // See also the comment on `fn obligations`, describing "livelock"  
941+             // See also the comment on `fn obligations`, describing cycle  
925942            // prevention, which happens before this can be reached. 
926943            ty:: Infer ( _)  => { 
927944                let  cause = self . cause ( ObligationCauseCode :: WellFormed ( None ) ) ; 
0 commit comments