diff options
author | Felix Mulder <felix.mulder@gmail.com> | 2016-11-14 17:10:54 +0100 |
---|---|---|
committer | Felix Mulder <felix.mulder@gmail.com> | 2016-11-17 10:04:23 +0100 |
commit | 6a398a2d551534157f14c4bba103c3dff9b85c18 (patch) | |
tree | 3fac284ff9d3dbb9a3fc149a615971576fbd8106 | |
parent | adb37eee8974be841ff5eef2655c23394c05badb (diff) | |
download | dotty-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.scala | 10 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/FrontEnd.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 15 | ||||
-rw-r--r-- | tests/neg/i1708.scala | 2 | ||||
-rw-r--r-- | tests/neg/i1708b.scala | 10 |
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 + } +} |