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 ;
99use tracing:: { debug, instrument, trace} ;
1010
@@ -31,53 +31,43 @@ 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 ( TypingMode :: non_body_analysis ( ) ) ;
41+ let infcx = tcx
42+ . infer_ctxt ( )
43+ . with_next_trait_solver ( true )
44+ . build ( TypingMode :: non_body_analysis ( ) ) ;
45+ let ocx = traits:: ObligationCtxt :: new ( & infcx) ;
46+
4247 let args = infcx. fresh_args_for_item ( DUMMY_SP , item_def_id) ;
4348 let impl_ty = ty. instantiate ( tcx, args) ;
4449 let param_env = ty:: ParamEnv :: empty ( ) ;
50+ let cause = ObligationCause :: dummy ( ) ;
4551
4652 let impl_args = infcx. fresh_args_for_item ( DUMMY_SP , impl_def_id) ;
4753 let impl_trait_ref = trait_ref. instantiate ( tcx, impl_args) ;
4854
4955 // Require the type the impl is implemented on to match
5056 // 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 {
57+ if ocx. eq ( & cause, param_env, impl_trait_ref. self_ty ( ) , impl_ty) . is_err ( ) {
5658 continue ;
57- } ;
58- let InferOk { value : ( ) , obligations } = eq_result;
59- // FIXME(eddyb) ignoring `obligations` might cause false positives.
60- drop ( obligations) ;
59+ }
60+
61+ ocx. register_obligations ( traits:: predicates_for_generics (
62+ |_, _| cause. clone ( ) ,
63+ param_env,
64+ tcx. predicates_of ( impl_def_id) . instantiate ( tcx, impl_args) ,
65+ ) ) ;
6166
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- }
67+ if !ocx. select_where_possible ( ) . is_empty ( ) {
68+ continue ;
8069 }
70+
8171 debug ! ( "found applicable impl for trait ref {trait_ref:?}" ) ;
8272
8373 cx. generated_synthetics . insert ( ( ty. skip_binder ( ) , trait_def_id) ) ;
0 commit comments