@@ -3,7 +3,7 @@ package transform
3
3
4
4
import ast .Trees .* , ast .tpd , core .*
5
5
import Contexts .* , Types .* , Decorators .* , Symbols .* , DenotTransformers .*
6
- import SymDenotations .* , Scopes .* , StdNames .* , NameOps .* , Names .*
6
+ import SymDenotations .* , Scopes .* , StdNames .* , NameOps .* , Names .* , NameKinds . *
7
7
import MegaPhase .MiniPhase
8
8
9
9
@@ -25,7 +25,24 @@ class SpecializeFunctions extends MiniPhase {
25
25
/** Create forwarders from the generic applys to the specialized ones.
26
26
*/
27
27
override def transformDefDef (ddef : DefDef )(using Context ) = {
28
- if ddef.name != nme.apply
28
+ // Note on special case for inline `apply`s:
29
+ // `apply` and `apply$retainedBody` are specialized in this transformation.
30
+ // `apply$retainedBody` have the name kind `BodyRetainerName`, these contain
31
+ // the runtime implementation of an inline `apply` that implements (or overrides)
32
+ // the `FunctionN.apply` method. The inline method is not specialized, it will
33
+ // be replaced with the implementation of `apply$retainedBody`. The following code
34
+ // inline def apply(x: Int): Double = x.toDouble:Double
35
+ // private def apply$retainedBody(x: Int): Double = x.toDouble:Double
36
+ // in is transformed into
37
+ // inline def apply(x: Int): Double = x.toDouble:Double
38
+ // private def apply$retainedBody(x: Int): Double = this.apply$mcDI$sp(x)
39
+ // def apply$mcDI$sp(v: Int): Double = x.toDouble:Double
40
+ // after erasure it will become
41
+ // def apply(v: Int): Double = this.apply$mcDI$sp(v) // from apply$retainedBody
42
+ // def apply$mcDI$sp(v: Int): Double = v.toDouble():Double
43
+ // def apply(v1: Object): Object = Double.box(this.apply(Int.unbox(v1))) // erasure bridge
44
+
45
+ if ddef.name.asTermName.exclude(BodyRetainerName ) != nme.apply
29
46
|| ddef.termParamss.length != 1
30
47
|| ddef.termParamss.head.length > 2
31
48
|| ! ctx.owner.isClass
@@ -44,12 +61,12 @@ class SpecializeFunctions extends MiniPhase {
44
61
defn.isSpecializableFunction(cls, paramTypes, retType)
45
62
}
46
63
47
- if (sym.is(Flags .Deferred ) || ! isSpecializable) return ddef
64
+ if (sym.is(Flags .Deferred ) || sym.is( Flags . Inline ) || ! isSpecializable) return ddef
48
65
49
66
val specializedApply = newSymbol(
50
67
cls,
51
68
specName.nn,
52
- sym.flags | Flags .Synthetic ,
69
+ ( sym.flags | Flags .Synthetic ) &~ Flags . Private , // Private flag can be set if the name is a BodyRetainerName
53
70
sym.info
54
71
).entered
55
72
0 commit comments