aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Martres <smarter@ubuntu.com>2017-03-28 18:20:18 +0200
committerGitHub <noreply@github.com>2017-03-28 18:20:18 +0200
commit9ba9b147fb8d7894761e2f2fb18b08601981db20 (patch)
tree0b8b34b9bbdeee0591c10f55f7e43b7d0d0ac02b
parentd9dedc5ac6690fa724271be33550e77696e193cb (diff)
parentb6411818b2e84c0a28c501e2814de4cfde720208 (diff)
downloaddotty-9ba9b147fb8d7894761e2f2fb18b08601981db20.tar.gz
dotty-9ba9b147fb8d7894761e2f2fb18b08601981db20.tar.bz2
dotty-9ba9b147fb8d7894761e2f2fb18b08601981db20.zip
Merge pull request #2139 from dotty-staging/fix/false-companion
Fix #2137: Create dummy companions for top-level objects without a real one
-rw-r--r--compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Namer.scala23
-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
6 files changed, 39 insertions, 3 deletions
diff --git a/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala b/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala
index c392880c5..fefa63f6f 100644
--- a/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala
+++ b/compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala
@@ -175,7 +175,7 @@ private class ExtractDependenciesCollector(implicit val ctx: Context) extends tp
override def traverse(tree: Tree)(implicit ctx: Context): Unit = {
tree match {
case Import(expr, selectors) =>
- def lookupImported(name: Name) = expr.tpe.select(name).typeSymbol
+ def lookupImported(name: Name) = expr.tpe.member(name).symbol
def addImported(name: Name) = {
// importing a name means importing both a term and a type (if they exist)
addDependency(lookupImported(name.toTermName))
diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala
index 2cefc52a0..4077d8d65 100644
--- a/compiler/src/dotty/tools/dotc/typer/Namer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala
@@ -570,8 +570,8 @@ class Namer { typer: Typer =>
/** Create links between companion object and companion class */
def createLinks(classTree: TypeDef, moduleTree: TypeDef)(implicit ctx: Context) = {
- val claz = ctx.denotNamed(classTree.name.encode).symbol
- val modl = ctx.denotNamed(moduleTree.name.encode).symbol
+ val claz = ctx.effectiveScope.lookup(classTree.name.encode)
+ val modl = ctx.effectiveScope.lookup(moduleTree.name.encode)
ctx.synthesizeCompanionMethod(nme.COMPANION_CLASS_METHOD, claz, modl).entered
ctx.synthesizeCompanionMethod(nme.COMPANION_MODULE_METHOD, modl, claz).entered
}
@@ -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.effectiveScope.lookup(moduleName.encode)
+ if (moduleSym.isDefinedInCurrentRun) {
+ val className = moduleName.stripModuleClassSuffix.toTypeName
+ val classSym = ctx.effectiveScope.lookup(className.encode)
+ 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
+}