@@ -13,116 +13,124 @@ pub(crate) struct BlanketImplFinder<'a, 'tcx> {
1313
1414impl < ' a , ' tcx > BlanketImplFinder < ' a , ' tcx > {
1515 pub ( crate ) fn get_blanket_impls ( & mut self , item_def_id : DefId ) -> Vec < Item > {
16- let param_env = self . cx . tcx . param_env ( item_def_id) ;
17- let ty = self . cx . tcx . bound_type_of ( item_def_id) ;
16+ let cx = & mut self . cx ;
17+ let param_env = cx. tcx . param_env ( item_def_id) ;
18+ let ty = cx. tcx . bound_type_of ( item_def_id) ;
1819
1920 trace ! ( "get_blanket_impls({:?})" , ty) ;
2021 let mut impls = Vec :: new ( ) ;
21- self . cx . with_all_traits ( |cx, all_traits| {
22- for & trait_def_id in all_traits {
23- if !cx. cache . access_levels . is_public ( trait_def_id)
24- || cx. generated_synthetics . get ( & ( ty. 0 , trait_def_id) ) . is_some ( )
25- {
22+ for trait_def_id in cx. tcx . all_traits ( ) {
23+ if !cx. cache . access_levels . is_public ( trait_def_id)
24+ || cx. generated_synthetics . get ( & ( ty. 0 , trait_def_id) ) . is_some ( )
25+ {
26+ continue ;
27+ }
28+ // NOTE: doesn't use `for_each_relevant_impl` to avoid looking at anything besides blanket impls
29+ let trait_impls = cx. tcx . trait_impls_of ( trait_def_id) ;
30+ ' blanket_impls: for & impl_def_id in trait_impls. blanket_impls ( ) {
31+ trace ! (
32+ "get_blanket_impls: Considering impl for trait '{:?}' {:?}" ,
33+ trait_def_id,
34+ impl_def_id
35+ ) ;
36+ let trait_ref = cx. tcx . bound_impl_trait_ref ( impl_def_id) . unwrap ( ) ;
37+ if !matches ! ( trait_ref. 0 . self_ty( ) . kind( ) , ty:: Param ( _) ) {
2638 continue ;
2739 }
28- // NOTE: doesn't use `for_each_relevant_impl` to avoid looking at anything besides blanket impls
29- let trait_impls = cx. tcx . trait_impls_of ( trait_def_id) ;
30- ' blanket_impls: for & impl_def_id in trait_impls. blanket_impls ( ) {
31- trace ! (
32- "get_blanket_impls: Considering impl for trait '{:?}' {:?}" ,
33- trait_def_id,
34- impl_def_id
35- ) ;
36- let trait_ref = cx. tcx . bound_impl_trait_ref ( impl_def_id) . unwrap ( ) ;
37- if !matches ! ( trait_ref. 0 . self_ty( ) . kind( ) , ty:: Param ( _) ) {
38- continue ;
39- }
40- let infcx = cx. tcx . infer_ctxt ( ) . build ( ) ;
41- let substs = infcx. fresh_substs_for_item ( DUMMY_SP , item_def_id) ;
42- let impl_ty = ty. subst ( infcx. tcx , substs) ;
43- let param_env = EarlyBinder ( param_env) . subst ( infcx. tcx , substs) ;
40+ let infcx = cx. tcx . infer_ctxt ( ) . build ( ) ;
41+ let substs = infcx. fresh_substs_for_item ( DUMMY_SP , item_def_id) ;
42+ let impl_ty = ty. subst ( infcx. tcx , substs) ;
43+ let param_env = EarlyBinder ( param_env) . subst ( infcx. tcx , substs) ;
4444
45- let impl_substs = infcx. fresh_substs_for_item ( DUMMY_SP , impl_def_id) ;
46- let impl_trait_ref = trait_ref. subst ( infcx. tcx , impl_substs) ;
45+ let impl_substs = infcx. fresh_substs_for_item ( DUMMY_SP , impl_def_id) ;
46+ let impl_trait_ref = trait_ref. subst ( infcx. tcx , impl_substs) ;
4747
48- // Require the type the impl is implemented on to match
49- // our type, and ignore the impl if there was a mismatch.
50- let cause = traits:: ObligationCause :: dummy ( ) ;
51- let Ok ( eq_result) = infcx. at ( & cause, param_env) . eq ( impl_trait_ref. self_ty ( ) , impl_ty) else {
48+ // Require the type the impl is implemented on to match
49+ // our type, and ignore the impl if there was a mismatch.
50+ let cause = traits:: ObligationCause :: dummy ( ) ;
51+ let Ok ( eq_result) = infcx. at ( & cause, param_env) . eq ( impl_trait_ref. self_ty ( ) , impl_ty) else {
5252 continue
5353 } ;
54- let InferOk { value : ( ) , obligations } = eq_result;
55- // FIXME(eddyb) ignoring `obligations` might cause false positives.
56- drop ( obligations) ;
54+ let InferOk { value : ( ) , obligations } = eq_result;
55+ // FIXME(eddyb) ignoring `obligations` might cause false positives.
56+ drop ( obligations) ;
5757
58- trace ! (
59- "invoking predicate_may_hold: param_env={:?}, impl_trait_ref={:?}, impl_ty={:?}" ,
58+ trace ! (
59+ "invoking predicate_may_hold: param_env={:?}, impl_trait_ref={:?}, impl_ty={:?}" ,
60+ param_env,
61+ impl_trait_ref,
62+ impl_ty
63+ ) ;
64+ let predicates = cx
65+ . tcx
66+ . predicates_of ( impl_def_id)
67+ . instantiate ( cx. tcx , impl_substs)
68+ . predicates
69+ . into_iter ( )
70+ . chain ( Some (
71+ ty:: Binder :: dummy ( impl_trait_ref)
72+ . to_poly_trait_predicate ( )
73+ . map_bound ( ty:: PredicateKind :: Trait )
74+ . to_predicate ( infcx. tcx ) ,
75+ ) ) ;
76+ for predicate in predicates {
77+ debug ! ( "testing predicate {:?}" , predicate) ;
78+ let obligation = traits:: Obligation :: new (
79+ traits:: ObligationCause :: dummy ( ) ,
6080 param_env,
61- impl_trait_ref,
62- impl_ty
81+ predicate,
6382 ) ;
64- let predicates = cx
65- . tcx
66- . predicates_of ( impl_def_id)
67- . instantiate ( cx. tcx , impl_substs)
68- . predicates
69- . into_iter ( )
70- . chain ( Some (
71- ty:: Binder :: dummy ( impl_trait_ref)
72- . to_poly_trait_predicate ( )
73- . map_bound ( ty:: PredicateKind :: Trait )
74- . to_predicate ( infcx. tcx ) ,
75- ) ) ;
76- for predicate in predicates {
77- debug ! ( "testing predicate {:?}" , predicate) ;
78- let obligation = traits:: Obligation :: new (
79- traits:: ObligationCause :: dummy ( ) ,
80- param_env,
81- predicate,
82- ) ;
83- match infcx. evaluate_obligation ( & obligation) {
84- Ok ( eval_result) if eval_result. may_apply ( ) => { }
85- Err ( traits:: OverflowError :: Canonical ) => { }
86- Err ( traits:: OverflowError :: ErrorReporting ) => { }
87- _ => continue ' blanket_impls,
88- }
83+ match infcx. evaluate_obligation ( & obligation) {
84+ Ok ( eval_result) if eval_result. may_apply ( ) => { }
85+ Err ( traits:: OverflowError :: Canonical ) => { }
86+ Err ( traits:: OverflowError :: ErrorReporting ) => { }
87+ _ => continue ' blanket_impls,
8988 }
90- debug ! (
91- "get_blanket_impls: found applicable impl for trait_ref={:?}, ty={:?}" ,
92- trait_ref, ty
93- ) ;
89+ }
90+ debug ! (
91+ "get_blanket_impls: found applicable impl for trait_ref={:?}, ty={:?}" ,
92+ trait_ref, ty
93+ ) ;
9494
95- cx. generated_synthetics . insert ( ( ty. 0 , trait_def_id) ) ;
95+ cx. generated_synthetics . insert ( ( ty. 0 , trait_def_id) ) ;
9696
97- impls. push ( Item {
98- name : None ,
99- attrs : Default :: default ( ) ,
100- visibility : Inherited ,
101- item_id : ItemId :: Blanket { impl_id : impl_def_id, for_ : item_def_id } ,
102- kind : Box :: new ( ImplItem ( Box :: new ( Impl {
103- unsafety : hir:: Unsafety :: Normal ,
104- generics : clean_ty_generics (
105- cx,
106- cx. tcx . generics_of ( impl_def_id) ,
107- cx. tcx . explicit_predicates_of ( impl_def_id) ,
108- ) ,
109- // FIXME(eddyb) compute both `trait_` and `for_` from
110- // the post-inference `trait_ref`, as it's more accurate.
111- trait_ : Some ( clean_trait_ref_with_bindings ( cx, trait_ref. 0 , ThinVec :: new ( ) ) ) ,
112- for_ : clean_middle_ty ( ty. 0 , cx, None ) ,
113- items : cx. tcx
114- . associated_items ( impl_def_id)
115- . in_definition_order ( )
116- . map ( |x| clean_middle_assoc_item ( x, cx) )
117- . collect :: < Vec < _ > > ( ) ,
118- polarity : ty:: ImplPolarity :: Positive ,
119- kind : ImplKind :: Blanket ( Box :: new ( clean_middle_ty ( trait_ref. 0 . self_ty ( ) , cx, None ) ) ) ,
120- } ) ) ) ,
121- cfg : None ,
122- } ) ;
123- }
97+ impls. push ( Item {
98+ name : None ,
99+ attrs : Default :: default ( ) ,
100+ visibility : Inherited ,
101+ item_id : ItemId :: Blanket { impl_id : impl_def_id, for_ : item_def_id } ,
102+ kind : Box :: new ( ImplItem ( Box :: new ( Impl {
103+ unsafety : hir:: Unsafety :: Normal ,
104+ generics : clean_ty_generics (
105+ cx,
106+ cx. tcx . generics_of ( impl_def_id) ,
107+ cx. tcx . explicit_predicates_of ( impl_def_id) ,
108+ ) ,
109+ // FIXME(eddyb) compute both `trait_` and `for_` from
110+ // the post-inference `trait_ref`, as it's more accurate.
111+ trait_ : Some ( clean_trait_ref_with_bindings (
112+ cx,
113+ trait_ref. 0 ,
114+ ThinVec :: new ( ) ,
115+ ) ) ,
116+ for_ : clean_middle_ty ( ty. 0 , cx, None ) ,
117+ items : cx
118+ . tcx
119+ . associated_items ( impl_def_id)
120+ . in_definition_order ( )
121+ . map ( |x| clean_middle_assoc_item ( x, cx) )
122+ . collect :: < Vec < _ > > ( ) ,
123+ polarity : ty:: ImplPolarity :: Positive ,
124+ kind : ImplKind :: Blanket ( Box :: new ( clean_middle_ty (
125+ trait_ref. 0 . self_ty ( ) ,
126+ cx,
127+ None ,
128+ ) ) ) ,
129+ } ) ) ) ,
130+ cfg : None ,
131+ } ) ;
124132 }
125- } ) ;
133+ }
126134
127135 impls
128136 }
0 commit comments