diff options
author | Som Snytt <som.snytt@gmail.com> | 2014-01-27 09:58:00 -0800 |
---|---|---|
committer | Som Snytt <som.snytt@gmail.com> | 2014-01-27 10:46:16 -0800 |
commit | d603cae2cd6b796534e55b25ee65385825904a10 (patch) | |
tree | 0270c82f52fe747b5181630bf852cfbc937afb31 | |
parent | 18c9196686410536f69f8e05b62f0cd7e0b91a8c (diff) | |
download | scala-d603cae2cd6b796534e55b25ee65385825904a10.tar.gz scala-d603cae2cd6b796534e55b25ee65385825904a10.tar.bz2 scala-d603cae2cd6b796534e55b25ee65385825904a10.zip |
SI-8182 Avert crash due to type args in pattern
Error out type args on binary op after emitting error.
Let the parse limp into the whirring blades.
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 10 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala | 2 | ||||
-rw-r--r-- | test/files/neg/t8182.check | 22 | ||||
-rw-r--r-- | test/files/neg/t8182.scala | 18 |
4 files changed, 49 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 0728fff74f..9e580d8bc8 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -837,8 +837,14 @@ self => if (samePrecedence) checkHeadAssoc(leftAssoc) - def loop(top: Tree): Tree = - if (canReduce) loop(finishBinaryOp(isExpr, popOpInfo(), top)) else top + def loop(top: Tree): Tree = if (canReduce) { + val info = popOpInfo() + if (!isExpr && info.targs.nonEmpty) { + syntaxError(info.offset, "type application is not allowed in pattern") + info.targs.foreach(_.setType(ErrorType)) + } + loop(finishBinaryOp(isExpr, info, top)) + } else top loop(top) } diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index cfee988efc..525dcffb0c 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -56,7 +56,7 @@ abstract class TreeBuilder { /** Create tree representing (unencoded) binary operation expression or pattern. */ def makeBinop(isExpr: Boolean, left: Tree, op: TermName, right: Tree, opPos: Position, targs: List[Tree] = Nil): Tree = { - require(isExpr || targs.isEmpty, s"Incompatible args to makeBinop: !isExpr but targs=$targs") + require(isExpr || targs.isEmpty || targs.exists(_.isErroneous), s"Incompatible args to makeBinop: !isExpr but targs=$targs") def mkSelection(t: Tree) = { def sel = atPos(opPos union t.pos)(Select(stripParens(t), op.encode)) diff --git a/test/files/neg/t8182.check b/test/files/neg/t8182.check new file mode 100644 index 0000000000..a156d70883 --- /dev/null +++ b/test/files/neg/t8182.check @@ -0,0 +1,22 @@ +t8182.scala:4: error: illegal start of simple pattern +} +^ +t8182.scala:7: error: illegal start of simple pattern +} +^ +t8182.scala:6: error: type application is not allowed in pattern + val a b[B] // error then continue as for X + ^ +t8182.scala:10: error: illegal start of simple pattern + case a b[B] => // bumpy recovery + ^ +t8182.scala:10: error: type application is not allowed in pattern + case a b[B] => // bumpy recovery + ^ +t8182.scala:11: error: '=>' expected but '}' found. + } + ^ +t8182.scala:16: error: type application is not allowed in pattern + case a B[T] b => + ^ +7 errors found diff --git a/test/files/neg/t8182.scala b/test/files/neg/t8182.scala new file mode 100644 index 0000000000..1b3bc9821f --- /dev/null +++ b/test/files/neg/t8182.scala @@ -0,0 +1,18 @@ + +trait X { + val a b // something missing +} +trait Y { + val a b[B] // error then continue as for X +} +trait Z { + (null: Any) match { + case a b[B] => // bumpy recovery + } +} +object B { def unapply[W](a: Any) = Some((1,2)) } +trait Z { + (null: Any) match { + case a B[T] b => + } +} |