aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-11-14 17:10:54 +0100
committerFelix Mulder <felix.mulder@gmail.com>2016-11-17 10:04:23 +0100
commit6a398a2d551534157f14c4bba103c3dff9b85c18 (patch)
tree3fac284ff9d3dbb9a3fc149a615971576fbd8106
parentadb37eee8974be841ff5eef2655c23394c05badb (diff)
downloaddotty-6a398a2d551534157f14c4bba103c3dff9b85c18.tar.gz
dotty-6a398a2d551534157f14c4bba103c3dff9b85c18.tar.bz2
dotty-6a398a2d551534157f14c4bba103c3dff9b85c18.zip
Unlink type when entering clashing package
Here we unlink the existing type that clashes with the package to be entered into the symbol table, issue an error and the proceed to enter the rest of the symbols. My concern with this approach is what happens during typechecking if other things reference the unlinked type.
-rw-r--r--src/dotty/tools/dotc/reporting/diagnostic/messages.scala10
-rw-r--r--src/dotty/tools/dotc/typer/FrontEnd.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala15
-rw-r--r--tests/neg/i1708.scala2
-rw-r--r--tests/neg/i1708b.scala10
5 files changed, 35 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
index 5e6a402ef..a2557194c 100644
--- a/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
+++ b/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
@@ -790,7 +790,8 @@ object messages {
val explanation = ""
}
- case class SeqWildcardPatternPos()(implicit ctx: Context) extends Message(31) {
+ case class SeqWildcardPatternPos()(implicit ctx: Context)
+ extends Message(31) {
val kind = "Syntax"
val msg = "`_*' can be used only for last argument"
val explanation = {
@@ -891,4 +892,11 @@ object messages {
|"""
}
}
+
+ case class PkgDuplicateSymbol(existing: Symbol)(implicit ctx: Context)
+ extends Message(33) {
+ val kind = "Duplicate Type"
+ val msg = hl"trying to define package with same name as `$existing`"
+ val explanation = ""
+ }
}
diff --git a/src/dotty/tools/dotc/typer/FrontEnd.scala b/src/dotty/tools/dotc/typer/FrontEnd.scala
index 4ce24b633..7bbf0169b 100644
--- a/src/dotty/tools/dotc/typer/FrontEnd.scala
+++ b/src/dotty/tools/dotc/typer/FrontEnd.scala
@@ -35,7 +35,7 @@ class FrontEnd extends Phase {
else new Parser(unit.source).parse()
val printer = if (ctx.settings.Xprint.value.contains("parser")) default else typr
printer.println("parsed:\n" + unit.untpdTree.show)
- if (Config.checkPositions)
+ if (Config.checkPositions)
unit.untpdTree.checkPos(nonOverlapping = !unit.isJava && !ctx.reporter.hasErrors)
}
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 687de1e7a..22b5517dd 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -21,6 +21,7 @@ import Inferencing._
import transform.ValueClasses._
import TypeApplications._
import language.implicitConversions
+import reporting.diagnostic.messages._
trait NamerContextOps { this: Context =>
@@ -264,7 +265,7 @@ class Namer { typer: Typer =>
def preExisting = ctx.effectiveScope.lookup(name)
if (ctx.owner is PackageClass)
if (preExisting.isDefinedInCurrentRun)
- errorName(s"${preExisting.showLocated} is compiled twice")
+ errorName(s"${preExisting.showLocated} has already been compiled\nonce during this run")
else name
else
if ((!ctx.owner.isClass || name.isTypeName) && preExisting.exists)
@@ -343,8 +344,18 @@ class Namer { typer: Typer =>
case Select(qual: RefTree, _) => createPackageSymbol(qual).moduleClass
}
val existing = pkgOwner.info.decls.lookup(pid.name)
+
if ((existing is Package) && (pkgOwner eq existing.owner)) existing
- else ctx.newCompletePackageSymbol(pkgOwner, pid.name.asTermName).entered
+ else {
+ // If the name exists as type we should unlink the existing name from the
+ // scope, issue an error and continue, as usual:
+ val existingTpe = pkgOwner.info.decls.lookup(pid.name.toTypeName)
+ if (existingTpe != NoSymbol) {
+ ctx.error(PkgDuplicateSymbol(existingTpe), pid.pos)
+ pkgOwner.info.decls.openForMutations.unlink(existingTpe)
+ }
+ ctx.newCompletePackageSymbol(pkgOwner, pid.name.asTermName).entered
+ }
}
/** Expand tree and store in `expandedTree` */
diff --git a/tests/neg/i1708.scala b/tests/neg/i1708.scala
new file mode 100644
index 000000000..47bc456f3
--- /dev/null
+++ b/tests/neg/i1708.scala
@@ -0,0 +1,2 @@
+package foo { trait identifier }
+package foo { class identifier } // error
diff --git a/tests/neg/i1708b.scala b/tests/neg/i1708b.scala
new file mode 100644
index 000000000..9bcf1864d
--- /dev/null
+++ b/tests/neg/i1708b.scala
@@ -0,0 +1,10 @@
+package foo {
+ trait id {
+ def bar: Int
+ }
+}
+package foo {
+ package id { // error
+ class Bar
+ }
+}