@@ -28,7 +28,7 @@ class SpecializeFunctions extends MiniPhase with InfoTransformer {
28
28
val apply = tp.decls.lookup(nme.apply)
29
29
if (! apply.exists) return tp
30
30
31
- val newApplys = new mutable. ListBuffer [Symbol ]
31
+ var newApplys : List [Symbol ] = Nil
32
32
33
33
var arity = 0
34
34
while (arity < 3 ) {
@@ -39,14 +39,15 @@ class SpecializeFunctions extends MiniPhase with InfoTransformer {
39
39
val argTypes = paramTypes.init
40
40
val retType = paramTypes.last
41
41
42
+ val isSpecializable = defn.isSpecializableFunction(sym.asClass, argTypes, retType)
43
+ if (! isSpecializable) return tp
44
+
42
45
val apply = baseType.member(nme.apply)
43
46
val overrideApply = tp.decls.find { sym =>
44
47
sym.is(Flags .Method , butNot = Flags .Deferred ) && sym.name == nme.apply && sym.info.matches(apply.info)
45
48
}
46
49
47
- def isSpecializable = defn.isSpecializableFunction(sym.asClass, argTypes, retType)
48
-
49
- if (overrideApply.exists && isSpecializable) {
50
+ if (overrideApply.exists) {
50
51
val specializedMethodName : Name = nme.apply.specializedFunction(retType, argTypes)
51
52
val applySpecialized = newSymbol(
52
53
sym,
@@ -55,7 +56,7 @@ class SpecializeFunctions extends MiniPhase with InfoTransformer {
55
56
overrideApply.info
56
57
)
57
58
58
- newApplys + = applySpecialized
59
+ newApplys :: = applySpecialized
59
60
}
60
61
}
61
62
arity += 1
@@ -71,49 +72,40 @@ class SpecializeFunctions extends MiniPhase with InfoTransformer {
71
72
case _ => tp
72
73
}
73
74
74
- /** Transforms the `Template` of the classes to contain forwarders from the
75
- * generic applys to the specialized ones. Also inserts the specialized applys
76
- * in the template body.
75
+ /** Create forwarders from the generic applys to the specialized ones.
77
76
*/
78
- override def transformTemplate (tree : Template )(using Context ) = {
79
- val cls = tree.symbol.owner.asClass
80
-
81
- val apply = cls.info.decls.lookup(nme.apply)
82
- if (! apply.exists || ! derivesFromFn012(cls)) return tree
83
-
84
- val applyBuf = new mutable.ListBuffer [Tree ]
85
- val newBody = tree.body.mapConserve {
86
- case ddef : DefDef
87
- if ddef.name == nme.apply &&
88
- ddef.vparamss.length == 1 &&
89
- ddef.vparamss.head.length < 3
90
- =>
91
- val paramTypes = ddef.vparamss.head.map(_.symbol.info)
92
- val retType = ddef.tpe.widen.finalResultType
93
-
94
- val specName = nme.apply.specializedFunction(retType, paramTypes)
95
- val specializedApply = cls.info.decls.lookup(specName)
96
-
97
- if (specializedApply.exists) {
98
- val specializedDecl =
99
- DefDef (specializedApply.asTerm, vparamss => {
100
- ddef.rhs
101
- .changeOwner(ddef.symbol, specializedApply)
102
- .subst(ddef.vparamss.head.map(_.symbol), vparamss.head.map(_.symbol))
103
- })
104
- applyBuf += specializedDecl
105
-
106
- // create a forwarding to the specialized apply
107
- val args = ddef.vparamss.head.map(vparam => ref(vparam.symbol))
108
- val rhs = This (cls).select(specializedApply).appliedToArgs(args)
109
- cpy.DefDef (ddef)(rhs = rhs)
110
- } else ddef
111
-
112
- case x => x
113
- }
114
-
115
- if applyBuf.isEmpty then tree
116
- else cpy.Template (tree)(body = applyBuf.toList ::: newBody)
77
+ override def transformDefDef (ddef : DefDef )(using Context ) = {
78
+ val sym = ddef.symbol
79
+
80
+ if ddef.name != nme.apply
81
+ || ddef.vparamss.length != 1
82
+ || ddef.vparamss.head.length > 2
83
+ || ! sym.owner.isClass
84
+ || ! derivesFromFn012(sym.owner.asClass)
85
+ then
86
+ return ddef
87
+
88
+ val cls = sym.owner.asClass
89
+ val paramTypes = ddef.vparamss.head.map(_.symbol.info)
90
+ val retType = ddef.tpe.widen.finalResultType
91
+
92
+ val specName = nme.apply.specializedFunction(retType, paramTypes)
93
+ val specializedApply = cls.asClass.info.decls.lookup(specName)
94
+
95
+ if (! specializedApply.exists) return ddef
96
+
97
+ val specializedDecl =
98
+ DefDef (specializedApply.asTerm, vparamss => {
99
+ ddef.rhs
100
+ .changeOwner(ddef.symbol, specializedApply)
101
+ .subst(ddef.vparamss.head.map(_.symbol), vparamss.head.map(_.symbol))
102
+ })
103
+
104
+ // create a forwarding to the specialized apply
105
+ val args = ddef.vparamss.head.map(vparam => ref(vparam.symbol))
106
+ val rhs = This (cls).select(specializedApply).appliedToArgs(args)
107
+ val ddef1 = cpy.DefDef (ddef)(rhs = rhs)
108
+ Thicket (ddef1, specializedDecl)
117
109
}
118
110
119
111
/** Dispatch to specialized `apply`s in user code when available */
0 commit comments