Skip to content

Commit ea06d66

Browse files
committed
Check that overriding members refine the types of overridden ones.
Somehow this was lost in porting (or was this done somewhere else in scalac?).
1 parent b60f085 commit ea06d66

File tree

5 files changed

+40
-22
lines changed

5 files changed

+40
-22
lines changed

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

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -240,20 +240,8 @@ object Denotations {
240240
val sym1 = denot1.symbol
241241
val sym2 = denot2.symbol
242242
val sym2Accessible = sym2.isAccessibleFrom(pre)
243-
def resultType(tp: Type) = tp match {
244-
case tp @ MethodType(Nil, _) => tp.resultType
245-
case ExprType(rt) => rt
246-
case _ => NoType
247-
}
248-
def isAsGood(tp1: Type, tp2: Type) =
249-
tp1 <:< tp2 || {
250-
val rtp1 = resultType(tp1)
251-
val rtp2 = resultType(tp2)
252-
rtp1 <:< rtp2
253-
}
254243
def prefer(info1: Type, sym1: Symbol, info2: Type, sym2: Symbol) =
255-
isAsGood(info1, info2) &&
256-
(sym1.isAsConcrete(sym2) || !(info2 <:< info1))
244+
info1.overrides(info2) && (sym1.isAsConcrete(sym2) || !info2.overrides(info1))
257245
if (sym2Accessible && prefer(info2, sym2, info1, sym1)) denot2
258246
else {
259247
val sym1Accessible = sym1.isAccessibleFrom(pre)

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,22 @@ object Types {
533533
ctx.typeComparer.isSameType(this, that)
534534
}
535535

536+
/** Is this type a legal type for a member that overrides another
537+
* member of type `that`? This is the same as `<:<`, except that
538+
* the types ()T and => T are identified, and T is seen as overriding
539+
* either type.
540+
*/
541+
final def overrides(that: Type)(implicit ctx: Context) = {
542+
def result(tp: Type): Type = tp match {
543+
case ExprType(_) | MethodType(Nil, _) => tp.resultType
544+
case _ => tp
545+
}
546+
this <:< that || {
547+
val rthat = result(that)
548+
(rthat ne that) && result(this) <:< rthat
549+
}
550+
}
551+
536552
/** Is this type close enough to that type so that members
537553
* with the two type would override each other?d
538554
* This means:

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,13 @@ object RefChecks {
134134
def infoString0(sym: Symbol, showLocation: Boolean) = {
135135
val sym1 = sym.underlyingSymbol
136136
def info = self.memberInfo(sym1)
137-
if (showLocation) sym1.showLocated
138-
else
139-
i"$sym1${
140-
if (sym1.isAliasType) i", which equals $info"
141-
else if (sym1.isAbstractType) i" with bounds $info"
142-
else if (sym1.is(Module)) ""
143-
else if (sym1.isTerm) i" of type $info"
144-
else ""}"
137+
i"${if (showLocation) sym1.showLocated else sym1}${
138+
if (sym1.isAliasType) i", which equals $info"
139+
else if (sym1.isAbstractType) i" with bounds $info"
140+
else if (sym1.is(Module)) ""
141+
else if (sym1.isTerm) i" of type $info"
142+
else ""
143+
}"
145144
}
146145

147146
/* Check that all conditions for overriding `other` by `member`
@@ -287,6 +286,10 @@ object RefChecks {
287286
overrideError("cannot be used here - term macros cannot override abstract methods")
288287
} else if (other.is(Macro) && !member.is(Macro)) { // (1.10)
289288
overrideError("cannot be used here - only term macros can override term macros")
289+
} else if (member.isTerm && !isDefaultGetter(member.name) && !(memberTp overrides otherTp)) {
290+
// types don't need to have their bounds in an overriding relationship
291+
// since we automatically form their intersection when selecting.
292+
overrideError("has incompatible type" + err.whyNoMatchStr(memberTp, otherTp))
290293
} else {
291294
checkOverrideDeprecated()
292295
}

test/dotc/tests.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class tests extends CompilerTest {
7373
@Test def neg_autoTupling2 = compileFile(negDir, "autoTuplingTest", xerrors = 4)
7474
@Test def neg_companions = compileFile(negDir, "companions", xerrors = 1)
7575
@Test def neg_over = compileFile(negDir, "over", xerrors = 1)
76-
@Test def neg_overrides = compileFile(negDir, "overrides", xerrors = 4)
76+
@Test def neg_overrides = compileFile(negDir, "overrides", xerrors = 5)
7777
@Test def neg_projections = compileFile(negDir, "projections", xerrors = 1)
7878
@Test def neg_i39 = compileFile(negDir, "i39", xerrors = 1)
7979
@Test def neg_i50_volatile = compileFile(negDir, "i50-volatile", xerrors = 4)

tests/neg/overrides.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,14 @@ class X {
5757
class Y extends X {
5858
def f: A[Int] = ???
5959
}
60+
61+
62+
class A1
63+
class B1
64+
65+
class X1 {
66+
def f(): A1 = ???
67+
}
68+
class Y1 extends X1 {
69+
override def f(): B1 = ???
70+
}

0 commit comments

Comments
 (0)