Skip to content

Commit 5860250

Browse files
committed
parameterize checkAllOverrides with a subtype checker
1 parent 93eb3bb commit 5860250

File tree

3 files changed

+20
-8
lines changed

3 files changed

+20
-8
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,12 +1071,15 @@ object Types {
10711071
* @param relaxedCheck if true type `Null` becomes a subtype of non-primitive value types in TypeComparer.
10721072
* @param matchLoosely if true the types `=> T` and `()T` are seen as overriding each other.
10731073
* @param checkClassInfo if true we check that ClassInfos are within bounds of abstract types
1074+
*
1075+
* @param isSubType a function used for checking subtype relationships.
10741076
*/
1075-
final def overrides(that: Type, relaxedCheck: Boolean, matchLoosely: => Boolean, checkClassInfo: Boolean = true)(using Context): Boolean = {
1077+
final def overrides(that: Type, relaxedCheck: Boolean, matchLoosely: => Boolean, checkClassInfo: Boolean = true,
1078+
isSubType: Context ?=> (Type, Type) => Boolean = (tp1, tp2) => tp1 frozen_<:< tp2)(using Context): Boolean = {
10761079
val overrideCtx = if relaxedCheck then ctx.relaxedOverrideContext else ctx
10771080
inContext(overrideCtx) {
10781081
!checkClassInfo && this.isInstanceOf[ClassInfo]
1079-
|| (this.widenExpr frozen_<:< that.widenExpr)
1082+
|| isSubType(this.widenExpr, that.widenExpr)
10801083
|| matchLoosely && {
10811084
val this1 = this.widenNullaryMethod
10821085
val that1 = that.widenNullaryMethod

compiler/src/dotty/tools/dotc/transform/OverridingPairs.scala

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,13 @@ object OverridingPairs:
200200
/** Let `member` and `other` be members of some common class C with types
201201
* `memberTp` and `otherTp` in C. Are the two symbols considered an overriding
202202
* pair in C? We assume that names already match so we test only the types here.
203-
* @param fallBack A function called if the initial test is false and
204-
* `member` and `other` are term symbols.
203+
* @param fallBack A function called if the initial test is false and
204+
* `member` and `other` are term symbols.
205+
* @param isSubType A function to be used for checking subtype relationships
206+
* between term fields.
205207
*/
206-
def isOverridingPair(member: Symbol, memberTp: Type, other: Symbol, otherTp: Type, fallBack: => Boolean = false)(using Context): Boolean =
208+
def isOverridingPair(member: Symbol, memberTp: Type, other: Symbol, otherTp: Type, fallBack: => Boolean = false,
209+
isSubType: Context ?=> (Type, Type) => Boolean = (tp1, tp2) => tp1 frozen_<:< tp2)(using Context): Boolean =
207210
if member.isType then // intersection of bounds to refined types must be nonempty
208211
memberTp.bounds.hi.hasSameKindAs(otherTp.bounds.hi)
209212
&& (
@@ -222,6 +225,6 @@ object OverridingPairs:
222225
val relaxedOverriding = ctx.explicitNulls && (member.is(JavaDefined) || other.is(JavaDefined))
223226
member.name.is(DefaultGetterName) // default getters are not checked for compatibility
224227
|| memberTp.overrides(otherTp, relaxedOverriding,
225-
member.matchNullaryLoosely || other.matchNullaryLoosely || fallBack)
228+
member.matchNullaryLoosely || other.matchNullaryLoosely || fallBack, isSubType = isSubType)
226229

227230
end OverridingPairs

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,13 @@ object RefChecks {
290290
* TODO check that classes are not overridden
291291
* TODO This still needs to be cleaned up; the current version is a straight port of what was there
292292
* before, but it looks too complicated and method bodies are far too large.
293+
*
294+
* @param isSubType A function used for checking the subtype relationship between
295+
* two types `tp1` and `tp2` when checking the compatibility
296+
* between overriding pairs, with possible adaptations applied
297+
* (e.g. box adaptation in capture checking).
293298
*/
294-
def checkAllOverrides(clazz: ClassSymbol)(using Context): Unit = {
299+
def checkAllOverrides(clazz: ClassSymbol, isSubType: Context ?=> Symbol => (Type, Type) => Boolean = _ => (tp1, tp2) => tp1 frozen_<:< tp2)(using Context): Unit = {
295300
val self = clazz.thisType
296301
val upwardsSelf = upwardsThisType(clazz)
297302
var hasErrors = false
@@ -344,7 +349,8 @@ object RefChecks {
344349
isOverridingPair(member, memberTp, other, otherTp,
345350
fallBack = warnOnMigration(
346351
overrideErrorMsg("no longer has compatible type"),
347-
(if (member.owner == clazz) member else clazz).srcPos, version = `3.0`))
352+
(if (member.owner == clazz) member else clazz).srcPos, version = `3.0`),
353+
isSubType = isSubType(member))
348354
catch case ex: MissingType =>
349355
// can happen when called with upwardsSelf as qualifier of memberTp and otherTp,
350356
// because in that case we might access types that are not members of the qualifier.

0 commit comments

Comments
 (0)