Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 4456800

Browse files
committed
Auto merge of rust-lang#14128 - Veykril:parser, r=Veykril
internal: Improve parser recovery for delimited lists Closes rust-lang/rust-analyzer#11188, rust-lang/rust-analyzer#10410, rust-lang/rust-analyzer#10173 Should probably be merged after the stable release as this might get the parser stuck if I missed something
2 parents 88b3d9f + 4f6b5f4 commit 4456800

33 files changed

+815
-365
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/hir-def/src/macro_expansion_tests/mbe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,7 @@ macro_rules! m {
14761476
/* parse error: expected identifier */
14771477
/* parse error: expected SEMICOLON */
14781478
/* parse error: expected SEMICOLON */
1479-
/* parse error: expected expression */
1479+
/* parse error: expected expression, item or let statement */
14801480
fn f() {
14811481
K::(C("0"));
14821482
}

crates/hir-def/src/macro_expansion_tests/mbe/regression.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -830,8 +830,7 @@ macro_rules! rgb_color {
830830
/* parse error: expected COMMA */
831831
/* parse error: expected R_ANGLE */
832832
/* parse error: expected SEMICOLON */
833-
/* parse error: expected SEMICOLON */
834-
/* parse error: expected expression */
833+
/* parse error: expected expression, item or let statement */
835834
pub fn new() {
836835
let _ = 0as u32<<(8+8);
837836
}
@@ -848,21 +847,21 @@ pub fn new() {
848847
849848
850849
851-
// LET_STMT@11..27
850+
// LET_STMT@11..28
852851
853852
854853
855854
856-
// CAST_EXPR@16..27
855+
// CAST_EXPR@16..28
857856
858857
859858
860-
// PATH_TYPE@19..27
861-
// PATH@19..27
862-
// PATH_SEGMENT@19..27
859+
// PATH_TYPE@19..28
860+
// PATH@19..28
861+
// PATH_SEGMENT@19..28
863862
864863
865-
// GENERIC_ARG_LIST@22..27
864+
// GENERIC_ARG_LIST@22..28
866865
867866
868867
@@ -877,9 +876,9 @@ pub fn new() {
877876
878877
879878
880-
// EXPR_STMT@27..28
881-
882-
879+
// CONST_ARG@27..28
880+
881+
883882
884883
885884

crates/ide-completion/src/context/analysis.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,8 +668,15 @@ fn classify_name_ref(
668668
};
669669
let after_if_expr = |node: SyntaxNode| {
670670
let prev_expr = (|| {
671+
let node = match node.parent().and_then(ast::ExprStmt::cast) {
672+
Some(stmt) => stmt.syntax().clone(),
673+
None => node,
674+
};
671675
let prev_sibling = non_trivia_sibling(node.into(), Direction::Prev)?.into_node()?;
672-
ast::ExprStmt::cast(prev_sibling)?.expr()
676+
677+
ast::ExprStmt::cast(prev_sibling.clone())
678+
.and_then(|it| it.expr())
679+
.or_else(|| ast::Expr::cast(prev_sibling))
673680
})();
674681
matches!(prev_expr, Some(ast::Expr::IfExpr(_)))
675682
};

crates/ide-completion/src/tests/expression.rs

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,3 +745,255 @@ fn return_value_no_block() {
745745
r#"fn f() -> i32 { match () { () => return $0 } }"#,
746746
);
747747
}
748+
749+
#[test]
750+
fn else_completion_after_if() {
751+
check_empty(
752+
r#"
753+
fn foo() { if foo {} $0 }
754+
"#,
755+
expect![[r#"
756+
fn foo() fn()
757+
bt u32
758+
kw const
759+
kw crate::
760+
kw else
761+
kw else if
762+
kw enum
763+
kw extern
764+
kw false
765+
kw fn
766+
kw for
767+
kw if
768+
kw if let
769+
kw impl
770+
kw let
771+
kw loop
772+
kw match
773+
kw mod
774+
kw return
775+
kw self::
776+
kw static
777+
kw struct
778+
kw trait
779+
kw true
780+
kw type
781+
kw union
782+
kw unsafe
783+
kw use
784+
kw while
785+
kw while let
786+
sn macro_rules
787+
sn pd
788+
sn ppd
789+
"#]],
790+
);
791+
check_empty(
792+
r#"
793+
fn foo() { if foo {} el$0 }
794+
"#,
795+
expect![[r#"
796+
fn foo() fn()
797+
bt u32
798+
kw const
799+
kw crate::
800+
kw else
801+
kw else if
802+
kw enum
803+
kw extern
804+
kw false
805+
kw fn
806+
kw for
807+
kw if
808+
kw if let
809+
kw impl
810+
kw let
811+
kw loop
812+
kw match
813+
kw mod
814+
kw return
815+
kw self::
816+
kw static
817+
kw struct
818+
kw trait
819+
kw true
820+
kw type
821+
kw union
822+
kw unsafe
823+
kw use
824+
kw while
825+
kw while let
826+
sn macro_rules
827+
sn pd
828+
sn ppd
829+
"#]],
830+
);
831+
check_empty(
832+
r#"
833+
fn foo() { bar(if foo {} $0) }
834+
"#,
835+
expect![[r#"
836+
fn foo() fn()
837+
bt u32
838+
kw crate::
839+
kw else
840+
kw else if
841+
kw false
842+
kw for
843+
kw if
844+
kw if let
845+
kw loop
846+
kw match
847+
kw return
848+
kw self::
849+
kw true
850+
kw unsafe
851+
kw while
852+
kw while let
853+
"#]],
854+
);
855+
check_empty(
856+
r#"
857+
fn foo() { bar(if foo {} el$0) }
858+
"#,
859+
expect![[r#"
860+
fn foo() fn()
861+
bt u32
862+
kw crate::
863+
kw else
864+
kw else if
865+
kw false
866+
kw for
867+
kw if
868+
kw if let
869+
kw loop
870+
kw match
871+
kw return
872+
kw self::
873+
kw true
874+
kw unsafe
875+
kw while
876+
kw while let
877+
"#]],
878+
);
879+
check_empty(
880+
r#"
881+
fn foo() { if foo {} $0 let x = 92; }
882+
"#,
883+
expect![[r#"
884+
fn foo() fn()
885+
bt u32
886+
kw const
887+
kw crate::
888+
kw else
889+
kw else if
890+
kw enum
891+
kw extern
892+
kw false
893+
kw fn
894+
kw for
895+
kw if
896+
kw if let
897+
kw impl
898+
kw let
899+
kw loop
900+
kw match
901+
kw mod
902+
kw return
903+
kw self::
904+
kw static
905+
kw struct
906+
kw trait
907+
kw true
908+
kw type
909+
kw union
910+
kw unsafe
911+
kw use
912+
kw while
913+
kw while let
914+
sn macro_rules
915+
sn pd
916+
sn ppd
917+
"#]],
918+
);
919+
check_empty(
920+
r#"
921+
fn foo() { if foo {} el$0 let x = 92; }
922+
"#,
923+
expect![[r#"
924+
fn foo() fn()
925+
bt u32
926+
kw const
927+
kw crate::
928+
kw else
929+
kw else if
930+
kw enum
931+
kw extern
932+
kw false
933+
kw fn
934+
kw for
935+
kw if
936+
kw if let
937+
kw impl
938+
kw let
939+
kw loop
940+
kw match
941+
kw mod
942+
kw return
943+
kw self::
944+
kw static
945+
kw struct
946+
kw trait
947+
kw true
948+
kw type
949+
kw union
950+
kw unsafe
951+
kw use
952+
kw while
953+
kw while let
954+
sn macro_rules
955+
sn pd
956+
sn ppd
957+
"#]],
958+
);
959+
check_empty(
960+
r#"
961+
fn foo() { if foo {} el$0 { let x = 92; } }
962+
"#,
963+
expect![[r#"
964+
fn foo() fn()
965+
bt u32
966+
kw const
967+
kw crate::
968+
kw else
969+
kw else if
970+
kw enum
971+
kw extern
972+
kw false
973+
kw fn
974+
kw for
975+
kw if
976+
kw if let
977+
kw impl
978+
kw let
979+
kw loop
980+
kw match
981+
kw mod
982+
kw return
983+
kw self::
984+
kw static
985+
kw struct
986+
kw trait
987+
kw true
988+
kw type
989+
kw union
990+
kw unsafe
991+
kw use
992+
kw while
993+
kw while let
994+
sn macro_rules
995+
sn pd
996+
sn ppd
997+
"#]],
998+
);
999+
}

0 commit comments

Comments
 (0)