@@ -37,6 +37,22 @@ pub enum LookingFor<'tcx> {
37
37
ReturnType ( Ty < ' tcx > ) ,
38
38
}
39
39
40
+ impl < ' tcx > LookingFor < ' tcx > {
41
+ pub fn is_method_name ( & self ) -> bool {
42
+ match * self {
43
+ LookingFor :: MethodName ( _) => true ,
44
+ _ => false ,
45
+ }
46
+ }
47
+
48
+ pub fn is_return_type ( & self ) -> bool {
49
+ match * self {
50
+ LookingFor :: ReturnType ( _) => true ,
51
+ _ => false ,
52
+ }
53
+ }
54
+ }
55
+
40
56
struct ProbeContext < ' a , ' gcx : ' a + ' tcx , ' tcx : ' a > {
41
57
fcx : & ' a FnCtxt < ' a , ' gcx , ' tcx > ,
42
58
span : Span ,
@@ -468,44 +484,81 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
468
484
469
485
debug ! ( "assemble_inherent_impl_probe {:?}" , impl_def_id) ;
470
486
471
- let item = match self . impl_or_trait_item ( impl_def_id) {
472
- Some ( m) => m,
473
- None => {
487
+ let items = self . impl_or_trait_item ( impl_def_id) ;
488
+ if items. len ( ) < 1 {
489
+ return // No method with correct name on this impl
490
+ }
491
+
492
+ if self . looking_for . is_method_name ( ) {
493
+ let item = items[ 0 ] ;
494
+
495
+ if !self . has_applicable_self ( & item) {
496
+ // No receiver declared. Not a candidate.
497
+ return self . record_static_candidate ( ImplSource ( impl_def_id) ) ;
498
+ }
499
+
500
+ if !item. vis . is_accessible_from ( self . body_id , & self . tcx . map ) {
501
+ self . private_candidate = Some ( item. def ( ) ) ;
474
502
return ;
475
- } // No method with correct name on this impl
476
- } ;
503
+ }
477
504
478
- if !self . has_applicable_self ( & item) {
479
- // No receiver declared. Not a candidate.
480
- return self . record_static_candidate ( ImplSource ( impl_def_id) ) ;
481
- }
505
+ let ( impl_ty, impl_substs) = self . impl_ty_and_substs ( impl_def_id) ;
506
+ let impl_ty = impl_ty. subst ( self . tcx , impl_substs) ;
482
507
483
- if !item. vis . is_accessible_from ( self . body_id , & self . tcx . map ) {
484
- self . private_candidate = Some ( item. def ( ) ) ;
485
- return ;
486
- }
508
+ // Determine the receiver type that the method itself expects.
509
+ let xform_self_ty = self . xform_self_ty ( & item, impl_ty, impl_substs) ;
487
510
488
- let ( impl_ty, impl_substs) = self . impl_ty_and_substs ( impl_def_id) ;
489
- let impl_ty = impl_ty. subst ( self . tcx , impl_substs) ;
490
-
491
- // Determine the receiver type that the method itself expects.
492
- let xform_self_ty = self . xform_self_ty ( & item, impl_ty, impl_substs) ;
493
-
494
- // We can't use normalize_associated_types_in as it will pollute the
495
- // fcx's fulfillment context after this probe is over.
496
- let cause = traits:: ObligationCause :: misc ( self . span , self . body_id ) ;
497
- let mut selcx = & mut traits:: SelectionContext :: new ( self . fcx ) ;
498
- let traits:: Normalized { value : xform_self_ty, obligations } =
499
- traits:: normalize ( selcx, cause, & xform_self_ty) ;
500
- debug ! ( "assemble_inherent_impl_probe: xform_self_ty = {:?}" ,
501
- xform_self_ty) ;
502
-
503
- self . inherent_candidates . push ( Candidate {
504
- xform_self_ty : xform_self_ty,
505
- item : item,
506
- kind : InherentImplCandidate ( impl_substs, obligations) ,
507
- import_id : self . import_id ,
508
- } ) ;
511
+ // We can't use normalize_associated_types_in as it will pollute the
512
+ // fcx's fulfillment context after this probe is over.
513
+ let cause = traits:: ObligationCause :: misc ( self . span , self . body_id ) ;
514
+ let mut selcx = & mut traits:: SelectionContext :: new ( self . fcx ) ;
515
+ let traits:: Normalized { value : xform_self_ty, obligations } =
516
+ traits:: normalize ( selcx, cause, & xform_self_ty) ;
517
+ debug ! ( "assemble_inherent_impl_probe: xform_self_ty = {:?}" ,
518
+ xform_self_ty) ;
519
+
520
+ self . inherent_candidates . push ( Candidate {
521
+ xform_self_ty : xform_self_ty,
522
+ item : item,
523
+ kind : InherentImplCandidate ( impl_substs, obligations) ,
524
+ import_id : self . import_id ,
525
+ } ) ;
526
+ } else {
527
+ for item in items {
528
+ if !self . has_applicable_self ( & item) {
529
+ // No receiver declared. Not a candidate.
530
+ self . record_static_candidate ( ImplSource ( impl_def_id) ) ;
531
+ continue
532
+ }
533
+
534
+ if !item. vis . is_accessible_from ( self . body_id , & self . tcx . map ) {
535
+ self . private_candidate = Some ( item. def ( ) ) ;
536
+ continue
537
+ }
538
+
539
+ let ( impl_ty, impl_substs) = self . impl_ty_and_substs ( impl_def_id) ;
540
+ let impl_ty = impl_ty. subst ( self . tcx , impl_substs) ;
541
+
542
+ // Determine the receiver type that the method itself expects.
543
+ let xform_self_ty = self . xform_self_ty ( & item, impl_ty, impl_substs) ;
544
+
545
+ // We can't use normalize_associated_types_in as it will pollute the
546
+ // fcx's fulfillment context after this probe is over.
547
+ let cause = traits:: ObligationCause :: misc ( self . span , self . body_id ) ;
548
+ let mut selcx = & mut traits:: SelectionContext :: new ( self . fcx ) ;
549
+ let traits:: Normalized { value : xform_self_ty, obligations } =
550
+ traits:: normalize ( selcx, cause, & xform_self_ty) ;
551
+ debug ! ( "assemble_inherent_impl_probe: xform_self_ty = {:?}" ,
552
+ xform_self_ty) ;
553
+
554
+ self . inherent_candidates . push ( Candidate {
555
+ xform_self_ty : xform_self_ty,
556
+ item : item,
557
+ kind : InherentImplCandidate ( impl_substs, obligations) ,
558
+ import_id : self . import_id ,
559
+ } ) ;
560
+ }
561
+ }
509
562
}
510
563
511
564
fn assemble_inherent_candidates_from_object ( & mut self ,
@@ -598,12 +651,11 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
598
651
599
652
let tcx = self . tcx ;
600
653
for bound_trait_ref in traits:: transitive_bounds ( tcx, bounds) {
601
- let item = match self . impl_or_trait_item ( bound_trait_ref. def_id ( ) ) {
602
- Some ( v) => v,
603
- None => {
604
- continue ;
605
- }
606
- } ;
654
+ let items = self . impl_or_trait_item ( bound_trait_ref. def_id ( ) ) ;
655
+ if items. len ( ) < 1 {
656
+ continue
657
+ }
658
+ let item = items[ 0 ] ;
607
659
608
660
if !self . has_applicable_self ( & item) {
609
661
self . record_static_candidate ( TraitSource ( bound_trait_ref. def_id ( ) ) ) ;
@@ -665,12 +717,11 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
665
717
debug ! ( "assemble_extension_candidates_for_trait(trait_def_id={:?})" ,
666
718
trait_def_id) ;
667
719
668
- let item = match self . impl_or_trait_item ( trait_def_id) {
669
- Some ( i) => i,
670
- None => {
671
- return Ok ( ( ) ) ;
672
- }
673
- } ;
720
+ let items = self . impl_or_trait_item ( trait_def_id) ;
721
+ if items. len ( ) < 1 {
722
+ return Ok ( ( ) ) ;
723
+ }
724
+ let item = items[ 0 ] ;
674
725
675
726
// Check whether `trait_def_id` defines a method with suitable name:
676
727
if !self . has_applicable_self ( & item) {
@@ -1351,16 +1402,17 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
1351
1402
}
1352
1403
1353
1404
/// Find the method with the appropriate name (or return type, as the case may be).
1354
- fn impl_or_trait_item ( & self , def_id : DefId ) -> Option < ty:: AssociatedItem > {
1405
+ fn impl_or_trait_item ( & self , def_id : DefId ) -> Vec < ty:: AssociatedItem > {
1355
1406
match self . looking_for {
1356
1407
LookingFor :: MethodName ( name) => {
1357
- self . fcx . associated_item ( def_id, name)
1408
+ self . fcx . associated_item ( def_id, name) . map_or ( Vec :: new ( ) , |x| vec ! [ x ] )
1358
1409
}
1359
1410
LookingFor :: ReturnType ( return_ty) => {
1360
1411
self . tcx
1361
1412
. associated_items ( def_id)
1362
1413
. map ( |did| self . tcx . associated_item ( did. def_id ) )
1363
- . find ( |m| self . matches_return_type ( m, return_ty) )
1414
+ . filter ( |m| self . matches_return_type ( m, return_ty) )
1415
+ . collect ( )
1364
1416
}
1365
1417
}
1366
1418
}
0 commit comments