@@ -4,6 +4,7 @@ package patmat
44
55import core ._
66import Types ._
7+ import TypeUtils ._
78import Contexts ._
89import Flags ._
910import ast ._
@@ -333,9 +334,11 @@ class SpaceEngine(using Context) extends SpaceLogic {
333334 // Since projections of types don't include null, intersection with null is empty.
334335 Empty
335336 else
336- val res = TypeComparer .provablyDisjoint(tp1, tp2)
337- if res then Empty
338- else Typ (AndType (tp1, tp2), decomposed = true )
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
339+ if tp1.classSymbol.isNumericValueClass && tp2.classSymbol.isNumericValueClass then intersection
340+ else if TypeComparer .provablyDisjoint(tp1, tp2) then Empty
341+ else intersection
339342 }
340343
341344 /** Return the space that represents the pattern `pat` */
@@ -407,7 +410,7 @@ class SpaceEngine(using Context) extends SpaceLogic {
407410 case tp => Typ (tp, decomposed = true )
408411 }
409412
410- private def unapplySeqInfo (resTp : Type , pos : SrcPos )( using Context ) : (Int , Type , Type ) = {
413+ private def unapplySeqInfo (resTp : Type , pos : SrcPos ): (Int , Type , Type ) = {
411414 var resultTp = resTp
412415 var elemTp = unapplySeqTypeElemTp(resultTp)
413416 var arity = productArity(resultTp, pos)
@@ -501,19 +504,20 @@ class SpaceEngine(using Context) extends SpaceLogic {
501504 }
502505
503506 /** Numeric literals, while being constant values of unrelated types (e.g. Char and Int),
504- * when used in a case may end up matching at runtime, because their equals may returns true.
505- * Because these are universally available, general purpose types, it would be good to avoid
506- * returning false positive warnings, such as in `(c: Char) match { case 67 => ... }` emitting a
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
507510 * reachability warning on the case. So the type `ConstantType(Constant(67, IntTag))` is
508511 * converted to `ConstantType(Constant(67, CharTag))`. #12805 */
509- def convertConstantType (tp : Type , pt : Type ): Type = tp match
512+ def convertConstantType (tp : Type , pt : Type ): Type = trace( i " convertConstantType( $tp , $pt ) " , show = true )( tp match
510513 case tp @ ConstantType (const) =>
511514 val converted = const.convertTo(pt)
512515 if converted == null then tp else ConstantType (converted)
513516 case _ => tp
517+ )
514518
515- def isPrimToBox (tp : Type , pt : Type ) =
516- tp.classSymbol.isPrimitiveValueClass && (defn.boxedType(tp).classSymbol eq pt.classSymbol)
519+ def isPrimToBox (tp : Type , pt : Type ): Boolean =
520+ tp.isPrimitiveValueType && (defn.boxedType(tp).classSymbol eq pt.classSymbol)
517521
518522 /** Adapt types by performing primitive value unboxing or boxing, or numeric constant conversion. #12805
519523 *
@@ -539,7 +543,10 @@ class SpaceEngine(using Context) extends SpaceLogic {
539543 def isSubType (tp1 : Type , tp2 : Type ): Boolean = trace(i " $tp1 <:< $tp2" , debug, show = true ) {
540544 if tp1 == constantNullType && ! ctx.mode.is(Mode .SafeNulls )
541545 then tp2 == constantNullType
542- else adaptType(tp1, tp2) <:< tp2
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)
543550 }
544551
545552 def isSameUnapply (tp1 : TermRef , tp2 : TermRef ): Boolean =
@@ -872,7 +879,7 @@ class SpaceEngine(using Context) extends SpaceLogic {
872879 /** Return the underlying type of non-module, non-constant, non-enum case singleton types.
873880 * Also widen ExprType to its result type, and rewrap any annotation wrappers.
874881 * For example, with `val opt = None`, widen `opt.type` to `None.type`. */
875- def toUnderlying (tp : Type )( using Context ) : Type = trace(i " toUnderlying( $tp) " , show = true )(tp match {
882+ def toUnderlying (tp : Type ): Type = trace(i " toUnderlying( $tp) " , show = true )(tp match {
876883 case _ : ConstantType => tp
877884 case tp : TermRef if tp.symbol.is(Module ) => tp
878885 case tp : TermRef if tp.symbol.isAllOf(EnumCase ) => tp
0 commit comments