@@ -31,7 +31,7 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
31
31
defn.DoubleType -> " D" ,
32
32
defn.CharType -> " C" ,
33
33
defn.UnitType -> " V" ,
34
- defn.AnyRefType -> " A " )
34
+ defn.AnyRefType -> " L " )
35
35
36
36
private def primitiveTypes (implicit ctx : Context ) =
37
37
List (defn.ByteType ,
@@ -48,10 +48,10 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
48
48
private def defn (implicit ctx: Context ) = ctx.definitions
49
49
50
50
private val specializationRequests : mutable.HashMap [Symbols .Symbol , List [Type ]] = mutable.HashMap .empty
51
-
51
+ private val genericToInstantiation : mutable. HashMap [ Symbols . Symbol , Type ] = mutable. HashMap .empty
52
52
/**
53
53
* A map that links symbols to their specialized variants.
54
- * Each symbol maps to another as map, from the list of specialization types to the specialized symbol.
54
+ * Each symbol maps to another map, from the list of specialization types to the specialized symbol.
55
55
*/
56
56
private val newSymbolMap : mutable.HashMap [Symbol , mutable.HashMap [List [Type ], Symbols .Symbol ]] = mutable.HashMap .empty
57
57
@@ -90,7 +90,7 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
90
90
(instantiations : List [Type ], names : List [String ], poly : PolyType , decl : Symbol )
91
91
(implicit ctx : Context ): List [Symbol ] = {
92
92
if (remainingTParams.nonEmpty) {
93
- ( for ( tpe <- specTypes) yield {
93
+ specTypes.map( tpe => {
94
94
generateSpecializations(remainingTParams.tail, specTypes)(tpe :: instantiations, specialisedTypeToSuffix(ctx)(tpe) :: names, poly, decl)
95
95
}).flatten
96
96
}
@@ -134,7 +134,7 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
134
134
case classInfo : ClassInfo =>
135
135
val newDecls = classInfo.decls
136
136
.filter(_.symbol.isCompleted) // we do not want to force symbols here.
137
- // if there's unforced symbol it means its not used in the source
137
+ // if there's unforced symbol it means its not used in the source
138
138
.filterNot(_.isConstructor)
139
139
.filter(requestedSpecialization)
140
140
.flatMap(decl => {
@@ -150,7 +150,7 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
150
150
case poly : PolyType if ! newSymbolMap.contains(sym) &&
151
151
requestedSpecialization(sym) &&
152
152
allowedToSpecialize(sym, poly.paramNames.length)=>
153
- generateSpecializations(poly.paramNames, getSpecTypes(sym, poly))(List .empty, List .empty, poly, sym)
153
+ generateSpecializations(poly.paramNames, getSpecTypes(sym, poly))(List .empty, List .empty, poly, sym)
154
154
case nil =>
155
155
}
156
156
tp
@@ -173,14 +173,20 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
173
173
val newSyms = declSpecs.values.toList
174
174
val instantiations = declSpecs.keys.toArray
175
175
var index = - 1
176
- println (s " specializing ${tree.symbol} for $origTParams" )
176
+ ctx.debuglog (s " specializing ${tree.symbol} for $origTParams" )
177
177
newSyms.map { newSym =>
178
178
index += 1
179
179
polyDefDef(newSym.asTerm, { tparams => vparams => {
180
180
val tmap : (Tree => Tree ) = _ match {
181
181
case Return (t, from) if from.symbol == tree.symbol => Return (t, ref(newSym))
182
- case t : TypeApply => transformTypeApply(t)
183
- case t : Apply => transformApply(t)
182
+ case t : TypeApply => {
183
+ (origTParams zip instantiations(index)).foreach(x => genericToInstantiation.put(x._1, x._2))
184
+ transformTypeApply(t)
185
+ }
186
+ case t : Apply => {
187
+ (origTParams zip instantiations(index)).foreach(x => genericToInstantiation.put(x._1, x._2))
188
+ transformApply(t)
189
+ }
184
190
case t => t
185
191
}
186
192
@@ -195,7 +201,7 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
195
201
196
202
val tp = new TreeMap () {
197
203
// needed to workaround https://github.com/lampepfl/dotty/issues/592
198
- override def transform (t : Tree )(implicit ctx : Context ) = super .transform(t ) match {
204
+ override def transform (tree1 : Tree )(implicit ctx : Context ) = super .transform(tree1 ) match {
199
205
case t @ Apply (fun, args) =>
200
206
assert(sameLength(args, fun.tpe.widen.firstParamTypes))
201
207
val newArgs = (args zip fun.tpe.widen.firstParamTypes).map{case (t, tpe) => t.ensureConforms(tpe)}
@@ -220,48 +226,25 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
220
226
}
221
227
}
222
228
223
- override def transformTypeApply (tree : tpd.TypeApply )(implicit ctx : Context , info : TransformerInfo ): Tree = {
224
- val TypeApply (fun, _) = tree
225
- if (fun.tpe.isParameterless) rewireTree(tree)
226
- tree
227
- }
228
-
229
- override def transformApply (tree : Apply )(implicit ctx : Context , info : TransformerInfo ): Tree = {
230
- val Apply (fun, args) = tree
231
- fun match {
232
- case fun : TypeApply => {
233
- val newFun = rewireTree(fun)
234
- if (fun ne newFun) {
235
- val as = (args zip newFun.tpe.widen.firstParamTypes).map{
236
- case (arg, tpe) =>
237
- arg.ensureConforms(tpe)
238
- }
239
- Apply (newFun,as)
240
- } else tree
241
- }
242
- case _ => tree
243
- }
244
- }
245
-
246
229
def rewireTree (tree : Tree )(implicit ctx : Context ): Tree = {
247
230
assert(tree.isInstanceOf [TypeApply ])
248
231
val TypeApply (fun,args) = tree
249
232
if (newSymbolMap.contains(fun.symbol)){
250
233
val newSymInfos = newSymbolMap(fun.symbol)
251
234
val betterDefs = newSymInfos.filter(x => (x._1 zip args).forall{a =>
252
235
val specializedType = a._1
253
- val argType = a._2
254
- argType.tpe <:< specializedType
236
+ val argType = genericToInstantiation.getOrElse( a._2.tpe.typeSymbol, a._2.tpe)
237
+ argType <:< specializedType
255
238
}).toList
256
239
257
240
if (betterDefs.length > 1 ) {
258
- ctx.debuglog(" Several specialized variants fit." )
241
+ ctx.debuglog(s " Several specialized variants fit for method ${fun.symbol.name} of ${fun.symbol.owner} . Defaulting to no specialization ." )
259
242
tree
260
243
}
261
244
262
245
else if (betterDefs.nonEmpty) {
263
- val best = betterDefs.head
264
- println (s " method ${fun.symbol.name} of ${fun.symbol.owner} rewired to specialized variant with type(s) : ${best ._1.map{case TypeRef (_, name) => name}.mkString(" , " )}" )
246
+ val bestDef = betterDefs.head
247
+ ctx.debuglog (s " method ${fun.symbol.name} of ${fun.symbol.owner} rewired to specialized variant with type(s) : ${bestDef ._1.map{case TypeRef (_, name) => name}.mkString(" , " )}" )
265
248
val prefix = fun match {
266
249
case Select (pre, name) =>
267
250
pre
@@ -272,9 +255,32 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
272
255
else EmptyTree
273
256
}
274
257
if (prefix ne EmptyTree )
275
- prefix.select(best ._2)
276
- else ref(best ._2)
258
+ prefix.select(bestDef ._2)
259
+ else ref(bestDef ._2)
277
260
} else tree
278
261
} else tree
279
262
}
263
+
264
+ override def transformTypeApply (tree : tpd.TypeApply )(implicit ctx : Context , info : TransformerInfo ): Tree = {
265
+ val TypeApply (fun, _) = tree
266
+ if (fun.tpe.isParameterless) rewireTree(tree)
267
+ tree
268
+ }
269
+
270
+ override def transformApply (tree : Apply )(implicit ctx : Context , info : TransformerInfo ): Tree = {
271
+ val Apply (fun, args) = tree
272
+ fun match {
273
+ case fun : TypeApply =>
274
+ val newFun = rewireTree(fun)
275
+ if (fun ne newFun) {
276
+ val as = (args zip newFun.tpe.widen.firstParamTypes).map{
277
+ case (arg, tpe) => arg.ensureConforms(tpe)
278
+ }
279
+ Apply (newFun,as)
280
+ } else tree
281
+ case fun : Apply =>
282
+ Apply (transformApply(fun), args)
283
+ case _ => tree
284
+ }
285
+ }
280
286
}
0 commit comments