summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala44
-rw-r--r--test/files/neg/t421.check2
-rw-r--r--test/files/neg/t5702-neg-bad-brace.check11
3 files changed, 38 insertions, 19 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index fa3302b125..cfa60cabc3 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -284,6 +284,25 @@ self =>
try body finally in copyFrom saved
}
+ /** Perform an operation while peeking ahead.
+ * Pushback if the operation yields an empty tree or blows to pieces.
+ */
+ @inline def peekingAhead(tree: =>Tree): Tree = {
+ @inline def peekahead() = {
+ in.prev copyFrom in
+ in.nextToken()
+ }
+ @inline def pushback() = {
+ in.next copyFrom in
+ in copyFrom in.prev
+ }
+ peekahead()
+ // try it, in case it is recoverable
+ val res = try tree catch { case e: Exception => pushback() ; throw e }
+ if (res.isEmpty) pushback()
+ res
+ }
+
class ParserTreeBuilder extends TreeBuilder {
val global: self.global.type = self.global
def unit = parser.unit
@@ -1825,26 +1844,23 @@ self =>
val top = simplePattern(badPattern3)
val base = opstack
// See SI-3189, SI-4832 for motivation. Cf SI-3480 for counter-motivation.
- def peekaheadDelim() = {
- def isCloseDelim = in.token match {
- case RBRACE => isXML
- case RPAREN => !isXML
- case _ => false
- }
- lookingAhead(isCloseDelim) && { in.nextToken() ; true }
+ def isCloseDelim = in.token match {
+ case RBRACE => isXML
+ case RPAREN => !isXML
+ case _ => false
}
- def isWildStar = top match {
- case Ident(nme.WILDCARD) if isRawStar => peekaheadDelim()
- case _ => false
+ def checkWildStar: Tree = top match {
+ case Ident(nme.WILDCARD) if isSequenceOK && isRawStar => peekingAhead (
+ if (isCloseDelim) atPos(top.pos.start, in.prev.offset)(Star(stripParens(top)))
+ else EmptyTree
+ )
+ case _ => EmptyTree
}
def loop(top: Tree): Tree = reducePatternStack(base, top) match {
case next if isIdentExcept(raw.BAR) => pushOpInfo(next) ; loop(simplePattern(badPattern3))
case next => next
}
- if (isSequenceOK && isWildStar)
- atPos(top.pos.start, in.prev.offset)(Star(stripParens(top)))
- else
- stripParens(loop(top))
+ checkWildStar orElse stripParens(loop(top))
}
def badPattern3(): Tree = {
diff --git a/test/files/neg/t421.check b/test/files/neg/t421.check
index d16e541868..dc5fa425ac 100644
--- a/test/files/neg/t421.check
+++ b/test/files/neg/t421.check
@@ -1,4 +1,4 @@
t421.scala:5: error: star patterns must correspond with varargs parameters
case Bar("foo",_*) => sys.error("huh?");
- ^
+ ^
one error found
diff --git a/test/files/neg/t5702-neg-bad-brace.check b/test/files/neg/t5702-neg-bad-brace.check
index a4a00814d3..503f7d95ed 100644
--- a/test/files/neg/t5702-neg-bad-brace.check
+++ b/test/files/neg/t5702-neg-bad-brace.check
@@ -1,7 +1,10 @@
t5702-neg-bad-brace.scala:14: error: Unmatched closing brace '}' ignored here
case List(1, _*} =>
^
-t5702-neg-bad-brace.scala:17: error: eof expected but '}' found.
-}
-^
-two errors found
+t5702-neg-bad-brace.scala:14: error: illegal start of simple pattern
+ case List(1, _*} =>
+ ^
+t5702-neg-bad-brace.scala:15: error: ')' expected but '}' found.
+ }
+ ^
+three errors found