@@ -140,7 +140,24 @@ struct lookup {
140
140
immutable_reference_mode, mutable_reference_mode] ;
141
141
142
142
loop {
143
- self . add_candidates_from_type ( ) ;
143
+ // Try to find a method that is keyed directly off of the
144
+ // type. This only happens for boxed traits, type params,
145
+ // classes, and self. If we see some sort of pointer, then
146
+ // we look at candidates for the pointed to type to match
147
+ // them against methods that take explicit self parameters.
148
+ // N.B.: this looking through boxes to match against
149
+ // explicit self parameters is *not* the same as
150
+ // autoderef.
151
+ // Try each of the possible matching semantics in turn.
152
+ for matching_modes. each |mode| {
153
+ match ty:: get ( self . self_ty ) . struct {
154
+ ty:: ty_box( mt) | ty:: ty_uniq( mt) | ty:: ty_rptr( _, mt) => {
155
+ self . add_candidates_from_type ( mt. ty , mode) ;
156
+ }
157
+ _ => { self . add_candidates_from_type ( self . self_ty , mode) ; }
158
+ }
159
+ if self . candidates . len ( ) > 0 u { break ; }
160
+ }
144
161
145
162
// if we found anything, stop now. otherwise continue to
146
163
// loop for impls in scope. Note: I don't love these
@@ -235,18 +252,17 @@ struct lookup {
235
252
ty:: item_path_str( self . tcx( ) , did) ) ) ;
236
253
}
237
254
238
- fn add_candidates_from_type ( ) {
239
- match ty:: get ( self . self_ty ) . struct {
255
+ fn add_candidates_from_type ( inner_ty : ty :: t , mode : method_lookup_mode ) {
256
+ match ty:: get ( inner_ty ) . struct {
240
257
// First, see whether this is a bounded parameter.
241
258
ty:: ty_param( p) => {
242
- self . add_candidates_from_param ( p. idx , p. def_id ) ;
259
+ self . add_candidates_from_param ( inner_ty , mode , p. idx , p. def_id ) ;
243
260
}
244
-
245
261
ty:: ty_trait( did, substs, _) => {
246
- self . add_candidates_from_trait ( did, substs) ;
262
+ self . add_candidates_from_trait ( inner_ty , mode , did, substs) ;
247
263
}
248
264
ty:: ty_class( did, substs) => {
249
- self . add_candidates_from_class ( did, substs) ;
265
+ self . add_candidates_from_class ( inner_ty , mode , did, substs) ;
250
266
}
251
267
ty:: ty_self => {
252
268
// Call is of the form "self.foo()" and appears in one
@@ -260,13 +276,15 @@ struct lookup {
260
276
tps : ~[ ] ,
261
277
} ;
262
278
263
- self . add_candidates_from_trait ( self_def_id, substs) ;
279
+ self . add_candidates_from_trait ( inner_ty, mode,
280
+ self_def_id, substs) ;
264
281
}
265
282
_ => ( )
266
283
}
267
284
}
268
285
269
- fn add_candidates_from_param ( n : uint , did : ast:: def_id ) {
286
+ fn add_candidates_from_param ( inner_ty : ty:: t , mode : method_lookup_mode ,
287
+ n : uint , did : ast:: def_id ) {
270
288
debug ! ( "add_candidates_from_param" ) ;
271
289
272
290
let tcx = self . tcx ( ) ;
@@ -304,6 +322,8 @@ struct lookup {
304
322
with bound_substs} ;
305
323
306
324
self . add_candidates_from_m (
325
+ inner_ty,
326
+ mode,
307
327
substs, trt_methods[ pos] ,
308
328
method_param ( { trait_id: trait_id,
309
329
method_num: pos,
@@ -315,7 +335,10 @@ struct lookup {
315
335
316
336
}
317
337
318
- fn add_candidates_from_trait ( did : ast:: def_id , trait_substs : ty:: substs ) {
338
+ fn add_candidates_from_trait ( inner_ty : ty:: t ,
339
+ mode : method_lookup_mode ,
340
+ did : ast:: def_id ,
341
+ trait_substs : ty:: substs ) {
319
342
320
343
debug ! ( "add_candidates_from_trait" ) ;
321
344
@@ -346,11 +369,14 @@ struct lookup {
346
369
with trait_substs} ;
347
370
348
371
self . add_candidates_from_m (
349
- substs, m, method_trait ( did, i) ) ;
372
+ inner_ty , mode , substs, m, method_trait ( did, i) ) ;
350
373
}
351
374
}
352
375
353
- fn add_candidates_from_class ( did : ast:: def_id , class_substs : ty:: substs ) {
376
+ fn add_candidates_from_class ( inner_ty : ty:: t ,
377
+ mode : method_lookup_mode ,
378
+ did : ast:: def_id ,
379
+ class_substs : ty:: substs ) {
354
380
355
381
debug ! ( "add_candidates_from_class" ) ;
356
382
@@ -371,7 +397,7 @@ struct lookup {
371
397
self . tcx ( ) , did, self . m_name , self . expr . span ) ;
372
398
373
399
self . add_candidates_from_m (
374
- class_substs, m, method_static ( m_declared) ) ;
400
+ inner_ty , mode , class_substs, m, method_static ( m_declared) ) ;
375
401
}
376
402
}
377
403
@@ -488,11 +514,42 @@ struct lookup {
488
514
return added_any;
489
515
}
490
516
491
- fn add_candidates_from_m ( self_substs : ty:: substs ,
517
+ fn add_candidates_from_m ( inner_ty : ty:: t ,
518
+ mode : method_lookup_mode ,
519
+ self_substs : ty:: substs ,
492
520
m : ty:: method ,
493
521
origin : method_origin ) {
494
522
let tcx = self . fcx . ccx . tcx ;
495
523
524
+ // If we don't have a self region but have an region pointer
525
+ // explicit self, we need to make up a new region.
526
+ let self_r = match self_substs. self_r {
527
+ none => {
528
+ match m. self_ty {
529
+ ast:: sty_region( _) =>
530
+ some ( self . fcx . infcx . next_region_var (
531
+ self . self_expr . span ,
532
+ self . self_expr . id ) ) ,
533
+ _ => none
534
+ }
535
+ }
536
+ some( _) => self_substs. self_r
537
+ } ;
538
+ let self_substs = { self_r: self_r with self_substs} ;
539
+
540
+ // Before we can be sure we succeeded we need to match the
541
+ // self type against the impl type that we get when we apply
542
+ // the explicit self parameter to whatever inner type we are
543
+ // looking at (which may be something that the self_type
544
+ // points to).
545
+ let impl_ty = transform_self_type_for_method (
546
+ self . tcx ( ) , self_substs. self_r ,
547
+ inner_ty, m. self_ty ) ;
548
+
549
+ let matches = self . check_type_match ( impl_ty, mode) ;
550
+ debug ! ( "matches = %?" , matches) ;
551
+ if matches. is_err ( ) { return ; }
552
+
496
553
// a bit hokey, but the method unbound has a bare protocol, whereas
497
554
// a.b has a protocol like fn@() (perhaps eventually fn&()):
498
555
let fty = ty:: mk_fn ( tcx, { proto: ty:: proto_vstore ( ty:: vstore_box)
@@ -507,7 +564,7 @@ struct lookup {
507
564
entry : { derefs : self . derefs ,
508
565
self_mode : get_mode_from_self_type ( m. self_ty ) ,
509
566
origin : origin} ,
510
- mode: subtyping_mode } ) ;
567
+ mode: mode } ) ;
511
568
}
512
569
513
570
fn add_inherent_and_extension_candidates ( optional_inherent_methods :
0 commit comments