@@ -24,7 +24,7 @@ use rustc_middle::traits::specialization_graph::OverlapMode;
2424use rustc_middle:: ty:: fast_reject:: { self , TreatParams } ;
2525use rustc_middle:: ty:: fold:: TypeFoldable ;
2626use rustc_middle:: ty:: subst:: Subst ;
27- use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
27+ use rustc_middle:: ty:: { self , ImplSubject , Ty , TyCtxt } ;
2828use rustc_span:: symbol:: sym;
2929use rustc_span:: DUMMY_SP ;
3030use std:: fmt:: Debug ;
@@ -307,46 +307,47 @@ fn negative_impl<'cx, 'tcx>(
307307 // create a parameter environment corresponding to a (placeholder) instantiation of impl1
308308 let impl1_env = tcx. param_env ( impl1_def_id) ;
309309
310- if let Some ( impl1_trait_ref) = tcx. impl_trait_ref ( impl1_def_id) {
311- // Normalize the trait reference. The WF rules ought to ensure
312- // that this always succeeds.
313- let impl1_trait_ref = match traits:: fully_normalize (
314- & infcx,
315- FulfillmentContext :: new ( ) ,
316- ObligationCause :: dummy ( ) ,
317- impl1_env,
318- impl1_trait_ref,
319- ) {
320- Ok ( impl1_trait_ref) => impl1_trait_ref,
321- Err ( err) => {
322- bug ! ( "failed to fully normalize {:?}: {:?}" , impl1_trait_ref, err) ;
323- }
324- } ;
325-
326- // Attempt to prove that impl2 applies, given all of the above.
327- let selcx = & mut SelectionContext :: new ( & infcx) ;
328- let impl2_substs = infcx. fresh_substs_for_item ( DUMMY_SP , impl2_def_id) ;
329- let ( impl2_trait_ref, obligations) =
330- impl_trait_ref_and_oblig ( selcx, impl1_env, impl2_def_id, impl2_substs) ;
331-
332- !obligations_satisfiable (
333- & infcx,
334- impl1_env,
335- impl1_def_id,
336- impl1_trait_ref,
337- impl2_trait_ref,
338- obligations,
339- )
340- } else {
341- let ty1 = tcx. type_of ( impl1_def_id) ;
342- let ty2 = tcx. type_of ( impl2_def_id) ;
343-
344- !obligations_satisfiable ( & infcx, impl1_env, impl1_def_id, ty1, ty2, iter:: empty ( ) )
310+ match tcx. impl_header ( impl1_def_id) {
311+ ImplSubject :: Trait ( impl1_trait_ref) => {
312+ // Normalize the trait reference. The WF rules ought to ensure
313+ // that this always succeeds.
314+ let impl1_trait_ref = match traits:: fully_normalize (
315+ & infcx,
316+ FulfillmentContext :: new ( ) ,
317+ ObligationCause :: dummy ( ) ,
318+ impl1_env,
319+ impl1_trait_ref,
320+ ) {
321+ Ok ( impl1_trait_ref) => impl1_trait_ref,
322+ Err ( err) => {
323+ bug ! ( "failed to fully normalize {:?}: {:?}" , impl1_trait_ref, err) ;
324+ }
325+ } ;
326+
327+ // Attempt to prove that impl2 applies, given all of the above.
328+ let selcx = & mut SelectionContext :: new ( & infcx) ;
329+ let impl2_substs = infcx. fresh_substs_for_item ( DUMMY_SP , impl2_def_id) ;
330+ let ( impl2_trait_ref, obligations) =
331+ impl_trait_ref_and_oblig ( selcx, impl1_env, impl2_def_id, impl2_substs) ;
332+
333+ !equate (
334+ & infcx,
335+ impl1_env,
336+ impl1_def_id,
337+ impl1_trait_ref,
338+ impl2_trait_ref,
339+ obligations,
340+ )
341+ }
342+ ImplSubject :: Inherent ( ty1) => {
343+ let ty2 = tcx. type_of ( impl2_def_id) ;
344+ !equate ( & infcx, impl1_env, impl1_def_id, ty1, ty2, iter:: empty ( ) )
345+ }
345346 }
346347 } )
347348}
348349
349- fn obligations_satisfiable < ' cx , ' tcx , T : Debug + ToTrace < ' tcx > > (
350+ fn equate < ' cx , ' tcx , T : Debug + ToTrace < ' tcx > > (
350351 infcx : & InferCtxt < ' cx , ' tcx > ,
351352 impl1_env : ty:: ParamEnv < ' tcx > ,
352353 impl1_def_id : DefId ,
0 commit comments