@@ -298,6 +298,7 @@ fn handle_control_flow_keywords(
298
298
T ! [ for ] if token. parent ( ) . and_then ( ast:: ForExpr :: cast) . is_some ( ) => {
299
299
nav_for_break_points ( sema, token)
300
300
}
301
+ T ! [ match ] | T ! [ =>] | T ! [ if ] => nav_for_branches ( sema, token) ,
301
302
_ => None ,
302
303
}
303
304
}
@@ -407,6 +408,64 @@ fn nav_for_exit_points(
407
408
Some ( navs)
408
409
}
409
410
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
+
410
469
pub ( crate ) fn find_loops (
411
470
sema : & Semantics < ' _ , RootDatabase > ,
412
471
token : & SyntaxToken ,
@@ -3614,4 +3673,155 @@ fn foo() {
3614
3673
"# ,
3615
3674
) ;
3616
3675
}
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
+ }
3617
3827
}
0 commit comments