Skip to content

Commit 503011f

Browse files
committed
Check types for overriding conditions.
Closes #241 -- that took a while!
1 parent 86e35e4 commit 503011f

File tree

4 files changed

+34
-15
lines changed

4 files changed

+34
-15
lines changed

Diff for: src/dotty/tools/dotc/typer/RefChecks.scala

+15-5
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ object RefChecks {
172172
val sym1 = sym.underlyingSymbol
173173
def info = self.memberInfo(sym1)
174174
i"${if (showLocation) sym1.showLocated else sym1}${
175-
if (sym1.isAliasType) i", which equals $info"
176-
else if (sym1.isAbstractType) i" with bounds $info"
175+
if (sym1.isAliasType) i", which equals ${info.bounds.hi}"
176+
else if (sym1.isAbstractType) i" with bounds$info"
177177
else if (sym1.is(Module)) ""
178178
else if (sym1.isTerm) i" of type $info"
179179
else ""
@@ -229,6 +229,18 @@ object RefChecks {
229229
(if (otherAccess == "") "public" else "at least " + otherAccess))
230230
}
231231

232+
def compatibleTypes =
233+
if (member.isType) { // intersection of bounds to refined types must be nonempty
234+
member.is(BaseTypeArg) ||
235+
(memberTp <:< otherTp) || {
236+
val jointBounds = (memberTp.bounds & otherTp.bounds).bounds
237+
jointBounds.lo <:< jointBounds.hi
238+
}
239+
}
240+
else
241+
isDefaultGetter(member.name) || // default getters are not checked for compatibility
242+
memberTp.overrides(otherTp)
243+
232244
//Console.println(infoString(member) + " overrides " + infoString(other) + " in " + clazz);//DEBUG
233245

234246
// return if we already checked this combination elsewhere
@@ -321,9 +333,7 @@ object RefChecks {
321333
overrideError("cannot be used here - term macros cannot override abstract methods")
322334
} else if (other.is(Macro) && !member.is(Macro)) { // (1.10)
323335
overrideError("cannot be used here - only term macros can override term macros")
324-
} else if (member.isTerm && !isDefaultGetter(member.name) && !(memberTp overrides otherTp)) {
325-
// types don't need to have their bounds in an overriding relationship
326-
// since we automatically form their intersection when selecting.
336+
} else if (!compatibleTypes) {
327337
overrideError("has incompatible type" + err.whyNoMatchStr(memberTp, otherTp))
328338
} else {
329339
checkOverrideDeprecated()

Diff for: test/dotc/tests.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ class tests extends CompilerTest {
121121
@Test def neg_autoTupling2 = compileFile(negDir, "autoTuplingTest", xerrors = 3)
122122
@Test def neg_companions = compileFile(negDir, "companions", xerrors = 1)
123123
@Test def neg_over = compileFile(negDir, "over", xerrors = 3)
124-
@Test def neg_overrides = compileFile(negDir, "overrides", xerrors = 10)
124+
@Test def neg_overrides = compileFile(negDir, "overrides", xerrors = 12)
125125
@Test def neg_overrideClass = compileFile(negDir, "overrideClass", List("-language:Scala2"), xerrors = 1)
126126
@Test def neg_i39 = compileFile(negDir, "i39", xerrors = 2)
127127
@Test def neg_i50_volatile = compileFile(negDir, "i50-volatile", xerrors = 6)

Diff for: tests/neg/overrides.scala

+18
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
class Foo {
2+
type A = Int
3+
type B >: Int <: Int
4+
def get: A = 42
5+
}
6+
class Bar extends Foo {
7+
override type A = Any // error
8+
type B >: String <: Any // error
9+
override def get: A = "bar"
10+
}
11+
object Test {
12+
def main(args: Array[String]): Unit = {
13+
val foo: Foo = new Bar
14+
val i: Int = foo.get
15+
}
16+
}
17+
118
package p1 {
219
abstract class T1 {
320
protected def bug(p: Int = 1): Int // without 'protected' compiles fine
@@ -102,3 +119,4 @@ class C extends A {
102119
override def m: Int = 42 // error: has incompatible type
103120
}
104121
}
122+

Diff for: tests/pos/overrides.scala

-9
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,3 @@ class B extends A[Int] {
1111
f(2)()
1212

1313
}
14-
15-
class A1
16-
class A2
17-
class X1 {
18-
type T = A1
19-
}
20-
class Y1 extends X1 {
21-
override type T = A2
22-
}

0 commit comments

Comments
 (0)