@@ -16,6 +16,7 @@ use super::MethodIndex;
16
16
use super :: NoMatch ;
17
17
use super :: TraitSource ;
18
18
19
+ use middle:: fast_reject;
19
20
use middle:: subst;
20
21
use middle:: subst:: Subst ;
21
22
use middle:: traits;
@@ -36,6 +37,7 @@ struct ProbeContext<'a, 'tcx:'a> {
36
37
span : Span ,
37
38
method_name : ast:: Name ,
38
39
steps : Rc < Vec < CandidateStep > > ,
40
+ opt_simplified_steps : Option < Vec < fast_reject:: SimplifiedType > > ,
39
41
inherent_candidates : Vec < Candidate > ,
40
42
extension_candidates : Vec < Candidate > ,
41
43
impl_dups : HashSet < ast:: DefId > ,
@@ -44,7 +46,7 @@ struct ProbeContext<'a, 'tcx:'a> {
44
46
45
47
struct CandidateStep {
46
48
self_ty : ty:: t ,
47
- adjustment : PickAdjustment
49
+ adjustment : PickAdjustment ,
48
50
}
49
51
50
52
struct Candidate {
@@ -123,16 +125,31 @@ pub fn probe(fcx: &FnCtxt,
123
125
// take place in the `fcx.infcx().probe` below.
124
126
let steps = create_steps ( fcx, span, self_ty) ;
125
127
128
+ // Create a list of simplified self types, if we can.
129
+ let mut simplified_steps = Vec :: new ( ) ;
130
+ for step in steps. iter ( ) {
131
+ match fast_reject:: simplify_type ( fcx. tcx ( ) , step. self_ty , true ) {
132
+ None => { break ; }
133
+ Some ( simplified_type) => { simplified_steps. push ( simplified_type) ; }
134
+ }
135
+ }
136
+ let opt_simplified_steps =
137
+ if simplified_steps. len ( ) < steps. len ( ) {
138
+ None // failed to convert at least one of the steps
139
+ } else {
140
+ Some ( simplified_steps)
141
+ } ;
142
+
126
143
debug ! ( "ProbeContext: steps for self_ty={} are {}" ,
127
144
self_ty. repr( fcx. tcx( ) ) ,
128
145
steps. repr( fcx. tcx( ) ) ) ;
129
146
130
147
// this creates one big transaction so that all type variables etc
131
148
// that we create during the probe process are removed later
132
- let mut steps = Some ( steps) ; // FIXME(#18101) need once closures
149
+ let mut dummy = Some ( ( steps, opt_simplified_steps ) ) ; // FIXME(#18101) need once closures
133
150
fcx. infcx ( ) . probe ( || {
134
- let steps = steps . take ( ) . unwrap ( ) ;
135
- let mut probe_cx = ProbeContext :: new ( fcx, span, method_name, steps) ;
151
+ let ( steps, opt_simplified_steps ) = dummy . take ( ) . unwrap ( ) ;
152
+ let mut probe_cx = ProbeContext :: new ( fcx, span, method_name, steps, opt_simplified_steps ) ;
136
153
probe_cx. assemble_inherent_candidates ( ) ;
137
154
probe_cx. assemble_extension_candidates_for_traits_in_scope ( call_expr_id) ;
138
155
probe_cx. pick ( )
@@ -177,7 +194,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
177
194
fn new ( fcx : & ' a FnCtxt < ' a , ' tcx > ,
178
195
span : Span ,
179
196
method_name : ast:: Name ,
180
- steps : Vec < CandidateStep > )
197
+ steps : Vec < CandidateStep > ,
198
+ opt_simplified_steps : Option < Vec < fast_reject:: SimplifiedType > > )
181
199
-> ProbeContext < ' a , ' tcx >
182
200
{
183
201
ProbeContext {
@@ -188,6 +206,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
188
206
extension_candidates : Vec :: new ( ) ,
189
207
impl_dups : HashSet :: new ( ) ,
190
208
steps : Rc :: new ( steps) ,
209
+ opt_simplified_steps : opt_simplified_steps,
191
210
static_candidates : Vec :: new ( ) ,
192
211
}
193
212
}
@@ -473,6 +492,10 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
473
492
trait_def_id. repr( self . tcx( ) ) ,
474
493
impl_def_id. repr( self . tcx( ) ) ) ;
475
494
495
+ if !self . impl_can_possibly_match ( impl_def_id) {
496
+ continue ;
497
+ }
498
+
476
499
let impl_pty = check:: impl_self_ty ( self . fcx , self . span , impl_def_id) ;
477
500
let impl_substs = impl_pty. substs ;
478
501
@@ -499,6 +522,22 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
499
522
}
500
523
}
501
524
525
+ fn impl_can_possibly_match ( & self , impl_def_id : ast:: DefId ) -> bool {
526
+ let simplified_steps = match self . opt_simplified_steps {
527
+ Some ( ref simplified_steps) => simplified_steps,
528
+ None => { return true ; }
529
+ } ;
530
+
531
+ let impl_type = ty:: lookup_item_type ( self . tcx ( ) , impl_def_id) ;
532
+ let impl_simplified_type =
533
+ match fast_reject:: simplify_type ( self . tcx ( ) , impl_type. ty , false ) {
534
+ Some ( simplified_type) => simplified_type,
535
+ None => { return true ; }
536
+ } ;
537
+
538
+ simplified_steps. contains ( & impl_simplified_type)
539
+ }
540
+
502
541
fn assemble_unboxed_closure_candidates ( & mut self ,
503
542
trait_def_id : ast:: DefId ,
504
543
method_ty : Rc < ty:: Method > ,
0 commit comments