Skip to content

Commit

Permalink
Specialized retained inline FunctionN apply methods
Browse files Browse the repository at this point in the history
Fixes #19724
  • Loading branch information
nicolasstucki committed Feb 27, 2024
1 parent 7f410aa commit 32f5580
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 19 deletions.
41 changes: 24 additions & 17 deletions compiler/src/dotty/tools/dotc/transform/Erasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1000,21 +1000,28 @@ object Erasure {
* which is then dropped in `typedStats`.
*/
private def addRetainedInlineBodies(stats: List[untpd.Tree])(using Context): List[untpd.Tree] =
lazy val retainerDef: Map[Symbol, DefDef] = stats.collect {
case stat: DefDef @unchecked if stat.symbol.name.is(BodyRetainerName) =>
val retainer = stat.symbol
val origName = retainer.name.asTermName.exclude(BodyRetainerName)
val targetName =
if retainer.hasAnnotation(defn.TargetNameAnnot) then
retainer.targetName.unmangle(BodyRetainerName).exclude(BodyRetainerName)
else origName
val inlineMeth = atPhase(typerPhase) {
retainer.owner.info.decl(origName)
.matchingDenotation(retainer.owner.thisType, stat.symbol.info, targetName)
.symbol
}
(inlineMeth, stat)
}.toMap
lazy val (rSyms, originalSyms, retainerDef): (List[Symbol], List[Symbol], Map[Symbol, DefDef]) =
val rSyms = List.newBuilder[Symbol]
val originalSyms = List.newBuilder[Symbol]
val retainerDef = stats.collect {
case stat: DefDef @unchecked if stat.symbol.name.is(BodyRetainerName) =>
val retainer = stat.symbol
val origName = retainer.name.asTermName.exclude(BodyRetainerName)
val targetName =
if retainer.hasAnnotation(defn.TargetNameAnnot) then
retainer.targetName.unmangle(BodyRetainerName).exclude(BodyRetainerName)
else origName
val inlineMeth = atPhase(typerPhase) {
retainer.owner.info.decl(origName)
.matchingDenotation(retainer.owner.thisType, stat.symbol.info, targetName)
.symbol
}
if inlineMeth.name.endsWith(nme.SPECIALIZED_SUFFIX.toSimpleName) then
rSyms += retainer
originalSyms += inlineMeth
(inlineMeth, stat)
}.toMap
(rSyms.result(), originalSyms.result(), retainerDef)
stats.mapConserve {
case stat: DefDef @unchecked if stat.symbol.isRetainedInlineMethod =>
val rdef = retainerDef(stat.symbol)
Expand All @@ -1024,8 +1031,8 @@ object Erasure {
val mapBody = TreeTypeMap(
oldOwners = rdef.symbol :: Nil,
newOwners = stat.symbol :: Nil,
substFrom = fromParams,
substTo = toParams)
substFrom = rSyms ::: fromParams,
substTo = originalSyms ::: toParams)
cpy.DefDef(stat)(rhs = mapBody.transform(rdef.rhs))
case stat => stat
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package transform

import ast.Trees.*, ast.tpd, core.*
import Contexts.*, Types.*, Decorators.*, Symbols.*, DenotTransformers.*
import SymDenotations.*, Scopes.*, StdNames.*, NameOps.*, Names.*
import SymDenotations.*, Scopes.*, StdNames.*, NameOps.*, Names.*, NameKinds.*
import MegaPhase.MiniPhase


Expand All @@ -25,7 +25,7 @@ class SpecializeFunctions extends MiniPhase {
/** Create forwarders from the generic applys to the specialized ones.
*/
override def transformDefDef(ddef: DefDef)(using Context) = {
if ddef.name != nme.apply
if ddef.name.asTermName.exclude(BodyRetainerName) != nme.apply
|| ddef.termParamss.length != 1
|| ddef.termParamss.head.length > 2
|| !ctx.owner.isClass
Expand All @@ -41,6 +41,8 @@ class SpecializeFunctions extends MiniPhase {
val paramTypes = ddef.termParamss.head.map(_.symbol.info)
val retType = sym.info.finalResultType
specName = nme.apply.specializedFunction(retType, paramTypes)
if ddef.name.is(BodyRetainerName) then
specName = BodyRetainerName(specName.nn.asTermName)
defn.isSpecializableFunction(cls, paramTypes, retType)
}

Expand Down
6 changes: 6 additions & 0 deletions tests/run/i19724.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class MyMapper extends (Int => Double):
inline def apply(v: Int): Double = v.toDouble

@main def Test =
val f: (Int => Double) = new MyMapper
assert(f(3) == 3.0)

0 comments on commit 32f5580

Please sign in to comment.