@@ -4,6 +4,7 @@ package patmat
4
4
5
5
import core ._
6
6
import Types ._
7
+ import TypeUtils ._
7
8
import Contexts ._
8
9
import Flags ._
9
10
import ast ._
@@ -333,9 +334,12 @@ class SpaceEngine(using Context) extends SpaceLogic {
333
334
// Since projections of types don't include null, intersection with null is empty.
334
335
Empty
335
336
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 = false )
338
+ // unrelated numeric value classes can equal each other, so let's not consider type space intersection empty
339
+ if tp1.classSymbol.isNumericValueClass && tp2.classSymbol.isNumericValueClass then intersection
340
+ else if isPrimToBox(tp1, tp2) || isPrimToBox(tp2, tp1) then intersection
341
+ else if TypeComparer .provablyDisjoint(tp1, tp2) then Empty
342
+ else intersection
339
343
}
340
344
341
345
/** Return the space that represents the pattern `pat` */
@@ -407,7 +411,7 @@ class SpaceEngine(using Context) extends SpaceLogic {
407
411
case tp => Typ (tp, decomposed = true )
408
412
}
409
413
410
- private def unapplySeqInfo (resTp : Type , pos : SrcPos )( using Context ) : (Int , Type , Type ) = {
414
+ private def unapplySeqInfo (resTp : Type , pos : SrcPos ): (Int , Type , Type ) = {
411
415
var resultTp = resTp
412
416
var elemTp = unapplySeqTypeElemTp(resultTp)
413
417
var arity = productArity(resultTp, pos)
@@ -500,35 +504,8 @@ class SpaceEngine(using Context) extends SpaceLogic {
500
504
}
501
505
}
502
506
503
- /** 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
- * reachability warning on the case. So the type `ConstantType(Constant(67, IntTag))` is
508
- * converted to `ConstantType(Constant(67, CharTag))`. #12805 */
509
- def convertConstantType (tp : Type , pt : Type ): Type = tp match
510
- case tp @ ConstantType (const) =>
511
- val converted = const.convertTo(pt)
512
- if converted == null then tp else ConstantType (converted)
513
- case _ => tp
514
-
515
- def isPrimToBox (tp : Type , pt : Type ) =
516
- tp.classSymbol.isPrimitiveValueClass && (defn.boxedType(tp).classSymbol eq pt.classSymbol)
517
-
518
- /** Adapt types by performing primitive value unboxing or boxing, or numeric constant conversion. #12805
519
- *
520
- * This makes these isSubType cases work like this:
521
- * {{{
522
- * 1 <:< Integer => (<skolem> : Integer) <:< Integer = true
523
- * ONE <:< Int => (<skolem> : Int) <:< Int = true
524
- * Integer <:< (1: Int) => (<skolem> : Int) <:< (1: Int) = false
525
- * }}}
526
- */
527
- def adaptType (tp1 : Type , tp2 : Type ): Type = trace(i " adaptType( $tp1, $tp2) " , show = true ) {
528
- if isPrimToBox(tp1, tp2) then defn.boxedType(tp1).narrow
529
- else if isPrimToBox(tp2, tp1) then defn.unboxedType(tp1).narrow
530
- else convertConstantType(tp1, tp2)
531
- }
507
+ def isPrimToBox (tp : Type , pt : Type ): Boolean =
508
+ tp.isPrimitiveValueType && (defn.boxedType(tp).classSymbol eq pt.classSymbol)
532
509
533
510
private val isSubspaceCache = mutable.HashMap .empty[(Space , Space , Context ), Boolean ]
534
511
@@ -539,7 +516,7 @@ class SpaceEngine(using Context) extends SpaceLogic {
539
516
def isSubType (tp1 : Type , tp2 : Type ): Boolean = trace(i " $tp1 <:< $tp2" , debug, show = true ) {
540
517
if tp1 == constantNullType && ! ctx.mode.is(Mode .SafeNulls )
541
518
then tp2 == constantNullType
542
- else adaptType( tp1, tp2) <:< tp2
519
+ else tp1 <:< tp2
543
520
}
544
521
545
522
def isSameUnapply (tp1 : TermRef , tp2 : TermRef ): Boolean =
@@ -872,7 +849,7 @@ class SpaceEngine(using Context) extends SpaceLogic {
872
849
/** Return the underlying type of non-module, non-constant, non-enum case singleton types.
873
850
* Also widen ExprType to its result type, and rewrap any annotation wrappers.
874
851
* 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 {
852
+ def toUnderlying (tp : Type ): Type = trace(i " toUnderlying( $tp) " , show = true )(tp match {
876
853
case _ : ConstantType => tp
877
854
case tp : TermRef if tp.symbol.is(Module ) => tp
878
855
case tp : TermRef if tp.symbol.isAllOf(EnumCase ) => tp
0 commit comments