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