Skip to content

Commit 5f7d0b7

Browse files
committed
Fix scala#505: Remove unnecessary boxing of synchronized block
`synchronized` is now treated as a magic method by the compiler and is no longer erased (similarly to `asInstanceOf` and `isInstanceOf`). Backend is updated to handle this new magic polymorphic method.
1 parent 0b8fe52 commit 5f7d0b7

File tree

5 files changed

+22
-7
lines changed

5 files changed

+22
-7
lines changed

compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
116116
val Throwable_Type: Type = defn.ThrowableType
117117
val Object_isInstanceOf: Symbol = defn.Any_isInstanceOf
118118
val Object_asInstanceOf: Symbol = defn.Any_asInstanceOf
119+
val Object_synchronized: Symbol = defn.Object_synchronized
119120
val Object_equals: Symbol = defn.Any_equals
120121
val ArrayClass: Symbol = defn.ArrayClass
121122
val UnitClass: Symbol = defn.UnitClass

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ class Definitions {
10771077
lazy val NoInitClasses: Set[Symbol] = NotRuntimeClasses + FunctionXXLClass
10781078

10791079
def isPolymorphicAfterErasure(sym: Symbol): Boolean =
1080-
(sym eq Any_isInstanceOf) || (sym eq Any_asInstanceOf)
1080+
(sym eq Any_isInstanceOf) || (sym eq Any_asInstanceOf) || (sym eq Object_synchronized)
10811081

10821082
def isTupleType(tp: Type)(implicit ctx: Context): Boolean = {
10831083
val arity = tp.dealias.argInfos.length

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,10 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer {
168168
val initSymbol = ctx.newSymbol(x.symbol.owner, initName, initFlags, MethodType(Nil, tpe), coord = x.pos)
169169
val rhs = x.rhs.changeOwnerAfter(x.symbol, initSymbol, this)
170170
val initialize = holderRef.select(lazyNme.initialize).appliedTo(rhs)
171-
val initBody =
172-
adaptToType(
173-
holderRef.select(defn.Object_synchronized).appliedTo(
174-
adaptToType(If(initialized, getValue, initialize), defn.ObjectType)),
175-
tpe)
171+
val initBody = holderRef
172+
.select(defn.Object_synchronized)
173+
.appliedToType(tpe)
174+
.appliedTo(If(initialized, getValue, initialize).ensureConforms(tpe))
176175
val initTree = DefDef(initSymbol, initBody)
177176

178177
// def x(): Int = if (x$lzy.initialized()) x$lzy.value() else x$lzycompute()

tests/run/i505.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
val a: Int = synchronized(1)
4+
val b: Long = synchronized(1L)
5+
val c: Boolean = synchronized(true)
6+
val d: Float = synchronized(1f)
7+
val e: Double = synchronized(1.0)
8+
val f: Byte = synchronized(1.toByte)
9+
val g: Char = synchronized('1')
10+
val h: Short = synchronized(1.toShort)
11+
val i: String = synchronized("Hello")
12+
val j: List[Int] = synchronized(List(1))
13+
synchronized(())
14+
}
15+
}

0 commit comments

Comments
 (0)