Skip to content

Commit 5c641c9

Browse files
committed
Enforce rule that laziness is preserved when overriding.
1 parent 0d6cdd9 commit 5c641c9

File tree

7 files changed

+23
-11
lines changed

7 files changed

+23
-11
lines changed

src/dotty/tools/backend/jvm/DottyBackendInterface.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{
131131

132132
val hashMethodSym: Symbol = NoSymbol // used to dispatch ## on primitives to ScalaRuntime.hash. Should be implemented by a miniphase
133133
val externalEqualsNumNum: Symbol = defn.BoxesRunTimeModule.requiredMethod(nme.equalsNumNum)
134-
lazy val externalEqualsNumChar: Symbol = ??? // ctx.requiredMethod(BoxesRunTimeTypeRef, nme.equalsNumChar) // this method is private
134+
val externalEqualsNumChar: Symbol = NoSymbol // ctx.requiredMethod(BoxesRunTimeTypeRef, nme.equalsNumChar) // this method is private
135135
val externalEqualsNumObject: Symbol = defn.BoxesRunTimeModule.requiredMethod(nme.equalsNumObject)
136136
val externalEquals: Symbol = defn.BoxesRunTimeClass.info.decl(nme.equals_).suchThat(toDenot(_).info.firstParamTypes.size == 2).symbol
137137
val MaxFunctionArity: Int = Definitions.MaxFunctionArity

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ object Contexts {
497497
}
498498

499499
@sharable object NoContext extends Context {
500-
lazy val base = unsupported("base")
500+
val base = null
501501
override val implicits: ContextualImplicits = new ContextualImplicits(Nil, null)(this)
502502
}
503503

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ object RefChecks {
211211
if (!(hasErrors && member.is(Synthetic) && member.is(Module))) {
212212
// suppress errors relating toi synthetic companion objects if other override
213213
// errors (e.g. relating to the companion class) have already been reported.
214-
if (member.owner == clazz) ctx.error(fullmsg+", member = $member", member.pos)
214+
if (member.owner == clazz) ctx.error(fullmsg, member.pos)
215215
else mixinOverrideErrors += new MixinOverrideError(member, fullmsg)
216216
hasErrors = true
217217
}
@@ -330,10 +330,12 @@ object RefChecks {
330330
"(this rule is designed to prevent ``accidental overrides'')")
331331
} else if (other.isStable && !member.isStable) { // (1.4)
332332
overrideError("needs to be a stable, immutable value")
333-
} else if (member.is(Lazy) && !other.isRealMethod && !other.is(Deferred | Lazy)) {
334-
overrideError("cannot override a concrete non-lazy value")
335-
} else if (other.is(Lazy, butNot = Deferred) && !other.isRealMethod && !member.is(Lazy)) {
336-
overrideError("must be declared lazy to override a concrete lazy value")
333+
} else if (member.is(ModuleVal) && !other.isRealMethod && !other.is(Deferred | Lazy)) {
334+
overrideError("may not override a concrete non-lazy value")
335+
} else if (member.is(Lazy, butNot = Module) && !other.isRealMethod && !other.is(Lazy)) {
336+
overrideError("may not override a non-lazy value")
337+
} else if (other.is(Lazy) && !other.isRealMethod && !member.is(Lazy)) {
338+
overrideError("must be declared lazy to override a lazy value")
337339
} else if (other.is(Deferred) && member.is(Macro) && member.extendedOverriddenSymbols.forall(_.is(Deferred))) { // (1.9)
338340
overrideError("cannot be used here - term macros cannot override abstract methods")
339341
} else if (other.is(Macro) && !member.is(Macro)) { // (1.10)

test/dotc/tests.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,10 @@ class tests extends CompilerTest {
117117
@Test def neg_autoTupling2 = compileFile(negDir, "autoTuplingTest", xerrors = 3)
118118
@Test def neg_companions = compileFile(negDir, "companions", xerrors = 1)
119119
@Test def neg_over = compileFile(negDir, "over", xerrors = 3)
120-
@Test def neg_overrides = compileFile(negDir, "overrides", xerrors = 12)
120+
@Test def neg_overrides = compileFile(negDir, "overrides", xerrors = 14)
121121
@Test def neg_overrideClass = compileFile(negDir, "overrideClass", List("-language:Scala2"), xerrors = 1)
122122
@Test def neg_i39 = compileFile(negDir, "i39", xerrors = 2)
123-
@Test def neg_i50_volatile = compileFile(negDir, "i50-volatile", xerrors = 6)
123+
@Test def neg_i50_volatile = compileFile(negDir, "i50-volatile", xerrors = 5)
124124
@Test def neg_zoo = compileFile(negDir, "zoo", xerrors = 12)
125125

126126
val negTailcallDir = negDir + "tailcall/"

tests/neg/overrides.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,16 @@ class Foo {
33
type B >: Int <: Int
44
def get: A = 42
55
}
6-
class Bar extends Foo {
6+
trait T {
7+
lazy val x: Int
8+
val y: Int
9+
}
10+
class Bar extends Foo with T {
711
override type A = Any // error
812
type B >: String <: Any // error
913
override def get: A = "bar"
14+
val x = 2 // error
15+
lazy val y = 3 // error
1016
}
1117
object Test {
1218
def main(args: Array[String]): Unit = {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
trait Message {
2+
def first(x: Int)
3+
def second
4+
}

tests/run/t429.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
object Test {
22
abstract class A {
33
Console.print("A");
4-
val x: Int;
4+
lazy val x: Int;
55
val y: Int = {Console.print("y"); x + 1}
66
}
77
class B extends A {

0 commit comments

Comments
 (0)