Skip to content

Commit fec05c9

Browse files
committed
Remove special overriding logic for explicit nulls
1 parent bd1f004 commit fec05c9

File tree

8 files changed

+16
-45
lines changed

8 files changed

+16
-45
lines changed

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -785,9 +785,6 @@ object Contexts {
785785
def withNotNullInfos(infos: List[NotNullInfo]): Context =
786786
if !c.explicitNulls || (c.notNullInfos eq infos) then c else c.fresh.setNotNullInfos(infos)
787787

788-
def relaxedOverrideContext: Context =
789-
c.withModeBits(c.mode &~ Mode.SafeNulls | Mode.RelaxedOverriding)
790-
791788
// TODO: Fix issue when converting ModeChanges and FreshModeChanges to extension givens
792789
extension (c: Context) {
793790
final def withModeBits(mode: Mode): Context =

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -478,12 +478,11 @@ object Denotations {
478478
else if sym1.is(Method) && !sym2.is(Method) then 1
479479
else 0
480480

481-
val relaxedOverriding = ctx.explicitNulls && (sym1.is(JavaDefined) || sym2.is(JavaDefined))
482481
val matchLoosely = sym1.matchNullaryLoosely || sym2.matchNullaryLoosely
483482

484-
if symScore <= 0 && info2.overrides(info1, relaxedOverriding, matchLoosely, checkClassInfo = false) then
483+
if symScore <= 0 && info2.overrides(info1, matchLoosely, checkClassInfo = false) then
485484
denot2
486-
else if symScore >= 0 && info1.overrides(info2, relaxedOverriding, matchLoosely, checkClassInfo = false) then
485+
else if symScore >= 0 && info1.overrides(info2, matchLoosely, checkClassInfo = false) then
487486
denot1
488487
else
489488
val jointInfo = infoMeet(info1, info2, safeIntersection)

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ object Mode {
105105

106106
/** Use previous Scheme for implicit resolution. Currently significant
107107
* in 3.0-migration where we use Scala-2's scheme instead and in 3.5 and 3.6-migration
108-
* where we use the previous scheme up to 3.4 for comparison with the new scheme.
108+
* where we use the previous scheme up to 3.4 for comparison with the new scheme.
109109
*/
110110
val OldImplicitResolution: Mode = newMode(15, "OldImplicitResolution")
111111

@@ -163,11 +163,6 @@ object Mode {
163163
*/
164164
val ForceInline: Mode = newMode(29, "ForceInline")
165165

166-
/** This mode is enabled when we check Java overriding in explicit nulls.
167-
* Type `Null` becomes a subtype of non-primitive value types in TypeComparer.
168-
*/
169-
val RelaxedOverriding: Mode = newMode(30, "RelaxedOverriding")
170-
171166
/** Skip inlining of methods. */
172167
val NoInline: Mode = newMode(31, "NoInline")
173168
}

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

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -967,18 +967,9 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
967967
|| compareGADT
968968
|| tryLiftedToThis1
969969
case _ =>
970-
// `Mode.RelaxedOverriding` is only enabled when checking Java overriding
971-
// in explicit nulls, and `Null` becomes a bottom type, which allows
972-
// `T | Null` being a subtype of `T`.
973-
// A type variable `T` from Java is translated to `T >: Nothing <: Any`.
974-
// However, `null` can always be a value of `T` for Java side.
975-
// So the best solution here is to let `Null` be a subtype of non-primitive
976-
// value types temporarily.
977970
def isNullable(tp: Type): Boolean = tp.dealias match
978971
case tp: TypeRef =>
979-
val tpSym = tp.symbol
980-
ctx.mode.is(Mode.RelaxedOverriding) && !tpSym.isPrimitiveValueClass ||
981-
tpSym.isNullableClass
972+
tp.symbol.isNullableClass
982973
case tp: TermRef =>
983974
// https://scala-lang.org/files/archive/spec/2.13/03-types.html#singleton-types
984975
// A singleton type is of the form p.type. Where p is a path pointing to a value which conforms to

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

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,17 +1160,14 @@ object Types extends TypeUtils {
11601160
*
11611161
* @param isSubType a function used for checking subtype relationships.
11621162
*/
1163-
final def overrides(that: Type, relaxedCheck: Boolean, matchLoosely: => Boolean, checkClassInfo: Boolean = true,
1163+
final def overrides(that: Type, matchLoosely: => Boolean, checkClassInfo: Boolean = true,
11641164
isSubType: (Type, Type) => Context ?=> Boolean = (tp1, tp2) => tp1 frozen_<:< tp2)(using Context): Boolean = {
1165-
val overrideCtx = if relaxedCheck then ctx.relaxedOverrideContext else ctx
1166-
inContext(overrideCtx) {
1167-
!checkClassInfo && this.isInstanceOf[ClassInfo]
1168-
|| isSubType(this.widenExpr, that.widenExpr)
1169-
|| matchLoosely && {
1170-
val this1 = this.widenNullaryMethod
1171-
val that1 = that.widenNullaryMethod
1172-
((this1 `ne` this) || (that1 `ne` that)) && this1.overrides(that1, relaxedCheck, false, checkClassInfo)
1173-
}
1165+
!checkClassInfo && this.isInstanceOf[ClassInfo]
1166+
|| isSubType(this.widenExpr, that.widenExpr)
1167+
|| matchLoosely && {
1168+
val this1 = this.widenNullaryMethod
1169+
val that1 = that.widenNullaryMethod
1170+
((this1 `ne` this) || (that1 `ne` that)) && this1.overrides(that1, false, checkClassInfo)
11741171
}
11751172
}
11761173

@@ -1196,8 +1193,7 @@ object Types extends TypeUtils {
11961193
*/
11971194
def matches(that: Type)(using Context): Boolean = {
11981195
record("matches")
1199-
val overrideCtx = if ctx.explicitNulls then ctx.relaxedOverrideContext else ctx
1200-
TypeComparer.matchesType(this, that, relaxed = !ctx.phase.erasedTypes)(using overrideCtx)
1196+
TypeComparer.matchesType(this, that, relaxed = !ctx.phase.erasedTypes)
12011197
}
12021198

12031199
/** This is the same as `matches` except that it also matches => T with T and

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -225,11 +225,7 @@ object OverridingPairs:
225225
}
226226
)
227227
else
228-
// releaxed override check for explicit nulls if one of the symbols is Java defined,
229-
// force `Null` to be a subtype of non-primitive value types during override checking.
230-
val relaxedOverriding = ctx.explicitNulls && (member.is(JavaDefined) || other.is(JavaDefined))
231228
member.name.is(DefaultGetterName) // default getters are not checked for compatibility
232-
|| memberTp.overrides(otherTp, relaxedOverriding,
233-
member.matchNullaryLoosely || other.matchNullaryLoosely || fallBack, isSubType = isSubType)
229+
|| memberTp.overrides(otherTp, member.matchNullaryLoosely || other.matchNullaryLoosely || fallBack, isSubType = isSubType)
234230

235231
end OverridingPairs

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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,8 @@ object ResolveSuper {
111111
// of the superaccessor's type, see i5433.scala for an example where this matters
112112
val otherTp = other.asSeenFrom(base.typeRef).info
113113
val accTp = acc.asSeenFrom(base.typeRef).info
114-
// Since the super class can be Java defined,
115-
// we use relaxed overriding check for explicit nulls if one of the symbols is Java defined.
116-
// This forces `Null` to be a subtype of non-primitive value types during override checking.
117-
val relaxedOverriding = ctx.explicitNulls && (sym.is(JavaDefined) || acc.is(JavaDefined))
118-
if !otherTp.overrides(accTp, relaxedOverriding, matchLoosely = true) then
114+
115+
if !otherTp.overrides(accTp, matchLoosely = true) then
119116
report.error(IllegalSuperAccessor(base, memberName, targetName, acc, accTp, other.symbol, otherTp), base.srcPos)
120117
bcs = bcs.tail
121118
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -906,7 +906,7 @@ object RefChecks {
906906
for (mbrd <- self.member(name).alternatives) {
907907
val mbr = mbrd.symbol
908908
val mbrType = mbr.info.asSeenFrom(self, mbr.owner)
909-
if (!mbrType.overrides(mbrd.info, relaxedCheck = false, matchLoosely = true))
909+
if (!mbrType.overrides(mbrd.info, matchLoosely = true))
910910
report.errorOrMigrationWarning(
911911
em"""${mbr.showLocated} is not a legal implementation of `$name` in $clazz
912912
| its type $mbrType

0 commit comments

Comments
 (0)