Skip to content

Commit ff81f2a

Browse files
committed
Fix erasure of *: and NonEmptyTuple
The erasure of these classes should be Product not Object. Otherwise we cannot discriminate in pattern matching between pairs and ().
1 parent 57b75d4 commit ff81f2a

File tree

5 files changed

+19
-12
lines changed

5 files changed

+19
-12
lines changed

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import unpickleScala2.Scala2Unpickler.ensureConstructor
88
import scala.collection.mutable
99
import collection.mutable
1010
import Denotations.SingleDenotation
11+
import util.SimpleIdentityMap
1112

1213
object Definitions {
1314

@@ -1265,7 +1266,13 @@ class Definitions {
12651266
def isValueSubClass(sym1: Symbol, sym2: Symbol): Boolean =
12661267
valueTypeEnc(sym2.asClass.name) % valueTypeEnc(sym1.asClass.name) == 0
12671268

1268-
lazy val erasedToObject: Set[Symbol] = Set(AnyClass, AnyValClass, TupleClass, NonEmptyTupleClass, SingletonClass)
1269+
lazy val specialErasure: SimpleIdentityMap[Symbol, ClassSymbol] =
1270+
SimpleIdentityMap.Empty[Symbol]
1271+
.updated(AnyClass, ObjectClass)
1272+
.updated(AnyValClass, ObjectClass)
1273+
.updated(SingletonClass, ObjectClass)
1274+
.updated(TupleClass, ObjectClass)
1275+
.updated(NonEmptyTupleClass, ProductClass)
12691276

12701277
// ----- Initialization ---------------------------------------------------
12711278

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ object TypeErasure {
4848
val sym = tp.symbol
4949
sym.isClass &&
5050
!erasureDependsOnArgs(sym) &&
51-
!defn.erasedToObject.contains(sym) &&
51+
!defn.specialErasure.contains(sym) &&
5252
!defn.isSyntheticFunctionClass(sym)
5353
case _: TermRef =>
5454
true
@@ -441,7 +441,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
441441
if ((cls eq defn.ObjectClass) || cls.isPrimitiveValueClass) Nil
442442
else parents.mapConserve(eraseParent) match {
443443
case tr :: trs1 =>
444-
assert(!tr.classSymbol.is(Trait), cls)
444+
assert(!tr.classSymbol.is(Trait), i"$cls has bad parents $parents%, %")
445445
val tr1 = if (cls is Trait) defn.ObjectType else tr
446446
tr1 :: trs1.filterNot(_ isRef defn.ObjectClass)
447447
case nil => nil
@@ -467,7 +467,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
467467

468468
private def erasePair(tp: Type)(implicit ctx: Context): Type = {
469469
val arity = tp.tupleArity
470-
if (arity < 0) defn.ObjectType
470+
if (arity < 0) defn.ProductType
471471
else if (arity <= Definitions.MaxTupleArity) defn.TupleType(arity)
472472
else defn.TupleXXLType
473473
}
@@ -524,8 +524,8 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
524524

525525
private def normalizeClass(cls: ClassSymbol)(implicit ctx: Context): ClassSymbol = {
526526
if (cls.owner == defn.ScalaPackageClass) {
527-
if (defn.erasedToObject.contains(cls))
528-
return defn.ObjectClass
527+
if (defn.specialErasure.contains(cls))
528+
return defn.specialErasure(cls)
529529
if (cls == defn.UnitClass)
530530
return defn.BoxedUnitClass
531531
}

compiler/src/dotty/tools/dotc/transform/Erasure.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,9 +398,9 @@ object Erasure {
398398

399399
def mapOwner(sym: Symbol): Symbol = {
400400
def recur(owner: Symbol): Symbol =
401-
if (defn.erasedToObject.contains(owner)) {
401+
if (defn.specialErasure.contains(owner)) {
402402
assert(sym.isConstructor, s"${sym.showLocated}")
403-
defn.ObjectClass
403+
defn.specialErasure(owner)
404404
} else if (defn.isSyntheticFunctionClass(owner))
405405
defn.erasedFunctionClass(owner)
406406
else

compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ object GenericSignatures {
198198
assert(!sym.isAliasType, "Unexpected alias type: " + sym)
199199
typeParamSig(sym.name.lastPart)
200200
}
201-
else if (defn.erasedToObject.contains(sym))
202-
jsig(defn.ObjectType)
201+
else if (defn.specialErasure.contains(sym))
202+
jsig(defn.specialErasure(sym).typeRef)
203203
else if (sym == defn.UnitClass || sym == defn.BoxedUnitModule)
204204
jsig(defn.BoxedUnitType)
205205
else if (sym == defn.NothingClass)

library/src-bootstrapped/scala/Tuple.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ object Tuple {
307307
}
308308
}
309309

310-
abstract sealed class NonEmptyTuple extends Tuple {
310+
abstract trait NonEmptyTuple extends Tuple {
311311
import Tuple._
312312
import NonEmptyTuple._
313313

@@ -473,7 +473,7 @@ object NonEmptyTuple {
473473
}
474474

475475
@showAsInfix
476-
sealed class *:[+H, +T <: Tuple] extends NonEmptyTuple
476+
sealed class *:[+H, +T <: Tuple] extends Object with NonEmptyTuple
477477

478478
object *: {
479479
inline def unapply[H, T <: Tuple](x: H *: T) = (x.head, x.tail)

0 commit comments

Comments
 (0)