@@ -300,55 +300,79 @@ fn negative_impl<'cx, 'tcx>(
300300 debug ! ( "negative_impl(impl1_def_id={:?}, impl2_def_id={:?})" , impl1_def_id, impl2_def_id) ;
301301 let tcx = selcx. infcx ( ) . tcx ;
302302
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-
307303 // Create an infcx, taking the predicates of impl1 as assumptions:
308304 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+ } ;
323323
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) ;
329329
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
332332 . 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+ }
350352 } 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+ }
352376 }
353377 } )
354378}
0 commit comments