summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-02-18 19:59:28 +0000
committerPaul Phillips <paulp@improving.org>2009-02-18 19:59:28 +0000
commit36b0e8178f74a2986bce5c9027b9a2b22a4e7527 (patch)
tree2f9722a329ecc0f8745e66407f95824de71e02d3
parent0e04072c89052a6fc296b77df64f6501c36d0c92 (diff)
downloadscala-36b0e8178f74a2986bce5c9027b9a2b22a4e7527.tar.gz
scala-36b0e8178f74a2986bce5c9027b9a2b22a4e7527.tar.bz2
scala-36b0e8178f74a2986bce5c9027b9a2b22a4e7527.zip
Fix and test case for #1565; an anonymous funct...
Fix and test case for #1565; an anonymous function can now be used as a statement (primarily for use in the interpreter) unless it cannot be distinguished from a self-type declaration.
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala16
-rw-r--r--test/files/neg/xmltruncated6.check2
-rw-r--r--test/files/pos/bug1565.scala18
3 files changed, 31 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index f08b08b3d7..b8b8d1bffb 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1075,9 +1075,17 @@ trait Parsers extends NewScanners with MarkupParsers {
Match(stripParens(t), cases)
}
}
- if (inToken == ARROW && location != InTemplate) {
+ // in order to allow anonymous functions as statements (as opposed to expressions) inside
+ // templates, we have to disambiguate them from self type declarations - bug #1565
+ // The case still missed is unparenthesized single argument, like "x: Int => x + 1", which
+ // may be impossible to distinguish from a self-type and so remains an error. (See #1564)
+ def lhsIsTypedParamList() = t match {
+ case Parens(xs) if xs forall (_.isInstanceOf[Typed]) => true
+ case _ => false
+ }
+ if (inToken == ARROW && (location != InTemplate || lhsIsTypedParamList)) {
t = atPos(inSkipToken) {
- Function(convertToParams(t), if (location == Local) expr() else block())
+ Function(convertToParams(t), if (location != InBlock) expr() else block())
}
}
stripParens(t)
@@ -2501,10 +2509,10 @@ trait Parsers extends NewScanners with MarkupParsers {
acceptStatSep()
} else if (isExprIntro) {
stats += statement(InBlock)
- if (inToken != RBRACE && inToken != CASE) acceptStatSep()
+ if (inToken != RBRACE && inToken != CASE && inToken != EOF) acceptStatSep()
} else if (isDefIntro || isLocalModifier || in.token == AT) {
stats ++= localDef
- if (inToken == RBRACE || inToken == CASE) {
+ if (inToken == RBRACE || inToken == CASE || inToken == EOF) {
syntaxError("block must end in result expression, not in definition", false)
stats += Literal(()).setPos(inCurrentPos)
} else acceptStatSep()
diff --git a/test/files/neg/xmltruncated6.check b/test/files/neg/xmltruncated6.check
index 6123114560..f638f2f090 100644
--- a/test/files/neg/xmltruncated6.check
+++ b/test/files/neg/xmltruncated6.check
@@ -1,4 +1,4 @@
-xmltruncated6.scala:2: error: ';' expected but eof found.
+xmltruncated6.scala:2: error: in XML literal: expected end of Scala block
val stuff = <a>{ "no closing brace"
^
one error found
diff --git a/test/files/pos/bug1565.scala b/test/files/pos/bug1565.scala
new file mode 100644
index 0000000000..9a5bfd0882
--- /dev/null
+++ b/test/files/pos/bug1565.scala
@@ -0,0 +1,18 @@
+object Bug1565 {
+ object X0 { 0; (a : Int, b : Int, c : Int) => println(List(a, b)) }
+ def x() = { 0; (a : Int, b : Int) => println(List(a, b)) ; 0 }
+
+ (a : Int, b : Int) => println(List(a, b))
+
+ // various function syntaxes to exercise the parser
+ val xs = List(1,2,3)
+ xs.filter(x => x < 2)
+ xs.filter((x) => x < 2)
+ xs.filter { x => x < 2 }
+ xs.filter { _ < 2 }
+ xs.filter (_ < 2)
+ xs.foreach { e =>
+ val buf0 = e + 1
+ buf0
+ }
+} \ No newline at end of file