22//! For details about how this works in rustc, see the method lookup page in the
33//! [rustc guide](https://rust-lang.github.io/rustc-guide/method-lookup.html)
44//! 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 } ;
66
77use arrayvec:: ArrayVec ;
88use base_db:: { CrateId , Edition } ;
@@ -435,8 +435,11 @@ pub fn iterate_method_candidates<T>(
435435 mode,
436436 & mut |ty, item| {
437437 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 ( ( ) )
440443 } ,
441444 ) ;
442445 slot
@@ -451,8 +454,8 @@ pub fn iterate_method_candidates_dyn(
451454 visible_from_module : Option < ModuleId > ,
452455 name : Option < & Name > ,
453456 mode : LookupMode ,
454- callback : & mut dyn FnMut ( & Ty , AssocItemId ) -> bool ,
455- ) -> bool {
457+ callback : & mut dyn FnMut ( & Ty , AssocItemId ) -> ControlFlow < ( ) > ,
458+ ) -> ControlFlow < ( ) > {
456459 match mode {
457460 LookupMode :: MethodCall => {
458461 // For method calls, rust first does any number of autoderef, and then one
@@ -480,7 +483,7 @@ pub fn iterate_method_candidates_dyn(
480483
481484 let deref_chain = autoderef_method_receiver ( db, krate, ty) ;
482485 for i in 0 ..deref_chain. len ( ) {
483- if iterate_method_candidates_with_autoref (
486+ iterate_method_candidates_with_autoref (
484487 & deref_chain[ i..] ,
485488 db,
486489 env. clone ( ) ,
@@ -489,11 +492,9 @@ pub fn iterate_method_candidates_dyn(
489492 visible_from_module,
490493 name,
491494 callback,
492- ) {
493- return true ;
494- }
495+ ) ?;
495496 }
496- false
497+ ControlFlow :: Continue ( ( ) )
497498 }
498499 LookupMode :: Path => {
499500 // No autoderef for path lookups
@@ -519,9 +520,9 @@ fn iterate_method_candidates_with_autoref(
519520 traits_in_scope : & FxHashSet < TraitId > ,
520521 visible_from_module : Option < ModuleId > ,
521522 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 (
525526 & deref_chain[ 0 ] ,
526527 & deref_chain[ 1 ..] ,
527528 db,
@@ -531,15 +532,15 @@ fn iterate_method_candidates_with_autoref(
531532 visible_from_module,
532533 name,
533534 & mut callback,
534- ) {
535- return true ;
536- }
535+ ) ?;
536+
537537 let refed = Canonical {
538538 binders : deref_chain[ 0 ] . binders . clone ( ) ,
539539 value : TyKind :: Ref ( Mutability :: Not , static_lifetime ( ) , deref_chain[ 0 ] . value . clone ( ) )
540540 . intern ( & Interner ) ,
541541 } ;
542- if iterate_method_candidates_by_receiver (
542+
543+ iterate_method_candidates_by_receiver (
543544 & refed,
544545 deref_chain,
545546 db,
@@ -549,15 +550,15 @@ fn iterate_method_candidates_with_autoref(
549550 visible_from_module,
550551 name,
551552 & mut callback,
552- ) {
553- return true ;
554- }
553+ ) ?;
554+
555555 let ref_muted = Canonical {
556556 binders : deref_chain[ 0 ] . binders . clone ( ) ,
557557 value : TyKind :: Ref ( Mutability :: Mut , static_lifetime ( ) , deref_chain[ 0 ] . value . clone ( ) )
558558 . intern ( & Interner ) ,
559559 } ;
560- if iterate_method_candidates_by_receiver (
560+
561+ iterate_method_candidates_by_receiver (
561562 & ref_muted,
562563 deref_chain,
563564 db,
@@ -567,10 +568,7 @@ fn iterate_method_candidates_with_autoref(
567568 visible_from_module,
568569 name,
569570 & mut callback,
570- ) {
571- return true ;
572- }
573- false
571+ )
574572}
575573
576574fn iterate_method_candidates_by_receiver (
@@ -582,13 +580,13 @@ fn iterate_method_candidates_by_receiver(
582580 traits_in_scope : & FxHashSet < TraitId > ,
583581 visible_from_module : Option < ModuleId > ,
584582 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 < ( ) > {
587585 // We're looking for methods with *receiver* type receiver_ty. These could
588586 // be found in any of the derefs of receiver_ty, so we have to go through
589587 // that.
590588 for self_ty in std:: iter:: once ( receiver_ty) . chain ( rest_of_deref_chain) {
591- if iterate_inherent_methods (
589+ iterate_inherent_methods (
592590 self_ty,
593591 db,
594592 env. clone ( ) ,
@@ -597,12 +595,11 @@ fn iterate_method_candidates_by_receiver(
597595 krate,
598596 visible_from_module,
599597 & mut callback,
600- ) {
601- return true ;
602- }
598+ ) ?
603599 }
600+
604601 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 (
606603 self_ty,
607604 db,
608605 env. clone ( ) ,
@@ -611,11 +608,10 @@ fn iterate_method_candidates_by_receiver(
611608 name,
612609 Some ( receiver_ty) ,
613610 & mut callback,
614- ) {
615- return true ;
616- }
611+ ) ?
617612 }
618- false
613+
614+ ControlFlow :: Continue ( ( ) )
619615}
620616
621617fn iterate_method_candidates_for_self_ty (
@@ -626,9 +622,9 @@ fn iterate_method_candidates_for_self_ty(
626622 traits_in_scope : & FxHashSet < TraitId > ,
627623 visible_from_module : Option < ModuleId > ,
628624 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 (
632628 self_ty,
633629 db,
634630 env. clone ( ) ,
@@ -637,9 +633,7 @@ fn iterate_method_candidates_for_self_ty(
637633 krate,
638634 visible_from_module,
639635 & mut callback,
640- ) {
641- return true ;
642- }
636+ ) ?;
643637 iterate_trait_method_candidates ( self_ty, db, env, krate, traits_in_scope, name, None , callback)
644638}
645639
@@ -651,22 +645,24 @@ fn iterate_trait_method_candidates(
651645 traits_in_scope : & FxHashSet < TraitId > ,
652646 name : Option < & Name > ,
653647 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 < ( ) > {
656650 let receiver_is_array = matches ! ( self_ty. value. kind( & Interner ) , chalk_ir:: TyKind :: Array ( ..) ) ;
657651 // if ty is `dyn Trait`, the trait doesn't need to be in scope
658652 let inherent_trait =
659653 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 ( ) ,
667662 } ;
668663 let traits =
669664 inherent_trait. chain ( env_traits. into_iter ( ) ) . chain ( traits_in_scope. iter ( ) . copied ( ) ) ;
665+
670666 ' traits: for t in traits {
671667 let data = db. trait_data ( t) ;
672668
@@ -701,12 +697,10 @@ fn iterate_trait_method_candidates(
701697 }
702698 known_implemented = true ;
703699 // 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) ?
707701 }
708702 }
709- false
703+ ControlFlow :: Continue ( ( ) )
710704}
711705
712706fn filter_inherent_impls_for_self_ty < ' i > (
@@ -744,12 +738,13 @@ fn iterate_inherent_methods(
744738 receiver_ty : Option < & Canonical < Ty > > ,
745739 krate : CrateId ,
746740 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 < ( ) > {
749743 let def_crates = match def_crates ( db, & self_ty. value , krate) {
750744 Some ( k) => k,
751- None => return false ,
745+ None => return ControlFlow :: Continue ( ( ) ) ,
752746 } ;
747+
753748 for krate in def_crates {
754749 let impls = db. inherent_impls_in_crate ( krate) ;
755750
@@ -779,13 +774,11 @@ fn iterate_inherent_methods(
779774 continue ;
780775 }
781776 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) ?;
785778 }
786779 }
787780 }
788- false
781+ ControlFlow :: Continue ( ( ) )
789782}
790783
791784/// Returns the self type for the index trait call.
0 commit comments