Skip to content

Commit c6af272

Browse files
oderskyDarkDimius
authored andcommitted
Option for testing for double bindings
A double binding is if a named type gets assigned two denotations in the same period. This is a side-effect and also a race condition, so it's very bad. I am trying to eliminate all causes of this. But one cause which will likely remain are double defitions in a prgram, if a user writes class C { val x: Int val x: Int } Then it's really hard to avoid setting two meanings of C.this.x! That's why the testing against double bindings is enabled by a -YnoDoubleBindings option. The understanding is that -YnoDoubleBindings should be set only if there are no double def errors anticipated. Otherwise the program might fail with an assertion error before the double def error is reported.
1 parent d079c02 commit c6af272

File tree

3 files changed

+16
-7
lines changed

3 files changed

+16
-7
lines changed

src/dotty/tools/dotc/config/ScalaSettings.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ class ScalaSettings extends Settings.SettingGroup {
163163
val Ytyperdebug = BooleanSetting("-Ytyper-debug", "Trace all type assignments.")
164164
val Ypatmatdebug = BooleanSetting("-Ypatmat-debug", "Trace pattern matching translation.")
165165
val Yexplainlowlevel = BooleanSetting("-Yexplainlowlevel", "When explaining type errors, show types at a lower level.")
166+
val YnoDoubleBindings = BooleanSetting("-YnoDoubleBindings", "Assert no namedtype is bound twice (should be enabled only if program is error-free).")
166167

167168
val optimise = BooleanSetting("-optimise", "Generates faster bytecode by applying optimisations to the program") withAbbreviation "-optimize"
168169

src/dotty/tools/dotc/core/Types.scala

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,8 +1078,10 @@ object Types {
10781078
this
10791079
}
10801080

1081-
private[dotc] final def setDenot(denot: Denotation): Unit = {
1082-
if (Config.checkTermRefs) checkSymAssign(denot.symbol)
1081+
private[dotc] final def setDenot(denot: Denotation)(implicit ctx: Context): Unit = {
1082+
if (Config.checkTermRefs)
1083+
if (ctx.settings.YnoDoubleBindings.value)
1084+
checkSymAssign(denot.symbol)
10831085
lastDenotation = denot
10841086
lastSymbol = denot.symbol
10851087
}
@@ -1092,8 +1094,14 @@ object Types {
10921094
this
10931095
}
10941096

1095-
private[dotc] final def setSym(sym: Symbol): Unit = {
1096-
if (Config.checkTermRefs) checkSymAssign(sym)
1097+
private[dotc] final def setSym(sym: Symbol)(implicit ctx: Context): Unit = {
1098+
if (Config.checkTermRefs)
1099+
if (ctx.settings.YnoDoubleBindings.value)
1100+
checkSymAssign(sym)
1101+
uncheckedSetSym(sym)
1102+
}
1103+
1104+
private[dotc] final def uncheckedSetSym(sym: Symbol): Unit = {
10971105
lastDenotation = null
10981106
lastSymbol = sym
10991107
checkedPeriod = Nowhere
@@ -1238,7 +1246,7 @@ object Types {
12381246
trait WithNonMemberSym extends NamedType {
12391247
def fixedSym: Symbol
12401248
assert(fixedSym ne NoSymbol)
1241-
setSym(fixedSym)
1249+
uncheckedSetSym(fixedSym)
12421250

12431251
override def withDenot(denot: Denotation)(implicit ctx: Context): ThisType = {
12441252
assert(denot.symbol eq fixedSym)

test/dotc/tests.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class tests extends CompilerTest {
1414
// "-Yshow-suppressed-errors",
1515
"-pagewidth", "160"
1616
)
17-
val twice = List("#runs", "2")
17+
val twice = List("#runs", "2", "-YnoDoubleBindings")
1818
val doErase = List("-Ystop-before:terminal")
1919

2020
val posDir = "./tests/pos/"
@@ -55,7 +55,7 @@ class tests extends CompilerTest {
5555
@Test def neg_typedapply() = compileFile(negDir, "typedapply", xerrors = 4)
5656
@Test def neg_typedidents() = compileFile(negDir, "typedIdents", xerrors = 2)
5757
@Test def neg_assignments() = compileFile(negDir, "assignments", xerrors = 3)
58-
@Test def neg_typers() = compileFile(negDir, "typers", xerrors = 10)
58+
@Test def neg_typers() = compileFile(negDir, "typers", xerrors = 13)
5959
@Test def neg_privates() = compileFile(negDir, "privates", xerrors = 2)
6060
@Test def neg_rootImports = compileFile(negDir, "rootImplicits", xerrors = 2)
6161
@Test def neg_templateParents() = compileFile(negDir, "templateParents", xerrors = 3)

0 commit comments

Comments
 (0)