diff options
author | Adriaan Moors <adriaan@lightbend.com> | 2016-08-26 09:21:38 +0200 |
---|---|---|
committer | Adriaan Moors <adriaan@lightbend.com> | 2016-08-30 19:24:04 +0200 |
commit | 92d1af11b04b4f7c8aafd4ff911bf747eb1029aa (patch) | |
tree | 097ee110e9c5a6a20a76469874cf8c26427a847b /src/compiler/scala/tools/nsc/transform/CleanUp.scala | |
parent | f12e6257eef36ffaa9e2a72afc3f83f59296bf67 (diff) | |
download | scala-92d1af11b04b4f7c8aafd4ff911bf747eb1029aa.tar.gz scala-92d1af11b04b4f7c8aafd4ff911bf747eb1029aa.tar.bz2 scala-92d1af11b04b4f7c8aafd4ff911bf747eb1029aa.zip |
Specialize erasure of `synchronized` primitive method
The goal is to avoid emitting unneeded `BoxedUnit` values,
which are the result of adapting a `Unit`-typed expression
inside a `synchronized(...)` to the erased type of
`synchronized`'s argument -- `Object`.
The proposed solution gives `synchronized` a polymorphic
type (the info of the type param is still erased so that
bounds checking works in the erased type system), so that
an application `synchronized(println("boo"))` erases to
`synchronized[Unit])(println("boo"))`, and no boxing is
performed on the `println("boo")` argument, whose expected
type is now `Unit` instead of `Object`.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/CleanUp.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/CleanUp.scala | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index 0fb6213d36..81df28bc87 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -456,6 +456,11 @@ abstract class CleanUp extends Statics with Transform with ast.TreeDSL { super.transform(treeCopy.ApplyDynamic(tree, atPos(fn.pos)(Ident(SymbolLiteral_dummy).setType(SymbolLiteral_dummy.info)), LIT(SymbolLiteral_bootstrap) :: arg :: Nil)) + // Drop the TypeApply, which was used in Erasure to make `synchronized { ... } ` erase like `...` + // (and to avoid boxing the argument to the polymorphic `synchronized` method). + case app@Apply(TypeApply(fun, _), args) if fun.symbol == Object_synchronized => + super.transform(treeCopy.Apply(app, fun, args)) + // Replaces `Array(Predef.wrapArray(ArrayValue(...).$asInstanceOf[...]), <tag>)` // with just `ArrayValue(...).$asInstanceOf[...]` // |