From 809cb9974f56d2aa9d044c66a4952fa9195a3a51 Mon Sep 17 00:00:00 2001 From: Ondrej Lhotak Date: Fri, 28 Aug 2026 15:29:55 +0200 Subject: [PATCH] gate Null <: TermRef under safeNulls for consistency with TypeRef MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The spec for conformance currently says: ``` - `´S =´ scala.Null` and: - ´T = q.C[T_1, ..., T_n]´ with ´n \geq 0´ and ´C´ does not derive from `scala.AnyVal` and ´C´ is not the hidden class of an `object`, or - ´T = q.x´ is a term designator with underlying type ´U´ and `scala.Null ´<: U´`, or ``` https://github.com/scala/scala3/blob/10770098fb9cbdef238fc677979a19a5bfb5ba7c/docs/_spec/03-types.md?plain=1#L1497-L1499 Under explicit nulls, the former is changed only in a safe-nulls context, but the latter is changed even in unsafe nulls. This change gates both under safe-nulls for consistency. --- compiler/src/dotty/tools/dotc/core/TypeComparer.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 6d4a771fa174..4a596075d988 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -1036,10 +1036,10 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling // scala.AnyRef [Scala 3: which scala.Null conforms to], the type denotes the set of values consisting // of null and the value denoted by p (i.e., the value v for which v eq p). [Otherwise,] the type // denotes the set consisting of only the value denoted by p. - !ctx.explicitNulls && isNullable(tp.underlying) && tp.isStable + !ctx.mode.is(Mode.SafeNulls) && isNullable(tp.underlying) && tp.isStable case tp: ThisType => // Same as above; this.type is also a singleton type in spec language - !ctx.explicitNulls && isNullable(tp.underlying) + !ctx.mode.is(Mode.SafeNulls) && isNullable(tp.underlying) case tp: RefinedOrRecType => isNullable(tp.parent) case tp: AppliedType => isNullable(tp.tycon) case AndType(tp1, tp2) => isNullable(tp1) && isNullable(tp2)