11use rustc_hir as hir;
2- use rustc_infer:: infer:: { DefineOpaqueTypes , InferOk , TyCtxtInferExt } ;
3- use rustc_infer:: traits;
2+ use rustc_infer:: infer:: TyCtxtInferExt ;
3+ use rustc_infer:: traits:: ObligationCause ;
44use rustc_middle:: ty:: { self , Upcast } ;
55use rustc_span:: def_id:: DefId ;
66use rustc_span:: DUMMY_SP ;
7- use rustc_trait_selection:: traits:: query :: evaluate_obligation :: InferCtxtExt ;
7+ use rustc_trait_selection:: traits;
88use thin_vec:: ThinVec ;
99
1010use crate :: clean;
@@ -30,53 +30,47 @@ pub(crate) fn synthesize_blanket_impls(
3030 }
3131 // NOTE: doesn't use `for_each_relevant_impl` to avoid looking at anything besides blanket impls
3232 let trait_impls = tcx. trait_impls_of ( trait_def_id) ;
33- ' blanket_impls : for & impl_def_id in trait_impls. blanket_impls ( ) {
33+ for & impl_def_id in trait_impls. blanket_impls ( ) {
3434 trace ! ( "considering impl `{impl_def_id:?}` for trait `{trait_def_id:?}`" ) ;
3535
3636 let trait_ref = tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) ;
3737 if !matches ! ( trait_ref. skip_binder( ) . self_ty( ) . kind( ) , ty:: Param ( _) ) {
3838 continue ;
3939 }
40- let infcx = tcx. infer_ctxt ( ) . build ( ) ;
40+ let infcx = tcx. infer_ctxt ( ) . with_next_trait_solver ( true ) . build ( ) ;
41+ let ocx = traits:: ObligationCtxt :: new ( & infcx) ;
42+
4143 let args = infcx. fresh_args_for_item ( DUMMY_SP , item_def_id) ;
4244 let impl_ty = ty. instantiate ( tcx, args) ;
4345 let param_env = ty:: ParamEnv :: empty ( ) ;
46+ let cause = ObligationCause :: dummy ( ) ;
4447
4548 let impl_args = infcx. fresh_args_for_item ( DUMMY_SP , impl_def_id) ;
4649 let impl_trait_ref = trait_ref. instantiate ( tcx, impl_args) ;
4750
4851 // Require the type the impl is implemented on to match
4952 // our type, and ignore the impl if there was a mismatch.
50- let Ok ( eq_result) = infcx. at ( & traits:: ObligationCause :: dummy ( ) , param_env) . eq (
51- DefineOpaqueTypes :: Yes ,
52- impl_trait_ref. self_ty ( ) ,
53- impl_ty,
54- ) else {
53+ if ocx. eq ( & cause, param_env, impl_trait_ref. self_ty ( ) , impl_ty) . is_err ( ) {
5554 continue ;
56- } ;
57- let InferOk { value : ( ) , obligations } = eq_result;
58- // FIXME(eddyb) ignoring `obligations` might cause false positives.
59- drop ( obligations) ;
55+ }
6056
61- let predicates = tcx
62- . predicates_of ( impl_def_id)
63- . instantiate ( tcx, impl_args)
64- . predicates
65- . into_iter ( )
66- . chain ( Some ( impl_trait_ref. upcast ( tcx) ) ) ;
67- for predicate in predicates {
68- let obligation = traits:: Obligation :: new (
69- tcx,
70- traits:: ObligationCause :: dummy ( ) ,
71- param_env,
72- predicate,
73- ) ;
74- match infcx. evaluate_obligation ( & obligation) {
75- Ok ( eval_result) if eval_result. may_apply ( ) => { }
76- Err ( traits:: OverflowError :: Canonical ) => { }
77- _ => continue ' blanket_impls,
78- }
57+ ocx. register_obligations ( traits:: predicates_for_generics (
58+ |_, _| cause. clone ( ) ,
59+ param_env,
60+ tcx. predicates_of ( impl_def_id) . instantiate ( tcx, impl_args) ,
61+ ) ) ;
62+
63+ ocx. register_obligation ( traits:: Obligation {
64+ cause,
65+ recursion_depth : 0 ,
66+ param_env,
67+ predicate : impl_trait_ref. upcast ( tcx) ,
68+ } ) ;
69+
70+ if !ocx. select_where_possible ( ) . is_empty ( ) {
71+ continue ;
7972 }
73+
8074 debug ! ( "found applicable impl for trait ref {trait_ref:?}" ) ;
8175
8276 cx. generated_synthetics . insert ( ( ty. skip_binder ( ) , trait_def_id) ) ;
0 commit comments