@@ -299,6 +299,7 @@ fn handle_control_flow_keywords(
299
299
T ! [ for ] if token. parent ( ) . and_then ( ast:: ForExpr :: cast) . is_some ( ) => {
300
300
nav_for_break_points ( sema, token)
301
301
}
302
+ T ! [ match ] | T ! [ =>] | T ! [ if ] => nav_for_branches ( sema, token) ,
302
303
_ => None ,
303
304
}
304
305
}
@@ -408,6 +409,64 @@ fn nav_for_exit_points(
408
409
Some ( navs)
409
410
}
410
411
412
+ fn nav_for_branches (
413
+ sema : & Semantics < ' _ , RootDatabase > ,
414
+ token : & SyntaxToken ,
415
+ ) -> Option < Vec < NavigationTarget > > {
416
+ let db = sema. db ;
417
+
418
+ let navs = match token. kind ( ) {
419
+ T ! [ match ] => sema
420
+ . descend_into_macros ( token. clone ( ) )
421
+ . into_iter ( )
422
+ . filter_map ( |token| {
423
+ let match_expr =
424
+ sema. token_ancestors_with_macros ( token) . find_map ( ast:: MatchExpr :: cast) ?;
425
+ let file_id = sema. hir_file_for ( match_expr. syntax ( ) ) ;
426
+ let focus_range = match_expr. match_token ( ) ?. text_range ( ) ;
427
+ let match_expr_in_file = InFile :: new ( file_id, match_expr. into ( ) ) ;
428
+ Some ( expr_to_nav ( db, match_expr_in_file, Some ( focus_range) ) )
429
+ } )
430
+ . flatten ( )
431
+ . collect_vec ( ) ,
432
+
433
+ T ! [ =>] => sema
434
+ . descend_into_macros ( token. clone ( ) )
435
+ . into_iter ( )
436
+ . filter_map ( |token| {
437
+ let match_arm =
438
+ sema. token_ancestors_with_macros ( token) . find_map ( ast:: MatchArm :: cast) ?;
439
+ let match_expr = sema
440
+ . ancestors_with_macros ( match_arm. syntax ( ) . clone ( ) )
441
+ . find_map ( ast:: MatchExpr :: cast) ?;
442
+ let file_id = sema. hir_file_for ( match_expr. syntax ( ) ) ;
443
+ let focus_range = match_arm. fat_arrow_token ( ) ?. text_range ( ) ;
444
+ let match_expr_in_file = InFile :: new ( file_id, match_expr. into ( ) ) ;
445
+ Some ( expr_to_nav ( db, match_expr_in_file, Some ( focus_range) ) )
446
+ } )
447
+ . flatten ( )
448
+ . collect_vec ( ) ,
449
+
450
+ T ! [ if ] => sema
451
+ . descend_into_macros ( token. clone ( ) )
452
+ . into_iter ( )
453
+ . filter_map ( |token| {
454
+ let if_expr =
455
+ sema. token_ancestors_with_macros ( token) . find_map ( ast:: IfExpr :: cast) ?;
456
+ let file_id = sema. hir_file_for ( if_expr. syntax ( ) ) ;
457
+ let focus_range = if_expr. if_token ( ) ?. text_range ( ) ;
458
+ let if_expr_in_file = InFile :: new ( file_id, if_expr. into ( ) ) ;
459
+ Some ( expr_to_nav ( db, if_expr_in_file, Some ( focus_range) ) )
460
+ } )
461
+ . flatten ( )
462
+ . collect_vec ( ) ,
463
+
464
+ _ => return Some ( Vec :: new ( ) ) ,
465
+ } ;
466
+
467
+ Some ( navs)
468
+ }
469
+
411
470
pub ( crate ) fn find_loops (
412
471
sema : & Semantics < ' _ , RootDatabase > ,
413
472
token : & SyntaxToken ,
@@ -3474,6 +3533,157 @@ fn main() {
3474
3533
fn f1<const N: buz$0>() {}
3475
3534
}
3476
3535
}
3536
+ "# ,
3537
+ ) ;
3538
+ }
3539
+
3540
+ #[ test]
3541
+ fn goto_def_for_match_keyword ( ) {
3542
+ check (
3543
+ r#"
3544
+ fn main() {
3545
+ match$0 0 {
3546
+ // ^^^^^
3547
+ 0 => {},
3548
+ _ => {},
3549
+ }
3550
+ }
3551
+ "# ,
3552
+ ) ;
3553
+ }
3554
+
3555
+ #[ test]
3556
+ fn goto_def_for_match_arm_fat_arrow ( ) {
3557
+ check (
3558
+ r#"
3559
+ fn main() {
3560
+ match 0 {
3561
+ 0 =>$0 {},
3562
+ // ^^
3563
+ _ => {},
3564
+ }
3565
+ }
3566
+ "# ,
3567
+ ) ;
3568
+ }
3569
+
3570
+ #[ test]
3571
+ fn goto_def_for_if_keyword ( ) {
3572
+ check (
3573
+ r#"
3574
+ fn main() {
3575
+ if$0 true {
3576
+ // ^^
3577
+ ()
3578
+ }
3579
+ }
3580
+ "# ,
3581
+ ) ;
3582
+ }
3583
+
3584
+ #[ test]
3585
+ fn goto_def_for_match_nested_in_if ( ) {
3586
+ check (
3587
+ r#"
3588
+ fn main() {
3589
+ if true {
3590
+ match$0 0 {
3591
+ // ^^^^^
3592
+ 0 => {},
3593
+ _ => {},
3594
+ }
3595
+ }
3596
+ }
3597
+ "# ,
3598
+ ) ;
3599
+ }
3600
+
3601
+ #[ test]
3602
+ fn goto_def_for_multiple_match_expressions ( ) {
3603
+ check (
3604
+ r#"
3605
+ fn main() {
3606
+ match 0 {
3607
+ 0 => {},
3608
+ _ => {},
3609
+ };
3610
+
3611
+ match$0 1 {
3612
+ // ^^^^^
3613
+ 1 => {},
3614
+ _ => {},
3615
+ }
3616
+ }
3617
+ "# ,
3618
+ ) ;
3619
+ }
3620
+
3621
+ #[ test]
3622
+ fn goto_def_for_nested_match_expressions ( ) {
3623
+ check (
3624
+ r#"
3625
+ fn main() {
3626
+ match 0 {
3627
+ 0 => match$0 1 {
3628
+ // ^^^^^
3629
+ 1 => {},
3630
+ _ => {},
3631
+ },
3632
+ _ => {},
3633
+ }
3634
+ }
3635
+ "# ,
3636
+ ) ;
3637
+ }
3638
+
3639
+ #[ test]
3640
+ fn goto_def_for_if_else_chains ( ) {
3641
+ check (
3642
+ r#"
3643
+ fn main() {
3644
+ if true {
3645
+ ()
3646
+ } else if$0 false {
3647
+ // ^^
3648
+ ()
3649
+ } else {
3650
+ ()
3651
+ }
3652
+ }
3653
+ "# ,
3654
+ ) ;
3655
+ }
3656
+
3657
+ #[ test]
3658
+ fn goto_def_for_match_with_guards ( ) {
3659
+ check (
3660
+ r#"
3661
+ fn main() {
3662
+ match 42 {
3663
+ x if x > 0 =>$0 {},
3664
+ // ^^
3665
+ _ => {},
3666
+ }
3667
+ }
3668
+ "# ,
3669
+ ) ;
3670
+ }
3671
+
3672
+ #[ test]
3673
+ fn goto_def_for_match_with_macro_arm ( ) {
3674
+ check (
3675
+ r#"
3676
+ macro_rules! arm {
3677
+ () => { 0 => {} };
3678
+ }
3679
+
3680
+ fn main() {
3681
+ match$0 0 {
3682
+ // ^^^^^
3683
+ arm!(),
3684
+ _ => {},
3685
+ }
3686
+ }
3477
3687
"# ,
3478
3688
) ;
3479
3689
}
0 commit comments