11use rustc_data_structures:: thin_vec:: ThinVec ;
22use rustc_hir as hir;
3- use rustc_infer:: infer:: { DefineOpaqueTypes , InferOk , TyCtxtInferExt } ;
4- use rustc_infer:: traits;
5- use rustc_middle:: ty:: { self , TypingMode , Unnormalized , Upcast } ;
3+ use rustc_infer:: infer:: TyCtxtInferExt ;
4+ use rustc_middle:: ty;
65use rustc_span:: DUMMY_SP ;
76use rustc_span:: def_id:: DefId ;
8- use rustc_trait_selection:: traits:: query :: evaluate_obligation :: InferCtxtExt ;
9- use tracing:: { debug, instrument, trace } ;
7+ use rustc_trait_selection:: traits;
8+ use tracing:: { debug, instrument} ;
109
1110use crate :: clean;
1211use crate :: clean:: {
@@ -20,68 +19,54 @@ pub(crate) fn synthesize_blanket_impls(
2019 item_def_id : DefId ,
2120) -> Vec < clean:: Item > {
2221 let tcx = cx. tcx ;
23- let ty = tcx. type_of ( item_def_id) ;
22+ let item_ty = tcx. type_of ( item_def_id) ;
23+ let param_env = ty:: ParamEnv :: empty ( ) ;
24+ let typing_mode = ty:: TypingMode :: non_body_analysis ( ) ;
25+ let cause = traits:: ObligationCause :: dummy ( ) ;
2426
2527 let mut blanket_impls = Vec :: new ( ) ;
28+
2629 for trait_def_id in tcx. visible_traits ( ) {
2730 if !cx. cache . effective_visibilities . is_reachable ( tcx, trait_def_id)
28- || cx. generated_synthetics . contains ( & ( ty . skip_binder ( ) , trait_def_id) )
31+ || cx. generated_synthetics . contains ( & ( item_ty . skip_binder ( ) , trait_def_id) )
2932 {
3033 continue ;
3134 }
32- // NOTE: doesn't use `for_each_relevant_impl` to avoid looking at anything besides blanket impls
33- 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:?}`" ) ;
3635
37- let trait_ref = tcx. impl_trait_ref ( impl_def_id) ;
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 ( ) ) ;
42- let args = infcx. fresh_args_for_item ( DUMMY_SP , item_def_id) ;
43- let impl_ty = ty. instantiate ( tcx, args) . skip_norm_wip ( ) ;
44- let param_env = ty:: ParamEnv :: empty ( ) ;
45-
46- let impl_args = infcx. fresh_args_for_item ( DUMMY_SP , impl_def_id) ;
47- let impl_trait_ref = trait_ref. instantiate ( tcx, impl_args) . skip_norm_wip ( ) ;
48-
49- // Require the type the impl is implemented on to match
50- // 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 {
36+ for & impl_def_id in tcx. trait_impls_of ( trait_def_id) . blanket_impls ( ) {
37+ let impl_trait_ref = tcx. impl_trait_ref ( impl_def_id) ;
38+
39+ let ty:: Param ( _) = impl_trait_ref. skip_binder ( ) . self_ty ( ) . kind ( ) else { continue } ;
40+
41+ let infcx = tcx. infer_ctxt ( ) . with_next_trait_solver ( true ) . build ( typing_mode) ;
42+
43+ let ocx = traits:: ObligationCtxt :: new ( & infcx) ;
44+
45+ let fresh_item_args = infcx. fresh_args_for_item ( DUMMY_SP , item_def_id) ;
46+ let fresh_item_ty = item_ty. instantiate ( tcx, fresh_item_args) . skip_normalization ( ) ;
47+
48+ let fresh_impl_args = infcx. fresh_args_for_item ( DUMMY_SP , impl_def_id) ;
49+ let fresh_impl_trait_ref =
50+ impl_trait_ref. instantiate ( tcx, fresh_impl_args) . skip_normalization ( ) ;
51+
52+ // Constraint inference variables.
53+ let result = ocx. eq ( & cause, param_env, fresh_impl_trait_ref. self_ty ( ) , fresh_item_ty) ;
54+ debug_assert ! ( result. is_ok( ) ) ;
55+
56+ ocx. register_obligations ( traits:: predicates_for_generics (
57+ |_, _| cause. clone ( ) ,
58+ |pred| ocx. normalize ( & cause, param_env, pred) ,
59+ param_env,
60+ tcx. predicates_of ( impl_def_id) . instantiate ( tcx, fresh_impl_args) ,
61+ ) ) ;
62+
63+ if !ocx. try_evaluate_obligations ( ) . is_empty ( ) {
5664 continue ;
57- } ;
58- let InferOk { value : ( ) , obligations } = eq_result;
59- // FIXME(eddyb) ignoring `obligations` might cause false positives.
60- drop ( obligations) ;
61-
62- let predicates = tcx
63- . predicates_of ( impl_def_id)
64- . instantiate ( tcx, impl_args)
65- . predicates
66- . into_iter ( )
67- . map ( Unnormalized :: skip_norm_wip)
68- . chain ( Some ( impl_trait_ref. upcast ( tcx) ) ) ;
69- for predicate in predicates {
70- let obligation = traits:: Obligation :: new (
71- tcx,
72- traits:: ObligationCause :: dummy ( ) ,
73- param_env,
74- predicate,
75- ) ;
76- match infcx. evaluate_obligation ( & obligation) {
77- Ok ( eval_result) if eval_result. may_apply ( ) => { }
78- Err ( traits:: OverflowError :: Canonical ) => { }
79- _ => continue ' blanket_impls,
80- }
8165 }
82- debug ! ( "found applicable impl for trait ref {trait_ref:?}" ) ;
8366
84- cx. generated_synthetics . insert ( ( ty. skip_binder ( ) , trait_def_id) ) ;
67+ debug ! ( "found applicable impl for trait ref {impl_trait_ref:?}" ) ;
68+
69+ cx. generated_synthetics . insert ( ( item_ty. skip_binder ( ) , trait_def_id) ) ;
8570
8671 blanket_impls. push ( clean:: Item {
8772 inner : Box :: new ( clean:: ItemInner {
@@ -96,11 +81,13 @@ pub(crate) fn synthesize_blanket_impls(
9681 // the post-inference `trait_ref`, as it's more accurate.
9782 trait_ : Some ( clean_trait_ref_with_constraints (
9883 cx,
99- ty:: Binder :: dummy ( trait_ref. instantiate_identity ( ) . skip_norm_wip ( ) ) ,
84+ ty:: Binder :: dummy (
85+ impl_trait_ref. instantiate_identity ( ) . skip_norm_wip ( ) ,
86+ ) ,
10087 ThinVec :: new ( ) ,
10188 ) ) ,
10289 for_ : clean_middle_ty (
103- ty:: Binder :: dummy ( ty . instantiate_identity ( ) . skip_norm_wip ( ) ) ,
90+ ty:: Binder :: dummy ( item_ty . instantiate_identity ( ) . skip_norm_wip ( ) ) ,
10491 cx,
10592 None ,
10693 None ,
@@ -114,7 +101,7 @@ pub(crate) fn synthesize_blanket_impls(
114101 polarity : ty:: ImplPolarity :: Positive ,
115102 kind : clean:: ImplKind :: Blanket ( Box :: new ( clean_middle_ty (
116103 ty:: Binder :: dummy (
117- trait_ref . instantiate_identity ( ) . skip_norm_wip ( ) . self_ty ( ) ,
104+ impl_trait_ref . instantiate_identity ( ) . skip_norm_wip ( ) . self_ty ( ) ,
118105 ) ,
119106 cx,
120107 None ,
0 commit comments