Skip to content

Commit b96a235

Browse files
committed
Add structural classes of dynamicApply before inlining
[Cherry-picked 7163042][modified]
1 parent d76a553 commit b96a235

File tree

6 files changed

+55
-5
lines changed

6 files changed

+55
-5
lines changed

Diff for: compiler/src/dotty/tools/dotc/core/Mode.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,6 @@ object Mode {
147147
*/
148148
val RelaxedOverriding: Mode = newMode(30, "RelaxedOverriding")
149149

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

Diff for: compiler/src/dotty/tools/dotc/inlines/Inlines.scala

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

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

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
361361
case tree @ Inlined(call, bindings, expansion) if !tree.inlinedFromOuterScope =>
362362
val pos = call.sourcePos
363363
CrossVersionChecks.checkExperimentalRef(call.symbol, pos)
364-
withMode(Mode.InlinedCall)(transform(call))
364+
withMode(Mode.NoInline)(transform(call))
365365
val callTrace = Inlines.inlineCallTrace(call.symbol, pos)(using ctx.withSource(pos.source))
366366
cpy.Inlined(tree)(callTrace, transformSub(bindings), transform(expansion)(using inlineContext(tree)))
367367
case templ: Template =>
@@ -512,7 +512,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
512512
if (sym.isEffectivelyErased) dropInlines.transform(rhs) else rhs
513513

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

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

Diff for: 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.*
@@ -17,6 +19,7 @@ import core.Symbols.*
1719
import transform.ValueClasses
1820
import ErrorReporting.*
1921
import reporting.*
22+
import inlines.Inlines
2023

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

215223
def fail(reason: String): Tree =

Diff for: 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)

Diff for: 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)