@@ -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