@@ -173,7 +173,7 @@ impl<DefId> SimplifiedType<DefId> {
173173
174174/// Given generic arguments, could they be unified after
175175/// 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 .
177177///
178178/// We use this to quickly reject impl/wc candidates without needing
179179/// to instantiate generic arguments/having to enter a probe.
@@ -182,15 +182,31 @@ impl<DefId> SimplifiedType<DefId> {
182182/// impls only have to overlap for some value, so we treat parameters
183183/// on both sides like inference variables.
184184#[ 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 > {
188186 _interner : PhantomData < I > ,
189187}
190188
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 }
194210 }
195211
196212 pub fn args_may_unify (
@@ -215,45 +231,6 @@ impl<I: Interner> DeepRejectCtxt<I> {
215231
216232 pub fn types_may_unify ( self , lhs : I :: Ty , rhs : I :: Ty ) -> bool {
217233 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-
257234 ( ty:: Ref ( _, lhs_ty, lhs_mutbl) , ty:: Ref ( _, rhs_ty, rhs_mutbl) ) => {
258235 lhs_mutbl == rhs_mutbl && self . types_may_unify ( lhs_ty, rhs_ty)
259236 }
@@ -262,37 +239,63 @@ impl<I: Interner> DeepRejectCtxt<I> {
262239 lhs_def == rhs_def && self . args_may_unify ( lhs_args, rhs_args)
263240 }
264241
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) ,
269244
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 ,
271246
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 ,
275263
276264 ( ty:: Tuple ( lhs) , ty:: Tuple ( rhs) ) => {
277265 lhs. len ( ) == rhs. len ( )
278266 && iter:: zip ( lhs. iter ( ) , rhs. iter ( ) )
279267 . all ( |( lhs, rhs) | self . types_may_unify ( lhs, rhs) )
280268 }
281269
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+
282274 ( ty:: RawPtr ( lhs_ty, lhs_mutbl) , ty:: RawPtr ( rhs_ty, rhs_mutbl) ) => {
283275 lhs_mutbl == rhs_mutbl && self . types_may_unify ( lhs_ty, rhs_ty)
284276 }
285277
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+
286287 ( ty:: Dynamic ( lhs_preds, ..) , ty:: Dynamic ( rhs_preds, ..) ) => {
287288 // Ideally we would walk the existential predicates here or at least
288289 // compare their length. But considering that the relevant `Relate` impl
289290 // actually sorts and deduplicates these, that doesn't work.
290291 lhs_preds. principal_def_id ( ) == rhs_preds. principal_def_id ( )
291292 }
292293
294+ // Placeholder types don't unify with anything on their own.
295+ ( ty:: Placeholder ( lhs) , ty:: Placeholder ( rhs) ) => lhs == rhs,
296+
293297 ( ty:: FnPtr ( lhs_sig_tys, lhs_hdr) , ty:: FnPtr ( rhs_sig_tys, rhs_hdr) ) => {
294298 let lhs_sig_tys = lhs_sig_tys. skip_binder ( ) . inputs_and_output ;
295-
296299 let rhs_sig_tys = rhs_sig_tys. skip_binder ( ) . inputs_and_output ;
297300
298301 lhs_hdr == rhs_hdr
@@ -313,7 +316,14 @@ impl<I: Interner> DeepRejectCtxt<I> {
313316 ty:: CoroutineWitness ( rhs_def_id, rhs_args) ,
314317 ) => lhs_def_id == rhs_def_id && self . args_may_unify ( lhs_args, rhs_args) ,
315318
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 ( _) , _)
317327 | ( _, ty:: Placeholder ( _) )
318328 | ( ty:: Bool , _)
319329 | ( _, ty:: Bool )
@@ -371,12 +381,8 @@ impl<I: Interner> DeepRejectCtxt<I> {
371381 ( ty:: ConstKind :: Value ( ..) , ty:: ConstKind :: Placeholder ( _) )
372382 | ( ty:: ConstKind :: Placeholder ( _) , ty:: ConstKind :: Value ( ..) ) => false ,
373383
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 ,
380386
381387 _ => true ,
382388 }
0 commit comments