Skip to content

Commit d73623f

Browse files
committed
changed to adding reified values as Apply() with an extra parameter list; disabled erasurepreservation cause it crashes; ObjectAny still shows up at the backend
1 parent ae6d185 commit d73623f

File tree

2 files changed

+108
-74
lines changed

2 files changed

+108
-74
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class Compiler {
111111
new LetOverApply, // Lift blocks from receivers of applications
112112
new ArrayConstructors) :: // Intercept creation of (non-generic) arrays and intrinsify.
113113
List(new AddReifiedTypes) :: // Add reified type parameters
114-
List(new ErasurePreservation) :: //
114+
// List(new ErasurePreservation) :: //
115115
List(new Erasure) :: // Rewrite types to JVM model, erasing all type parameters, abstract types and refinements.
116116
List(new ElimObjectAny, // Eliminate ObjcetAny to Object
117117
new ElimErasedValueType, // Expand erased value types to their underlying implementation types

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

Lines changed: 107 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -13,99 +13,133 @@ import dotty.tools.dotc.core.Constants.*
1313

1414
class AddReifiedTypes extends MiniPhase with InfoTransformer {
1515
import ast.tpd.*
16+
17+
final val DEBUG = false
1618

1719
override def phaseName: String = "addReifiedTypes"
1820
override def description: String = "add reified type values to methods"
1921

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-
}
22+
override def transformInfo(tp: Type, sym: Symbol)(using Context): Type =
23+
if (sym.is(Flags.Method)) then {
24+
val res = addReifiedParams(tp)
25+
//println(s"Transforming method info for ${sym.name}, from: ${tp.show} to: ${res.show}")
26+
res
27+
}
28+
else tp
2929

30-
def addReifiedParams(tp: Type, typeParamNames: List[Name])(using Context): Type = tp match {
30+
def addReifiedParams(tp: Type)(using Context): Type = tp match {
31+
case pt: PolyType =>
32+
val reifiedParamNames = pt.paramNames.map(name => termName(s"reified_$name"))
33+
val reifiedParamTypes = reifiedParamNames.map(_ => defn.ReifiedValueType)
34+
pt.resType match {
35+
case mt: MethodType =>
36+
// println(s"Adding reified params to method pt. method type $mt: ${pt.show}")
37+
val rest = addReifiedParams(mt.resType)
38+
val reifiedList = MethodType(reifiedParamNames, reifiedParamTypes, rest)
39+
pt.derivedLambdaType(
40+
pt.paramNames,
41+
pt.paramInfos,
42+
mt.derivedLambdaType(
43+
mt.paramNames,
44+
mt.paramInfos,
45+
reifiedList
46+
)
47+
)
48+
case other =>
49+
// println(s"Adding reified params to method pt. other $other: ${pt.show}")
50+
val rest = addReifiedParams(other)
51+
val reifiedList = MethodType(reifiedParamNames, reifiedParamTypes, rest)
52+
pt.derivedLambdaType(
53+
pt.paramNames,
54+
pt.paramInfos,
55+
reifiedList
56+
)
57+
}
3158
case mt: MethodType =>
32-
val newParamNames = typeParamNames.map(name => termName(s"reified_$name"))
33-
val newParamTypes = newParamNames.map(_ => defn.ReifiedValueType)
59+
// println(s"Adding reified params to method mt. method type $mt: ${tp.show}")
3460
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)
61+
mt.paramNames,
62+
mt.paramInfos,
63+
addReifiedParams(mt.resType)
4464
)
4565
case _ => tp
4666
}
4767

