Skip to content

Commit 0e479ee

Browse files
authored
Merge pull request #14463 from adampauls/missing-argument-parsing
Parse empty arguments in (invalid) `Apply` more often
2 parents d09dd2a + e2537c5 commit 0e479ee

18 files changed

+112
-66
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -249,11 +249,11 @@ object Parsers {
249249

250250
/** Skip on error to next safe point.
251251
*/
252-
protected def skip(): Unit =
252+
protected def skip(stopAtComma: Boolean): Unit =
253253
val lastRegion = in.currentRegion
254254
def atStop =
255255
in.token == EOF
256-
|| skipStopTokens.contains(in.token) && (in.currentRegion eq lastRegion)
256+
|| ((stopAtComma && in.token == COMMA) || skipStopTokens.contains(in.token)) && (in.currentRegion eq lastRegion)
257257
while !atStop do
258258
in.nextToken()
259259
lastErrorOffset = in.offset
@@ -278,7 +278,7 @@ object Parsers {
278278
if (in.token == EOF) incompleteInputError(msg)
279279
else
280280
syntaxError(msg, offset)
281-
skip()
281+
skip(stopAtComma = true)
282282

283283
/** Consume one token of the specified type, or
284284
* signal an error if it is not there.
@@ -346,7 +346,7 @@ object Parsers {
346346
false // it's a statement that might be legal in an outer context
347347
else
348348
in.nextToken() // needed to ensure progress; otherwise we might cycle forever
349-
skip()
349+
skip(stopAtComma=false)
350350
true
351351

352352
in.observeOutdented()
@@ -881,7 +881,8 @@ object Parsers {
881881
val next = in.lookahead.token
882882
next == LBRACKET || next == LPAREN
883883

884-
/** Is current ident a `*`, and is it followed by a `)` or `, )`? */
884+
/** Is current ident a `*`, and is it followed by a `)`, `, )`, `,EOF`? The latter two are not
885+
syntactically valid, but we need to include them here for error recovery. */
885886
def followingIsVararg(): Boolean =
886887
in.isIdent(nme.raw.STAR) && {
887888
val lookahead = in.LookaheadScanner()
@@ -890,7 +891,7 @@ object Parsers {
890891
|| lookahead.token == COMMA
891892
&& {
892893
lookahead.nextToken()
893-
lookahead.token == RPAREN
894+
lookahead.token == RPAREN || lookahead.token == EOF
894895
}
895896
}
896897

compiler/src/dotty/tools/dotc/parsing/Scanners.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,8 +659,6 @@ object Scanners {
659659
&& (token == RPAREN || token == RBRACKET || token == RBRACE || token == OUTDENT)
660660
then
661661
() /* skip the trailing comma */
662-
else if token == EOF then // e.g. when the REPL is parsing "val List(x, y, _*,"
663-
() /* skip the trailing comma */
664662
else
665663
reset()
666664
case END =>

compiler/src/dotty/tools/repl/Main.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package dotty.tools.repl
22

33
/** Main entry point to the REPL */
4+
// To test, run bin/scala
45
object Main {
56
def main(args: Array[String]): Unit =
67
new ReplDriver(args).tryRunning

tests/neg/arg-eof.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Test:
2+
case class Widget(name: String, other: Int = 5)
3+
Widget(name = "foo", // error // error

tests/neg/i1679.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
class A[T]
22
object o {
33
// Testing compiler crash, this test should be modified when named type argument are completely implemented
4-
val x: A[T=Int, T=Int] = ??? // error: ']' expected, but '=' found
4+
val x: A[T=Int, T=Int] = ??? // error: ']' expected, but '=' found // error
55
}

tests/neg/t1625.check

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- [E040] Syntax Error: tests/neg/t1625.scala:2:20 ---------------------------------------------------------------------
2+
2 | def foo(x: String*, y: String*, c: String*): Int // error: an identifier expected, but ',' found // error: an identifier expected, but ',' found
3+
| ^
4+
| an identifier expected, but ',' found
5+
-- [E040] Syntax Error: tests/neg/t1625.scala:2:32 ---------------------------------------------------------------------
6+
2 | def foo(x: String*, y: String*, c: String*): Int // error: an identifier expected, but ',' found // error: an identifier expected, but ',' found
7+
| ^
8+
| an identifier expected, but ',' found

tests/neg/t1625.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
trait T3 {
2-
def foo(x: String*, y: String*, c: String*): Int // error: an identifier expected, but ',' found
3-
}
2+
def foo(x: String*, y: String*, c: String*): Int // error: an identifier expected, but ',' found // error: an identifier expected, but ',' found
3+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
-- [E032] Syntax Error: tests/neg/t5702-neg-bad-and-wild.scala:10:22 ---------------------------------------------------
2+
10 | case List(1, _*,) => // error: pattern expected // error
3+
| ^
4+
| pattern expected
5+
|
6+
| longer explanation available when compiling with `-explain`
7+
-- [E032] Syntax Error: tests/neg/t5702-neg-bad-and-wild.scala:12:23 ---------------------------------------------------
8+
12 | case List(1, _*3,) => // error: pattern expected // error // error
9+
| ^
10+
| pattern expected
11+
|
12+
| longer explanation available when compiling with `-explain`
13+
-- [E032] Syntax Error: tests/neg/t5702-neg-bad-and-wild.scala:15:18 ---------------------------------------------------
14+
15 | case List(x*, 1) => // error: pattern expected
15+
| ^
16+
| pattern expected
17+
|
18+
| longer explanation available when compiling with `-explain`
19+
-- [E031] Syntax Error: tests/neg/t5702-neg-bad-and-wild.scala:17:18 ---------------------------------------------------
20+
17 | case (1, x: _*) => // error: bad use of _* (sequence pattern not allowed)
21+
| ^
22+
| * can be used only for last argument
23+
|
24+
| longer explanation available when compiling with `-explain`
25+
-- [E032] Syntax Error: tests/neg/t5702-neg-bad-and-wild.scala:23:17 ---------------------------------------------------
26+
23 | val K(ns @ _*, x) = k // error: pattern expected
27+
| ^
28+
| pattern expected
29+
|
30+
| longer explanation available when compiling with `-explain`
31+
-- Error: tests/neg/t5702-neg-bad-and-wild.scala:10:21 -----------------------------------------------------------------
32+
10 | case List(1, _*,) => // error: pattern expected // error
33+
| ^
34+
| Values of types Null and Int cannot be compared with == or !=
35+
-- [E006] Not Found Error: tests/neg/t5702-neg-bad-and-wild.scala:12:20 ------------------------------------------------
36+
12 | case List(1, _*3,) => // error: pattern expected // error // error
37+
| ^
38+
| Not found: *
39+
|
40+
| longer explanation available when compiling with `-explain`
41+
-- Error: tests/neg/t5702-neg-bad-and-wild.scala:12:22 -----------------------------------------------------------------
42+
12 | case List(1, _*3,) => // error: pattern expected // error // error
43+
| ^
44+
| Values of types Null and Int cannot be compared with == or !=

tests/neg/t5702-neg-bad-brace.check

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- [E032] Syntax Error: tests/neg/t5702-neg-bad-brace.scala:8:21 -------------------------------------------------------
2+
8 | case List(1, _*} => // error: pattern expected
3+
| ^
4+
| pattern expected
5+
|
6+
| longer explanation available when compiling with `-explain`
7+
-- [E040] Syntax Error: tests/neg/t5702-neg-bad-brace.scala:11:0 -------------------------------------------------------
8+
11 |} // error: eof expected, but '}' found
9+
|^
10+
|eof expected, but '}' found

tests/neg/t5702-neg-bad-brace.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
object Test {
3+
4+
def main(args: Array[String]) = {
5+
val is = List(1,2,3)
6+
7+
is match {
8+
case List(1, _*} => // error: pattern expected
9+
}
10+
}
11+
} // error: eof expected, but '}' found
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-- [E032] Syntax Error: tests/neg/trailing-comma-pattern.scala:3:8 -----------------------------------------------------
2+
3 |// error
3+
| ^
4+
| pattern expected
5+
|
6+
| longer explanation available when compiling with `-explain`
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Test:
2+
val List(x, y, _*,
3+
// error
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- [E032] Syntax Error: tests/neg/trailing-comma-pattern2.scala:2:21 ---------------------------------------------------
2+
2 | val List(x, y, _*, ) // error
3+
| ^
4+
| pattern expected
5+
|
6+
| longer explanation available when compiling with `-explain`
7+
-- [E040] Syntax Error: tests/neg/trailing-comma-pattern2.scala:3:8 ----------------------------------------------------
8+
3 |// error
9+
| ^
10+
| '=' expected, but unindent found
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Test:
2+
val List(x, y, _*, ) // error
3+
// error
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Test:
2+
val List(x, y, _*,
3+
) = List(1, 2, 3)

tests/untried/neg/t5702-neg-bad-and-wild.check

Lines changed: 0 additions & 28 deletions
This file was deleted.

tests/untried/neg/t5702-neg-bad-brace.check

Lines changed: 0 additions & 10 deletions
This file was deleted.

tests/untried/neg/t5702-neg-bad-brace.scala

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)