@@ -51,15 +51,35 @@ pub enum SimplifiedType {
51
51
/// generic parameters as if they were inference variables in that case.
52
52
#[ derive( PartialEq , Eq , Debug , Clone , Copy ) ]
53
53
pub 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.
55
69
///
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 ,
63
83
}
64
84
65
85
/// Tries to simplify a type by only returning the outermost injective¹ layer, if one exists.
@@ -87,6 +107,7 @@ pub fn simplify_type<'tcx>(
87
107
tcx : TyCtxt < ' tcx > ,
88
108
ty : Ty < ' tcx > ,
89
109
treat_params : TreatParams ,
110
+ treat_projections : TreatProjections ,
90
111
) -> Option < SimplifiedType > {
91
112
match * ty. kind ( ) {
92
113
ty:: Bool => Some ( BoolSimplifiedType ) ,
@@ -115,19 +136,13 @@ pub fn simplify_type<'tcx>(
115
136
ty:: FnPtr ( f) => Some ( FunctionSimplifiedType ( f. skip_binder ( ) . inputs ( ) . len ( ) ) ) ,
116
137
ty:: Placeholder ( ..) => Some ( PlaceholderSimplifiedType ) ,
117
138
ty:: Param ( _) => match treat_params {
118
- TreatParams :: AsPlaceholder => Some ( PlaceholderSimplifiedType ) ,
119
- TreatParams :: AsInfer => None ,
139
+ TreatParams :: ForLookup => Some ( PlaceholderSimplifiedType ) ,
140
+ TreatParams :: AsCandidateKey => None ,
120
141
} ,
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 ,
131
146
} ,
132
147
ty:: Foreign ( def_id) => Some ( ForeignSimplifiedType ( def_id) ) ,
133
148
ty:: Bound ( ..) | ty:: Infer ( _) | ty:: Error ( _) => None ,
@@ -295,8 +310,8 @@ impl DeepRejectCtxt {
295
310
// Depending on the value of `treat_obligation_params`, we either
296
311
// treat generic parameters like placeholders or like inference variables.
297
312
ty:: Param ( _) => match self . treat_obligation_params {
298
- TreatParams :: AsPlaceholder => false ,
299
- TreatParams :: AsInfer => true ,
313
+ TreatParams :: ForLookup => false ,
314
+ TreatParams :: AsCandidateKey => true ,
300
315
} ,
301
316
302
317
ty:: Infer ( _) => true ,
@@ -333,8 +348,8 @@ impl DeepRejectCtxt {
333
348
let k = impl_ct. kind ( ) ;
334
349
match obligation_ct. kind ( ) {
335
350
ty:: ConstKind :: Param ( _) => match self . treat_obligation_params {
336
- TreatParams :: AsPlaceholder => false ,
337
- TreatParams :: AsInfer => true ,
351
+ TreatParams :: ForLookup => false ,
352
+ TreatParams :: AsCandidateKey => true ,
338
353
} ,
339
354
340
355
// As we don't necessarily eagerly evaluate constants,
0 commit comments