4868
override def transformDefDef(tree: DefDef)(using Context): Tree = {
4969
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)
70+
// if there are no type parameters, no need to add reified params
71+
if (!tree.paramss.exists(_.exists(_.isInstanceOf[TypeDef]))) return tree
5472

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.ReifiedValueType,
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-
}
73+
var newParamss = List.empty[ParamClause]
74+
var typeParams = List.empty[TypeDef]
75+
for (clause <- tree.paramss){
76+
clause match {
77+
// def A[U, V](u: U, v: V)
78+
// case [U, V]
79+
case tparams: List[?] if tparams.nonEmpty && tparams.head.isInstanceOf[TypeDef] =>
80+
newParamss = newParamss :+ clause.asInstanceOf[ParamClause]
81+
typeParams = tparams.asInstanceOf[List[TypeDef]]
82+
case vparams: List[?] =>
83+
newParamss = newParamss :+ clause.asInstanceOf[ParamClause]
84+
if (typeParams.nonEmpty) {
85+
println(s"TransformDefDef for tree: ${tree.show} Adding reified value at end for method ${sym.name} with type params: ${typeParams.map(_.name)}")
86+
newParamss = newParamss :+ createReifiedClause(typeParams, sym)
87+
typeParams = Nil
88+
}
7789
}
78-
79-
if (added) cpy.DefDef(tree)(paramss = newParamss)
80-
else tree
81-
} else tree
90+
}
91+
if (typeParams.nonEmpty) {
92+
println(s"TransformDefDef for tree: ${tree.show} Adding reified value at end for method ${sym.name} with type params: ${typeParams.map(_.name)}")
93+
newParamss = newParamss :+ createReifiedClause(typeParams, sym)
94+
}
95+
cpy.DefDef(tree)(paramss = newParamss)
96+
}
97+
98+
def createReifiedClause(typeParams: List[TypeDef], sym: Symbol)(using Context): ParamClause = {
99+
typeParams.map {
100+
tparam =>
101+
val reifiedName = termName(s"reified_${tparam.name}")
102+
val reifiedSym = newSymbol(sym, reifiedName, Flags.Param, defn.ReifiedValueType)
103+
ValDef(reifiedSym.asTerm)
104+
}
82105
}
83106

84107
override def transformApply(tree: Apply)(using Context): Tree = {
85-
val sym = tree.fun.symbol
86-
if (sym.exists && sym.info.isInstanceOf[PolyType]) {
87-
val poly = sym.info.asInstanceOf[PolyType]
88-
val methodType = poly.resultType match {
89-
case mt: MethodType => mt
90-
case _ => null
91-
}
92-
93-
if (methodType != null) {
94-
val expectedParams = methodType.paramInfos.length
95-
val currentArgs = tree.args.length
96-
97-
if (currentArgs < expectedParams) {
98-
val reifiedArgs = tree.fun match {
99-
case TypeApply(_, targs) =>
100-
targs.map(targ => createReifiedValue(targ.tpe))
101-
case _ =>
102-
poly.paramNames.map(_ => createReifiedValue(defn.ReifiedValueType))
103-
}
104-
return cpy.Apply(tree)(tree.fun, tree.args ++ reifiedArgs)
105-
}
108+
val fun = tree.fun
109+
val args = tree.args
110+
val funType = fun.tpe.widen
111+
val resType = funType match {
112+
case mt: MethodType =>
113+
println(s"TransformApply tree type: ${tree.tpe.show}, method type: ${mt.resType.show}")
114+
mt.resType
115+
case _ => tree.tpe
116+
}
117+
if (isReifiedParamMethod(resType)){
118+
val reifiedArgs = collectReifiedArgs(fun)
119+
val innerApply = cpy.Apply(tree)(fun, args).withType(resType)
120+
val outerResType = resType match {
121+
case mt: MethodType => mt.resType
122+
case _ => resType
106123
}
124+
println(s"Transforming Apply: ${tree.show}, fun type: ${funType.show}, res type: ${resType.show}, with reified args: ${reifiedArgs.map(_.show)}")
125+
Apply(innerApply, reifiedArgs).withType(outerResType)
126+
} else tree
127+
}
128+
129+
def isReifiedParamMethod(tpe: Type)(using Context): Boolean = tpe match {
130+
case mt: MethodType =>
131+
mt.paramNames.nonEmpty && mt.paramNames.head.toString.startsWith("reified_")
132+
case _ => false
133+
}
134+
135+
def collectReifiedArgs(tree: Tree)(using Context): List[Tree] = {
136+
tree match {
137+
case ta: TypeApply =>
138+
ta.args.map(arg => createReifiedValue(arg.tpe))
139+
case a: Apply =>
140+
collectReifiedArgs(a.fun)
141+
case _ => Nil
107142
}
108-
tree
109143
}
110144

111145
def createReifiedValue(tpe: Type)(using Context): Tree = {

0 commit comments

Comments
 (0)