Skip to content

Commit ae129da

Browse files
author
AlexSikia
committed
debugging
# with '#' will be ignored, and an empty message aborts the commit.
1 parent f5176f8 commit ae129da

File tree

2 files changed

+66
-22
lines changed

2 files changed

+66
-22
lines changed

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

Lines changed: 62 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,23 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
102102
(implicit ctx: Context): List[Symbol] = {
103103
val newSym =
104104
ctx.newSymbol(decl.owner, (decl.name + names.mkString).toTermName,
105-
decl.flags | Flags.Synthetic,
106-
poly.derivedPolyType(poly.paramNames, poly.paramBounds,
107-
poly.instantiate(instantiations.toList)))
105+
decl.flags | Flags.Synthetic, poly.instantiate(instantiations.toList))
106+
107+
/* The following generated symbols which kept type bounds. It served, as illustrated by the `this_specialization`
108+
* test, as a way of keeping type bounds when instantiating a `this` referring to a generic class. However,
109+
* because type bounds are not transitive, this did not work out and we introduced casts instead.
110+
*
111+
* ctx.newSymbol(decl.owner, (decl.name + names.mkString).toTermName,
112+
* decl.flags | Flags.Synthetic,
113+
* poly.derivedPolyType(poly.paramNames,
114+
* (poly.paramBounds zip instantiations).map
115+
* {case (bounds, instantiation) =>
116+
* TypeBounds(bounds.lo, AndType(bounds.hi, instantiation))},
117+
* poly.instantiate(indices, instantiations)
118+
* )
119+
* )
120+
*/
121+
108122
val map = newSymbolMap.getOrElse(decl, mutable.HashMap.empty)
109123
map.put(instantiations, newSym)
110124
newSymbolMap.put(decl, map)
@@ -152,39 +166,31 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
152166
def specialize(decl : Symbol): List[Tree] = {
153167
if (newSymbolMap.contains(decl)) {
154168
val declSpecs = newSymbolMap(decl)
155-
var failedSpec: List[Symbol] = List()
156169
val newSyms = declSpecs.values.toList
157170
val instantiations = declSpecs.keys.toArray
158171
var index = -1
159172
println(s"specializing ${tree.symbol} for $origTParams")
160-
/*val attempted = newSyms.zip(*/newSyms.map { newSym =>
173+
newSyms.map { newSym =>
161174
index += 1
162175
polyDefDef(newSym.asTerm, { tparams => vparams => {
163-
//assert(tparams.isEmpty)
164-
165176
val tmap: (Tree => Tree) = _ match {
166177
case Return(t, from) if from.symbol == tree.symbol => Return(t, ref(newSym))
167178
case t: TypeApply => transformTypeApply(t)
179+
case t: Apply => transformApply(t)
168180
case t => t
169181
}
170182

171183
new TreeTypeMap(
172184
treeMap = tmap,
173-
typeMap = _ /*match {
174-
case t if !poly.bounds.contains(t) => {
175-
failedSpec = newSym :: failedSpec
176-
t
177-
}
178-
case t => t*/
185+
typeMap = _
179186
.substDealias(origTParams, instantiations(index))
180187
.subst(origVParams, vparams.flatten.map(_.tpe))
181188
,
182189
oldOwners = tree.symbol :: Nil,
183190
newOwners = newSym :: Nil
184191
).transform(tree.rhs)
185192
}})
186-
}//)
187-
//attempted.filterNot(a => failedSpec.contains(a._1)).map(_._2)
193+
}
188194
} else Nil
189195
}
190196
val specialized_trees = specialize(tree.symbol)
@@ -194,20 +200,55 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
194200
}
195201

196202
override def transformTypeApply(tree: tpd.TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree = {
203+
val TypeApply(fun, _) = tree
204+
if (fun.tpe.isParameterless) rewireTree(tree)
205+
tree
206+
}
197207

208+
override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree = {
209+
val Apply(fun, args) = tree
210+
fun match {
211+
case fun: TypeApply => {
212+
println(
213+
s"""
214+
|args -> ${args}
215+
216+
|f.fun -> ${fun.fun.tree}
217+
""".stripMargin)
218+
219+
val newFun = rewireTree(fun)
220+
if (fun ne newFun) {
221+
val b = (args zip newFun.tpe.firstParamTypes)
222+
val a = b.map{
223+
case (arg, tpe) =>
224+
arg.ensureConforms(tpe)
225+
}
226+
Apply(newFun,a)
227+
/* zip (instantiations zip paramTypes)).map{
228+
case (argType, (specType, castType)) => argType.ensureConforms(specType)})*/
229+
} else tree
230+
}
231+
case _ => tree
232+
}
233+
}
234+
235+
def rewireTree(tree: Tree)(implicit ctx: Context): Tree = {
236+
assert(tree.isInstanceOf[TypeApply])
198237
val TypeApply(fun,args) = tree
199238
if (newSymbolMap.contains(fun.symbol)){
200239
val newSymInfos = newSymbolMap(fun.symbol)
201240
val betterDefs = newSymInfos.filter(x => (x._1 zip args).forall{a =>
202-
val specializedType = a._1
203-
val argType = a._2
241+
val specializedType = a._1
242+
val argType = a._2
204243
argType.tpe <:< specializedType
205244
}).toList
206245

207-
if (betterDefs.length > 1) ctx.debuglog("Several specialized variants fit.")
208-
//assert(betterDefs.length < 2) // TODO: How to select the best if there are several ?
246+
if (betterDefs.length > 1) {
247+
ctx.debuglog("Several specialized variants fit.")
248+
tree
249+
}
209250

210-
if (betterDefs.nonEmpty) {
251+
else if (betterDefs.nonEmpty) {
211252
val best = betterDefs.head
212253
println(s"method ${fun.symbol.name} of ${fun.symbol.owner} rewired to specialized variant with type (${best._1})")
213254
val prefix = fun match {
@@ -225,4 +266,4 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
225266
} else tree
226267
} else tree
227268
}
228-
}
269+
}
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
sealed abstract class Foo[@specialized +A] {
22
def bop[@specialized B >: A]: Foo[B] = new Bar[B](this)
3+
//def bip[@specialized C >: A, @specialized D >: A]: Foo[D] = new Cho[D, C](new Bar[C](this))
34
}
45

5-
case class Bar[@specialized a](tl: Foo[a]) extends Foo[a]
6+
case class Bar[@specialized a](tl: Foo[a]) extends Foo[a]
7+
8+
//case class Cho[@specialized c, @specialized d](tl: Bar[d]) extends Foo[c]

0 commit comments

Comments
 (0)