Skip to content

Commit 83bf74b

Browse files
committed
Add a TypeSpecializer Phase
Adds `TypeSpecializer.scala`, a phase which runs just before erasure.
1 parent 57a2a01 commit 83bf74b

File tree

5 files changed

+91
-2
lines changed

5 files changed

+91
-2
lines changed

out/.keep

Whitespace-only changes.

src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class Compiler {
5757
new ClassTags,
5858
new ElimByName,
5959
new ResolveSuper),
60+
List(new TypeSpecializer),
6061
List(new Erasure),
6162
List(new ElimErasedValueType,
6263
new VCInline,

src/dotty/tools/dotc/ast/TreeTypeMap.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ final class TreeTypeMap(
6060

6161
def mapType(tp: Type) =
6262
mapOwnerThis(typeMap(tp).substSym(substFrom, substTo))
63-
63+
6464
private def updateDecls(prevStats: List[Tree], newStats: List[Tree]): Unit =
6565
if (prevStats.isEmpty) assert(newStats.isEmpty)
6666
else {

src/dotty/tools/dotc/transform/FullParameterization.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ trait FullParameterization {
138138
* fully parameterized method definition derived from `originalDef`, which
139139
* has `derived` as symbol and `fullyParameterizedType(originalDef.symbol.info)`
140140
* as info.
141-
* `abstractOverClass` defines weather the DefDef should abstract over type parameters
141+
* `abstractOverClass` defines whether the DefDef should abstract over type parameters
142142
* of class that contained original defDef
143143
*/
144144
def fullyParameterizedDef(derived: TermSymbol, originalDef: DefDef, abstractOverClass: Boolean = true)(implicit ctx: Context): Tree =
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package dotty.tools.dotc.transform
2+
3+
import dotty.tools.dotc.ast.TreeTypeMap
4+
import dotty.tools.dotc.ast.tpd._
5+
import dotty.tools.dotc.core.Contexts.Context
6+
import dotty.tools.dotc.core.Flags
7+
import dotty.tools.dotc.core.Types._
8+
import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, MiniPhaseTransform}
9+
import dotty.tools.dotc.core.Decorators._
10+
import scala.collection.mutable.{ListBuffer, ArrayBuffer}
11+
12+
class TypeSpecializer extends MiniPhaseTransform {
13+
14+
override def phaseName = "Type Specializer"
15+
16+
final val maxTparamsToSpecialize = 2
17+
18+
private final def specialisedTypes(implicit ctx: Context) =
19+
Map(ctx.definitions.ByteType -> "$mcB$sp",
20+
ctx.definitions.BooleanType -> "$mcZ$sp",
21+
ctx.definitions.ShortType -> "$mcS$sp",
22+
ctx.definitions.IntType -> "$mcI$sp",
23+
ctx.definitions.LongType -> "$mcJ$sp",
24+
ctx.definitions.FloatType -> "$mcF$sp",
25+
ctx.definitions.DoubleType -> "$mcD$sp",
26+
ctx.definitions.CharType -> "$mcC$sp",
27+
ctx.definitions.UnitType -> "$mcV$sp")
28+
29+
override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
30+
31+
def rewireType(tpe: Type) = tpe match {
32+
case tpe: TermRef => tpe.widen
33+
case _ => tpe
34+
}
35+
36+
tree.tpe.widen match {
37+
38+
case poly: PolyType if !(tree.symbol.isPrimaryConstructor
39+
|| (tree.symbol is Flags.Label)
40+
|| (tree.tparams.length > maxTparamsToSpecialize)) => {
41+
val origTParams = tree.tparams.map(_.symbol)
42+
val origVParams = tree.vparamss.flatten.map(_.symbol)
43+
println(s"specializing ${tree.symbol} for Tparams: ${origTParams.length}")
44+
45+
def specialize(instatiations: collection.mutable.ListBuffer[Type], names: collection.mutable.ArrayBuffer[String]): Tree = {
46+
47+
val newSym = ctx.newSymbol(tree.symbol.owner, (tree.name + names.mkString).toTermName, tree.symbol.flags | Flags.Synthetic, poly.instantiate(instatiations.toList))
48+
polyDefDef(newSym, { tparams => vparams => {
49+
assert(tparams.isEmpty)
50+
new TreeTypeMap(
51+
typeMap = _
52+
.substDealias(origTParams, instatiations.toList)
53+
.subst(origVParams, vparams.flatten.map(_.tpe)),
54+
oldOwners = tree.symbol :: Nil,
55+
newOwners = newSym :: Nil
56+
).transform(tree.rhs)
57+
}
58+
})
59+
}
60+
61+
def generateSpecializations(remainingTParams: List[TypeDef])
62+
(instatiated: ArrayBuffer[TypeDef], instatiations: ListBuffer[Type],
63+
names: ArrayBuffer[String]): Iterable[Tree] = {
64+
if (remainingTParams.nonEmpty) {
65+
val typeToSpecialize = remainingTParams.head
66+
specialisedTypes.flatMap { tpnme =>
67+
val tpe = tpnme._1
68+
val nme = tpnme._2
69+
instatiated.+=(typeToSpecialize)
70+
instatiations.+=(tpe)
71+
names.+=(nme)
72+
val r = generateSpecializations(remainingTParams.tail)(instatiated, instatiations, names)
73+
instatiated.drop(1)
74+
instatiations.drop(1)
75+
names.drop(1)
76+
r
77+
}
78+
} else
79+
List(specialize(instatiations, names))
80+
}
81+
82+
83+
Thicket(tree :: generateSpecializations(tree.tparams)(ArrayBuffer.empty, ListBuffer.empty, ArrayBuffer.empty).toList)
84+
}
85+
case _ => tree
86+
}
87+
}
88+
}

0 commit comments

Comments
 (0)