diff --git a/src/main/grammars/RustParser.bnf b/src/main/grammars/RustParser.bnf index 35ecdad62a5..5c9b4ce198b 100644 --- a/src/main/grammars/RustParser.bnf +++ b/src/main/grammars/RustParser.bnf @@ -1302,7 +1302,13 @@ private IndexArg ::= '[' Expr ']' CallExpr ::= Expr !<> ValueArgumentList { elementTypeFactory = "org.rust.lang.core.stubs.StubImplementationsKt.factory" } -ValueArgumentList ::= '(' <>? ')' { pin = 1 } +ValueArgumentList ::= '(' ValueArgument_with_recover* ')' { pin = 1 } + +private ValueArgument_with_recover ::= !')' AnyExpr (',' | &')') { + pin = 1 + recoverWhile = ValueArgument_recover +} +private ValueArgument_recover ::= !(Expr_first | ')' | '}' | Item_first | let | ';') DotExpr ::= Expr '.' MethodOrField { elementTypeFactory = "org.rust.lang.core.stubs.StubImplementationsKt.factory" diff --git a/src/main/kotlin/org/rust/lang/core/parser/RustParserDefinition.kt b/src/main/kotlin/org/rust/lang/core/parser/RustParserDefinition.kt index 4399af7b437..305216c4827 100644 --- a/src/main/kotlin/org/rust/lang/core/parser/RustParserDefinition.kt +++ b/src/main/kotlin/org/rust/lang/core/parser/RustParserDefinition.kt @@ -92,6 +92,6 @@ class RustParserDefinition : ParserDefinition { /** * Should be increased after any change of parser rules */ - const val PARSER_VERSION: Int = LEXER_VERSION + 24 + const val PARSER_VERSION: Int = LEXER_VERSION + 25 } } diff --git a/src/test/kotlin/org/rust/ide/typing/assist/RsSmartEnterProcessorTest.kt b/src/test/kotlin/org/rust/ide/typing/assist/RsSmartEnterProcessorTest.kt index 0c2256cad28..dac7065f4c5 100644 --- a/src/test/kotlin/org/rust/ide/typing/assist/RsSmartEnterProcessorTest.kt +++ b/src/test/kotlin/org/rust/ide/typing/assist/RsSmartEnterProcessorTest.kt @@ -27,12 +27,10 @@ class RsSmartEnterProcessorTest : RsTestBase() { fun `test fix nested method call`() = doTest(""" fn double(x: i32) -> i32 { /*caret*/double(double(x - double(x) } """, """ fn double(x: i32) -> i32 { double(double(x));/*caret*/ - double(x) } """) diff --git a/src/test/resources/org/rust/lang/core/parser/fixtures/complete/expr.rs b/src/test/resources/org/rust/lang/core/parser/fixtures/complete/expr.rs index 13500804392..270129bb013 100644 --- a/src/test/resources/org/rust/lang/core/parser/fixtures/complete/expr.rs +++ b/src/test/resources/org/rust/lang/core/parser/fixtures/complete/expr.rs @@ -70,6 +70,8 @@ fn test() -> u32 { || { 0; yield 0; }; + foo(bar, true, "", 1, 1.1); + return (x = y) /* return */ + 1 } diff --git a/src/test/resources/org/rust/lang/core/parser/fixtures/complete/expr.txt b/src/test/resources/org/rust/lang/core/parser/fixtures/complete/expr.txt index 2a3c8fcf849..e8314be5f19 100644 --- a/src/test/resources/org/rust/lang/core/parser/fixtures/complete/expr.txt +++ b/src/test/resources/org/rust/lang/core/parser/fixtures/complete/expr.txt @@ -832,6 +832,35 @@ FILE PsiElement(})('}') PsiElement(;)(';') PsiWhiteSpace('\n\n ') + RsExprStmtImpl(EXPR_STMT) + RsCallExprImpl(CALL_EXPR) + RsPathExprImpl(PATH_EXPR) + RsPathImpl(PATH) + PsiElement(identifier)('foo') + RsValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + RsPathExprImpl(PATH_EXPR) + RsPathImpl(PATH) + PsiElement(identifier)('bar') + PsiElement(,)(',') + PsiWhiteSpace(' ') + RsLitExprImpl(LIT_EXPR) + PsiElement(BOOL_LITERAL)('true') + PsiElement(,)(',') + PsiWhiteSpace(' ') + RsLitExprImpl(LIT_EXPR) + PsiElement(STRING_LITERAL)('""') + PsiElement(,)(',') + PsiWhiteSpace(' ') + RsLitExprImpl(LIT_EXPR) + PsiElement(INTEGER_LITERAL)('1') + PsiElement(,)(',') + PsiWhiteSpace(' ') + RsLitExprImpl(LIT_EXPR) + PsiElement(FLOAT_LITERAL)('1.1') + PsiElement())(')') + PsiElement(;)(';') + PsiWhiteSpace('\n\n ') RsRetExprImpl(RET_EXPR) PsiElement(return)('return') PsiWhiteSpace(' ') diff --git a/src/test/resources/org/rust/lang/core/parser/fixtures/partial/exprs.rs b/src/test/resources/org/rust/lang/core/parser/fixtures/partial/exprs.rs index 2d3e0707c25..d067850488d 100644 --- a/src/test/resources/org/rust/lang/core/parser/fixtures/partial/exprs.rs +++ b/src/test/resources/org/rust/lang/core/parser/fixtures/partial/exprs.rs @@ -11,4 +11,24 @@ fn foo() { for a in b {} let _ = 0.0.0e92; + + foo1(1, , 2); + foo2(,, 2); + foo3(1,,); + + foo4(1,; + foo5(; + + foo6(1, + let _ = 0; + foo7( + let _ = 0; + + { foo8(1, }; + { foo9( }; + + foo10(1, + fn a() {} + foo11( + fn a() {} } diff --git a/src/test/resources/org/rust/lang/core/parser/fixtures/partial/exprs.txt b/src/test/resources/org/rust/lang/core/parser/fixtures/partial/exprs.txt index c70d457f55a..05f1372fa6d 100644 --- a/src/test/resources/org/rust/lang/core/parser/fixtures/partial/exprs.txt +++ b/src/test/resources/org/rust/lang/core/parser/fixtures/partial/exprs.txt @@ -111,5 +111,212 @@ FILE RsFieldLookupImpl(FIELD_LOOKUP) PsiElement(INTEGER_LITERAL)('0e92') PsiElement(;)(';') + PsiWhiteSpace('\n\n ') + RsExprStmtImpl(EXPR_STMT) + RsCallExprImpl(CALL_EXPR) + RsPathExprImpl(PATH_EXPR) + RsPathImpl(PATH) + PsiElement(identifier)('foo1') + RsValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + RsLitExprImpl(LIT_EXPR) + PsiElement(INTEGER_LITERAL)('1') + PsiElement(,)(',') + PsiWhiteSpace(' ') + PsiErrorElement:',' unexpected + PsiElement(,)(',') + PsiWhiteSpace(' ') + RsLitExprImpl(LIT_EXPR) + PsiElement(INTEGER_LITERAL)('2') + PsiElement())(')') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + RsExprStmtImpl(EXPR_STMT) + RsCallExprImpl(CALL_EXPR) + RsPathExprImpl(PATH_EXPR) + RsPathImpl(PATH) + PsiElement(identifier)('foo2') + RsValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + PsiErrorElement: expected, got ',' + + PsiElement(,)(',') + PsiElement(,)(',') + PsiWhiteSpace(' ') + RsLitExprImpl(LIT_EXPR) + PsiElement(INTEGER_LITERAL)('2') + PsiElement())(')') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + RsExprStmtImpl(EXPR_STMT) + RsCallExprImpl(CALL_EXPR) + RsPathExprImpl(PATH_EXPR) + RsPathImpl(PATH) + PsiElement(identifier)('foo3') + RsValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + RsLitExprImpl(LIT_EXPR) + PsiElement(INTEGER_LITERAL)('1') + PsiElement(,)(',') + PsiErrorElement:',' unexpected + PsiElement(,)(',') + PsiElement())(')') + PsiElement(;)(';') + PsiWhiteSpace('\n\n ') + RsExprStmtImpl(EXPR_STMT) + RsCallExprImpl(CALL_EXPR) + RsPathExprImpl(PATH_EXPR) + RsPathImpl(PATH) + PsiElement(identifier)('foo4') + RsValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + RsLitExprImpl(LIT_EXPR) + PsiElement(INTEGER_LITERAL)('1') + PsiElement(,)(',') + PsiErrorElement: expected, got ';' + + PsiElement(;)(';') + PsiWhiteSpace('\n ') + RsExprStmtImpl(EXPR_STMT) + RsCallExprImpl(CALL_EXPR) + RsPathExprImpl(PATH_EXPR) + RsPathImpl(PATH) + PsiElement(identifier)('foo5') + RsValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + PsiErrorElement: expected, got ';' + + PsiElement(;)(';') + PsiWhiteSpace('\n\n ') + RsExprStmtImpl(EXPR_STMT) + RsCallExprImpl(CALL_EXPR) + RsPathExprImpl(PATH_EXPR) + RsPathImpl(PATH) + PsiElement(identifier)('foo6') + RsValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + RsLitExprImpl(LIT_EXPR) + PsiElement(INTEGER_LITERAL)('1') + PsiElement(,)(',') + PsiErrorElement: expected, got 'let' + + PsiWhiteSpace('\n ') + RsLetDeclImpl(LET_DECL) + PsiElement(let)('let') + PsiWhiteSpace(' ') + RsPatWildImpl(PAT_WILD) + PsiElement(_)('_') + PsiWhiteSpace(' ') + PsiElement(=)('=') + PsiWhiteSpace(' ') + RsLitExprImpl(LIT_EXPR) + PsiElement(INTEGER_LITERAL)('0') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + RsExprStmtImpl(EXPR_STMT) + RsCallExprImpl(CALL_EXPR) + RsPathExprImpl(PATH_EXPR) + RsPathImpl(PATH) + PsiElement(identifier)('foo7') + RsValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + PsiErrorElement: expected, got 'let' + + PsiWhiteSpace('\n ') + RsLetDeclImpl(LET_DECL) + PsiElement(let)('let') + PsiWhiteSpace(' ') + RsPatWildImpl(PAT_WILD) + PsiElement(_)('_') + PsiWhiteSpace(' ') + PsiElement(=)('=') + PsiWhiteSpace(' ') + RsLitExprImpl(LIT_EXPR) + PsiElement(INTEGER_LITERAL)('0') + PsiElement(;)(';') + PsiWhiteSpace('\n\n ') + RsExprStmtImpl(EXPR_STMT) + RsBlockExprImpl(BLOCK_EXPR) + RsBlockImpl(BLOCK) + PsiElement({)('{') + PsiWhiteSpace(' ') + RsCallExprImpl(CALL_EXPR) + RsPathExprImpl(PATH_EXPR) + RsPathImpl(PATH) + PsiElement(identifier)('foo8') + RsValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + RsLitExprImpl(LIT_EXPR) + PsiElement(INTEGER_LITERAL)('1') + PsiElement(,)(',') + PsiErrorElement: expected, got '}' + + PsiWhiteSpace(' ') + PsiElement(})('}') + PsiElement(;)(';') + PsiWhiteSpace('\n ') + RsExprStmtImpl(EXPR_STMT) + RsBlockExprImpl(BLOCK_EXPR) + RsBlockImpl(BLOCK) + PsiElement({)('{') + PsiWhiteSpace(' ') + RsCallExprImpl(CALL_EXPR) + RsPathExprImpl(PATH_EXPR) + RsPathImpl(PATH) + PsiElement(identifier)('foo9') + RsValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + PsiErrorElement: expected, got '}' + + PsiWhiteSpace(' ') + PsiElement(})('}') + PsiElement(;)(';') + PsiWhiteSpace('\n\n ') + RsExprStmtImpl(EXPR_STMT) + RsCallExprImpl(CALL_EXPR) + RsPathExprImpl(PATH_EXPR) + RsPathImpl(PATH) + PsiElement(identifier)('foo10') + RsValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + RsLitExprImpl(LIT_EXPR) + PsiElement(INTEGER_LITERAL)('1') + PsiElement(,)(',') + PsiErrorElement: expected, got 'fn' + + PsiWhiteSpace('\n ') + RsFunctionImpl(FUNCTION) + PsiElement(fn)('fn') + PsiWhiteSpace(' ') + PsiElement(identifier)('a') + RsValueParameterListImpl(VALUE_PARAMETER_LIST) + PsiElement(()('(') + PsiElement())(')') + PsiWhiteSpace(' ') + RsBlockImpl(BLOCK) + PsiElement({)('{') + PsiElement(})('}') + PsiWhiteSpace('\n ') + RsExprStmtImpl(EXPR_STMT) + RsCallExprImpl(CALL_EXPR) + RsPathExprImpl(PATH_EXPR) + RsPathImpl(PATH) + PsiElement(identifier)('foo11') + RsValueArgumentListImpl(VALUE_ARGUMENT_LIST) + PsiElement(()('(') + PsiErrorElement: expected, got 'fn' + + PsiWhiteSpace('\n ') + RsFunctionImpl(FUNCTION) + PsiElement(fn)('fn') + PsiWhiteSpace(' ') + PsiElement(identifier)('a') + RsValueParameterListImpl(VALUE_PARAMETER_LIST) + PsiElement(()('(') + PsiElement())(')') + PsiWhiteSpace(' ') + RsBlockImpl(BLOCK) + PsiElement({)('{') + PsiElement(})('}') PsiWhiteSpace('\n') PsiElement(})('}')