aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Martres <smarter@ubuntu.com>2017-03-23 17:31:43 +0100
committerGuillaume Martres <smarter@ubuntu.com>2017-03-23 21:11:17 +0100
commit65455bbcaace514ea34a30a3fc102c8ecee16498 (patch)
tree0255ecba500bc6011652d9c6c6e80b128ae9b5a3
parent6ab7c1da8987806e0e3cbc820781b6ef955c109b (diff)
downloaddotty-65455bbcaace514ea34a30a3fc102c8ecee16498.tar.gz
dotty-65455bbcaace514ea34a30a3fc102c8ecee16498.tar.bz2
dotty-65455bbcaace514ea34a30a3fc102c8ecee16498.zip
Fix #2137: Create dummy companions for top-level objects without a real one
Previously, we sometimes ended up forcing a companion class symbol from a previous run or from the classpath which lead to weird issues like in `false-companion`. Even if we end up not forcing such a symbol, its presence can still lead to issue: before this commit incremental compilation of `dotty-compiler-bootstrapped` was broken because we recorded a false dependency on the non-bootstrapped `dotty-compiler` jar. The added test is currently marked pending because it does not work with JUnit (which doesn't handle separate compilation), only partest. I didn't managed to get it to work right, and this won't be necessary once our testing framework is overhauled by https://github.com/lampepfl/dotty/pull/2125 anyway, so I'll just have to remember to enable this test afterwards.
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Namer.scala19
-rw-r--r--tests/pending/pos/false-companion/00_outerinnerTest_2.scala5
-rw-r--r--tests/pending/pos/false-companion/01_outerinnerFoo_2.scala5
-rw-r--r--tests/pending/pos/false-companion/outerFoo_1.scala2
-rw-r--r--tests/pending/pos/false-companion/outerinnerFoo_1.scala5
5 files changed, 36 insertions, 0 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala
index 2cefc52a0..706e8b5bf 100644
--- a/compiler/src/dotty/tools/dotc/typer/Namer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala
@@ -605,6 +605,25 @@ class Namer { typer: Typer =>
case EmptyTree =>
}
}
+
+ // If a top-level object has no companion class in the current run, we
+ // enter a dummy companion class symbol (`denot.isAbsent` returns true) in
+ // scope. This ensures that we never use a companion from a previous run
+ // or from the classpath. See tests/pos/false-companion for an
+ // example where this matters.
+ if (ctx.owner.is(PackageClass)) {
+ for (cdef @ TypeDef(moduleName, _) <- moduleDef.values) {
+ val moduleSym = ctx.denotNamed(moduleName.encode).symbol
+ if (moduleSym.isDefinedInCurrentRun) {
+ val className = moduleName.stripModuleClassSuffix.toTypeName
+ val classSym = ctx.denotNamed(className.encode).symbol
+ if (!classSym.isDefinedInCurrentRun) {
+ val absentClassSymbol = ctx.newClassSymbol(ctx.owner, className, EmptyFlags, _ => NoType)
+ enterSymbol(absentClassSymbol)
+ }
+ }
+ }
+ }
}
stats.foreach(expand)
diff --git a/tests/pending/pos/false-companion/00_outerinnerTest_2.scala b/tests/pending/pos/false-companion/00_outerinnerTest_2.scala
new file mode 100644
index 000000000..8f5802343
--- /dev/null
+++ b/tests/pending/pos/false-companion/00_outerinnerTest_2.scala
@@ -0,0 +1,5 @@
+package outer
+package inner
+object Test {
+ val x: Foo = new Foo
+}
diff --git a/tests/pending/pos/false-companion/01_outerinnerFoo_2.scala b/tests/pending/pos/false-companion/01_outerinnerFoo_2.scala
new file mode 100644
index 000000000..111f7fcd5
--- /dev/null
+++ b/tests/pending/pos/false-companion/01_outerinnerFoo_2.scala
@@ -0,0 +1,5 @@
+package outer
+package inner
+object Foo {
+ // val a: Int = 1
+}
diff --git a/tests/pending/pos/false-companion/outerFoo_1.scala b/tests/pending/pos/false-companion/outerFoo_1.scala
new file mode 100644
index 000000000..8c2ef109c
--- /dev/null
+++ b/tests/pending/pos/false-companion/outerFoo_1.scala
@@ -0,0 +1,2 @@
+package outer
+class Foo
diff --git a/tests/pending/pos/false-companion/outerinnerFoo_1.scala b/tests/pending/pos/false-companion/outerinnerFoo_1.scala
new file mode 100644
index 000000000..29f3df724
--- /dev/null
+++ b/tests/pending/pos/false-companion/outerinnerFoo_1.scala
@@ -0,0 +1,5 @@
+package outer
+package inner
+object Foo {
+ val a: Int = 1
+}