Skip to content

Commit

Permalink
Add structural classes of dynamicApply before inlining
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasstucki committed Nov 9, 2023
1 parent a90db4f commit 7163042
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 5 deletions.
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Mode.scala
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,6 @@ object Mode {
*/
val RelaxedOverriding: Mode = newMode(30, "RelaxedOverriding")

/** We are checking the original call of an Inlined node */
val InlinedCall: Mode = newMode(31, "InlinedCall")
/** Skip inlining of methods. */
val NoInline: Mode = newMode(31, "NoInline")
}
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/inlines/Inlines.scala
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ object Inlines:
)
&& !ctx.typer.hasInliningErrors
&& !ctx.base.stopInlining
&& !ctx.mode.is(Mode.NoInline)
}

private def needsTransparentInlining(tree: Tree)(using Context): Boolean =
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/transform/PostTyper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
case tree @ Inlined(call, bindings, expansion) if !tree.inlinedFromOuterScope =>
val pos = call.sourcePos
CrossVersionChecks.checkExperimentalRef(call.symbol, pos)
withMode(Mode.InlinedCall)(transform(call))
withMode(Mode.NoInline)(transform(call))
val callTrace = ref(call.symbol)(using ctx.withSource(pos.source)).withSpan(pos.span)
cpy.Inlined(tree)(callTrace, transformSub(bindings), transform(expansion)(using inlineContext(tree)))
case templ: Template =>
Expand Down Expand Up @@ -520,7 +520,7 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
if (sym.isEffectivelyErased) dropInlines.transform(rhs) else rhs

private def registerNeedsInlining(tree: Tree)(using Context): Unit =
if tree.symbol.is(Inline) && !Inlines.inInlineMethod && !ctx.mode.is(Mode.InlinedCall) then
if tree.symbol.is(Inline) && !Inlines.inInlineMethod && !ctx.mode.is(Mode.NoInline) then
ctx.compilationUnit.needsInlining = true

/** Check if the definition has macro annotation and sets `compilationUnit.hasMacroAnnotations` if needed. */
Expand Down
10 changes: 9 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/Dynamic.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.ast.untpd
import dotty.tools.dotc.core.Constants.Constant
import dotty.tools.dotc.core.Contexts.*
import dotty.tools.dotc.core.Flags.*
import dotty.tools.dotc.core.Mode
import dotty.tools.dotc.core.Names.{Name, TermName}
import dotty.tools.dotc.core.StdNames.*
import dotty.tools.dotc.core.Types.*
Expand All @@ -18,6 +20,7 @@ import ErrorReporting.*
import dotty.tools.dotc.transform.ValueClasses
import dotty.tools.dotc.transform.TypeUtils.isPrimitiveValueType
import reporting.*
import inlines.Inlines

object Dynamic {
private def isDynamicMethod(name: Name): Boolean =
Expand Down Expand Up @@ -210,7 +213,12 @@ trait Dynamic {
case _ => tree
case other => tree
case _ => tree
addClassOfs(typed(scall))

// We type the application of `applyDynamic` without inlining (arguments are already typed and inlined),
// to be able to add the add the Class arguments before we inline the method.
val call = addClassOfs(withMode(Mode.NoInline)(typed(scall)))
if Inlines.needsInlining(call) then Inlines.inlineCall(call)
else call
}

def fail(reason: String): Tree =
Expand Down
8 changes: 8 additions & 0 deletions tests/run/i17761.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Normal
test
ArraySeq(class java.lang.String, int)
ArraySeq(test, 42)
Transparent
test
ArraySeq(class java.lang.String, int)
ArraySeq(test, 42)
33 changes: 33 additions & 0 deletions tests/run/i17761.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
class MyRecord extends Selectable:
def applyDynamic(name: String, paramClasses: Class[_]*)(args: Any*): Any = {
println(name)
println(paramClasses)
println(args)
()
}

class MyRecordTransparent extends Selectable:
inline transparent def applyDynamic(name: String, paramClasses: Class[_]*)(args: Any*): Any = {
println(name)
println(paramClasses)
println(args)
()
}

type Person = MyRecord {
def test(a: String, b: Int): Unit
}


type PersonTransparent = MyRecordTransparent {
def test(a: String, b: Int): Unit
}

val person = MyRecord().asInstanceOf[Person]
val personTransparent = MyRecordTransparent().asInstanceOf[PersonTransparent]

@main def Test: Unit =
println("Normal")
person.test("test", 42)
println("Transparent")
personTransparent.test("test", 42)

0 comments on commit 7163042

Please sign in to comment.