2
2
//! For details about how this works in rustc, see the method lookup page in the
3
3
//! [rustc guide](https://rust-lang.github.io/rustc-guide/method-lookup.html)
4
4
//! and the corresponding code mostly in librustc_typeck/check/method/probe.rs.
5
- use std:: { iter, sync:: Arc } ;
5
+ use std:: { iter, ops :: ControlFlow , sync:: Arc } ;
6
6
7
7
use arrayvec:: ArrayVec ;
8
8
use base_db:: { CrateId , Edition } ;
@@ -435,8 +435,11 @@ pub fn iterate_method_candidates<T>(
435
435
mode,
436
436
& mut |ty, item| {
437
437
assert ! ( slot. is_none( ) ) ;
438
- slot = callback ( ty, item) ;
439
- slot. is_some ( )
438
+ if let Some ( it) = callback ( ty, item) {
439
+ slot = Some ( it) ;
440
+ return ControlFlow :: Break ( ( ) ) ;
441
+ }
442
+ ControlFlow :: Continue ( ( ) )
440
443
} ,
441
444
) ;
442
445
slot
@@ -451,8 +454,8 @@ pub fn iterate_method_candidates_dyn(
451
454
visible_from_module : Option < ModuleId > ,
452
455
name : Option < & Name > ,
453
456
mode : LookupMode ,
454
- callback : & mut dyn FnMut ( & Ty , AssocItemId ) -> bool ,
455
- ) -> bool {
457
+ callback : & mut dyn FnMut ( & Ty , AssocItemId ) -> ControlFlow < ( ) > ,
458
+ ) -> ControlFlow < ( ) > {
456
459
match mode {
457
460
LookupMode :: MethodCall => {
458
461
// For method calls, rust first does any number of autoderef, and then one
@@ -480,7 +483,7 @@ pub fn iterate_method_candidates_dyn(
480
483
481
484
let deref_chain = autoderef_method_receiver ( db, krate, ty) ;
482
485
for i in 0 ..deref_chain. len ( ) {
483
- if iterate_method_candidates_with_autoref (
486
+ iterate_method_candidates_with_autoref (
484
487
& deref_chain[ i..] ,
485
488
db,
486
489
env. clone ( ) ,
@@ -489,11 +492,9 @@ pub fn iterate_method_candidates_dyn(
489
492
visible_from_module,
490
493
name,
491
494
callback,
492
- ) {
493
- return true ;
494
- }
495
+ ) ?;
495
496
}
496
- false
497
+ ControlFlow :: Continue ( ( ) )
497
498
}
498
499
LookupMode :: Path => {
499
500
// No autoderef for path lookups
@@ -519,9 +520,9 @@ fn iterate_method_candidates_with_autoref(
519
520
traits_in_scope : & FxHashSet < TraitId > ,
520
521
visible_from_module : Option < ModuleId > ,
521
522
name : Option < & Name > ,
522
- mut callback : & mut dyn FnMut ( & Ty , AssocItemId ) -> bool ,
523
- ) -> bool {
524
- if iterate_method_candidates_by_receiver (
523
+ mut callback : & mut dyn FnMut ( & Ty , AssocItemId ) -> ControlFlow < ( ) > ,
524
+ ) -> ControlFlow < ( ) > {
525
+ iterate_method_candidates_by_receiver (
525
526
& deref_chain[ 0 ] ,
526
527
& deref_chain[ 1 ..] ,
527
528
db,
@@ -531,15 +532,15 @@ fn iterate_method_candidates_with_autoref(
531
532
visible_from_module,
532
533
name,
533
534
& mut callback,
534
- ) {
535
- return true ;
536
- }
535
+ ) ?;
536
+
537
537
let refed = Canonical {
538
538
binders : deref_chain[ 0 ] . binders . clone ( ) ,
539
539
value : TyKind :: Ref ( Mutability :: Not , static_lifetime ( ) , deref_chain[ 0 ] . value . clone ( ) )
540
540
. intern ( & Interner ) ,
541
541
} ;
542
- if iterate_method_candidates_by_receiver (
542
+
543
+ iterate_method_candidates_by_receiver (
543
544
& refed,
544
545
deref_chain,
545
546
db,
@@ -549,15 +550,15 @@ fn iterate_method_candidates_with_autoref(
549
550
visible_from_module,
550
551
name,
551
552
& mut callback,
552
- ) {
553
- return true ;
554
- }
553
+ ) ?;
554
+
555
555
let ref_muted = Canonical {
556
556
binders : deref_chain[ 0 ] . binders . clone ( ) ,
557
557
value : TyKind :: Ref ( Mutability :: Mut , static_lifetime ( ) , deref_chain[ 0 ] . value . clone ( ) )
558
558
. intern ( & Interner ) ,
559
559
} ;
560
- if iterate_method_candidates_by_receiver (
560
+
561
+ iterate_method_candidates_by_receiver (
561
562
& ref_muted,
562
563
deref_chain,
563
564
db,
@@ -567,10 +568,7 @@ fn iterate_method_candidates_with_autoref(
567
568
visible_from_module,
568
569
name,
569
570
& mut callback,
570
- ) {
571
- return true ;
572
- }
573
- false
571
+ )
574
572
}
575
573
576
574
fn iterate_method_candidates_by_receiver (
@@ -582,13 +580,13 @@ fn iterate_method_candidates_by_receiver(
582
580
traits_in_scope : & FxHashSet < TraitId > ,
583
581
visible_from_module : Option < ModuleId > ,
584
582
name : Option < & Name > ,
585
- mut callback : & mut dyn FnMut ( & Ty , AssocItemId ) -> bool ,
586
- ) -> bool {
583
+ mut callback : & mut dyn FnMut ( & Ty , AssocItemId ) -> ControlFlow < ( ) > ,
584
+ ) -> ControlFlow < ( ) > {
587
585
// We're looking for methods with *receiver* type receiver_ty. These could
588
586
// be found in any of the derefs of receiver_ty, so we have to go through
589
587
// that.
590
588
for self_ty in std:: iter:: once ( receiver_ty) . chain ( rest_of_deref_chain) {
591
- if iterate_inherent_methods (
589
+ iterate_inherent_methods (
592
590
self_ty,
593
591
db,
594
592
env. clone ( ) ,
@@ -597,12 +595,11 @@ fn iterate_method_candidates_by_receiver(
597
595
krate,
598
596
visible_from_module,
599
597
& mut callback,
600
- ) {
601
- return true ;
602
- }
598
+ ) ?
603
599
}
600
+
604
601
for self_ty in std:: iter:: once ( receiver_ty) . chain ( rest_of_deref_chain) {
605
- if iterate_trait_method_candidates (
602
+ iterate_trait_method_candidates (
606
603
self_ty,
607
604
db,
608
605
env. clone ( ) ,
@@ -611,11 +608,10 @@ fn iterate_method_candidates_by_receiver(
611
608
name,
612
609
Some ( receiver_ty) ,
613
610
& mut callback,
614
- ) {
615
- return true ;
616
- }
611
+ ) ?
617
612
}
618
- false
613
+
614
+ ControlFlow :: Continue ( ( ) )
619
615
}
620
616
621
617
fn iterate_method_candidates_for_self_ty (
@@ -626,9 +622,9 @@ fn iterate_method_candidates_for_self_ty(
626
622
traits_in_scope : & FxHashSet < TraitId > ,
627
623
visible_from_module : Option < ModuleId > ,
628
624
name : Option < & Name > ,
629
- mut callback : & mut dyn FnMut ( & Ty , AssocItemId ) -> bool ,
630
- ) -> bool {
631
- if iterate_inherent_methods (
625
+ mut callback : & mut dyn FnMut ( & Ty , AssocItemId ) -> ControlFlow < ( ) > ,
626
+ ) -> ControlFlow < ( ) > {
627
+ iterate_inherent_methods (
632
628
self_ty,
633
629
db,
634
630
env. clone ( ) ,
@@ -637,9 +633,7 @@ fn iterate_method_candidates_for_self_ty(
637
633
krate,
638
634
visible_from_module,
639
635
& mut callback,
640
- ) {
641
- return true ;
642
- }
636
+ ) ?;
643
637
iterate_trait_method_candidates ( self_ty, db, env, krate, traits_in_scope, name, None , callback)
644
638
}
645
639
@@ -651,22 +645,24 @@ fn iterate_trait_method_candidates(
651
645
traits_in_scope : & FxHashSet < TraitId > ,
652
646
name : Option < & Name > ,
653
647
receiver_ty : Option < & Canonical < Ty > > ,
654
- callback : & mut dyn FnMut ( & Ty , AssocItemId ) -> bool ,
655
- ) -> bool {
648
+ callback : & mut dyn FnMut ( & Ty , AssocItemId ) -> ControlFlow < ( ) > ,
649
+ ) -> ControlFlow < ( ) > {
656
650
let receiver_is_array = matches ! ( self_ty. value. kind( & Interner ) , chalk_ir:: TyKind :: Array ( ..) ) ;
657
651
// if ty is `dyn Trait`, the trait doesn't need to be in scope
658
652
let inherent_trait =
659
653
self_ty. value . dyn_trait ( ) . into_iter ( ) . flat_map ( |t| all_super_traits ( db. upcast ( ) , t) ) ;
660
- let env_traits = if let TyKind :: Placeholder ( _) = self_ty. value . kind ( & Interner ) {
661
- // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
662
- env. traits_in_scope_from_clauses ( & self_ty. value )
663
- . flat_map ( |t| all_super_traits ( db. upcast ( ) , t) )
664
- . collect ( )
665
- } else {
666
- Vec :: new ( )
654
+ let env_traits = match self_ty. value . kind ( & Interner ) {
655
+ TyKind :: Placeholder ( _) => {
656
+ // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
657
+ env. traits_in_scope_from_clauses ( & self_ty. value )
658
+ . flat_map ( |t| all_super_traits ( db. upcast ( ) , t) )
659
+ . collect ( )
660
+ }
661
+ _ => Vec :: new ( ) ,
667
662
} ;
668
663
let traits =
669
664
inherent_trait. chain ( env_traits. into_iter ( ) ) . chain ( traits_in_scope. iter ( ) . copied ( ) ) ;
665
+
670
666
' traits: for t in traits {
671
667
let data = db. trait_data ( t) ;
672
668
@@ -701,12 +697,10 @@ fn iterate_trait_method_candidates(
701
697
}
702
698
known_implemented = true ;
703
699
// FIXME: we shouldn't be ignoring the binders here
704
- if callback ( & self_ty. value , * item) {
705
- return true ;
706
- }
700
+ callback ( & self_ty. value , * item) ?
707
701
}
708
702
}
709
- false
703
+ ControlFlow :: Continue ( ( ) )
710
704
}
711
705
712
706
fn filter_inherent_impls_for_self_ty < ' i > (
@@ -744,12 +738,13 @@ fn iterate_inherent_methods(
744
738
receiver_ty : Option < & Canonical < Ty > > ,
745
739
krate : CrateId ,
746
740
visible_from_module : Option < ModuleId > ,
747
- callback : & mut dyn FnMut ( & Ty , AssocItemId ) -> bool ,
748
- ) -> bool {
741
+ callback : & mut dyn FnMut ( & Ty , AssocItemId ) -> ControlFlow < ( ) > ,
742
+ ) -> ControlFlow < ( ) > {
749
743
let def_crates = match def_crates ( db, & self_ty. value , krate) {
750
744
Some ( k) => k,
751
- None => return false ,
745
+ None => return ControlFlow :: Continue ( ( ) ) ,
752
746
} ;
747
+
753
748
for krate in def_crates {
754
749
let impls = db. inherent_impls_in_crate ( krate) ;
755
750
@@ -779,13 +774,11 @@ fn iterate_inherent_methods(
779
774
continue ;
780
775
}
781
776
let receiver_ty = receiver_ty. map ( |x| & x. value ) . unwrap_or ( & self_ty. value ) ;
782
- if callback ( receiver_ty, item) {
783
- return true ;
784
- }
777
+ callback ( receiver_ty, item) ?;
785
778
}
786
779
}
787
780
}
788
- false
781
+ ControlFlow :: Continue ( ( ) )
789
782
}
790
783
791
784
/// Returns the self type for the index trait call.
0 commit comments