Skip to content

Commit 8a52ace

Browse files
committed
Clean up code
Refines names of variables and refactors small (outdated) parts of the code.
1 parent 6579d82 commit 8a52ace

File tree

3 files changed

+96
-105
lines changed

3 files changed

+96
-105
lines changed

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

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class PreSpecializer extends MiniPhaseTransform {
9393
val args = annot.arguments
9494
if (args.isEmpty) primitiveTypes
9595
else args.head match {
96-
case a @ Typed(SeqLiteral(types), _) =>
96+
case _ @ Typed(SeqLiteral(types), _) =>
9797
types.map(t => primitiveCompanionToPrimitive(t.tpe))
9898
case a @ Ident(groupName) => // Matches `@specialized` annotations on Specializable Groups
9999
specializableToPrimitive(a.tpe.asInstanceOf[Type], groupName)
@@ -106,18 +106,16 @@ class PreSpecializer extends MiniPhaseTransform {
106106

107107
override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
108108
val tparams = tree.tparams.map(_.symbol)
109-
val st = tparams.zipWithIndex.map{case(sym, i) => (i, getSpec(sym))}
110-
sendRequests(st, tree)
109+
val requests = tparams.zipWithIndex.map{case(sym, i) => (i, getSpec(sym))}
110+
if (requests.nonEmpty) sendRequests(requests, tree)
111111
tree
112112
}
113113

114114
def sendRequests(requests: List[(Int, List[Type])], tree: tpd.Tree)(implicit ctx: Context): Unit = {
115-
if (requests.nonEmpty) {
116-
requests.map{
117-
case (index, types) if types.nonEmpty =>
118-
ctx.specializePhase.asInstanceOf[TypeSpecializer].registerSpecializationRequest(tree.symbol)(index, types)
119-
case _ =>
120-
}
115+
requests.map {
116+
case (index, types) if types.nonEmpty =>
117+
ctx.specializePhase.asInstanceOf[TypeSpecializer].registerSpecializationRequest(tree.symbol)(index, types)
118+
case _ =>
121119
}
122120
}
123121
}

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

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -34,38 +34,38 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
3434

3535
/**
3636
* Methods requested for specialization
37-
* Generic Symbol => List[ (position in type args list, specialized type requested) ]
37+
* Generic Symbol => List[ (position in list of args, specialized type requested) ]
3838
*/
3939
private val specializationRequests: mutable.HashMap[Symbols.Symbol, List[(Int, List[Type])]] = mutable.HashMap.empty
4040

4141
/**
42-
* A list of instantiation values of generics (helps with recursive polymorphic methods)
42+
* A list of instantiation values of generics (for recursive polymorphic methods)
4343
*/
4444
private val genericToInstantiation: mutable.HashMap[Symbols.Symbol, Type] = mutable.HashMap.empty
4545

4646
/**
4747
* A map that links symbols to their specialized variants.
4848
* Each symbol maps to another map, from the list of specialization types to the specialized symbol.
49-
* Generic symbol => Map[ Tuple(position in type args list, specialized Type) => Specialized Symbol ]
49+
* Generic symbol =>
50+
* Map{ List of [ Tuple(position in list of args, specialized Type) ] for each variant => Specialized Symbol }
5051
*/
5152
private val newSymbolMap: mutable.HashMap[Symbol, mutable.HashMap[List[(Int, Type)], Symbols.Symbol]] = mutable.HashMap.empty
5253

5354
/**
5455
* A map from specialised symbols to the indices of their remaining generic types
5556
*/
56-
private val newSymbolsGenericIndices: mutable.HashMap[Symbol, List[Int]] = mutable.HashMap.empty
57+
private val newSymToGenIndices: mutable.HashMap[Symbol, List[Int]] = mutable.HashMap.empty
5758

5859
/**
5960
* A list of symbols gone through the specialisation pipeline
6061
* Is used to make calls to transformInfo idempotent
6162
*/
62-
private val specialized: ListBuffer[Symbol] = ListBuffer.empty
63+
private val processed: ListBuffer[Symbol] = ListBuffer.empty
6364

6465
def allowedToSpecialize(sym: Symbol, numOfTypes: Int)(implicit ctx: Context) =
6566
numOfTypes > 0 &&
6667
sym.name != nme.asInstanceOf_ &&
6768
!newSymbolMap.contains(sym) &&
68-
!sym.name.toString.contains("$sp") &&
6969
!(sym is Flags.JavaDefined) &&
7070
!sym.isPrimaryConstructor
7171

@@ -88,7 +88,8 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
8888
def requestedSpecialization(decl: Symbol)(implicit ctx: Context): Boolean =
8989
ctx.settings.Yspecialize.value != 0 || specializationRequests.contains(decl)
9090

91-
def registerSpecializationRequest(method: Symbols.Symbol)(index: Int, arguments: List[Type])(implicit ctx: Context) = {
91+
def registerSpecializationRequest(method: Symbols.Symbol)(index: Int, arguments: List[Type])
92+
(implicit ctx: Context) = {
9293
if (ctx.phaseId > this.treeTransformPhase.id)
9394
assert(ctx.phaseId <= this.treeTransformPhase.id)
9495
val prev = specializationRequests.getOrElse(method, List.empty)
@@ -104,7 +105,7 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
104105
}
105106

106107
def specializeMethods(sym: Symbol) = {
107-
specialized += sym
108+
processed += sym
108109
sym.info match {
109110
case classInfo: ClassInfo =>
110111
val newDecls = classInfo.decls
@@ -114,7 +115,7 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
114115
.flatMap(decl => {
115116
decl.info.widen match {
116117
case poly: PolyType if allowedToSpecialize(decl.symbol, poly.paramNames.length) =>
117-
generateMethodSpecializations(getSpecTypes(decl, poly))(List.empty, poly, decl)
118+
generateMethodSpecializations(getSpecTypes(decl, poly), List.empty)(poly, decl)
118119
case _ => Nil
119120
}
120121
})
@@ -128,54 +129,59 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
128129
}
129130
else if (requestedSpecialization(sym) &&
130131
allowedToSpecialize(sym, poly.paramNames.length)) {
131-
generateMethodSpecializations(getSpecTypes(sym, poly))(List.empty, poly, sym)
132+
generateMethodSpecializations(getSpecTypes(sym, poly), List.empty)(poly, sym)
132133
tp
133134
}
134135
else tp
135136
case _ => tp
136137
}
137138
}
138139

139-
def generateMethodSpecializations(specTypes: List[(Int, List[Type])])
140-
(instantiations: List[(Int, Type)], poly: PolyType, decl: Symbol)
140+
def generateMethodSpecializations(specTypes: List[(Int, List[Type])], instantiations: List[(Int, Type)])
141+
(poly: PolyType, decl: Symbol)
141142
(implicit ctx: Context): List[Symbol] = {
142143
if (specTypes.nonEmpty) {
143144
specTypes.head match{
144145
case (i, tpes) if tpes.nonEmpty =>
145146
tpes.flatMap(tpe =>
146-
generateMethodSpecializations(specTypes.tail)((i, tpe) :: instantiations, poly, decl)
147+
generateMethodSpecializations(specTypes.tail, (i, tpe) :: instantiations)(poly, decl)
147148
)
148149
case (i, nil) =>
149-
generateMethodSpecializations(specTypes.tail)(instantiations, poly, decl)
150+
generateMethodSpecializations(specTypes.tail, instantiations)(poly, decl)
150151
}
151152
}
152153
else {
153154
if (instantiations.isEmpty) Nil
154155
else generateSpecializedSymbol(instantiations.reverse, poly, decl) :: Nil
155156
}
156157
}
158+
157159
def generateSpecializedSymbol(instantiations: List[(Int, Type)], poly: PolyType, decl: Symbol)
158160
(implicit ctx: Context): Symbol = {
159161
val indices = instantiations.map(_._1)
160162
val instanceTypes = instantiations.map(_._2)
161-
val newSym = ctx.newSymbol(decl.owner, NameOps.NameDecorator(decl.name).specializedFor(Nil, Nil, instanceTypes, instanceTypes.map(_.asInstanceOf[NamedType].name)),
162-
decl.flags | Flags.Synthetic, {
163-
if (indices.length != poly.paramNames.length) // Partial Specialisation case
164-
poly.instantiate(indices, instanceTypes) // Returns a PolyType with uninstantiated types kept generic
165-
else
166-
poly.instantiate(instanceTypes) // Returns a MethodType, as no polymorphic types remains
167-
})
163+
val newSym = ctx.newSymbol(
164+
decl.owner,
165+
NameOps.NameDecorator(decl.name)
166+
.specializedFor(Nil, Nil, instanceTypes, instanceTypes.map(_.asInstanceOf[NamedType].name)),
167+
decl.flags | Flags.Synthetic,
168+
{ if (indices.length != poly.paramNames.length) // Partial Specialisation case
169+
poly.instantiate(indices, instanceTypes) // Returns a PolyType with uninstantiated types kept generic
170+
else
171+
poly.instantiate(instanceTypes) // Returns a MethodType, no polymorphic type remains
172+
}
173+
)
168174

169175
val map = newSymbolMap.getOrElse(decl, mutable.HashMap.empty)
170176
map.put(instantiations, newSym)
171177
newSymbolMap.put(decl, map)
172178

173-
newSymbolsGenericIndices.put(newSym, indices)
179+
newSymToGenIndices.put(newSym, indices)
174180

175181
newSym
176182
}
177183

178-
if (!specialized.contains(sym) &&
184+
if (!processed.contains(sym) &&
179185
(sym ne defn.ScalaPredefModule.moduleClass) &&
180186
!(sym is Flags.JavaDefined) &&
181187
!(sym is Flags.Scala2x) &&
@@ -204,50 +210,53 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
204210
case (_, i) => instantiation.getOrElse(i, {
205211
holePos += 1
206212
PolyParam(pt, holePos)
207-
}
208-
).widen
213+
}).widen
209214
}
210215
}
211216

