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;
88
99use thin_vec:: ThinVec ;
1010
@@ -31,53 +31,47 @@ pub(crate) fn synthesize_blanket_impls(
3131 }
3232 // NOTE: doesn't use `for_each_relevant_impl` to avoid looking at anything besides blanket impls
3333 let trait_impls = tcx. trait_impls_of ( trait_def_id) ;
34- ' blanket_impls : for & impl_def_id in trait_impls. blanket_impls ( ) {
34+ for & impl_def_id in trait_impls. blanket_impls ( ) {
3535 trace ! ( "considering impl `{impl_def_id:?}` for trait `{trait_def_id:?}`" ) ;
3636
3737 let trait_ref = tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) ;
3838 if !matches ! ( trait_ref. skip_binder( ) . self_ty( ) . kind( ) , ty:: Param ( _) ) {
3939 continue ;
4040 }
41- let infcx = tcx. infer_ctxt ( ) . build ( ) ;
41+ let infcx = tcx. infer_ctxt ( ) . with_next_trait_solver ( true ) . build ( ) ;
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+ }
6157
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- }
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+ ) ) ;
63+
64+ ocx. register_obligation ( traits:: Obligation {
65+ cause,
66+ recursion_depth : 0 ,
67+ param_env,
68+ predicate : impl_trait_ref. upcast ( tcx) ,
69+ } ) ;
70+
71+ if !ocx. select_where_possible ( ) . is_empty ( ) {
72+ continue ;
8073 }
74+
8175 debug ! ( "found applicable impl for trait ref {trait_ref:?}" ) ;
8276
8377 cx. generated_synthetics . insert ( ( ty. skip_binder ( ) , trait_def_id) ) ;
0 commit comments