Skip to content

Commit 9b48172

Browse files
committed
Optimize matchs in Types
1 parent e0a1725 commit 9b48172

File tree

3 files changed

+13
-12
lines changed

3 files changed

+13
-12
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -757,10 +757,10 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
757757
isSubType(hi1, tp2, approx.addLow) || compareGADT || tryLiftedToThis1
758758
case _ =>
759759
def isNullable(tp: Type): Boolean = tp.widenDealias match {
760-
case tp: TypeRef =>
760+
case tp: TypeRef =>
761761
if ctx.mode.is(Mode.UnsafeNullsSubType) then
762762
tp.symbol.isNullableClassAfterErasure
763-
else
763+
else
764764
tp.symbol.isNullableClass
765765
case tp: RefinedOrRecType => isNullable(tp.parent)
766766
case tp: AppliedType => isNullable(tp.tycon)

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

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import Denotations._
2020
import Periods._
2121
import CheckRealizable._
2222
import Variances.{Variance, varianceFromInt, varianceToInt, setStructuralVariances, Invariant}
23+
import typer.Nullables
2324
import util.Stats._
2425
import util.SimpleIdentitySet
2526
import ast.tpd._
@@ -30,6 +31,7 @@ import Hashable._
3031
import Uniques._
3132
import collection.mutable
3233
import config.Config
34+
import config.Feature
3335
import annotation.{tailrec, constructorOnly}
3436
import language.implicitConversions
3537
import scala.util.hashing.{ MurmurHash3 => hashing }
@@ -783,7 +785,7 @@ object Types {
783785
go(l).meet(go(r), pre, safeIntersection = ctx.base.pendingMemberSearches.contains(name))
784786

785787
def goOr(tp: OrType) = tp match {
786-
case OrNull(tp1) if config.Feature.enabled(nme.unsafeNulls) =>
788+
case OrNull(tp1) if Feature.unsafeNullsEnabled =>
787789
// Selecting `name` from a type `T | Null` is like selecting `name` from `T`, if
788790
// unsafeNulls is enabled. This can throw at runtime, but we trade soundness for usability.
789791
tp1.findMember(name, pre.stripNull, required, excluded)
@@ -1032,12 +1034,8 @@ object Types {
10321034
*/
10331035
def matches(that: Type)(using Context): Boolean = {
10341036
record("matches")
1035-
TypeComparer.matchesType(this, that, relaxed = !ctx.phase.erasedTypes) ||
1036-
(ctx.explicitNulls &&
1037-
// TODO: optimize, for example, add a parameter to ignore Null type?
1038-
TypeComparer.matchesType(
1039-
this.stripAllNulls, that.stripAllNulls,
1040-
relaxed = !ctx.phase.erasedTypes))
1037+
Nullables.useUnsafeNullsSubTypeIf(ctx.explicitNulls)(
1038+
TypeComparer.matchesType(this, that, relaxed = !ctx.phase.erasedTypes))
10411039
}
10421040

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

tests/explicit-nulls/neg/unsafe-scope.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,19 @@ class S {
55
val s: String | Null = ???
66

77
val x: String = s // error
8-
val xs: Array[String | Null] = s // error
8+
val xl = s.length // error
9+
val xs: Array[String | Null] | Null = s // error
910

1011
{
1112
import scala.language.unsafeNulls
1213
// ensure the previous search cache is not used here
1314
val y: String = s
14-
val ys: Array[String | Null] = s
15+
val yl = s.length
16+
val ys: Array[String | Null] | Null = s
1517
}
1618

1719
val z: String = s // error
18-
val zs: Array[String | Null] = s // error
20+
val zl = s.length // error
21+
val zs: Array[String | Null] | Null = s // error
1922
}
2023
}

0 commit comments

Comments
 (0)