Skip to content

Commit 7713bb6

Browse files
authored
Add structural classes of dynamicApply before inlining (#18766)
Fixes #17761
2 parents 22063fa + 7163042 commit 7713bb6

File tree

6 files changed

+55
-5
lines changed

6 files changed

+55
-5
lines changed

compiler/src/dotty/tools/dotc/core/Mode.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,6 @@ object Mode {
163163
*/
164164
val RelaxedOverriding: Mode = newMode(30, "RelaxedOverriding")
165165

166-
/** We are checking the original call of an Inlined node */
167-
val InlinedCall: Mode = newMode(31, "InlinedCall")
166+
/** Skip inlining of methods. */
167+
val NoInline: Mode = newMode(31, "NoInline")
168168
}

compiler/src/dotty/tools/dotc/inlines/Inlines.scala

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ object Inlines:
6464
)
6565
&& !ctx.typer.hasInliningErrors
6666
&& !ctx.base.stopInlining
67+
&& !ctx.mode.is(Mode.NoInline)
6768
}
6869

6970
private def needsTransparentInlining(tree: Tree)(using Context): Boolean =

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
366366
case tree @ Inlined(call, bindings, expansion) if !tree.inlinedFromOuterScope =>
367367
val pos = call.sourcePos
368368
CrossVersionChecks.checkExperimentalRef(call.symbol, pos)
369-
withMode(Mode.InlinedCall)(transform(call))
369+
withMode(Mode.NoInline)(transform(call))
370370
val callTrace = ref(call.symbol)(using ctx.withSource(pos.source)).withSpan(pos.span)
371371
cpy.Inlined(tree)(callTrace, transformSub(bindings), transform(expansion)(using inlineContext(tree)))
372372
case templ: Template =>
@@ -520,7 +520,7 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
520520
if (sym.isEffectivelyErased) dropInlines.transform(rhs) else rhs
521521

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

526526
/** Check if the definition has macro annotation and sets `compilationUnit.hasMacroAnnotations` if needed. */

compiler/src/dotty/tools/dotc/typer/Dynamic.scala

+9-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import dotty.tools.dotc.ast.tpd
77
import dotty.tools.dotc.ast.untpd
88
import dotty.tools.dotc.core.Constants.Constant
99
import dotty.tools.dotc.core.Contexts.*
10+
import dotty.tools.dotc.core.Flags.*
11+
import dotty.tools.dotc.core.Mode
1012
import dotty.tools.dotc.core.Names.{Name, TermName}
1113
import dotty.tools.dotc.core.StdNames.*
1214
import dotty.tools.dotc.core.Types.*
@@ -18,6 +20,7 @@ import ErrorReporting.*
1820
import dotty.tools.dotc.transform.ValueClasses
1921
import dotty.tools.dotc.transform.TypeUtils.isPrimitiveValueType
2022
import reporting.*
23+
import inlines.Inlines
2124

2225
object Dynamic {
2326
private def isDynamicMethod(name: Name): Boolean =
@@ -210,7 +213,12 @@ trait Dynamic {
210213
case _ => tree
211214
case other => tree
212215
case _ => tree
213-
addClassOfs(typed(scall))
216+
217+
// We type the application of `applyDynamic` without inlining (arguments are already typed and inlined),
218+
// to be able to add the add the Class arguments before we inline the method.
219+
val call = addClassOfs(withMode(Mode.NoInline)(typed(scall)))
220+
if Inlines.needsInlining(call) then Inlines.inlineCall(call)
221+
else call
214222
}
215223

216224
def fail(reason: String): Tree =

tests/run/i17761.check

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Normal
2+
test
3+
ArraySeq(class java.lang.String, int)
4+
ArraySeq(test, 42)
5+
Transparent
6+
test
7+
ArraySeq(class java.lang.String, int)
8+
ArraySeq(test, 42)

tests/run/i17761.scala

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class MyRecord extends Selectable:
2+
def applyDynamic(name: String, paramClasses: Class[_]*)(args: Any*): Any = {
3+
println(name)
4+
println(paramClasses)
5+
println(args)
6+
()
7+
}
8+
9+
class MyRecordTransparent extends Selectable:
10+
inline transparent def applyDynamic(name: String, paramClasses: Class[_]*)(args: Any*): Any = {
11+
println(name)
12+
println(paramClasses)
13+
println(args)
14+
()
15+
}
16+
17+
type Person = MyRecord {
18+
def test(a: String, b: Int): Unit
19+
}
20+
21+
22+
type PersonTransparent = MyRecordTransparent {
23+
def test(a: String, b: Int): Unit
24+
}
25+
26+
val person = MyRecord().asInstanceOf[Person]
27+
val personTransparent = MyRecordTransparent().asInstanceOf[PersonTransparent]
28+
29+
@main def Test: Unit =
30+
println("Normal")
31+
person.test("test", 42)
32+
println("Transparent")
33+
personTransparent.test("test", 42)

0 commit comments

Comments
 (0)