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