diff --git a/compiler/src/dotty/tools/dotc/core/Contexts.scala b/compiler/src/dotty/tools/dotc/core/Contexts.scala index e9fbd6065261..27859abaae52 100644 --- a/compiler/src/dotty/tools/dotc/core/Contexts.scala +++ b/compiler/src/dotty/tools/dotc/core/Contexts.scala @@ -712,6 +712,9 @@ object Contexts { def withNotNullInfos(infos: List[NotNullInfo]): Context = if c.notNullInfos eq infos then c else c.fresh.setNotNullInfos(infos) + + def relaxedOverrideContext: Context = + c.withModeBits(c.mode &~ Mode.SafeNulls | Mode.RelaxedOverriding) end ops // TODO: Fix issue when converting ModeChanges and FreshModeChanges to extension givens diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 70d1ea29c1a8..e9eb8ed78d02 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -1112,9 +1112,7 @@ object Types { */ def matches(that: Type)(using Context): Boolean = { record("matches") - val overrideCtx = if ctx.explicitNulls - then ctx.retractMode(Mode.SafeNulls).addMode(Mode.RelaxedOverriding) - else ctx + val overrideCtx = if ctx.explicitNulls then ctx.relaxedOverrideContext else ctx TypeComparer.matchesType(this, that, relaxed = !ctx.phase.erasedTypes)(using overrideCtx) } diff --git a/compiler/src/dotty/tools/dotc/transform/OverridingPairs.scala b/compiler/src/dotty/tools/dotc/transform/OverridingPairs.scala index 0490f8c513e3..7a0516c38991 100644 --- a/compiler/src/dotty/tools/dotc/transform/OverridingPairs.scala +++ b/compiler/src/dotty/tools/dotc/transform/OverridingPairs.scala @@ -219,7 +219,7 @@ object OverridingPairs: // releaxed override check for explicit nulls if one of the symbols is Java defined, // force `Null` to be a subtype of non-primitive value types during override checking. val overrideCtx = if ctx.explicitNulls && (member.is(JavaDefined) || other.is(JavaDefined)) - then ctx.retractMode(Mode.SafeNulls).addMode(Mode.RelaxedOverriding) else ctx + then ctx.relaxedOverrideContext else ctx member.name.is(DefaultGetterName) // default getters are not checked for compatibility || memberTp.overrides(otherTp, member.matchNullaryLoosely || other.matchNullaryLoosely || fallBack diff --git a/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala b/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala index aa5ac62d6c9d..3c03fa012464 100644 --- a/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala +++ b/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala @@ -115,7 +115,7 @@ object ResolveSuper { // we use relaxed overriding check for explicit nulls if one of the symbols is Java defined. // This forces `Null` to be a subtype of non-primitive value types during override checking. val overrideCtx = if ctx.explicitNulls && (sym.is(JavaDefined) || acc.is(JavaDefined)) - then ctx.retractMode(Mode.SafeNulls).addMode(Mode.RelaxedOverriding) else ctx + then ctx.relaxedOverrideContext else ctx if !otherTp.overrides(accTp, matchLoosely = true)(using overrideCtx) then report.error(IllegalSuperAccessor(base, memberName, targetName, acc, accTp, other.symbol, otherTp), base.srcPos) bcs = bcs.tail