Skip to content

Commit e6042a5

Browse files
committed
Workaround TreeChecker & specialised tuples
1 parent ad0c52b commit e6042a5

File tree

4 files changed

+22
-2
lines changed

4 files changed

+22
-2
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,6 +1329,9 @@ class Definitions {
13291329

13301330
@tu lazy val TupleType: Array[TypeRef | Null] = mkArityArray("scala.Tuple", MaxTupleArity, 1)
13311331

1332+
def isSpecializedTuple(cls: Symbol): Boolean =
1333+
TupleSpecializedClasses.exists(tupleCls => cls.name.isSpecializedNameOf(tupleCls.name))
1334+
13321335
def SpecialisedTuple(base: Symbol, args: List[Type]): Symbol = base.owner.requiredClass(base.name.specializedName(args))
13331336

13341337
private class FunType(prefix: String):

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,16 @@ object NameOps {
278278
classTags.fold(nme.EMPTY)(_ ++ _) ++ nme.specializedTypeNames.suffix)
279279
}
280280

281+
def isSpecializedNameOf(base: N)(using Context): Boolean =
282+
import Decorators.*
283+
val sb = new StringBuilder
284+
sb.append(base.toString)
285+
sb.append(nme.specializedTypeNames.prefix.toString)
286+
sb.append(nme.specializedTypeNames.separator)
287+
val prefix = sb.toString()
288+
val suffix = nme.specializedTypeNames.suffix.toString
289+
name.startsWith(prefix) && name.endsWith(suffix)
290+
281291
def specializedName(args: List[Type])(using Context): N =
282292
val sb = new StringBuilder
283293
sb.append(name.toString)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ class SpecializeTuples extends MiniPhase:
2424
override def transformApply(tree: Apply)(using Context): Tree = tree match
2525
case Apply(TypeApply(fun: NameTree, targs), args)
2626
if fun.name == nme.apply && fun.symbol.exists && defn.isSpecializableTuple(fun.symbol.owner.companionClass, targs.map(_.tpe)) =>
27-
Apply(Select(New(defn.SpecialisedTuple(fun.symbol.owner.companionClass, targs.map(_.tpe)).typeRef), nme.CONSTRUCTOR), args)
27+
Apply(Select(New(defn.SpecialisedTuple(fun.symbol.owner.companionClass, targs.map(_.tpe)).typeRef), nme.CONSTRUCTOR), args).withType(tree.tpe)
2828
case Apply(TypeApply(fun: NameTree, targs), args)
2929
if fun.name == nme.CONSTRUCTOR && fun.symbol.exists && defn.isSpecializableTuple(fun.symbol.owner, targs.map(_.tpe)) =>
30-
Apply(Select(New(defn.SpecialisedTuple(fun.symbol.owner, targs.map(_.tpe)).typeRef), nme.CONSTRUCTOR), args)
30+
Apply(Select(New(defn.SpecialisedTuple(fun.symbol.owner, targs.map(_.tpe)).typeRef), nme.CONSTRUCTOR), args).withType(tree.tpe)
3131
case _ => tree
3232
end transformApply
3333

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,13 @@ class TreeChecker extends Phase with SymTransformer {
421421
assert(tree.qual.typeOpt.isInstanceOf[ThisType], i"expect prefix of Super to be This, actual = ${tree.qual}")
422422
super.typedSuper(tree, pt)
423423

424+
override def typedApply(tree: untpd.Apply, pt: Type)(using Context): Tree = tree match
425+
case Apply(Select(qual, nme.CONSTRUCTOR), _)
426+
if !ctx.phase.erasedTypes
427+
&& defn.isSpecializedTuple(qual.typeOpt.typeSymbol) =>
428+
promote(tree) // e.g. `new Tuple2$mcII$sp(7, 8)` should keep its `(7, 8)` type instead of `Tuple2$mcII$sp`
429+
case _ => super.typedApply(tree, pt)
430+
424431
override def typedTyped(tree: untpd.Typed, pt: Type)(using Context): Tree =
425432
val tpt1 = checkSimpleKinded(typedType(tree.tpt))
426433
val expr1 = tree.expr match

0 commit comments

Comments
 (0)