Skip to content

Commit 9ff512b

Browse files
committed
Strip back adapting & converting types in match analysis
Rather than trying to fix the types such that subtyping returns true for these cases, we can rely on the numeric opt-out of using provablyDisjoint and extend it to boxed numerics.
1 parent f914c28 commit 9ff512b

File tree

2 files changed

+4
-59
lines changed

2 files changed

+4
-59
lines changed

compiler/src/dotty/tools/dotc/transform/patmat/Space.scala

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,10 @@ class SpaceEngine(using Context) extends SpaceLogic {
334334
// Since projections of types don't include null, intersection with null is empty.
335335
Empty
336336
else
337-
val intersection = Typ(AndType(tp1, tp2), decomposed = true)
338-
// unrelated numeric value classes can equal each other, so let's not consider type space interection empty
337+
val intersection = Typ(AndType(tp1, tp2), decomposed = false)
338+
// unrelated numeric value classes can equal each other, so let's not consider type space intersection empty
339339
if tp1.classSymbol.isNumericValueClass && tp2.classSymbol.isNumericValueClass then intersection
340+
else if isPrimToBox(tp1, tp2) || isPrimToBox(tp2, tp1) then intersection
340341
else if TypeComparer.provablyDisjoint(tp1, tp2) then Empty
341342
else intersection
342343
}
@@ -503,37 +504,9 @@ class SpaceEngine(using Context) extends SpaceLogic {
503504
}
504505
}
505506

506-
/** Numeric literals, while being constant values of unrelated types (e.g. Char and Int),
507-
* when used in a case may end up matching at runtime as their equals may returns true.
508-
* Because these are universally available, general purpose types, it would be good to avoid,
509-
* for example in `(c: Char) match { case 67 => ... }`, emitting a false positive
510-
* reachability warning on the case. So the type `ConstantType(Constant(67, IntTag))` is
511-
* converted to `ConstantType(Constant(67, CharTag))`. #12805 */
512-
def convertConstantType(tp: Type, pt: Type): Type = trace(i"convertConstantType($tp, $pt)", show = true)(tp match
513-
case tp @ ConstantType(const) =>
514-
val converted = const.convertTo(pt)
515-
if converted == null then tp else ConstantType(converted)
516-
case _ => tp
517-
)
518-
519507
def isPrimToBox(tp: Type, pt: Type): Boolean =
520508
tp.isPrimitiveValueType && (defn.boxedType(tp).classSymbol eq pt.classSymbol)
521509

522-
/** Adapt types by performing primitive value unboxing or boxing, or numeric constant conversion. #12805
523-
*
524-
* This makes these isSubType cases work like this:
525-
* {{{
526-
* 1 <:< Integer => (<skolem> : Integer) <:< Integer = true
527-
* ONE <:< Int => (<skolem> : Int) <:< Int = true
528-
* Integer <:< (1: Int) => (<skolem> : Int) <:< (1: Int) = false
529-
* }}}
530-
*/
531-
def adaptType(tp1: Type, tp2: Type): Type = trace(i"adaptType($tp1, $tp2)", show = true) {
532-
if isPrimToBox(tp1, tp2) then defn.boxedType(tp1).narrow
533-
else if isPrimToBox(tp2, tp1) then defn.unboxedType(tp1).narrow
534-
else convertConstantType(tp1, tp2)
535-
}
536-
537510
private val isSubspaceCache = mutable.HashMap.empty[(Space, Space, Context), Boolean]
538511

539512
override def isSubspace(a: Space, b: Space)(using Context): Boolean =
@@ -543,10 +516,7 @@ class SpaceEngine(using Context) extends SpaceLogic {
543516
def isSubType(tp1: Type, tp2: Type): Boolean = trace(i"$tp1 <:< $tp2", debug, show = true) {
544517
if tp1 == constantNullType && !ctx.mode.is(Mode.SafeNulls)
545518
then tp2 == constantNullType
546-
else
547-
val tp1a = adaptType(tp1, tp2)
548-
if tp1a eq tp1 then tp1 <:< tp2
549-
else trace(i"$tp1a <:< $tp2 (adapted)", debug, show = true)(tp1a <:< tp2)
519+
else tp1 <:< tp2
550520
}
551521

552522
def isSameUnapply(tp1: TermRef, tp2: TermRef): Boolean =

compiler/test/dotty/tools/dotc/transform/SpaceEngineTest.scala

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)