aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Martres <smarter@ubuntu.com>2014-12-28 17:42:04 +0100
committerGuillaume Martres <smarter@ubuntu.com>2015-02-11 16:33:20 +0100
commit5150cad821a9e7db821732eeb19019b96e1975a0 (patch)
treed69db0675c5b79952ec8e44f7dff48fc24316e34
parent03a2c6e74c07d08e79ee3323d3c1c38eb3d588ef (diff)
downloaddotty-5150cad821a9e7db821732eeb19019b96e1975a0.tar.gz
dotty-5150cad821a9e7db821732eeb19019b96e1975a0.tar.bz2
dotty-5150cad821a9e7db821732eeb19019b96e1975a0.zip
Prevent block types with references to local symbols
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala2
-rw-r--r--test/dotc/tests.scala2
-rw-r--r--tests/neg/escapingRefs.scala10
-rw-r--r--tests/pos/anonClassSubtyping.scala9
4 files changed, 22 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 59aba4723..1e07cbf79 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -472,7 +472,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val Block(stats, expr) = block
val leaks = escapingRefs(block)
if (leaks.isEmpty) block
- else if (isFullyDefined(pt, ForceDegree.all)) {
+ else if (isFullyDefined(pt, ForceDegree.none)) {
val expr1 = Typed(expr, TypeTree(pt))
cpy.Block(block)(stats, expr1) withType expr1.tpe // no assignType here because avoid is redundant
} else if (!forcedDefined) {
diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala
index 524f3ce12..a9ce5a18a 100644
--- a/test/dotc/tests.scala
+++ b/test/dotc/tests.scala
@@ -67,6 +67,7 @@ class tests extends CompilerTest {
@Test def pos_subtyping = compileFile(posDir, "subtyping")
@Test def pos_t2613 = compileFile(posSpecialDir, "t2613")(allowDeepSubtypes)
@Test def pos_packageObj = compileFile(posDir, "i0239")
+ @Test def pos_anonClassSubtyping = compileFile(posDir, "anonClassSubtyping")
@Test def pos_all = compileFiles(posDir, failedOther)
@@ -119,6 +120,7 @@ class tests extends CompilerTest {
@Test def neg_i0248_inherit_refined = compileFile(negDir, "i0248-inherit-refined", xerrors = 4)
@Test def neg_i0281 = compileFile(negDir, "i0281-null-primitive-conforms", xerrors = 3)
@Test def neg_moduleSubtyping = compileFile(negDir, "moduleSubtyping", xerrors = 4)
+ @Test def neg_escapingRefs = compileFile(negDir, "escapingRefs", xerrors = 2)
@Test def dotc = compileDir(dotcDir + "tools/dotc", failedOther)(allowDeepSubtypes)
@Test def dotc_ast = compileDir(dotcDir + "tools/dotc/ast", failedOther) // similar to dotc_config
diff --git a/tests/neg/escapingRefs.scala b/tests/neg/escapingRefs.scala
new file mode 100644
index 000000000..9a76eb414
--- /dev/null
+++ b/tests/neg/escapingRefs.scala
@@ -0,0 +1,10 @@
+object O {
+ class A
+ class B
+ def f[T](x: T, y: T): T = y
+
+ val x: A = f(new A { }, new B { })
+
+ val y = f({ class C { def member: Int = 1 }; new C }, { class C { def member: Int = 1 }; new C })
+ val z = y.member
+}
diff --git a/tests/pos/anonClassSubtyping.scala b/tests/pos/anonClassSubtyping.scala
new file mode 100644
index 000000000..b5591d826
--- /dev/null
+++ b/tests/pos/anonClassSubtyping.scala
@@ -0,0 +1,9 @@
+object O {
+ class A
+ class B
+ def f[T](x: T, y: T): T = x
+
+ val x: A = f(new A { }, new A)
+
+ val y: A | B = f(new A { }, new B)
+}