@@ -51,15 +51,35 @@ pub enum SimplifiedType {
5151/// generic parameters as if they were inference variables in that case. 
5252#[ derive( PartialEq ,  Eq ,  Debug ,  Clone ,  Copy ) ]  
5353pub  enum  TreatParams  { 
54-     /// Treat parameters as placeholders in the given environment. 
54+     /// Treat parameters as infer vars. This is the correct mode for caching 
55+      /// an impl's type for lookup. 
56+      AsCandidateKey , 
57+     /// Treat parameters as placeholders in the given environment. This is the 
58+      /// correct mode for *lookup*, as during candidate selection. 
59+      ForLookup , 
60+ } 
61+ 
62+ /// During fast-rejection, we have the choice of treating projection types 
63+ /// as either simplifyable or not, depending on whether we expect the projection 
64+ /// to be normalized/rigid. 
65+ #[ derive( PartialEq ,  Eq ,  Debug ,  Clone ,  Copy ) ]  
66+ pub  enum  TreatProjections  { 
67+     /// In candidates, we may be able to normalize the projection 
68+      /// after instantiating the candidate and equating it with a goal. 
5569     /// 
56-      /// Note that this also causes us to treat projections as if they were 
57-      /// placeholders. This is only correct if the given projection cannot 
58-      /// be normalized in the current context. Even if normalization fails, 
59-      /// it may still succeed later if the projection contains any inference 
60-      /// variables. 
61-      AsPlaceholder , 
62-     AsInfer , 
70+      /// We must assume that the `impl<T> Trait<T> for <T as Id>::This` 
71+      /// can apply to all self types so we don't return a simplified type 
72+      /// for `<T as Id>::This`. 
73+      AsCandidateKey , 
74+     /// In the old solver we don't try to normalize projections 
75+      /// when looking up impls and only access them by using the 
76+      /// current self type. This means that if the self type is 
77+      /// a projection which could later be normalized, we must not 
78+      /// treat it as rigid. 
79+      ForLookup , 
80+     /// We can treat projections in the self type as opaque as 
81+      /// we separately look up impls for the normalized self type. 
82+      NextSolverLookup , 
6383} 
6484
6585/// Tries to simplify a type by only returning the outermost injective¹ layer, if one exists. 
@@ -87,6 +107,7 @@ pub fn simplify_type<'tcx>(
87107    tcx :  TyCtxt < ' tcx > , 
88108    ty :  Ty < ' tcx > , 
89109    treat_params :  TreatParams , 
110+     treat_projections :  TreatProjections , 
90111)  -> Option < SimplifiedType >  { 
91112    match  * ty. kind ( )  { 
92113        ty:: Bool  => Some ( BoolSimplifiedType ) , 
@@ -115,19 +136,13 @@ pub fn simplify_type<'tcx>(
115136        ty:: FnPtr ( f)  => Some ( FunctionSimplifiedType ( f. skip_binder ( ) . inputs ( ) . len ( ) ) ) , 
116137        ty:: Placeholder ( ..)  => Some ( PlaceholderSimplifiedType ) , 
117138        ty:: Param ( _)  => match  treat_params { 
118-             TreatParams :: AsPlaceholder  => Some ( PlaceholderSimplifiedType ) , 
119-             TreatParams :: AsInfer  => None , 
139+             TreatParams :: ForLookup  => Some ( PlaceholderSimplifiedType ) , 
140+             TreatParams :: AsCandidateKey  => None , 
120141        } , 
121-         ty:: Alias ( ..)  => match  treat_params { 
122-             // When treating `ty::Param` as a placeholder, projections also 
123-             // don't unify with anything else as long as they are fully normalized. 
124-             // 
125-             // We will have to be careful with lazy normalization here. 
126-             TreatParams :: AsPlaceholder  if  !ty. has_non_region_infer ( )  => { 
127-                 debug ! ( "treating `{}` as a placeholder" ,  ty) ; 
128-                 Some ( PlaceholderSimplifiedType ) 
129-             } 
130-             TreatParams :: AsPlaceholder  | TreatParams :: AsInfer  => None , 
142+         ty:: Alias ( ..)  => match  treat_projections { 
143+             TreatProjections :: ForLookup  if  !ty. needs_infer ( )  => Some ( PlaceholderSimplifiedType ) , 
144+             TreatProjections :: NextSolverLookup  => Some ( PlaceholderSimplifiedType ) , 
145+             TreatProjections :: AsCandidateKey  | TreatProjections :: ForLookup  => None , 
131146        } , 
132147        ty:: Foreign ( def_id)  => Some ( ForeignSimplifiedType ( def_id) ) , 
133148        ty:: Bound ( ..)  | ty:: Infer ( _)  | ty:: Error ( _)  => None , 
@@ -295,8 +310,8 @@ impl DeepRejectCtxt {
295310            // Depending on the value of `treat_obligation_params`, we either 
296311            // treat generic parameters like placeholders or like inference variables. 
297312            ty:: Param ( _)  => match  self . treat_obligation_params  { 
298-                 TreatParams :: AsPlaceholder  => false , 
299-                 TreatParams :: AsInfer  => true , 
313+                 TreatParams :: ForLookup  => false , 
314+                 TreatParams :: AsCandidateKey  => true , 
300315            } , 
301316
302317            ty:: Infer ( _)  => true , 
@@ -333,8 +348,8 @@ impl DeepRejectCtxt {
333348        let  k = impl_ct. kind ( ) ; 
334349        match  obligation_ct. kind ( )  { 
335350            ty:: ConstKind :: Param ( _)  => match  self . treat_obligation_params  { 
336-                 TreatParams :: AsPlaceholder  => false , 
337-                 TreatParams :: AsInfer  => true , 
351+                 TreatParams :: ForLookup  => false , 
352+                 TreatParams :: AsCandidateKey  => true , 
338353            } , 
339354
340355            // As we don't necessarily eagerly evaluate constants, 
0 commit comments