@@ -512,23 +512,46 @@ class SpaceEngine(using Context) extends SpaceLogic {
512512 if converted == null then tp else ConstantType (converted)
513513 case _ => tp
514514
515- /** Adapt types by performing primitive value boxing. #12805 */
516- def maybeBox (tp1 : Type , tp2 : Type ): Type =
517- if tp1.classSymbol.isPrimitiveValueClass && ! tp2.classSymbol.isPrimitiveValueClass then
518- defn.boxedType(tp1).narrow
519- else tp1
515+ private lazy val defn = ctx.definitions
516+ private lazy val ByteClass = defn.ByteClass
517+ private lazy val ShortClass = defn.ShortClass
518+ private lazy val CharClass = defn.CharClass
519+ private lazy val IntClass = defn.IntClass
520+ private lazy val LongClass = defn.LongClass
521+ private lazy val FloatClass = defn.FloatClass
522+ private lazy val DoubleClass = defn.DoubleClass
523+ private lazy val UnitClass = defn.UnitClass
524+ private lazy val BooleanClass = defn.BooleanClass
525+
526+ /** Adapt types by performing primitive value unboxing or boxing, or numeric constant conversion. #12805 */
527+ def adaptType (tp1 : Type , tp2 : Type ): Type = trace(i " adaptType( $tp1, $tp2) " , show = true )((tp1.classSymbol, tp2.classSymbol) match {
528+ case ( ByteClass , defn.BoxedByteClass ) => defn.BoxedByteClass .typeRef.narrow
529+ case ( ShortClass , defn.BoxedShortClass ) => defn.BoxedShortClass .typeRef.narrow
530+ case ( CharClass , defn.BoxedCharClass ) => defn.BoxedCharClass .typeRef.narrow
531+ case ( IntClass , defn.BoxedIntClass ) => defn.BoxedIntClass .typeRef.narrow // 1 <:< Integer => (<skolem> : Integer) <:< Integer = true
532+ case ( LongClass , defn.BoxedLongClass ) => defn.BoxedLongClass .typeRef.narrow
533+ case ( FloatClass , defn.BoxedFloatClass ) => defn.BoxedFloatClass .typeRef.narrow
534+ case ( DoubleClass , defn.BoxedDoubleClass ) => defn.BoxedDoubleClass .typeRef.narrow
535+ case ( UnitClass , defn.BoxedUnitClass ) => defn.BoxedUnitClass .typeRef.narrow
536+ case (BooleanClass , defn.BoxedBooleanClass ) => defn.BoxedBooleanClass .typeRef.narrow
537+
538+ case ( defn.BoxedByteClass , ByteClass ) => defn.ByteType .narrow
539+ case ( defn.BoxedShortClass , ShortClass ) => defn.ShortType .narrow
540+ case ( defn.BoxedCharClass , CharClass ) => defn.CharType .narrow
541+ case ( defn.BoxedIntClass , IntClass ) => defn.IntType .narrow // ONE <:< Int => (<skolem> : Int) <:< Int = true
542+ case ( defn.BoxedLongClass , LongClass ) => defn.LongType .narrow
543+ case ( defn.BoxedFloatClass , FloatClass ) => defn.FloatType .narrow
544+ case ( defn.BoxedDoubleClass , DoubleClass ) => defn.DoubleType .narrow
545+ case ( defn.BoxedUnitClass , UnitClass ) => defn.UnitType .narrow
546+ case (defn.BoxedBooleanClass , BooleanClass ) => defn.BooleanType .narrow
547+
548+ case _ => convertConstantType(tp1, tp2)
549+ })
520550
521551 /** Is `tp1` a subtype of `tp2`? */
522- def isSubType (_tp1 : Type , tp2 : Type ): Boolean = {
523- val tp1 = maybeBox(convertConstantType(_tp1, tp2), tp2)
524- // debug.println(TypeComparer.explained(_.isSubType(tp1, tp2)))
525- val res = if (ctx.explicitNulls) {
526- tp1 <:< tp2
527- } else {
528- (tp1 != constantNullType || tp2 == constantNullType) && tp1 <:< tp2
529- }
530- debug.println(i " $tp1 <:< $tp2 = $res" )
531- res
552+ def isSubType (tp1 : Type , tp2 : Type ): Boolean = trace(i " $tp1 <:< $tp1" , debug, show = true ) {
553+ if tp1 == constantNullType && ! ctx.explicitNulls then tp2 == constantNullType
554+ else adaptType(tp1, tp2) <:< tp2
532555 }
533556
534557 def isSameUnapply (tp1 : TermRef , tp2 : TermRef ): Boolean =
0 commit comments