Skip to content

Commit 32f5580

Browse files
committed
Specialized retained inline FunctionN apply methods
Fixes #19724
1 parent 7f410aa commit 32f5580

File tree

3 files changed

+34
-19
lines changed

3 files changed

+34
-19
lines changed

Diff for: compiler/src/dotty/tools/dotc/transform/Erasure.scala

+24-17
Original file line numberDiff line numberDiff line change
@@ -1000,21 +1000,28 @@ object Erasure {
10001000
* which is then dropped in `typedStats`.
10011001
*/
10021002
private def addRetainedInlineBodies(stats: List[untpd.Tree])(using Context): List[untpd.Tree] =
1003-
lazy val retainerDef: Map[Symbol, DefDef] = stats.collect {
1004-
case stat: DefDef @unchecked if stat.symbol.name.is(BodyRetainerName) =>
1005-
val retainer = stat.symbol
1006-
val origName = retainer.name.asTermName.exclude(BodyRetainerName)
1007-
val targetName =
1008-
if retainer.hasAnnotation(defn.TargetNameAnnot) then
1009-
retainer.targetName.unmangle(BodyRetainerName).exclude(BodyRetainerName)
1010-
else origName
1011-
val inlineMeth = atPhase(typerPhase) {
1012-
retainer.owner.info.decl(origName)
1013-
.matchingDenotation(retainer.owner.thisType, stat.symbol.info, targetName)
1014-
.symbol
1015-
}
1016-
(inlineMeth, stat)
1017-
}.toMap
1003+
lazy val (rSyms, originalSyms, retainerDef): (List[Symbol], List[Symbol], Map[Symbol, DefDef]) =
1004+
val rSyms = List.newBuilder[Symbol]
1005+
val originalSyms = List.newBuilder[Symbol]
1006+
val retainerDef = stats.collect {
1007+
case stat: DefDef @unchecked if stat.symbol.name.is(BodyRetainerName) =>
1008+
val retainer = stat.symbol
1009+
val origName = retainer.name.asTermName.exclude(BodyRetainerName)
1010+
val targetName =
1011+
if retainer.hasAnnotation(defn.TargetNameAnnot) then
1012+
retainer.targetName.unmangle(BodyRetainerName).exclude(BodyRetainerName)
1013+
else origName
1014+
val inlineMeth = atPhase(typerPhase) {
1015+
retainer.owner.info.decl(origName)
1016+
.matchingDenotation(retainer.owner.thisType, stat.symbol.info, targetName)
1017+
.symbol
1018+
}
1019+
if inlineMeth.name.endsWith(nme.SPECIALIZED_SUFFIX.toSimpleName) then
1020+
rSyms += retainer
1021+
originalSyms += inlineMeth
1022+
(inlineMeth, stat)
1023+
}.toMap
1024+
(rSyms.result(), originalSyms.result(), retainerDef)
10181025
stats.mapConserve {
10191026
case stat: DefDef @unchecked if stat.symbol.isRetainedInlineMethod =>
10201027
val rdef = retainerDef(stat.symbol)
@@ -1024,8 +1031,8 @@ object Erasure {
10241031
val mapBody = TreeTypeMap(
10251032
oldOwners = rdef.symbol :: Nil,
10261033
newOwners = stat.symbol :: Nil,
1027-
substFrom = fromParams,
1028-
substTo = toParams)
1034+
substFrom = rSyms ::: fromParams,
1035+
substTo = originalSyms ::: toParams)
10291036
cpy.DefDef(stat)(rhs = mapBody.transform(rdef.rhs))
10301037
case stat => stat
10311038
}

Diff for: compiler/src/dotty/tools/dotc/transform/SpecializeFunctions.scala

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package transform
33

44
import ast.Trees.*, ast.tpd, core.*
55
import Contexts.*, Types.*, Decorators.*, Symbols.*, DenotTransformers.*
6-
import SymDenotations.*, Scopes.*, StdNames.*, NameOps.*, Names.*
6+
import SymDenotations.*, Scopes.*, StdNames.*, NameOps.*, Names.*, NameKinds.*
77
import MegaPhase.MiniPhase
88

99

@@ -25,7 +25,7 @@ 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+
if ddef.name.asTermName.exclude(BodyRetainerName) != nme.apply
2929
|| ddef.termParamss.length != 1
3030
|| ddef.termParamss.head.length > 2
3131
|| !ctx.owner.isClass
@@ -41,6 +41,8 @@ class SpecializeFunctions extends MiniPhase {
4141
val paramTypes = ddef.termParamss.head.map(_.symbol.info)
4242
val retType = sym.info.finalResultType
4343
specName = nme.apply.specializedFunction(retType, paramTypes)
44+
if ddef.name.is(BodyRetainerName) then
45+
specName = BodyRetainerName(specName.nn.asTermName)
4446
defn.isSpecializableFunction(cls, paramTypes, retType)
4547
}
4648

Diff for: tests/run/i19724.scala

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class MyMapper extends (Int => Double):
2+
inline def apply(v: Int): Double = v.toDouble
3+
4+
@main def Test =
5+
val f: (Int => Double) = new MyMapper
6+
assert(f(3) == 3.0)

0 commit comments

Comments
 (0)