@@ -298,6 +298,7 @@ fn handle_control_flow_keywords(
298298 T ! [ for ] if token. parent ( ) . and_then ( ast:: ForExpr :: cast) . is_some ( ) => {
299299 nav_for_break_points ( sema, token)
300300 }
301+ T ! [ match ] | T ! [ =>] | T ! [ if ] => nav_for_branches ( sema, token) ,
301302 _ => None ,
302303 }
303304}
@@ -407,6 +408,64 @@ fn nav_for_exit_points(
407408 Some ( navs)
408409}
409410
411+ fn nav_for_branches (
412+ sema : & Semantics < ' _ , RootDatabase > ,
413+ token : & SyntaxToken ,
414+ ) -> Option < Vec < NavigationTarget > > {
415+ let db = sema. db ;
416+
417+ let navs = match token. kind ( ) {
418+ T ! [ match ] => sema
419+ . descend_into_macros ( token. clone ( ) )
420+ . into_iter ( )
421+ . filter_map ( |token| {
422+ let match_expr =
423+ sema. token_ancestors_with_macros ( token) . find_map ( ast:: MatchExpr :: cast) ?;
424+ let file_id = sema. hir_file_for ( match_expr. syntax ( ) ) ;
425+ let focus_range = match_expr. match_token ( ) ?. text_range ( ) ;
426+ let match_expr_in_file = InFile :: new ( file_id, match_expr. into ( ) ) ;
427+ Some ( expr_to_nav ( db, match_expr_in_file, Some ( focus_range) ) )
428+ } )
429+ . flatten ( )
430+ . collect_vec ( ) ,
431+
432+ T ! [ =>] => sema
433+ . descend_into_macros ( token. clone ( ) )
434+ . into_iter ( )
435+ . filter_map ( |token| {
436+ let match_arm =
437+ sema. token_ancestors_with_macros ( token) . find_map ( ast:: MatchArm :: cast) ?;
438+ let match_expr = sema
439+ . ancestors_with_macros ( match_arm. syntax ( ) . clone ( ) )
440+ . find_map ( ast:: MatchExpr :: cast) ?;
441+ let file_id = sema. hir_file_for ( match_expr. syntax ( ) ) ;
442+ let focus_range = match_arm. fat_arrow_token ( ) ?. text_range ( ) ;
443+ let match_expr_in_file = InFile :: new ( file_id, match_expr. into ( ) ) ;
444+ Some ( expr_to_nav ( db, match_expr_in_file, Some ( focus_range) ) )
445+ } )
446+ . flatten ( )
447+ . collect_vec ( ) ,
448+
449+ T ! [ if ] => sema
450+ . descend_into_macros ( token. clone ( ) )
451+ . into_iter ( )
452+ . filter_map ( |token| {
453+ let if_expr =
454+ sema. token_ancestors_with_macros ( token) . find_map ( ast:: IfExpr :: cast) ?;
455+ let file_id = sema. hir_file_for ( if_expr. syntax ( ) ) ;
456+ let focus_range = if_expr. if_token ( ) ?. text_range ( ) ;
457+ let if_expr_in_file = InFile :: new ( file_id, if_expr. into ( ) ) ;
458+ Some ( expr_to_nav ( db, if_expr_in_file, Some ( focus_range) ) )
459+ } )
460+ . flatten ( )
461+ . collect_vec ( ) ,
462+
463+ _ => return Some ( Vec :: new ( ) ) ,
464+ } ;
465+
466+ Some ( navs)
467+ }
468+
410469pub ( crate ) fn find_loops (
411470 sema : & Semantics < ' _ , RootDatabase > ,
412471 token : & SyntaxToken ,
@@ -3614,4 +3673,155 @@ fn foo() {
36143673 "# ,
36153674 ) ;
36163675 }
3676+
3677+ #[ test]
3678+ fn goto_def_for_match_keyword ( ) {
3679+ check (
3680+ r#"
3681+ fn main() {
3682+ match$0 0 {
3683+ // ^^^^^
3684+ 0 => {},
3685+ _ => {},
3686+ }
3687+ }
3688+ "# ,
3689+ ) ;
3690+ }
3691+
3692+ #[ test]
3693+ fn goto_def_for_match_arm_fat_arrow ( ) {
3694+ check (
3695+ r#"
3696+ fn main() {
3697+ match 0 {
3698+ 0 =>$0 {},
3699+ // ^^
3700+ _ => {},
3701+ }
3702+ }
3703+ "# ,
3704+ ) ;
3705+ }
3706+
3707+ #[ test]
3708+ fn goto_def_for_if_keyword ( ) {
3709+ check (
3710+ r#"
3711+ fn main() {
3712+ if$0 true {
3713+ // ^^
3714+ ()
3715+ }
3716+ }
3717+ "# ,
3718+ ) ;
3719+ }
3720+
3721+ #[ test]
3722+ fn goto_def_for_match_nested_in_if ( ) {
3723+ check (
3724+ r#"
3725+ fn main() {
3726+ if true {
3727+ match$0 0 {
3728+ // ^^^^^
3729+ 0 => {},
3730+ _ => {},
3731+ }
3732+ }
3733+ }
3734+ "# ,
3735+ ) ;
3736+ }
3737+
3738+ #[ test]
3739+ fn goto_def_for_multiple_match_expressions ( ) {
3740+ check (
3741+ r#"
3742+ fn main() {
3743+ match 0 {
3744+ 0 => {},
3745+ _ => {},
3746+ };
3747+
3748+ match$0 1 {
3749+ // ^^^^^
3750+ 1 => {},
3751+ _ => {},
3752+ }
3753+ }
3754+ "# ,
3755+ ) ;
3756+ }
3757+
3758+ #[ test]
3759+ fn goto_def_for_nested_match_expressions ( ) {
3760+ check (
3761+ r#"
3762+ fn main() {
3763+ match 0 {
3764+ 0 => match$0 1 {
3765+ // ^^^^^
3766+ 1 => {},
3767+ _ => {},
3768+ },
3769+ _ => {},
3770+ }
3771+ }
3772+ "# ,
3773+ ) ;
3774+ }
3775+
3776+ #[ test]
3777+ fn goto_def_for_if_else_chains ( ) {
3778+ check (
3779+ r#"
3780+ fn main() {
3781+ if true {
3782+ ()
3783+ } else if$0 false {
3784+ // ^^
3785+ ()
3786+ } else {
3787+ ()
3788+ }
3789+ }
3790+ "# ,
3791+ ) ;
3792+ }
3793+
3794+ #[ test]
3795+ fn goto_def_for_match_with_guards ( ) {
3796+ check (
3797+ r#"
3798+ fn main() {
3799+ match 42 {
3800+ x if x > 0 =>$0 {},
3801+ // ^^
3802+ _ => {},
3803+ }
3804+ }
3805+ "# ,
3806+ ) ;
3807+ }
3808+
3809+ #[ test]
3810+ fn goto_def_for_match_with_macro_arm ( ) {
3811+ check (
3812+ r#"
3813+ macro_rules! arm {
3814+ () => { 0 => {} };
3815+ }
3816+
3817+ fn main() {
3818+ match$0 0 {
3819+ // ^^^^^
3820+ arm!(),
3821+ _ => {},
3822+ }
3823+ }
3824+ "# ,
3825+ ) ;
3826+ }
36173827}
0 commit comments