Skip to content

Commit 6c7234b

Browse files
committed
This version is additionally able to _throw_ in case a lazy val would be assigned twice.
1 parent 0a6bc93 commit 6c7234b

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

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

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,21 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
187187
def mkNonThreadSafeDef(target: Tree, flag: Tree, rhs: Tree)(implicit ctx: Context) = {
188188
val setFlag = flag.becomes(Literal(Constants.Constant(true)))
189189
val flagSet = setFlag :: Nil
190-
val targetSet = if (isWildcardArg(rhs)) flagSet else target.becomes(rhs) :: flagSet
191-
val init = Block(targetSet, target.ensureApplied)
190+
191+
val init = evalOnce(rhs) { rhsRef =>
192+
val targetSet = if (isWildcardArg(rhs)) flagSet else target.becomes(rhsRef) :: flagSet
193+
val checkValidity =
194+
tpd.If(
195+
target.select(defn.Any_!=).appliedTo(tpd.defaultValue(target.tpe.widenDealias)).select(defn.Boolean_&&).
196+
appliedTo(
197+
target.select(defn.Any_!=).appliedTo(rhsRef)
198+
),
199+
tpd.Throw(tpd.New(ctx.requiredClass("java.lang.IllegalStateException").namedType, Nil)),
200+
tpd.EmptyTree
201+
)
202+
Block(checkValidity :: targetSet, rhsRef)
203+
}
204+
192205
If(flag.ensureApplied, target.ensureApplied, init)
193206
}
194207

0 commit comments

Comments
 (0)