@@ -13,116 +13,124 @@ pub(crate) struct BlanketImplFinder<'a, 'tcx> {
13
13
14
14
impl < ' a , ' tcx > BlanketImplFinder < ' a , ' tcx > {
15
15
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) ;
18
19
19
20
trace ! ( "get_blanket_impls({:?})" , ty) ;
20
21
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 ( _) ) {
26
38
continue ;
27
39
}
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) ;
44
44
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) ;
47
47
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 {
52
52
continue
53
53
} ;
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) ;
57
57
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 ( ) ,
60
80
param_env,
61
- impl_trait_ref,
62
- impl_ty
81
+ predicate,
63
82
) ;
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,
89
88
}
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
+ ) ;
94
94
95
- cx. generated_synthetics . insert ( ( ty. 0 , trait_def_id) ) ;
95
+ cx. generated_synthetics . insert ( ( ty. 0 , trait_def_id) ) ;
96
96
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
+ } ) ;
124
132
}
125
- } ) ;
133
+ }
126
134
127
135
impls
128
136
}
0 commit comments