@@ -135,74 +135,26 @@ struct lookup {
135
135
}
136
136
}
137
137
138
- loop {
139
- match ty:: get ( self . self_ty ) . struct {
140
- // First, see whether this is a bounded parameter.
141
- ty:: ty_param( p) => {
142
- self . add_candidates_from_param ( p. idx , p. def_id ) ;
143
- }
138
+ let matching_modes =
139
+ [ subtyping_mode, assignability_mode,
140
+ immutable_reference_mode, mutable_reference_mode] ;
144
141
145
- ty:: ty_trait( did, substs, _) => {
146
- self . add_candidates_from_trait ( did, substs) ;
147
- }
148
- ty:: ty_class( did, substs) => {
149
- self . add_candidates_from_class ( did, substs) ;
150
- }
151
- ty:: ty_self => {
152
- // Call is of the form "self.foo()" and appears in one
153
- // of a trait's provided methods.
154
- let self_def_id = self . fcx . self_impl_def_id . expect (
155
- ~"unexpected `none` for self_impl_def_id ") ;
156
-
157
- let substs = {
158
- self_r : none,
159
- self_ty : none,
160
- tps : ~[ ] ,
161
- } ;
162
-
163
- self . add_candidates_from_trait ( self_def_id, substs) ;
164
- }
165
- _ => ( )
166
- }
142
+ loop {
143
+ self . add_candidates_from_type ( ) ;
167
144
168
145
// if we found anything, stop now. otherwise continue to
169
146
// loop for impls in scope. Note: I don't love these
170
147
// semantics, but that's what we had so I am preserving
171
148
// it.
172
149
if self . candidates . len ( ) > 0 u { break ; }
173
150
174
- // Look for inherent and extension methods, using subtyping.
175
- self . add_inherent_and_extension_candidates
176
- ( optional_inherent_methods, subtyping_mode) ;
177
-
178
- // if we found anything, stop before trying borrows
179
- if self . candidates . len ( ) > 0 u {
180
- debug ! ( "(checking method) found at least one inherent \
181
- method; giving up looking now") ;
182
- break ;
151
+ // Try each of the possible matching semantics in turn.
152
+ for matching_modes. each |mode| {
153
+ self . add_inherent_and_extension_candidates (
154
+ optional_inherent_methods, mode) ;
155
+ // If we find anything, stop.
156
+ if self . candidates . len ( ) > 0 u { break ; }
183
157
}
184
-
185
- // Again, look for inherent and extension methods, this time using
186
- // assignability.
187
- self . add_inherent_and_extension_candidates
188
- ( optional_inherent_methods, assignability_mode) ;
189
-
190
- // If we found anything, stop before trying auto-ref.
191
- if self . candidates . len ( ) > 0 u { break ; }
192
-
193
- // Now look for inherent and extension methods, this time using an
194
- // immutable reference.
195
- self . add_inherent_and_extension_candidates
196
- ( optional_inherent_methods, immutable_reference_mode) ;
197
-
198
- // if we found anything, stop before attempting mutable auto-ref.
199
- if self . candidates . len ( ) > 0 u { break ; }
200
-
201
- // Now look for inherent and extension methods, this time using a
202
- // mutable reference.
203
- self . add_inherent_and_extension_candidates
204
- ( optional_inherent_methods, mutable_reference_mode) ;
205
-
206
158
// if we found anything, stop before attempting auto-deref.
207
159
if self . candidates . len ( ) > 0 u {
208
160
debug ! ( "(checking method) found at least one inherent \
@@ -283,6 +235,37 @@ struct lookup {
283
235
ty:: item_path_str( self . tcx( ) , did) ) ) ;
284
236
}
285
237
238
+ fn add_candidates_from_type ( ) {
239
+ match ty:: get ( self . self_ty ) . struct {
240
+ // First, see whether this is a bounded parameter.
241
+ ty:: ty_param( p) => {
242
+ self . add_candidates_from_param ( p. idx , p. def_id ) ;
243
+ }
244
+
245
+ ty:: ty_trait( did, substs, _) => {
246
+ self . add_candidates_from_trait ( did, substs) ;
247
+ }
248
+ ty:: ty_class( did, substs) => {
249
+ self . add_candidates_from_class ( did, substs) ;
250
+ }
251
+ ty:: ty_self => {
252
+ // Call is of the form "self.foo()" and appears in one
253
+ // of a trait's provided methods.
254
+ let self_def_id = self . fcx . self_impl_def_id . expect (
255
+ ~"unexpected `none` for self_impl_def_id ") ;
256
+
257
+ let substs = {
258
+ self_r : none,
259
+ self_ty : none,
260
+ tps : ~[ ] ,
261
+ } ;
262
+
263
+ self . add_candidates_from_trait ( self_def_id, substs) ;
264
+ }
265
+ _ => ( )
266
+ }
267
+ }
268
+
286
269
fn add_candidates_from_param ( n : uint , did : ast:: def_id ) {
287
270
debug ! ( "add_candidates_from_param" ) ;
288
271
@@ -420,6 +403,43 @@ struct lookup {
420
403
*/
421
404
}
422
405
406
+ fn check_type_match ( impl_ty : ty:: t ,
407
+ mode : method_lookup_mode )
408
+ -> result < ( ) , ty:: type_err > {
409
+ // Depending on our argument, we find potential matches by
410
+ // checking subtypability, type assignability, or reference
411
+ // subtypability. Collect the matches.
412
+ let matches;
413
+ match mode {
414
+ subtyping_mode => {
415
+ matches = self . fcx . can_mk_subty ( self . self_ty , impl_ty) ;
416
+ }
417
+ assignability_mode => {
418
+ matches = self . fcx . can_mk_assignty ( self . self_expr ,
419
+ self . borrow_lb ,
420
+ self . self_ty ,
421
+ impl_ty) ;
422
+ }
423
+ immutable_reference_mode => {
424
+ let region = self . fcx . infcx . next_region_var (
425
+ self . self_expr . span ,
426
+ self . self_expr . id ) ;
427
+ let tm = { ty: self . self_ty , mutbl: ast:: m_imm } ;
428
+ let ref_ty = ty:: mk_rptr ( self . tcx ( ) , region, tm) ;
429
+ matches = self . fcx . can_mk_subty ( ref_ty, impl_ty) ;
430
+ }
431
+ mutable_reference_mode => {
432
+ let region = self . fcx . infcx . next_region_var (
433
+ self . self_expr . span ,
434
+ self . self_expr . id ) ;
435
+ let tm = { ty: self . self_ty , mutbl: ast:: m_mutbl } ;
436
+ let ref_ty = ty:: mk_rptr ( self . tcx ( ) , region, tm) ;
437
+ matches = self . fcx . can_mk_subty ( ref_ty, impl_ty) ;
438
+ }
439
+ }
440
+ matches
441
+ }
442
+
423
443
// Returns true if any were added and false otherwise.
424
444
fn add_candidates_from_impl ( im : @resolve3:: Impl , mode : method_lookup_mode )
425
445
-> bool {
@@ -440,35 +460,7 @@ struct lookup {
440
460
self . tcx ( ) , impl_substs. self_r ,
441
461
impl_ty, m. self_type ) ;
442
462
443
- // Depending on our argument, we find potential matches by
444
- // checking subtypability, type assignability, or reference
445
- // subtypability. Collect the matches.
446
- let matches;
447
- match mode {
448
- subtyping_mode =>
449
- matches = self . fcx . can_mk_subty ( self . self_ty , impl_ty) ,
450
- assignability_mode =>
451
- matches = self . fcx . can_mk_assignty ( self . self_expr ,
452
- self . borrow_lb ,
453
- self . self_ty ,
454
- impl_ty) ,
455
- immutable_reference_mode => {
456
- let region = self . fcx . infcx . next_region_var (
457
- self . self_expr . span ,
458
- self . self_expr . id ) ;
459
- let tm = { ty: self . self_ty , mutbl: ast:: m_imm } ;
460
- let ref_ty = ty:: mk_rptr ( self . tcx ( ) , region, tm) ;
461
- matches = self . fcx . can_mk_subty ( ref_ty, impl_ty) ;
462
- }
463
- mutable_reference_mode => {
464
- let region = self . fcx . infcx . next_region_var (
465
- self . self_expr . span ,
466
- self . self_expr . id ) ;
467
- let tm = { ty: self . self_ty , mutbl: ast:: m_mutbl } ;
468
- let ref_ty = ty:: mk_rptr ( self . tcx ( ) , region, tm) ;
469
- matches = self . fcx . can_mk_subty ( ref_ty, impl_ty) ;
470
- }
471
- }
463
+ let matches = self . check_type_match ( impl_ty, mode) ;
472
464
debug ! ( "matches = %?" , matches) ;
473
465
match matches {
474
466
result:: err( _) => { /* keep looking */ }
0 commit comments