@@ -148,41 +148,41 @@ pub enum Mode {
148
148
}
149
149
150
150
impl < ' a , ' gcx , ' tcx > FnCtxt < ' a , ' gcx , ' tcx > {
151
- pub fn probe_return ( & self ,
152
- span : Span ,
153
- mode : Mode ,
154
- return_type : Ty < ' tcx > ,
155
- self_ty : Ty < ' tcx > ,
156
- scope_expr_id : ast:: NodeId )
157
- -> PickResult < ' tcx > {
151
+ pub fn probe_for_return_type ( & self ,
152
+ span : Span ,
153
+ mode : Mode ,
154
+ return_type : Ty < ' tcx > ,
155
+ self_ty : Ty < ' tcx > ,
156
+ scope_expr_id : ast:: NodeId )
157
+ -> PickResult < ' tcx > {
158
158
debug ! ( "probe(self_ty={:?}, return_type={}, scope_expr_id={})" ,
159
159
self_ty,
160
160
return_type,
161
161
scope_expr_id) ;
162
- self . _probe ( span, mode, LookingFor :: ReturnType ( return_type) , self_ty, scope_expr_id)
162
+ self . probe_for ( span, mode, LookingFor :: ReturnType ( return_type) , self_ty, scope_expr_id)
163
163
}
164
164
165
- pub fn probe_method ( & self ,
166
- span : Span ,
167
- mode : Mode ,
168
- item_name : ast:: Name ,
169
- self_ty : Ty < ' tcx > ,
170
- scope_expr_id : ast:: NodeId )
171
- -> PickResult < ' tcx > {
165
+ pub fn probe_for_name ( & self ,
166
+ span : Span ,
167
+ mode : Mode ,
168
+ item_name : ast:: Name ,
169
+ self_ty : Ty < ' tcx > ,
170
+ scope_expr_id : ast:: NodeId )
171
+ -> PickResult < ' tcx > {
172
172
debug ! ( "probe(self_ty={:?}, item_name={}, scope_expr_id={})" ,
173
173
self_ty,
174
174
item_name,
175
175
scope_expr_id) ;
176
- self . _probe ( span, mode, LookingFor :: MethodName ( item_name) , self_ty, scope_expr_id)
176
+ self . probe_for ( span, mode, LookingFor :: MethodName ( item_name) , self_ty, scope_expr_id)
177
177
}
178
178
179
- fn _probe ( & self ,
180
- span : Span ,
181
- mode : Mode ,
182
- looking_for : LookingFor < ' tcx > ,
183
- self_ty : Ty < ' tcx > ,
184
- scope_expr_id : ast:: NodeId )
185
- -> PickResult < ' tcx > {
179
+ fn probe_for ( & self ,
180
+ span : Span ,
181
+ mode : Mode ,
182
+ looking_for : LookingFor < ' tcx > ,
183
+ self_ty : Ty < ' tcx > ,
184
+ scope_expr_id : ast:: NodeId )
185
+ -> PickResult < ' tcx > {
186
186
187
187
// FIXME(#18741) -- right now, creating the steps involves evaluating the
188
188
// `*` operator, which registers obligations that then escape into
@@ -263,6 +263,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
263
263
264
264
let final_ty = match looking_for {
265
265
& LookingFor :: MethodName ( _) => autoderef. unambiguous_final_ty ( ) ,
266
+ // Since ReturnType case tries to coerce the returned type to the
267
+ // expected one, we need all the information!
266
268
& LookingFor :: ReturnType ( _) => self_ty,
267
269
} ;
268
270
match final_ty. sty {
@@ -636,10 +638,10 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
636
638
match * method {
637
639
ty:: ImplOrTraitItem :: MethodTraitItem ( ref x) => {
638
640
self . probe ( |_| {
639
- let output = self . replace_late_bound_regions_with_fresh_var (
640
- self . span , infer:: FnCall , & x. fty . sig . output ( ) ) ;
641
641
let substs = self . fresh_substs_for_item ( self . span , method. def_id ( ) ) ;
642
- let output = output. 0 . subst ( self . tcx , substs) ;
642
+ let output = x. fty . sig . output ( ) . subst ( self . tcx , substs) ;
643
+ let ( output, _) = self . replace_late_bound_regions_with_fresh_var (
644
+ self . span , infer:: FnCall , & output) ;
643
645
self . can_sub_types ( output, expected) . is_ok ( )
644
646
} )
645
647
}
@@ -958,10 +960,17 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
958
960
let steps = self . steps . clone ( ) ;
959
961
960
962
match self . looking_for {
961
- LookingFor :: MethodName ( _) => steps. iter ( )
962
- . filter_map ( |step| self . pick_step ( step) )
963
- . next ( ) ,
963
+ LookingFor :: MethodName ( _) => {
964
+ // find the first step that works
965
+ steps. iter ( )
966
+ . filter_map ( |step| self . pick_step ( step) )
967
+ . next ( )
968
+ }
964
969
LookingFor :: ReturnType ( _) => {
970
+ // Normally, we stop at the first step where we find a positive match.
971
+ // But when we are scanning for methods with a suitable return type,
972
+ // these methods have distinct names and hence may not shadow one another
973
+ // (also, this is just for hints, so precision is less important).
965
974
let mut ret = Vec :: new ( ) ;
966
975
967
976
for step in steps. iter ( ) {
@@ -1058,10 +1067,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
1058
1067
match self . looking_for {
1059
1068
LookingFor :: MethodName ( _) => it. nth ( 0 ) ,
1060
1069
LookingFor :: ReturnType ( _) => {
1061
- let mut ret = Vec :: new ( ) ;
1062
- it. filter_map ( |entry| entry. ok ( ) )
1063
- . map ( |mut v| { ret. append ( & mut v) ; } )
1064
- . all ( |_| true ) ;
1070
+ let ret = it. filter_map ( |entry| entry. ok ( ) )
1071
+ . flat_map ( |v| v)
1072
+ . collect :: < Vec < _ > > ( ) ;
1065
1073
1066
1074
if ret. len ( ) < 1 {
1067
1075
None
0 commit comments