212217
if (newSymbolMap.contains(decl)) {
213-
val declSpecs = newSymbolMap(decl)
214-
val newSyms = declSpecs.values.toList
215-
val instantiations = declSpecs.keys.toArray
218+
val specInfo = newSymbolMap(decl)
219+
val newSyms = specInfo.values.toList
220+
val instantiationss = specInfo.keys.toArray
216221
var index = -1
217222
ctx.debuglog(s"specializing ${tree.symbol} for $origTParams")
218223
newSyms.map { newSym =>
219224
index += 1
220225
val newSymType = newSym.info.widenDealias
221226
polyDefDef(newSym.asTerm, { tparams => vparams => {
222227
val instTypes = newSymType match {
223-
case pt: PolyType => makeTypesList(origTParams, instantiations(index).toMap, pt)
224-
case _ => instantiations(index).map(_._2)
228+
case pt: PolyType =>
229+
makeTypesList(origTParams, instantiationss(index).toMap, pt) // Will add missing PolyParams
230+
case _ => instantiationss(index).map(_._2)
225231
}
226232

227233
val treemap: (Tree => Tree) = _ match {
228234
case Return(t, from) if from.symbol == tree.symbol => Return(t, ref(newSym))
229235
case t: TypeApply =>
230-
(origTParams zip instTypes).foreach(x => genericToInstantiation.put(x._1, x._2))
236+
(origTParams zip instTypes)
237+
.foreach{case (genTpe, instTpe) => genericToInstantiation.put(genTpe, instTpe)}
231238
transformTypeApply(t)
232239
case t: Apply =>
233-
(origTParams zip instTypes).foreach(x => genericToInstantiation.put(x._1, x._2))
240+
(origTParams zip instTypes)
241+
.foreach{case (genTpe, instTpe) => genericToInstantiation.put(genTpe, instTpe)}
234242
transformApply(t)
235243
case t => t
236244
}
237245

238246
val abstractPolyType = tree.symbol.info.widenDealias.asInstanceOf[PolyType]
247+
val vparamTpes = vparams.flatten.map(_.tpe)
239248
val typemap = new TypeMap {
240249
override def apply(tp: Type): Type = {
241250
val t = mapOver(tp)
242251
.substDealias(origTParams, instTypes)
243252
.substParams(abstractPolyType, instTypes)
244-
.subst(origVParams, vparams.flatten.map(_.tpe))
253+
.subst(origVParams, vparamTpes)
245254
newSymType match {
246255
case mt: MethodType if tparams.isEmpty =>
247-
t.substParams(newSymType.asInstanceOf[MethodType], vparams.flatten.map(_.tpe))
256+
t.substParams(newSymType.asInstanceOf[MethodType], vparamTpes)
248257
case pt: PolyType =>
249258
t.substParams(newSymType.asInstanceOf[PolyType], tparams)
250-
.substParams(newSymType.resultType.asInstanceOf[MethodType], vparams.flatten.map(_.tpe))
259+
.substParams(newSymType.resultType.asInstanceOf[MethodType], vparamTpes)
251260
case _ => t
252261
}
253262
}
@@ -265,11 +274,13 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
265274
override def transform(tree1: Tree)(implicit ctx: Context) = super.transform(tree1) match {
266275
case t @ Apply(fun, args) =>
267276
assert(sameLength(args, fun.tpe.widen.firstParamTypes),
268-
s"Wrong number of parameters. Expected: ${fun.tpe.widen.firstParamTypes.length}. Found: ${args.length}")
277+
s"Wrong number of parameters." +
278+
s"Expected: ${fun.tpe.widen.firstParamTypes.length}." +
279+
s"Found: ${args.length}")
269280
val newArgs = (args zip fun.tpe.widen.firstParamTypes).map{
270-
case(tr, tpe) =>
281+
case(arg, tpe) =>
271282
assert(tpe.widen ne NoType, "Bad cast when specializing")
272-
tr.ensureConforms(typemap(tpe.widen))
283+
arg.ensureConforms(typemap(tpe.widen))
273284
}
274285
if (sameTypes(args, newArgs)) {
275286
t
@@ -308,23 +319,22 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
308319
assert(tree.isInstanceOf[TypeApply])
309320
val TypeApply(fun,args) = tree
310321
if (newSymbolMap.contains(fun.symbol)){
311-
val newSymInfos = newSymbolMap(fun.symbol)
312-
val betterDefs = newSymInfos.filter(
313-
x => {
314-
val instantiation = x._1
315-
instantiation.forall { x =>
316-
val ord = x._1
317-
val tp = x._2
318-
args(ord).tpe <:< tp
319-
}}).toList
322+
val newSymInfo = newSymbolMap(fun.symbol)
323+
val betterDefs = newSymInfo.filter{
324+
case (instantiations, symbol) => {
325+
instantiations.forall {
326+
case (ord, specTpe) =>
327+
args(ord).tpe <:< specTpe
328+
}}}.toList
320329

321330
if (betterDefs.length > 1) {
322-
ctx.debuglog(s"Several specialized variants fit for ${fun.symbol.name} of ${fun.symbol.owner}. Defaulting to no specialization.")
331+
ctx.debuglog(s"Several specialized variants fit for ${fun.symbol.name} of ${fun.symbol.owner}." +
332+
s" Defaulting to no specialization.")
323333
tree
324334
}
325335

326336
else if (betterDefs.nonEmpty) {
327-
val bestDef = betterDefs.head
337+
val newFunSym = betterDefs.head._2
328338
ctx.debuglog(s"method ${fun.symbol.name} of ${fun.symbol.owner} rewired to specialized variant")
329339
val prefix = fun match {
330340
case Select(pre, name) =>
@@ -336,8 +346,8 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
336346
else EmptyTree
337347
case _ => EmptyTree
338348
}
339-
if (prefix ne EmptyTree) prefix.select(bestDef._2)
340-
else ref(bestDef._2)
349+
if (prefix ne EmptyTree) prefix.select(newFunSym)
350+
else ref(newFunSym)
341351
} else tree
342352
} else tree
343353
}
@@ -357,8 +367,10 @@ class TypeSpecializer extends MiniPhaseTransform with InfoTransformer {
357367
if (fun ne newFun) {
358368
newFun.symbol.info.widenDealias match {
359369
case pt: PolyType => // Need to apply types to the remaining generics first
360-
val tpeOfRemainingGenerics = typeArgs.zipWithIndex.filterNot(x => newSymbolsGenericIndices(newFun.symbol).contains(x._2)).map(_._1)
361-
assert(tpeOfRemainingGenerics.nonEmpty, s"Remaining generics on ${newFun.symbol.name} not properly instantiated: missing types")
370+
val tpeOfRemainingGenerics =
371+
typeArgs.zipWithIndex.filterNot(x => newSymToGenIndices(newFun.symbol).contains(x._2)).map(_._1)
372+
assert(tpeOfRemainingGenerics.nonEmpty,
373+
s"Remaining generics on ${newFun.symbol.name} not properly instantiated: missing types")
362374
Apply(TypeApply(newFun, tpeOfRemainingGenerics), args)
363375
case _ =>
364376
Apply(newFun, args)

0 commit comments

Comments
 (0)