@@ -20,28 +20,28 @@ class SpecializeFunctions extends MiniPhase with InfoTransformer {
20
20
21
21
/** Transforms the type to include decls for specialized applys */
22
22
override def transformInfo (tp : Type , sym : Symbol )(implicit ctx : Context ) = tp match {
23
- case tp : ClassInfo if ! sym.is(Flags .Package ) && (tp.decls ne EmptyScope ) =>
23
+ case tp : ClassInfo if ! sym.is(Flags .Package ) && (tp.decls ne EmptyScope ) && derivesFromFn012(sym) =>
24
24
var newApplys = Map .empty[Name , Symbol ]
25
25
26
- tp.parents.foreach { parent =>
27
- List (0 , 1 , 2 ).foreach { arity =>
28
- val func = defn.FunctionClass (arity)
29
- if (parent.derivesFrom(func)) {
30
- val typeParams = tp.cls.typeRef.baseType(func).argInfos
31
- val isSpecializable =
32
- defn.isSpecializableFunction(
33
- parent.classSymbol.asClass,
34
- typeParams.init,
35
- typeParams.last
36
- )
37
-
38
- if (isSpecializable && tp.decls.lookup(nme.apply).exists) {
39
- val interface = specInterface(typeParams)
40
- val specializedMethodName = nme.apply.specializedFunction(typeParams.last, typeParams.init)
41
- newApplys += (specializedMethodName -> interface)
42
- }
26
+ var arity = 0
27
+ while (arity < 3 ) {
28
+ val func = defn.FunctionClass (arity)
29
+ if (tp.derivesFrom(func)) {
30
+ val typeParams = tp.cls.typeRef.baseType(func).argInfos
31
+ val isSpecializable =
32
+ defn.isSpecializableFunction(
33
+ sym.asClass,
34
+ typeParams.init,
35
+ typeParams.last
36
+ )
37
+
38
+ if (isSpecializable && tp.decls.lookup(nme.apply).exists) {
39
+ val interface = specInterface(typeParams)
40
+ val specializedMethodName = nme.apply.specializedFunction(typeParams.last, typeParams.init)
41
+ newApplys += (specializedMethodName -> interface)
43
42
}
44
43
}
44
+ arity += 1
45
45
}
46
46
47
47
def newDecls =
@@ -68,39 +68,41 @@ class SpecializeFunctions extends MiniPhase with InfoTransformer {
68
68
* in the template body.
69
69
*/
70
70
override def transformTemplate (tree : Template )(implicit ctx : Context ) = {
71
- val applyBuf = new mutable.ListBuffer [Tree ]
72
- val newBody = tree.body.mapConserve {
73
- case dt : DefDef if dt.name == nme.apply && dt.vparamss.length == 1 =>
74
- val cls = tree.symbol.enclosingClass.asClass
75
- val typeParams = dt.vparamss.head.map(_.symbol.info)
76
- val retType = dt.tpe.widen.finalResultType
77
-
78
- val specName = specializedName(nme.apply, typeParams :+ retType)
79
- val specializedApply = cls.info.decls.lookup(specName)
80
- if (specializedApply.exists) {
81
- val apply = specializedApply.asTerm
82
- val specializedDecl =
83
- polyDefDef(apply, trefs => vrefss => {
84
- dt.rhs
85
- .changeOwner(dt.symbol, apply)
86
- .subst(dt.vparamss.flatten.map(_.symbol), vrefss.flatten.map(_.symbol))
71
+ val cls = tree.symbol.enclosingClass.asClass
72
+ if (derivesFromFn012(cls)) {
73
+ val applyBuf = new mutable.ListBuffer [Tree ]
74
+ val newBody = tree.body.mapConserve {
75
+ case dt : DefDef if dt.name == nme.apply && dt.vparamss.length == 1 =>
76
+ val typeParams = dt.vparamss.head.map(_.symbol.info)
77
+ val retType = dt.tpe.widen.finalResultType
78
+
79
+ val specName = specializedName(nme.apply, typeParams :+ retType)
80
+ val specializedApply = cls.info.decls.lookup(specName)
81
+ if (specializedApply.exists) {
82
+ val apply = specializedApply.asTerm
83
+ val specializedDecl =
84
+ polyDefDef(apply, trefs => vrefss => {
85
+ dt.rhs
86
+ .changeOwner(dt.symbol, apply)
87
+ .subst(dt.vparamss.flatten.map(_.symbol), vrefss.flatten.map(_.symbol))
88
+ })
89
+ applyBuf += specializedDecl
90
+
91
+ // create a forwarding to the specialized apply
92
+ cpy.DefDef (dt)(rhs = {
93
+ tpd
94
+ .ref(apply)
95
+ .appliedToArgs(dt.vparamss.head.map(vparam => ref(vparam.symbol)))
87
96
})
88
- applyBuf += specializedDecl
97
+ } else dt
89
98
90
- // create a forwarding to the specialized apply
91
- cpy.DefDef (dt)(rhs = {
92
- tpd
93
- .ref(apply)
94
- .appliedToArgs(dt.vparamss.head.map(vparam => ref(vparam.symbol)))
95
- })
96
- } else dt
97
-
98
- case x => x
99
- }
99
+ case x => x
100
+ }
100
101
101
- cpy.Template (tree)(
102
- body = applyBuf.toList ++ newBody
103
- )
102
+ cpy.Template (tree)(
103
+ body = applyBuf.toList ::: newBody
104
+ )
105
+ } else tree
104
106
}
105
107
106
108
/** Dispatch to specialized `apply`s in user code when available */
@@ -146,4 +148,9 @@ class SpecializeFunctions extends MiniPhase with InfoTransformer {
146
148
147
149
private def specInterface (typeParams : List [Type ])(implicit ctx : Context ) =
148
150
ctx.getClassIfDefined(functionName(typeParams).specializedFunction(typeParams.last, typeParams.init))
151
+
152
+ private def derivesFromFn012 (sym : Symbol )(implicit ctx : Context ): Boolean =
153
+ sym.derivesFrom(defn.FunctionClass (0 )) ||
154
+ sym.derivesFrom(defn.FunctionClass (1 )) ||
155
+ sym.derivesFrom(defn.FunctionClass (2 ))
149
156
}
0 commit comments