diff options
author | Guillaume Martres <smarter@ubuntu.com> | 2017-03-28 18:20:18 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-28 18:20:18 +0200 |
commit | 9ba9b147fb8d7894761e2f2fb18b08601981db20 (patch) | |
tree | 0b8b34b9bbdeee0591c10f55f7e43b7d0d0ac02b /compiler/src/dotty/tools/dotc | |
parent | d9dedc5ac6690fa724271be33550e77696e193cb (diff) | |
parent | b6411818b2e84c0a28c501e2814de4cfde720208 (diff) | |
download | dotty-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
Diffstat (limited to 'compiler/src/dotty/tools/dotc')
-rw-r--r-- | compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala | 2 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Namer.scala | 23 |
2 files changed, 22 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) |