Skip to content

Commit ca2d35e

Browse files
committed
init adding reified values to methods
1 parent ab780f1 commit ca2d35e

File tree

2 files changed

+106
-2
lines changed

2 files changed

+106
-2
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,9 @@ class Compiler {
109109
new ParamForwarding, // Add forwarders for aliases of superclass parameters
110110
new TupleOptimizations, // Optimize generic operations on tuples
111111
new LetOverApply, // Lift blocks from receivers of applications
112-
new ArrayConstructors, // Intercept creation of (non-generic) arrays and intrinsify.
113-
new ErasurePreservation) :: //
112+
new ArrayConstructors) :: // Intercept creation of (non-generic) arrays and intrinsify.
113+
List(new AddReifiedTypes) :: // Add reified type parameters
114+
List(new ErasurePreservation) :: //
114115
List(new Erasure) :: // Rewrite types to JVM model, erasing all type parameters, abstract types and refinements.
115116
List(new ElimErasedValueType, // Expand erased value types to their underlying implementation types
116117
new PureStats, // Remove pure stats from blocks
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package dotty.tools
2+
package dotc
3+
package transform
4+
5+
import core.DenotTransformers.*
6+
import dotty.tools.dotc.transform.MegaPhase.MiniPhase
7+
import core.Contexts.Context
8+
import core.Types.*
9+
import core.Names.*
10+
import core.Symbols.*
11+
import dotty.tools.dotc.core.Flags
12+
import dotty.tools.dotc.core.Constants.*
13+
14+
class AddReifiedTypes extends MiniPhase with InfoTransformer {
15+
import ast.tpd.*
16+
17+
override def phaseName: String = "addReifiedTypes"
18+
override def description: String = "add reified type values to methods"
19+
20+
override def transformInfo(tp: Type, sym: Symbol)(using Context): Type = tp match {
21+
case pt: PolyType =>
22+
pt.derivedLambdaType(
23+
pt.paramNames,
24+
pt.paramInfos,
25+
addReifiedParams(pt.resType, pt.paramNames)
26+
)
27+
case _ => tp
28+
}
29+
30+
def addReifiedParams(tp: Type, typeParamNames: List[Name])(using Context): Type = tp match {
31+
case mt: MethodType =>
32+
val newParamNames = typeParamNames.map(name => termName(s"reified_$name"))
33+
val newParamTypes = newParamNames.map(_ => defn.AnyType)
34+
mt.derivedLambdaType(
35+
mt.paramNames ++ newParamNames,
36+
mt.paramInfos ++ newParamTypes,
37+
mt.resultType
38+
)
39+
case pt: PolyType =>
40+
pt.derivedLambdaType(
41+
pt.paramNames,
42+
pt.paramInfos,
43+
addReifiedParams(pt.resType, typeParamNames)
44+
)
45+
case _ => tp
46+
}
47+
48+
override def transformDefDef(tree: DefDef)(using Context): Tree = {
49+
val sym = tree.symbol
50+
val typeParams = tree.paramss.collectFirst {
51+
case tparams: List[?] if tparams.nonEmpty && tparams.head.isInstanceOf[TypeDef] =>
52+
tparams.asInstanceOf[List[TypeDef]]
53+
}.getOrElse(Nil)
54+
55+
if (typeParams.nonEmpty) {
56+
val newParamDefs = typeParams.map { tparam =>
57+
val paramName = termName(s"reified_${tparam.name}")
58+
val paramSym = newSymbol(
59+
sym,
60+
paramName,
61+
Flags.Param,
62+
defn.AnyType
63+
).asTerm
64+
ValDef(paramSym)
65+
}
66+
67+
var added = false
68+
val newParamss = tree.paramss.map { clause =>
69+
val isTypeClause = clause.nonEmpty && clause.head.isInstanceOf[TypeDef]
70+
if (!isTypeClause && !added) {
71+
added = true
72+
val newClause: ParamClause = clause.asInstanceOf[List[ValDef]] ++ newParamDefs
73+
newClause
74+
} else {
75+
clause
76+
}
77+
}
78+
79+
if (added) cpy.DefDef(tree)(paramss = newParamss)
80+
else tree
81+
} else tree
82+
}
83+
84+
override def transformApply(tree: Apply)(using Context): Tree = {
85+
val sym = tree.fun.symbol
86+
if (sym.exists && sym.is(Flags.Method) && sym.info.isInstanceOf[PolyType]) {
87+
val reifiedArgs = tree.fun match {
88+
case TypeApply(_, targs) =>
89+
targs.map(targ => createReifiedValue(targ.tpe))
90+
case _ =>
91+
val poly = sym.info.asInstanceOf[PolyType]
92+
poly.paramNames.map(_ => createReifiedValue(defn.AnyType))
93+
}
94+
cpy.Apply(tree)(tree.fun, tree.args ++ reifiedArgs)
95+
} else {
96+
tree
97+
}
98+
}
99+
100+
def createReifiedValue(tpe: Type)(using Context): Tree = {
101+
Literal(Constant(()))
102+
}
103+
}

0 commit comments

Comments
 (0)