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