@@ -3,7 +3,7 @@ package transform
33
44import ast .Trees .* , ast .tpd , core .*
55import Contexts .* , Types .* , Decorators .* , Symbols .* , DenotTransformers .*
6- import SymDenotations .* , Scopes .* , StdNames .* , NameOps .* , Names .*
6+ import SymDenotations .* , Scopes .* , StdNames .* , NameOps .* , Names .* , NameKinds . *
77import MegaPhase .MiniPhase
88
99
@@ -25,7 +25,24 @@ class SpecializeFunctions extends MiniPhase {
2525 /** Create forwarders from the generic applys to the specialized ones.
2626 */
2727 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
2946 || ddef.termParamss.length != 1
3047 || ddef.termParamss.head.length > 2
3148 || ! ctx.owner.isClass
@@ -44,12 +61,12 @@ class SpecializeFunctions extends MiniPhase {
4461 defn.isSpecializableFunction(cls, paramTypes, retType)
4562 }
4663
47- if (sym.is(Flags .Deferred ) || ! isSpecializable) return ddef
64+ if (sym.is(Flags .Deferred ) || sym.is( Flags . Inline ) || ! isSpecializable) return ddef
4865
4966 val specializedApply = newSymbol(
5067 cls,
5168 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
5370 sym.info
5471 ).entered
5572
0 commit comments