Skip to content

Commit b205858

Browse files
oderskysmarter
authored andcommitted
Generalize NewWithArgs
I noted another useless boxing (in Positioned.scala), where we have ``` (new Span(x): Span).coord ``` The allocation should be eliminated but was not.
1 parent ee9b034 commit b205858

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,15 @@ object TreeExtractors {
1919
}
2020
}
2121

22-
/** Match new C(args) and extract (C, args) */
22+
/** Match new C(args) and extract (C, args).
23+
* Also admit new C(args): T and {new C(args)}.
24+
*/
2325
object NewWithArgs {
2426
def unapply(t: Tree)(using Context): Option[(Type, List[Tree])] = t match {
2527
case Apply(Select(New(_), nme.CONSTRUCTOR), args) =>
2628
Some((t.tpe, args))
29+
case Typed(expr, _) => unapply(expr)
30+
case Block(Nil, expr) => unapply(expr)
2731
case _ =>
2832
None
2933
}

compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -983,26 +983,38 @@ class TestBCode extends DottyBytecodeTest {
983983
|class Foo {
984984
| val FreshApprox: ApproxState = new ApproxState(4)
985985
| var approx: ApproxState = FreshApprox
986-
| def meth: Boolean = approx == FreshApprox
986+
| def meth1: Boolean = approx == FreshApprox
987+
| def meth2: Boolean = (new ApproxState(4): ApproxState) == FreshApprox
987988
|}
988989
""".stripMargin
989990

990991
checkBCode(source) { dir =>
991992
val clsIn = dir.lookupName("Foo.class", directory = false).input
992993
val clsNode = loadClassNode(clsIn)
993-
val meth = getMethod(clsNode, "meth")
994+
val meth1 = getMethod(clsNode, "meth1")
995+
val meth2 = getMethod(clsNode, "meth2")
996+
val instructions1 = instructionsFromMethod(meth1)
997+
val instructions2 = instructionsFromMethod(meth2)
994998

995-
val instructions = instructionsFromMethod(meth)
996999
val isFrameLine = (x: Instruction) => x.isInstanceOf[FrameEntry] || x.isInstanceOf[LineNumber]
1000+
9971001
// No allocations of ApproxState
998-
assertSameCode(instructions.filterNot(isFrameLine), List(
1002+
1003+
assertSameCode(instructions1.filterNot(isFrameLine), List(
9991004
VarOp(ALOAD, 0), Invoke(INVOKEVIRTUAL, "Foo", "approx", "()I", false),
10001005
VarOp(ALOAD, 0), Invoke(INVOKEVIRTUAL, "Foo", "FreshApprox", "()I", false),
10011006
Jump(IF_ICMPNE, Label(7)), Op(ICONST_1),
10021007
Jump(GOTO, Label(10)),
10031008
Label(7), Op(ICONST_0),
1004-
Label(10), Op(IRETURN)
1005-
))
1009+
Label(10), Op(IRETURN)))
1010+
1011+
assertSameCode(instructions2.filterNot(isFrameLine), List(
1012+
Op(ICONST_4),
1013+
VarOp(ALOAD, 0), Invoke(INVOKEVIRTUAL, "Foo", "FreshApprox", "()I", false),
1014+
Jump(IF_ICMPNE, Label(6)), Op(ICONST_1),
1015+
Jump(GOTO, Label(9)),
1016+
Label(6), Op(ICONST_0),
1017+
Label(9), Op(IRETURN)))
10061018
}
10071019
}
10081020
}

0 commit comments

Comments
 (0)