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