@@ -173,7 +173,7 @@ impl<DefId> SimplifiedType<DefId> {
173
173
174
174
/// Given generic arguments, could they be unified after
175
175
/// replacing parameters with inference variables or placeholders.
176
- /// This behavior is toggled using the `TreatParams` fields .
176
+ /// This behavior is toggled using the const generics .
177
177
///
178
178
/// We use this to quickly reject impl/wc candidates without needing
179
179
/// to instantiate generic arguments/having to enter a probe.
@@ -182,15 +182,31 @@ impl<DefId> SimplifiedType<DefId> {
182
182
/// impls only have to overlap for some value, so we treat parameters
183
183
/// on both sides like inference variables.
184
184
#[ derive( Debug , Clone , Copy ) ]
185
- pub struct DeepRejectCtxt < I : Interner > {
186
- treat_lhs_params : TreatParams ,
187
- treat_rhs_params : TreatParams ,
185
+ pub struct DeepRejectCtxt < I : Interner , const TREAT_LHS_PARAMS : bool , const TREAT_RHS_PARAMS : bool > {
188
186
_interner : PhantomData < I > ,
189
187
}
190
188
191
- impl < I : Interner > DeepRejectCtxt < I > {
192
- pub fn new ( _interner : I , treat_lhs_params : TreatParams , treat_rhs_params : TreatParams ) -> Self {
193
- DeepRejectCtxt { treat_lhs_params, treat_rhs_params, _interner : PhantomData }
189
+ impl TreatParams {
190
+ pub const fn into_bool ( & self ) -> bool {
191
+ match * self {
192
+ TreatParams :: InstantiateWithInfer => true ,
193
+ TreatParams :: AsRigid => false ,
194
+ }
195
+ }
196
+ }
197
+
198
+ #[ macro_export]
199
+ macro_rules! new_reject_ctxt {
200
+ ( $interner: expr, $lhs: ident, $rhs: ident) => {
201
+ DeepRejectCtxt :: <_, { TreatParams :: $lhs. into_bool( ) } , { TreatParams :: $rhs. into_bool( ) } >:: new( $interner)
202
+ }
203
+ }
204
+
205
+ impl < I : Interner , const TREAT_LHS_PARAMS : bool , const TREAT_RHS_PARAMS : bool >
206
+ DeepRejectCtxt < I , TREAT_LHS_PARAMS , TREAT_RHS_PARAMS >
207
+ {
208
+ pub fn new ( _interner : I ) -> Self {
209
+ DeepRejectCtxt { _interner : PhantomData }
194
210
}
195
211
196
212
pub fn args_may_unify (
@@ -215,45 +231,6 @@ impl<I: Interner> DeepRejectCtxt<I> {
215
231
216
232
pub fn types_may_unify ( self , lhs : I :: Ty , rhs : I :: Ty ) -> bool {
217
233
match ( lhs. kind ( ) , rhs. kind ( ) ) {
218
- ( ty:: Error ( _) , _) | ( _, ty:: Error ( _) ) => true ,
219
-
220
- // As we're walking the whole type, it may encounter projections
221
- // inside of binders and what not, so we're just going to assume that
222
- // projections can unify with other stuff.
223
- //
224
- // Looking forward to lazy normalization this is the safer strategy anyways.
225
- ( ty:: Alias ( ..) , _) | ( _, ty:: Alias ( ..) ) => true ,
226
-
227
- // Bound type variables may unify with rigid types e.g. when using
228
- // non-lifetime binders.
229
- ( ty:: Bound ( ..) , _) | ( _, ty:: Bound ( ..) ) => true ,
230
-
231
- ( ty:: Infer ( var) , _) => self . var_and_ty_may_unify ( var, rhs) ,
232
- ( _, ty:: Infer ( var) ) => self . var_and_ty_may_unify ( var, lhs) ,
233
-
234
- ( ty:: Param ( lhs) , ty:: Param ( rhs) ) => {
235
- match ( self . treat_lhs_params , self . treat_rhs_params ) {
236
- ( TreatParams :: AsRigid , TreatParams :: AsRigid ) => lhs == rhs,
237
- ( TreatParams :: InstantiateWithInfer , _)
238
- | ( _, TreatParams :: InstantiateWithInfer ) => true ,
239
- }
240
- }
241
- ( ty:: Param ( _) , _) => self . treat_lhs_params == TreatParams :: InstantiateWithInfer ,
242
- ( _, ty:: Param ( _) ) => self . treat_rhs_params == TreatParams :: InstantiateWithInfer ,
243
-
244
- // Placeholder types don't unify with anything on their own.
245
- ( ty:: Placeholder ( lhs) , ty:: Placeholder ( rhs) ) => lhs == rhs,
246
-
247
- // Purely rigid types, use structural equivalence.
248
- ( ty:: Bool , ty:: Bool )
249
- | ( ty:: Char , ty:: Char )
250
- | ( ty:: Int ( _) , ty:: Int ( _) )
251
- | ( ty:: Uint ( _) , ty:: Uint ( _) )
252
- | ( ty:: Float ( _) , ty:: Float ( _) )
253
- | ( ty:: Str , ty:: Str )
254
- | ( ty:: Never , ty:: Never )
255
- | ( ty:: Foreign ( _) , ty:: Foreign ( _) ) => lhs == rhs,
256
-
257
234
( ty:: Ref ( _, lhs_ty, lhs_mutbl) , ty:: Ref ( _, rhs_ty, rhs_mutbl) ) => {
258
235
lhs_mutbl == rhs_mutbl && self . types_may_unify ( lhs_ty, rhs_ty)
259
236
}
@@ -262,37 +239,63 @@ impl<I: Interner> DeepRejectCtxt<I> {
262
239
lhs_def == rhs_def && self . args_may_unify ( lhs_args, rhs_args)
263
240
}
264
241
265
- ( ty:: Pat ( lhs_ty, _) , ty:: Pat ( rhs_ty, _) ) => {
266
- // FIXME(pattern_types): take pattern into account
267
- self . types_may_unify ( lhs_ty, rhs_ty)
268
- }
242
+ ( ty:: Infer ( var) , _) => self . var_and_ty_may_unify ( var, rhs) ,
243
+ ( _, ty:: Infer ( var) ) => self . var_and_ty_may_unify ( var, lhs) ,
269
244
270
- ( ty:: Slice ( lhs_ty ) , ty:: Slice ( rhs_ty ) ) => self . types_may_unify ( lhs_ty , rhs_ty ) ,
245
+ ( ty:: Int ( _ ) , ty:: Int ( _ ) ) | ( ty :: Uint ( _ ) , ty :: Uint ( _ ) ) => lhs == rhs ,
271
246
272
- ( ty:: Array ( lhs_ty, lhs_len) , ty:: Array ( rhs_ty, rhs_len) ) => {
273
- self . types_may_unify ( lhs_ty, rhs_ty) && self . consts_may_unify ( lhs_len, rhs_len)
274
- }
247
+ ( ty:: Param ( lhs) , ty:: Param ( rhs) ) => match ( TREAT_LHS_PARAMS , TREAT_RHS_PARAMS ) {
248
+ ( false , false ) => lhs == rhs,
249
+ ( true , _) | ( _, true ) => true ,
250
+ } ,
251
+
252
+ // As we're walking the whole type, it may encounter projections
253
+ // inside of binders and what not, so we're just going to assume that
254
+ // projections can unify with other stuff.
255
+ //
256
+ // Looking forward to lazy normalization this is the safer strategy anyways.
257
+ ( ty:: Alias ( ..) , _) | ( _, ty:: Alias ( ..) ) => true ,
258
+
259
+ ( ty:: Bound ( ..) , _) | ( _, ty:: Bound ( ..) ) => true ,
260
+
261
+ ( ty:: Param ( _) , _) => TREAT_LHS_PARAMS ,
262
+ ( _, ty:: Param ( _) ) => TREAT_RHS_PARAMS ,
275
263
276
264
( ty:: Tuple ( lhs) , ty:: Tuple ( rhs) ) => {
277
265
lhs. len ( ) == rhs. len ( )
278
266
&& iter:: zip ( lhs. iter ( ) , rhs. iter ( ) )
279
267
. all ( |( lhs, rhs) | self . types_may_unify ( lhs, rhs) )
280
268
}
281
269
270
+ ( ty:: Array ( lhs_ty, lhs_len) , ty:: Array ( rhs_ty, rhs_len) ) => {
271
+ self . types_may_unify ( lhs_ty, rhs_ty) && self . consts_may_unify ( lhs_len, rhs_len)
272
+ }
273
+
282
274
( ty:: RawPtr ( lhs_ty, lhs_mutbl) , ty:: RawPtr ( rhs_ty, rhs_mutbl) ) => {
283
275
lhs_mutbl == rhs_mutbl && self . types_may_unify ( lhs_ty, rhs_ty)
284
276
}
285
277
278
+ ( ty:: Slice ( lhs_ty) , ty:: Slice ( rhs_ty) ) => self . types_may_unify ( lhs_ty, rhs_ty) ,
279
+
280
+ ( ty:: Float ( _) , ty:: Float ( _) )
281
+ | ( ty:: Str , ty:: Str )
282
+ | ( ty:: Bool , ty:: Bool )
283
+ | ( ty:: Char , ty:: Char )
284
+ | ( ty:: Never , ty:: Never )
285
+ | ( ty:: Foreign ( _) , ty:: Foreign ( _) ) => lhs == rhs,
286
+
286
287
( ty:: Dynamic ( lhs_preds, ..) , ty:: Dynamic ( rhs_preds, ..) ) => {
287
288
// Ideally we would walk the existential predicates here or at least
288
289
// compare their length. But considering that the relevant `Relate` impl
289
290
// actually sorts and deduplicates these, that doesn't work.
290
291
lhs_preds. principal_def_id ( ) == rhs_preds. principal_def_id ( )
291
292
}
292
293
294
+ // Placeholder types don't unify with anything on their own.
295
+ ( ty:: Placeholder ( lhs) , ty:: Placeholder ( rhs) ) => lhs == rhs,
296
+
293
297
( ty:: FnPtr ( lhs_sig_tys, lhs_hdr) , ty:: FnPtr ( rhs_sig_tys, rhs_hdr) ) => {
294
298
let lhs_sig_tys = lhs_sig_tys. skip_binder ( ) . inputs_and_output ;
295
-
296
299
let rhs_sig_tys = rhs_sig_tys. skip_binder ( ) . inputs_and_output ;
297
300
298
301
lhs_hdr == rhs_hdr
@@ -313,7 +316,14 @@ impl<I: Interner> DeepRejectCtxt<I> {
313
316
ty:: CoroutineWitness ( rhs_def_id, rhs_args) ,
314
317
) => lhs_def_id == rhs_def_id && self . args_may_unify ( lhs_args, rhs_args) ,
315
318
316
- ( ty:: Placeholder ( _) , _)
319
+ ( ty:: Pat ( lhs_ty, _) , ty:: Pat ( rhs_ty, _) ) => {
320
+ // FIXME(pattern_types): take pattern into account
321
+ self . types_may_unify ( lhs_ty, rhs_ty)
322
+ }
323
+
324
+ ( ty:: Error ( ..) , _)
325
+ | ( _, ty:: Error ( ..) )
326
+ | ( ty:: Placeholder ( _) , _)
317
327
| ( _, ty:: Placeholder ( _) )
318
328
| ( ty:: Bool , _)
319
329
| ( _, ty:: Bool )
@@ -371,12 +381,8 @@ impl<I: Interner> DeepRejectCtxt<I> {
371
381
( ty:: ConstKind :: Value ( ..) , ty:: ConstKind :: Placeholder ( _) )
372
382
| ( ty:: ConstKind :: Placeholder ( _) , ty:: ConstKind :: Value ( ..) ) => false ,
373
383
374
- ( ty:: ConstKind :: Param ( _) , ty:: ConstKind :: Value ( ..) ) => {
375
- self . treat_lhs_params == TreatParams :: InstantiateWithInfer
376
- }
377
- ( ty:: ConstKind :: Value ( ..) , ty:: ConstKind :: Param ( _) ) => {
378
- self . treat_rhs_params == TreatParams :: InstantiateWithInfer
379
- }
384
+ ( ty:: ConstKind :: Param ( _) , ty:: ConstKind :: Value ( ..) ) => TREAT_LHS_PARAMS ,
385
+ ( ty:: ConstKind :: Value ( ..) , ty:: ConstKind :: Param ( _) ) => TREAT_RHS_PARAMS ,
380
386
381
387
_ => true ,
382
388
}
0 commit comments