@@ -300,55 +300,79 @@ fn negative_impl<'cx, 'tcx>(
300
300
debug ! ( "negative_impl(impl1_def_id={:?}, impl2_def_id={:?})" , impl1_def_id, impl2_def_id) ;
301
301
let tcx = selcx. infcx ( ) . tcx ;
302
302
303
- // create a parameter environment corresponding to a (placeholder) instantiation of impl1
304
- let impl1_env = tcx. param_env ( impl1_def_id) ;
305
- let impl1_trait_ref = tcx. impl_trait_ref ( impl1_def_id) . unwrap ( ) ;
306
-
307
303
// Create an infcx, taking the predicates of impl1 as assumptions:
308
304
tcx. infer_ctxt ( ) . enter ( |infcx| {
309
- // Normalize the trait reference. The WF rules ought to ensure
310
- // that this always succeeds.
311
- let impl1_trait_ref = match traits:: fully_normalize (
312
- & infcx,
313
- FulfillmentContext :: new ( ) ,
314
- ObligationCause :: dummy ( ) ,
315
- impl1_env,
316
- impl1_trait_ref,
317
- ) {
318
- Ok ( impl1_trait_ref) => impl1_trait_ref,
319
- Err ( err) => {
320
- bug ! ( "failed to fully normalize {:?}: {:?}" , impl1_trait_ref, err) ;
321
- }
322
- } ;
305
+ // create a parameter environment corresponding to a (placeholder) instantiation of impl1
306
+ let impl1_env = tcx. param_env ( impl1_def_id) ;
307
+
308
+ if let Some ( impl1_trait_ref) = tcx. impl_trait_ref ( impl1_def_id) {
309
+ // Normalize the trait reference. The WF rules ought to ensure
310
+ // that this always succeeds.
311
+ let impl1_trait_ref = match traits:: fully_normalize (
312
+ & infcx,
313
+ FulfillmentContext :: new ( ) ,
314
+ ObligationCause :: dummy ( ) ,
315
+ impl1_env,
316
+ impl1_trait_ref,
317
+ ) {
318
+ Ok ( impl1_trait_ref) => impl1_trait_ref,
319
+ Err ( err) => {
320
+ bug ! ( "failed to fully normalize {:?}: {:?}" , impl1_trait_ref, err) ;
321
+ }
322
+ } ;
323
323
324
- // Attempt to prove that impl2 applies, given all of the above.
325
- let selcx = & mut SelectionContext :: new ( & infcx) ;
326
- let impl2_substs = infcx. fresh_substs_for_item ( DUMMY_SP , impl2_def_id) ;
327
- let ( impl2_trait_ref, obligations) =
328
- impl_trait_ref_and_oblig ( selcx, impl1_env, impl2_def_id, impl2_substs) ;
324
+ // Attempt to prove that impl2 applies, given all of the above.
325
+ let selcx = & mut SelectionContext :: new ( & infcx) ;
326
+ let impl2_substs = infcx. fresh_substs_for_item ( DUMMY_SP , impl2_def_id) ;
327
+ let ( impl2_trait_ref, obligations) =
328
+ impl_trait_ref_and_oblig ( selcx, impl1_env, impl2_def_id, impl2_substs) ;
329
329
330
- // do the impls unify? If not, not disjoint.
331
- let Ok ( InferOk { obligations : more_obligations, .. } ) = infcx
330
+ // do the impls unify? If not, not disjoint.
331
+ let Ok ( InferOk { obligations : more_obligations, .. } ) = infcx
332
332
. at ( & ObligationCause :: dummy ( ) , impl1_env)
333
- . eq ( impl1_trait_ref, impl2_trait_ref)
334
- else {
335
- debug ! (
336
- "explicit_disjoint: {:?} does not unify with {:?}" ,
337
- impl1_trait_ref, impl2_trait_ref
338
- ) ;
339
- return false ;
340
- } ;
341
-
342
- let opt_failing_obligation = obligations
343
- . into_iter ( )
344
- . chain ( more_obligations)
345
- . find ( |o| negative_impl_exists ( selcx, impl1_env, impl1_def_id, o) ) ;
346
-
347
- if let Some ( failing_obligation) = opt_failing_obligation {
348
- debug ! ( "overlap: obligation unsatisfiable {:?}" , failing_obligation) ;
349
- true
333
+ . eq ( impl1_trait_ref, impl2_trait_ref) else {
334
+ debug ! (
335
+ "explicit_disjoint: {:?} does not unify with {:?}" ,
336
+ impl1_trait_ref, impl2_trait_ref
337
+ ) ;
338
+ return false ;
339
+ } ;
340
+
341
+ let opt_failing_obligation = obligations
342
+ . into_iter ( )
343
+ . chain ( more_obligations)
344
+ . find ( |o| negative_impl_exists ( selcx, impl1_env, impl1_def_id, o) ) ;
345
+
346
+ if let Some ( failing_obligation) = opt_failing_obligation {
347
+ debug ! ( "overlap: obligation unsatisfiable {:?}" , failing_obligation) ;
348
+ true
349
+ } else {
350
+ false
351
+ }
350
352
} else {
351
- false
353
+ let ty1 = tcx. type_of ( impl1_def_id) ;
354
+ let ty2 = tcx. type_of ( impl2_def_id) ;
355
+
356
+ let Ok ( InferOk { obligations, .. } ) = infcx
357
+ . at ( & ObligationCause :: dummy ( ) , impl1_env)
358
+ . eq ( ty1, ty2) else {
359
+ debug ! (
360
+ "explicit_disjoint: {:?} does not unify with {:?}" ,
361
+ ty1, ty2
362
+ ) ;
363
+ return false ;
364
+ } ;
365
+
366
+ let opt_failing_obligation = obligations
367
+ . into_iter ( )
368
+ . find ( |o| negative_impl_exists ( selcx, impl1_env, impl1_def_id, o) ) ;
369
+
370
+ if let Some ( failing_obligation) = opt_failing_obligation {
371
+ debug ! ( "overlap: obligation unsatisfiable {:?}" , failing_obligation) ;
372
+ true
373
+ } else {
374
+ false
375
+ }
352
376
}
353
377
} )
354
378
}
0 commit comments