Skip to content

Commit 6a398a2

Browse files
committed
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.
1 parent adb37ee commit 6a398a2

File tree

5 files changed

+35
-4
lines changed

5 files changed

+35
-4
lines changed

src/dotty/tools/dotc/reporting/diagnostic/messages.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,8 @@ object messages {
790790
val explanation = ""
791791
}
792792

793-
case class SeqWildcardPatternPos()(implicit ctx: Context) extends Message(31) {
793+
case class SeqWildcardPatternPos()(implicit ctx: Context)
794+
extends Message(31) {
794795
val kind = "Syntax"
795796
val msg = "`_*' can be used only for last argument"
796797
val explanation = {
@@ -891,4 +892,11 @@ object messages {
891892
|"""
892893
}
893894
}
895+
896+
case class PkgDuplicateSymbol(existing: Symbol)(implicit ctx: Context)
897+
extends Message(33) {
898+
val kind = "Duplicate Type"
899+
val msg = hl"trying to define package with same name as `$existing`"
900+
val explanation = ""
901+
}
894902
}

src/dotty/tools/dotc/typer/FrontEnd.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class FrontEnd extends Phase {
3535
else new Parser(unit.source).parse()
3636
val printer = if (ctx.settings.Xprint.value.contains("parser")) default else typr
3737
printer.println("parsed:\n" + unit.untpdTree.show)
38-
if (Config.checkPositions)
38+
if (Config.checkPositions)
3939
unit.untpdTree.checkPos(nonOverlapping = !unit.isJava && !ctx.reporter.hasErrors)
4040
}
4141

src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import Inferencing._
2121
import transform.ValueClasses._
2222
import TypeApplications._
2323
import language.implicitConversions
24+
import reporting.diagnostic.messages._
2425

2526
trait NamerContextOps { this: Context =>
2627

@@ -264,7 +265,7 @@ class Namer { typer: Typer =>
264265
def preExisting = ctx.effectiveScope.lookup(name)
265266
if (ctx.owner is PackageClass)
266267
if (preExisting.isDefinedInCurrentRun)
267-
errorName(s"${preExisting.showLocated} is compiled twice")
268+
errorName(s"${preExisting.showLocated} has already been compiled\nonce during this run")
268269
else name
269270
else
270271
if ((!ctx.owner.isClass || name.isTypeName) && preExisting.exists)
@@ -343,8 +344,18 @@ class Namer { typer: Typer =>
343344
case Select(qual: RefTree, _) => createPackageSymbol(qual).moduleClass
344345
}
345346
val existing = pkgOwner.info.decls.lookup(pid.name)
347+
346348
if ((existing is Package) && (pkgOwner eq existing.owner)) existing
347-
else ctx.newCompletePackageSymbol(pkgOwner, pid.name.asTermName).entered
349+
else {
350+
// If the name exists as type we should unlink the existing name from the
351+
// scope, issue an error and continue, as usual:
352+
val existingTpe = pkgOwner.info.decls.lookup(pid.name.toTypeName)
353+
if (existingTpe != NoSymbol) {
354+
ctx.error(PkgDuplicateSymbol(existingTpe), pid.pos)
355+
pkgOwner.info.decls.openForMutations.unlink(existingTpe)
356+
}
357+
ctx.newCompletePackageSymbol(pkgOwner, pid.name.asTermName).entered
358+
}
348359
}
349360

350361
/** Expand tree and store in `expandedTree` */

tests/neg/i1708.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
package foo { trait identifier }
2+
package foo { class identifier } // error

tests/neg/i1708b.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package foo {
2+
trait id {
3+
def bar: Int
4+
}
5+
}
6+
package foo {
7+
package id { // error
8+
class Bar
9+
}
10+
}

0 commit comments

Comments
 (0)