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