@@ -19,118 +19,119 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
1919
2020 trace ! ( "get_blanket_impls({:?})" , ty) ;
2121 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) ;
4243
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) ;
4546
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) ;
5354
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={:?}" ,
7757 param_env,
78- predicate,
58+ trait_ref,
59+ ty
7960 ) ;
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+ }
8687 }
8788 }
89+ true
90+ } else {
91+ false
8892 }
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 ;
92100 }
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- }
101101
102- self . cx . generated_synthetics . insert ( ( ty, trait_def_id) ) ;
102+ cx. generated_synthetics . insert ( ( ty, trait_def_id) ) ;
103103
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+ }
132132 }
133- }
133+ } ) ;
134+
134135 impls
135136 }
136137}
0 commit comments