11use  rustc_hir as  hir; 
2- use  rustc_infer:: infer:: { DefineOpaqueTypes ,   InferOk ,   TyCtxtInferExt } ; 
3- use  rustc_infer:: traits; 
4- use  rustc_middle:: ty:: { self ,  TypingMode ,   Upcast } ; 
2+ use  rustc_infer:: infer:: TyCtxtInferExt ; 
3+ use  rustc_infer:: traits:: ObligationCause ; 
4+ use  rustc_middle:: ty:: { self ,  TypingMode } ; 
55use  rustc_span:: DUMMY_SP ; 
66use  rustc_span:: def_id:: DefId ; 
7- use  rustc_trait_selection:: traits:: query :: evaluate_obligation :: InferCtxtExt ; 
7+ use  rustc_trait_selection:: traits; 
88use  thin_vec:: ThinVec ; 
9- use  tracing:: { debug,  instrument,  trace } ; 
9+ use  tracing:: { debug,  instrument} ; 
1010
1111use  crate :: clean; 
1212use  crate :: clean:: { 
@@ -22,6 +22,9 @@ pub(crate) fn synthesize_blanket_impls(
2222    let  tcx = cx. tcx ; 
2323    let  ty = tcx. type_of ( item_def_id) ; 
2424
25+     let  infcx =
26+         tcx. infer_ctxt ( ) . with_next_trait_solver ( true ) . build ( TypingMode :: non_body_analysis ( ) ) ; 
27+ 
2528    let  mut  blanket_impls = Vec :: new ( ) ; 
2629    for  trait_def_id in  tcx. visible_traits ( )  { 
2730        if  !cx. cache . effective_visibilities . is_reachable ( tcx,  trait_def_id) 
@@ -31,53 +34,37 @@ pub(crate) fn synthesize_blanket_impls(
3134        } 
3235        // NOTE: doesn't use `for_each_relevant_impl` to avoid looking at anything besides blanket impls 
3336        let  trait_impls = tcx. trait_impls_of ( trait_def_id) ; 
34-         ' blanket_impls:  for  & impl_def_id in  trait_impls. blanket_impls ( )  { 
35-             trace ! ( "considering impl `{impl_def_id:?}` for trait `{trait_def_id:?}`" ) ; 
36- 
37+         for  & impl_def_id in  trait_impls. blanket_impls ( )  { 
3738            let  trait_ref = tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) ; 
38-             if  !matches ! ( trait_ref. skip_binder( ) . self_ty( ) . kind( ) ,  ty:: Param ( _) )  { 
39-                 continue ; 
40-             } 
41-             let  infcx = tcx. infer_ctxt ( ) . build ( TypingMode :: non_body_analysis ( ) ) ; 
39+ 
40+             let  ty:: Param ( _)  = trait_ref. skip_binder ( ) . self_ty ( ) . kind ( )  else  {  continue  } ; 
41+ 
42+             let  ocx = traits:: ObligationCtxt :: new ( & infcx) ; 
43+ 
4244            let  args = infcx. fresh_args_for_item ( DUMMY_SP ,  item_def_id) ; 
4345            let  impl_ty = ty. instantiate ( tcx,  args) ; 
4446            let  param_env = ty:: ParamEnv :: empty ( ) ; 
47+             let  cause = ObligationCause :: dummy ( ) ; 
4548
4649            let  impl_args = infcx. fresh_args_for_item ( DUMMY_SP ,  impl_def_id) ; 
4750            let  impl_trait_ref = trait_ref. instantiate ( tcx,  impl_args) ; 
4851
4952            // Require the type the impl is implemented on to match 
5053            // our type, and ignore the impl if there was a mismatch. 
51-             let  Ok ( eq_result)  = infcx. at ( & traits:: ObligationCause :: dummy ( ) ,  param_env) . eq ( 
52-                 DefineOpaqueTypes :: Yes , 
53-                 impl_trait_ref. self_ty ( ) , 
54-                 impl_ty, 
55-             )  else  { 
54+             if  ocx. eq ( & cause,  param_env,  impl_trait_ref. self_ty ( ) ,  impl_ty) . is_err ( )  { 
5655                continue ; 
57-             } ; 
58-             let  InferOk  {  value :  ( ) ,  obligations }  = eq_result; 
59-             // FIXME(eddyb) ignoring `obligations` might cause false positives. 
60-             drop ( obligations) ; 
56+             } 
57+ 
58+             ocx. register_obligations ( traits:: predicates_for_generics ( 
59+                 |_,  _| cause. clone ( ) , 
60+                 param_env, 
61+                 tcx. predicates_of ( impl_def_id) . instantiate ( tcx,  impl_args) , 
62+             ) ) ; 
6163
62-             let  predicates = tcx
63-                 . predicates_of ( impl_def_id) 
64-                 . instantiate ( tcx,  impl_args) 
65-                 . predicates 
66-                 . into_iter ( ) 
67-                 . chain ( Some ( impl_trait_ref. upcast ( tcx) ) ) ; 
68-             for  predicate in  predicates { 
69-                 let  obligation = traits:: Obligation :: new ( 
70-                     tcx, 
71-                     traits:: ObligationCause :: dummy ( ) , 
72-                     param_env, 
73-                     predicate, 
74-                 ) ; 
75-                 match  infcx. evaluate_obligation ( & obligation)  { 
76-                     Ok ( eval_result)  if  eval_result. may_apply ( )  => { } 
77-                     Err ( traits:: OverflowError :: Canonical )  => { } 
78-                     _ => continue  ' blanket_impls, 
79-                 } 
64+             if  !ocx. select_where_possible ( ) . is_empty ( )  { 
65+                 continue ; 
8066            } 
67+ 
8168            debug ! ( "found applicable impl for trait ref {trait_ref:?}" ) ; 
8269
8370            cx. generated_synthetics . insert ( ( ty. skip_binder ( ) ,  trait_def_id) ) ; 
0 commit comments