summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2013-06-25 17:08:45 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-06-25 17:08:45 -0700
commit807dc9e15fa36cc92a9bd2802dbfbff2de5d0dec (patch)
tree14c9e0b3412df3ff8bb699d7effb0c0b57f930c0
parent2a17db002758379fe0b9ee2a4e41ac9e3ca6c30d (diff)
parent9f2b2894ba2b45135943e943d13898aefc333cc2 (diff)
downloadscala-807dc9e15fa36cc92a9bd2802dbfbff2de5d0dec.tar.gz
scala-807dc9e15fa36cc92a9bd2802dbfbff2de5d0dec.tar.bz2
scala-807dc9e15fa36cc92a9bd2802dbfbff2de5d0dec.zip
Merge pull request #2659 from retronym/ticket/7584
SI-7584 Fix typer regression with by-name parameter types
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala11
-rw-r--r--test/files/pos/t7584.scala11
-rw-r--r--test/files/run/t7584.check6
-rw-r--r--test/files/run/t7584.flags1
-rw-r--r--test/files/run/t7584.scala14
5 files changed, 41 insertions, 2 deletions
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 30ec555bc5..5c92512193 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -98,7 +98,7 @@ abstract class TreeInfo {
*/
def isStableIdentifier(tree: Tree, allowVolatile: Boolean): Boolean =
tree match {
- case Ident(_) => symOk(tree.symbol) && tree.symbol.isStable && !tree.symbol.hasVolatileType // TODO SPEC: not required by spec
+ case i @ Ident(_) => isStableIdent(i)
case Select(qual, _) => isStableMemberOf(tree.symbol, qual, allowVolatile) && isPath(qual, allowVolatile)
case Apply(Select(free @ Ident(_), nme.apply), _) if free.symbol.name endsWith nme.REIFY_FREE_VALUE_SUFFIX =>
// see a detailed explanation of this trick in `GenSymbols.reifyFreeTerm`
@@ -119,6 +119,13 @@ abstract class TreeInfo {
typeOk(tree.tpe) && (allowVolatile || !hasVolatileType(tree)) && !definitions.isByNameParamType(tree.tpe)
)
+ private def isStableIdent(tree: Ident): Boolean = (
+ symOk(tree.symbol)
+ && tree.symbol.isStable
+ && !definitions.isByNameParamType(tree.tpe)
+ && !tree.symbol.hasVolatileType // TODO SPEC: not required by spec
+ )
+
/** Is `tree`'s type volatile? (Ignored if its symbol has the @uncheckedStable annotation.)
*/
def hasVolatileType(tree: Tree): Boolean =
@@ -201,7 +208,7 @@ abstract class TreeInfo {
}
def isWarnableSymbol = {
val sym = tree.symbol
- (sym == null) || !(sym.isModule || sym.isLazy) || {
+ (sym == null) || !(sym.isModule || sym.isLazy || definitions.isByNameParamType(sym.tpe_*)) || {
debuglog("'Pure' but side-effecting expression in statement position: " + tree)
false
}
diff --git a/test/files/pos/t7584.scala b/test/files/pos/t7584.scala
new file mode 100644
index 0000000000..52d127ecb9
--- /dev/null
+++ b/test/files/pos/t7584.scala
@@ -0,0 +1,11 @@
+object Test {
+ def fold[A, B](f: (A, => B) => B) = ???
+ def f[A, B](x: A, y: B): B = ???
+ def bip[A, B] = fold[A, B]((x, y) => f(x, y))
+ def bop[A, B] = fold[A, B](f)
+
+ // these work:
+ fold[Int, Int]((x, y) => f(x, y))
+ fold[Int, Int](f)
+}
+
diff --git a/test/files/run/t7584.check b/test/files/run/t7584.check
new file mode 100644
index 0000000000..9f53e5dde5
--- /dev/null
+++ b/test/files/run/t7584.check
@@ -0,0 +1,6 @@
+no calls
+call A
+a
+call B twice
+b
+b
diff --git a/test/files/run/t7584.flags b/test/files/run/t7584.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/files/run/t7584.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/run/t7584.scala b/test/files/run/t7584.scala
new file mode 100644
index 0000000000..6d7f4f7ebb
--- /dev/null
+++ b/test/files/run/t7584.scala
@@ -0,0 +1,14 @@
+// Test case added to show the behaviour of functions with
+// by-name parameters. The evaluation behaviour was already correct.
+//
+// We did flush out a spurious "pure expression does nothing in statement position"
+// warning, hence -Xfatal-warnings in the flags file.
+object Test extends App {
+ def foo(f: (=> Int, => Int) => Unit) = f({println("a"); 0}, {println("b"); 1})
+ println("no calls")
+ foo((a, b) => ())
+ println("call A")
+ foo((a, b) => a)
+ println("call B twice")
+ foo((a, b) => {b; b})
+}