From af46cd8eae752d885667240fcc7db7411b48748f Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Tue, 28 May 2019 19:16:21 +0200 Subject: [PATCH 1/4] Don't force BoxedUnitType when forcing UnitType Otherwise we might end up trying to initialize UnitType recursively, which happens to work with the current implementation of non-volatile lazy vals, but won't work after the next commit. --- .../dotty/tools/dotc/core/Definitions.scala | 42 ++++++++++++------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 0d02b50cb259..602ea6e920d1 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -470,10 +470,10 @@ class Definitions { def ArrayModule(implicit ctx: Context): ClassSymbol = ArrayModuleType.symbol.moduleClass.asClass - lazy val UnitType: TypeRef = valueTypeRef("scala.Unit", BoxedUnitType, java.lang.Void.TYPE, UnitEnc, nme.specializedTypeNames.Void) + lazy val UnitType: TypeRef = valueTypeRef("scala.Unit", java.lang.Void.TYPE, UnitEnc, nme.specializedTypeNames.Void) def UnitClass(implicit ctx: Context): ClassSymbol = UnitType.symbol.asClass def UnitModuleClass(implicit ctx: Context): Symbol = UnitType.symbol.asClass.linkedClass - lazy val BooleanType: TypeRef = valueTypeRef("scala.Boolean", BoxedBooleanType, java.lang.Boolean.TYPE, BooleanEnc, nme.specializedTypeNames.Boolean) + lazy val BooleanType: TypeRef = valueTypeRef("scala.Boolean", java.lang.Boolean.TYPE, BooleanEnc, nme.specializedTypeNames.Boolean) def BooleanClass(implicit ctx: Context): ClassSymbol = BooleanType.symbol.asClass lazy val Boolean_notR: TermRef = BooleanClass.requiredMethodRef(nme.UNARY_!) def Boolean_! : Symbol = Boolean_notR.symbol @@ -492,13 +492,13 @@ class Definitions { }) def Boolean_!= : Symbol = Boolean_neqeqR.symbol - lazy val ByteType: TypeRef = valueTypeRef("scala.Byte", BoxedByteType, java.lang.Byte.TYPE, ByteEnc, nme.specializedTypeNames.Byte) + lazy val ByteType: TypeRef = valueTypeRef("scala.Byte", java.lang.Byte.TYPE, ByteEnc, nme.specializedTypeNames.Byte) def ByteClass(implicit ctx: Context): ClassSymbol = ByteType.symbol.asClass - lazy val ShortType: TypeRef = valueTypeRef("scala.Short", BoxedShortType, java.lang.Short.TYPE, ShortEnc, nme.specializedTypeNames.Short) + lazy val ShortType: TypeRef = valueTypeRef("scala.Short", java.lang.Short.TYPE, ShortEnc, nme.specializedTypeNames.Short) def ShortClass(implicit ctx: Context): ClassSymbol = ShortType.symbol.asClass - lazy val CharType: TypeRef = valueTypeRef("scala.Char", BoxedCharType, java.lang.Character.TYPE, CharEnc, nme.specializedTypeNames.Char) + lazy val CharType: TypeRef = valueTypeRef("scala.Char", java.lang.Character.TYPE, CharEnc, nme.specializedTypeNames.Char) def CharClass(implicit ctx: Context): ClassSymbol = CharType.symbol.asClass - lazy val IntType: TypeRef = valueTypeRef("scala.Int", BoxedIntType, java.lang.Integer.TYPE, IntEnc, nme.specializedTypeNames.Int) + lazy val IntType: TypeRef = valueTypeRef("scala.Int", java.lang.Integer.TYPE, IntEnc, nme.specializedTypeNames.Int) def IntClass(implicit ctx: Context): ClassSymbol = IntType.symbol.asClass lazy val Int_minusR: TermRef = IntClass.requiredMethodRef(nme.MINUS, List(IntType)) def Int_- : Symbol = Int_minusR.symbol @@ -514,7 +514,7 @@ class Definitions { def Int_>= : Symbol = Int_geR.symbol lazy val Int_leR: TermRef = IntClass.requiredMethodRef(nme.LE, List(IntType)) def Int_<= : Symbol = Int_leR.symbol - lazy val LongType: TypeRef = valueTypeRef("scala.Long", BoxedLongType, java.lang.Long.TYPE, LongEnc, nme.specializedTypeNames.Long) + lazy val LongType: TypeRef = valueTypeRef("scala.Long", java.lang.Long.TYPE, LongEnc, nme.specializedTypeNames.Long) def LongClass(implicit ctx: Context): ClassSymbol = LongType.symbol.asClass lazy val Long_XOR_Long: Symbol = LongType.member(nme.XOR).requiredSymbol("method", nme.XOR, LongType.denot)( x => (x is Method) && (x.info.firstParamTypes.head isRef defn.LongClass) @@ -529,9 +529,9 @@ class Definitions { lazy val Long_divR: TermRef = LongClass.requiredMethodRef(nme.DIV, List(LongType)) def Long_/ : Symbol = Long_divR.symbol - lazy val FloatType: TypeRef = valueTypeRef("scala.Float", BoxedFloatType, java.lang.Float.TYPE, FloatEnc, nme.specializedTypeNames.Float) + lazy val FloatType: TypeRef = valueTypeRef("scala.Float", java.lang.Float.TYPE, FloatEnc, nme.specializedTypeNames.Float) def FloatClass(implicit ctx: Context): ClassSymbol = FloatType.symbol.asClass - lazy val DoubleType: TypeRef = valueTypeRef("scala.Double", BoxedDoubleType, java.lang.Double.TYPE, DoubleEnc, nme.specializedTypeNames.Double) + lazy val DoubleType: TypeRef = valueTypeRef("scala.Double", java.lang.Double.TYPE, DoubleEnc, nme.specializedTypeNames.Double) def DoubleClass(implicit ctx: Context): ClassSymbol = DoubleType.symbol.asClass lazy val BoxedUnitType: TypeRef = ctx.requiredClassRef("scala.runtime.BoxedUnit") @@ -1361,13 +1361,14 @@ class Definitions { private lazy val ScalaNumericValueTypes: collection.Set[TypeRef] = ScalaNumericValueTypeList.toSet private lazy val ScalaValueTypes: collection.Set[TypeRef] = ScalaNumericValueTypes + UnitType + BooleanType - private lazy val ScalaBoxedTypes = ScalaValueTypes map (t => boxedTypes(t.name)) val ScalaNumericValueClasses: PerRun[collection.Set[Symbol]] = new PerRun(implicit ctx => ScalaNumericValueTypes.map(_.symbol)) val ScalaValueClasses: PerRun[collection.Set[Symbol]] = new PerRun(implicit ctx => ScalaValueTypes.map(_.symbol)) - val ScalaBoxedClasses: PerRun[collection.Set[Symbol]] = new PerRun(implicit ctx => ScalaBoxedTypes.map(_.symbol)) - private val boxedTypes = mutable.Map[TypeName, TypeRef]() + val ScalaBoxedClasses: PerRun[collection.Set[Symbol]] = new PerRun(implicit ctx => + Set(BoxedByteClass, BoxedShortClass, BoxedCharClass, BoxedIntClass, BoxedLongClass, BoxedFloatClass, BoxedDoubleClass, BoxedUnitClass, BoxedBooleanClass) + ) + private val valueTypeEnc = mutable.Map[TypeName, PrimitiveClassEnc]() private val typeTags = mutable.Map[TypeName, Name]().withDefaultValue(nme.specializedTypeNames.Object) @@ -1375,9 +1376,8 @@ class Definitions { // private val javaTypeToValueTypeRef = mutable.Map[Class[_], TypeRef]() // private val valueTypeNamesToJavaType = mutable.Map[TypeName, Class[_]]() - private def valueTypeRef(name: String, boxed: TypeRef, jtype: Class[_], enc: Int, tag: Name): TypeRef = { + private def valueTypeRef(name: String, jtype: Class[_], enc: Int, tag: Name): TypeRef = { val vcls = ctx.requiredClassRef(name) - boxedTypes(vcls.name) = boxed valueTypeEnc(vcls.name) = enc typeTags(vcls.name) = tag // unboxedTypeRef(boxed.name) = vcls @@ -1387,7 +1387,19 @@ class Definitions { } /** The type of the boxed class corresponding to primitive value type `tp`. */ - def boxedType(tp: Type)(implicit ctx: Context): TypeRef = boxedTypes(scalaClassName(tp)) + def boxedType(tp: Type)(implicit ctx: Context): TypeRef = { + val cls = tp.classSymbol + if (cls eq ByteClass) BoxedByteType + else if (cls eq ShortClass) BoxedShortType + else if (cls eq CharClass) BoxedCharType + else if (cls eq IntClass) BoxedIntType + else if (cls eq LongClass) BoxedLongType + else if (cls eq FloatClass) BoxedFloatType + else if (cls eq DoubleClass) BoxedDoubleType + else if (cls eq UnitClass) BoxedUnitType + else if (cls eq BooleanClass) BoxedBooleanType + else sys.error(s"Not a primitive value type: $tp") + } /** The JVM tag for `tp` if it's a primitive, `java.lang.Object` otherwise. */ def typeTag(tp: Type)(implicit ctx: Context): Name = typeTags(scalaClassName(tp)) From 2c231ff3307687f63a35978fd799e58acb839f38 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Tue, 28 May 2019 17:21:54 +0200 Subject: [PATCH 2/4] Make lazy vals thread-safe by default Previously this required using `@volatile` but that would not be consistent with Scala 2. The old behavior of non-volatile lazy vals can be recovered by using the newly-introduced `@threadUnsafe`. --- .../dotty/tools/dotc/core/Definitions.scala | 2 + .../dotc/transform/AugmentScala2Traits.scala | 10 +- .../dotty/tools/dotc/transform/LazyVals.scala | 36 ++-- .../dotty/tools/dotc/transform/SymUtils.scala | 2 + .../src/dotty/tools/dotc/typer/Typer.scala | 10 -- .../backend/jvm/DottyBytecodeTests.scala | 21 ++- .../{lazy-vals-spec.md => lazy-vals-init.md} | 9 +- .../reference/changed-features/lazy-vals.md | 27 --- .../threadUnsafe-annotation.md | 18 ++ docs/sidebar.yml | 6 +- .../src/scala/annotation/threadUnsafe.scala | 7 + tests/pos/lazyvals.scala | 2 +- tests/pos/scala2traits/dotty-subclass.scala | 2 +- tests/run/Lazies1.scala | 2 +- tests/run/Lazies2.scala | 4 +- tests/run/i1692.scala | 2 +- tests/run/i1692b.scala | 157 ++++++++++++++++++ tests/run/i1856.scala | 6 +- tests/run/i2275.scala | 2 +- tests/run/i4451.scala | 14 +- tests/run/statics.scala | 2 +- 21 files changed, 251 insertions(+), 90 deletions(-) rename docs/docs/reference/changed-features/{lazy-vals-spec.md => lazy-vals-init.md} (93%) delete mode 100644 docs/docs/reference/changed-features/lazy-vals.md create mode 100644 docs/docs/reference/other-new-features/threadUnsafe-annotation.md create mode 100644 library/src/scala/annotation/threadUnsafe.scala create mode 100644 tests/run/i1692b.scala diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 602ea6e920d1..060362e6d91c 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -891,6 +891,8 @@ class Definitions { def TASTYLongSignatureAnnot(implicit ctx: Context): ClassSymbol = TASTYLongSignatureAnnotType.symbol.asClass lazy val TailrecAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.tailrec") def TailrecAnnot(implicit ctx: Context): ClassSymbol = TailrecAnnotType.symbol.asClass + lazy val ThreadUnsafeAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.threadUnsafe") + def ThreadUnsafeAnnot(implicit ctx: Context): ClassSymbol = ThreadUnsafeAnnotType.symbol.asClass lazy val TransientParamAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.constructorOnly") def TransientParamAnnot(implicit ctx: Context): ClassSymbol = TransientParamAnnotType.symbol.asClass lazy val CompileTimeOnlyAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.compileTimeOnly") diff --git a/compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala b/compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala index c95c516865e6..655923ad3d6c 100644 --- a/compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala +++ b/compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala @@ -25,7 +25,6 @@ object AugmentScala2Traits { * These symbols would have been added between Unpickling and Mixin in the Scala2 pipeline. * * Specifically, we: - * - Mark all lazy val fields as @volatile to get the proper Scala 2 semantics. * - Add trait setters for vals defined in traits. * - Expand the names of all private getters and setters as well as super accessors in the trait and make * not-private. @@ -57,14 +56,9 @@ class AugmentScala2Traits extends MiniPhase with IdentityDenotTransformer { this info = MethodType(getter.info.resultType :: Nil, defn.UnitType)) for (sym <- mixin.info.decls) { - if (sym.isGetter) - if (sym.is(Lazy)) { - if (!sym.hasAnnotation(defn.VolatileAnnot)) - sym.addAnnotation(Annotation(defn.VolatileAnnot, Nil)) - } - else if (!sym.is(Deferred) && !sym.setter.exists && + if (sym.isGetter && !sym.is(LazyOrDeferred) && !sym.setter.exists && !sym.info.resultType.isInstanceOf[ConstantType]) - traitSetter(sym.asTerm).enteredAfter(thisPhase) + traitSetter(sym.asTerm).enteredAfter(thisPhase) if ((sym.is(PrivateAccessor) && !sym.name.is(ExpandedName) && (sym.isGetter || sym.isSetter)) // strangely, Scala 2 fields are also methods that have Accessor set. || sym.isSuperAccessor) // scala2 superaccessors are pickled as private, but are compiled as public expanded diff --git a/compiler/src/dotty/tools/dotc/transform/LazyVals.scala b/compiler/src/dotty/tools/dotc/transform/LazyVals.scala index 1f57105fa9fe..bfb1b689a168 100644 --- a/compiler/src/dotty/tools/dotc/transform/LazyVals.scala +++ b/compiler/src/dotty/tools/dotc/transform/LazyVals.scala @@ -74,18 +74,18 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer { else { val isField = sym.owner.isClass if (isField) { - if (sym.isVolatile || - (sym.is(Module)/* || ctx.scala2Mode*/) && - // TODO assume @volatile once LazyVals uses static helper constructs instead of - // ones in the companion object. - !sym.is(Synthetic)) - // module class is user-defined. - // Should be threadsafe, to mimic safety guaranteed by global object - transformMemberDefVolatile(tree) - else if (sym.is(Module)) // synthetic module + if (sym.is(SyntheticModule)) transformSyntheticModule(tree) + else if (sym.isThreadUnsafe) { + if (sym.is(Module)) { + ctx.error(em"@threadUnsafe is only supported on lazy vals", sym.sourcePos) + transformMemberDefThreadSafe(tree) + } + else + transformMemberDefThreadUnsafe(tree) + } else - transformMemberDefNonVolatile(tree) + transformMemberDefThreadSafe(tree) } else transformLocalDef(tree) } @@ -196,7 +196,7 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer { ref(field).becomes(nullLiteral) } - /** Create non-threadsafe lazy accessor equivalent to such code + /** Create thread-unsafe lazy accessor equivalent to such code * ``` * def methodSymbol() = { * if (!flag) { @@ -208,7 +208,7 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer { * } * ``` */ - def mkNonThreadSafeDef(sym: Symbol, flag: Symbol, target: Symbol, rhs: Tree)(implicit ctx: Context): DefDef = { + def mkThreadUnsafeDef(sym: Symbol, flag: Symbol, target: Symbol, rhs: Tree)(implicit ctx: Context): DefDef = { val targetRef = ref(target) val flagRef = ref(flag) val stats = targetRef.becomes(rhs) :: flagRef.becomes(Literal(Constant(true))) :: nullOut(nullableFor(sym)) @@ -220,7 +220,7 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer { DefDef(sym.asTerm, Block(List(init), targetRef.ensureApplied)) } - /** Create non-threadsafe lazy accessor for not-nullable types equivalent to such code + /** Create thread-unsafe lazy accessor for not-nullable types equivalent to such code * ``` * def methodSymbol() = { * if (target eq null) { @@ -231,7 +231,7 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer { * } * ``` */ - def mkDefNonThreadSafeNonNullable(sym: Symbol, target: Symbol, rhs: Tree)(implicit ctx: Context): DefDef = { + def mkDefThreadUnsafeNonNullable(sym: Symbol, target: Symbol, rhs: Tree)(implicit ctx: Context): DefDef = { val targetRef = ref(target) val stats = targetRef.becomes(rhs) :: nullOut(nullableFor(sym)) val init = If( @@ -242,7 +242,7 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer { DefDef(sym.asTerm, Block(List(init), targetRef.ensureApplied)) } - def transformMemberDefNonVolatile(x: ValOrDefDef)(implicit ctx: Context): Thicket = { + def transformMemberDefThreadUnsafe(x: ValOrDefDef)(implicit ctx: Context): Thicket = { val claz = x.symbol.owner.asClass val tpe = x.tpe.widen.resultType.widen assert(!(x.symbol is Mutable)) @@ -255,13 +255,13 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer { val containerTree = ValDef(containerSymbol, defaultValue(tpe)) if (x.tpe.isNotNull && tpe <:< defn.ObjectType) { // can use 'null' value instead of flag - Thicket(containerTree, mkDefNonThreadSafeNonNullable(x.symbol, containerSymbol, x.rhs)) + Thicket(containerTree, mkDefThreadUnsafeNonNullable(x.symbol, containerSymbol, x.rhs)) } else { val flagName = LazyBitMapName.fresh(x.name.asTermName) val flagSymbol = ctx.newSymbol(x.symbol.owner, flagName, containerFlags | Private, defn.BooleanType).enteredAfter(this) val flag = ValDef(flagSymbol, Literal(Constant(false))) - Thicket(containerTree, flag, mkNonThreadSafeDef(x.symbol, flagSymbol, containerSymbol, x.rhs)) + Thicket(containerTree, flag, mkThreadUnsafeDef(x.symbol, flagSymbol, containerSymbol, x.rhs)) } } @@ -365,7 +365,7 @@ class LazyVals extends MiniPhase with IdentityDenotTransformer { DefDef(methodSymbol, loop) } - def transformMemberDefVolatile(x: ValOrDefDef)(implicit ctx: Context): Thicket = { + def transformMemberDefThreadSafe(x: ValOrDefDef)(implicit ctx: Context): Thicket = { assert(!(x.symbol is Mutable)) val tpe = x.tpe.widen.resultType.widen diff --git a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala index 3a3873977be8..5c25530b247d 100644 --- a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala +++ b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala @@ -54,6 +54,8 @@ class SymUtils(val self: Symbol) extends AnyVal { def isTypeTestOrCast(implicit ctx: Context): Boolean = isTypeCast || isTypeTest + def isThreadUnsafe(implicit ctx: Context): Boolean = self.hasAnnotation(defn.ThreadUnsafeAnnot) + def isVolatile(implicit ctx: Context): Boolean = self.hasAnnotation(defn.VolatileAnnot) def isAnyOverride(implicit ctx: Context): Boolean = self.is(Override) || self.is(AbsOverride) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 52b315025376..8b3272a0405c 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1477,20 +1477,10 @@ class Typer extends Namer val vdef1 = assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym) if (sym.is(Inline, butNot = DeferredOrTermParamOrAccessor)) checkInlineConformant(rhs1, isFinal = sym.is(Final), em"right-hand side of inline $sym") - patchIfLazy(vdef1) patchFinalVals(vdef1) vdef1.setDefTree } - /** Add a @volitile to lazy vals when rewriting from Scala2 */ - private def patchIfLazy(vdef: ValDef)(implicit ctx: Context): Unit = { - val sym = vdef.symbol - if (sym.is(Lazy, butNot = Deferred | Module | Synthetic) && !sym.isVolatile && - ctx.scala2Mode && ctx.settings.rewrite.value.isDefined && - !ctx.isAfterTyper) - patch(Span(toUntyped(vdef).span.start), "@volatile ") - } - /** Adds inline to final vals with idempotent rhs * * duplicating scalac behavior: for final vals that have rhs as constant, we do not create a field diff --git a/compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala b/compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala index 66cecaeb3685..2f170d3876e7 100644 --- a/compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala +++ b/compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala @@ -524,22 +524,35 @@ class TestBCode extends DottyBytecodeTest { } /** Test that the size of lazy field accesors is under a certain threshold - * - * - Changed from 19 to 14 */ @Test def lazyFields = { - val source = + val sourceUnsafe = + """import scala.annotation.threadUnsafe + | + |class Test { + | @threadUnsafe lazy val test = 1 + |} + """.stripMargin + + val sourceSafe = """class Test { | lazy val test = 1 |} """.stripMargin - checkBCode(source) { dir => + checkBCode(sourceUnsafe) { dir => val clsIn = dir.lookupName("Test.class", directory = false).input val clsNode = loadClassNode(clsIn) val method = getMethod(clsNode, "test") assertEquals(14, instructionsFromMethod(method).size) } + + checkBCode(sourceSafe) { dir => + val clsIn = dir.lookupName("Test.class", directory = false).input + val clsNode = loadClassNode(clsIn) + val method = getMethod(clsNode, "test") + assertEquals(94, instructionsFromMethod(method).size) + } } /* Test that objects compile to *final* classes. */ diff --git a/docs/docs/reference/changed-features/lazy-vals-spec.md b/docs/docs/reference/changed-features/lazy-vals-init.md similarity index 93% rename from docs/docs/reference/changed-features/lazy-vals-spec.md rename to docs/docs/reference/changed-features/lazy-vals-init.md index 0eec0242f583..4e5a4031f158 100644 --- a/docs/docs/reference/changed-features/lazy-vals-spec.md +++ b/docs/docs/reference/changed-features/lazy-vals-init.md @@ -1,6 +1,6 @@ --- layout: doc-page -title: Changed: Lazy Vals - More Details +title: Lazy Vals initialization --- Dotty implements [Version 6](https://docs.scala-lang.org/sips/improved-lazy-val-initialization.html#version-6---no-synchronization-on-this-and-concurrent-initialization-of-fields) @@ -19,7 +19,7 @@ Given a lazy field of the form: ```scala class Foo { - @volatile lazy val bar = + lazy val bar = } ``` @@ -69,9 +69,8 @@ val. This id grows with the number of volatile lazy vals defined in the class. ## Note on recursive lazy vals -Ideally recursive lazy vals should be flagged as an error. The current behavior for `@volatile` -recursive lazy vals is undefined (initialization may result in a deadlock). Non `@volatile` lazy -vals behave as in Scala 2. +Ideally recursive lazy vals should be flagged as an error. The current behavior for +recursive lazy vals is undefined (initialization may result in a deadlock). ## Reference diff --git a/docs/docs/reference/changed-features/lazy-vals.md b/docs/docs/reference/changed-features/lazy-vals.md deleted file mode 100644 index 0d9d74d2f3e2..000000000000 --- a/docs/docs/reference/changed-features/lazy-vals.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -layout: doc-page -title: Changed: Lazy Vals ---- - -Lazy field initialization no longer guarantees safe publishing. This change was done -to avoid the performance overhead of thread synchonization because most lazy vals are only used in -a single-threaded context. - -## Compatibility considerations - -To get back safe publishing (Scala 2's default) you need to annotate a lazy val with `@volatile`. In - -```scala -@volatile lazy val x = expr -``` - -it is guaranteed that readers of a lazy val will see the value of `x` once it is assigned. - -Local lazy vals (i.e. defined inside methods) are left unchanged. - -The [ScalaFix](https://scalacenter.github.io/scalafix/) rewrite tool -as well as Dotty's own `-language:Scala2 -rewrite` option will rewrite all normal -lazy vals to volatile ones in order to keep their semantics compatible -with current Scala's. - -[More details](./lazy-vals-spec.html) diff --git a/docs/docs/reference/other-new-features/threadUnsafe-annotation.md b/docs/docs/reference/other-new-features/threadUnsafe-annotation.md new file mode 100644 index 000000000000..db7d164d0f99 --- /dev/null +++ b/docs/docs/reference/other-new-features/threadUnsafe-annotation.md @@ -0,0 +1,18 @@ +--- +layout: doc-page +title: threadUnsafe annotation +--- + +A new annotation `@threadUnsafe` can be used on a field which defines a lazy +val. When this annotation is used, the initialization of the lazy val will use a +faster mechanism which is not thread-safe. + +### Example + +```scala +import scala.annotation.threadUnsafe + +class Hello { + @threadUnsafe lazy val x: Int = 1 +} +``` diff --git a/docs/sidebar.yml b/docs/sidebar.yml index 30f25b0f88af..8df98cfdf14f 100644 --- a/docs/sidebar.yml +++ b/docs/sidebar.yml @@ -99,10 +99,10 @@ sidebar: url: docs/reference/other-new-features/kind-polymorphism.html - title: Tupled Function url: docs/reference/other-new-features/tupled-function.html + - title: threadUnsafe Annotation + url: docs/reference/other-new-features/threadUnsafe-annotation.html - title: Other Changed Features subsection: - - title: Volatile Lazy Vals - url: docs/reference/changed-features/lazy-vals.html - title: Structural Types url: docs/reference/changed-features/structural-types.html - title: Operators @@ -129,6 +129,8 @@ sidebar: url: docs/reference/changed-features/eta-expansion.html - title: Compiler Plugins url: docs/reference/changed-features/compiler-plugins.html + - title: Lazy Vals initialization + url: docs/reference/changed-features/lazy-vals-init.html - title: Dropped Features subsection: - title: DelayedInit diff --git a/library/src/scala/annotation/threadUnsafe.scala b/library/src/scala/annotation/threadUnsafe.scala new file mode 100644 index 000000000000..36fecec941c2 --- /dev/null +++ b/library/src/scala/annotation/threadUnsafe.scala @@ -0,0 +1,7 @@ +package scala.annotation + +/** This annotation can only be used on a field which defines a lazy val. + * When this annotation is used, the initialization of the lazy val will use a + * faster mechanism which is not thread-safe. + */ +final class threadUnsafe extends StaticAnnotation diff --git a/tests/pos/lazyvals.scala b/tests/pos/lazyvals.scala index 93a82cd0ce42..7ec7b53d6dec 100644 --- a/tests/pos/lazyvals.scala +++ b/tests/pos/lazyvals.scala @@ -10,7 +10,7 @@ trait Iterator { val leading = new Leading class Trailing { - @volatile lazy val it = leading.finish() + lazy val it = leading.finish() } val trailing = new Trailing (leading, trailing) diff --git a/tests/pos/scala2traits/dotty-subclass.scala b/tests/pos/scala2traits/dotty-subclass.scala index 62720b993a6c..dd40b1144f45 100644 --- a/tests/pos/scala2traits/dotty-subclass.scala +++ b/tests/pos/scala2traits/dotty-subclass.scala @@ -3,7 +3,7 @@ class Sub extends T trait DT { - @volatile lazy val dx = 2 + lazy val dx = 2 } diff --git a/tests/run/Lazies1.scala b/tests/run/Lazies1.scala index 34fecaf80da3..7ccf1a82b50e 100644 --- a/tests/run/Lazies1.scala +++ b/tests/run/Lazies1.scala @@ -1,4 +1,4 @@ -object T{ @volatile lazy val s = null} +object T{ lazy val s = null} object Test{ def main(args: Array[String]): Unit = { T.s diff --git a/tests/run/Lazies2.scala b/tests/run/Lazies2.scala index 6b9aa8a39343..b348e678a847 100644 --- a/tests/run/Lazies2.scala +++ b/tests/run/Lazies2.scala @@ -1,5 +1,5 @@ -class T{ @volatile lazy val s = null} -object T{ @volatile lazy val s = null} +class T{ lazy val s = null} +object T{ lazy val s = null} object Test{ def main(args: Array[String]): Unit = { T.s diff --git a/tests/run/i1692.scala b/tests/run/i1692.scala index a200f5d66a3e..b413964f0751 100644 --- a/tests/run/i1692.scala +++ b/tests/run/i1692.scala @@ -8,7 +8,7 @@ class LazyNullable(a: => Int) { lazy val l1 = b // null out b private[this] val c = "C" - @volatile lazy val l2 = c // null out c + lazy val l2 = c // null out c private[this] val d = "D" lazy val l3 = d + d // null out d (Scalac require single use?) diff --git a/tests/run/i1692b.scala b/tests/run/i1692b.scala new file mode 100644 index 000000000000..a46a58f5868f --- /dev/null +++ b/tests/run/i1692b.scala @@ -0,0 +1,157 @@ +import scala.annotation.threadUnsafe + +class VCInt(val x: Int) extends AnyVal +class VCString(val x: String) extends AnyVal + +class LazyNullable(a: => Int) { + @threadUnsafe lazy val l0 = a // null out a + + private[this] val b = "B" + @threadUnsafe lazy val l1 = b // null out b + + private[this] val c = "C" + @threadUnsafe lazy val l2 = c // null out c + + private[this] val d = "D" + @threadUnsafe lazy val l3 = d + d // null out d (Scalac require single use?) + + private [this] val e = "E" + @threadUnsafe lazy val l4 = try e finally () // null out e + + private[this] val i = "I" + // null out i even though the try ends up lifted, because the LazyVals phase runs before the LiftTry phase + @threadUnsafe lazy val l5 = try i catch { case e: Exception => () } +} + +object LazyNullable2 { + private[this] val a = "A" + @threadUnsafe lazy val l0 = a // null out a +} + +class LazyNotNullable { + private[this] val a = 'A'.toInt // not nullable type + @threadUnsafe lazy val l0 = a + + private[this] val b = new VCInt('B'.toInt) // not nullable type + @threadUnsafe lazy val l1 = b + + private[this] val c = new VCString("C") // should be nullable but is not?? + @threadUnsafe lazy val l2 = c + + @threadUnsafe private[this] lazy val d = "D" // not nullable because lazy + @threadUnsafe lazy val l3 = d + + private val e = "E" // not nullable because not private[this] + @threadUnsafe lazy val l4 = e + + private[this] val f = "F" // not nullable because used in mutiple @threadUnsafe lazy vals + @threadUnsafe lazy val l5 = f + @threadUnsafe lazy val l6 = f + + private[this] val g = "G" // not nullable because used outside a @threadUnsafe lazy val initializer + def foo = g + @threadUnsafe lazy val l7 = g + + private[this] val h = "H" // not nullable because field and @threadUnsafe lazy val not defined in the same class + class Inner { + @threadUnsafe lazy val l8 = h + } + +} + +trait LazyTrait { + private val a = "A" + @threadUnsafe lazy val l0 = a +} + +class Foo(val x: String) + +class LazyNotNullable2(x: String) extends Foo(x) { + @threadUnsafe lazy val y = x // not nullable. Here x is super.x +} + + +object Test { + def main(args: Array[String]): Unit = { + nullableTests() + notNullableTests() + } + + def nullableTests() = { + val lz = new LazyNullable('A'.toInt) + + def assertNull(fieldName: String) = { + val value = readField(fieldName, lz) + assert(value == null, s"$fieldName was $value, null expected") + } + + assert(lz.l0 == 'A'.toInt) + assertNull("a") + + assert(lz.l1 == "B") + assertNull("b") + + assert(lz.l2 == "C") + assertNull("c") + + assert(lz.l3 == "DD") + assertNull("d") + + assert(lz.l4 == "E") + assertNull("e") + + assert(lz.l5 == "I") + assertNull("i") + + assert(LazyNullable2.l0 == "A") + assert(readField("a", LazyNullable2) == null) + } + + def notNullableTests() = { + val lz = new LazyNotNullable + + def assertNotNull(fieldName: String) = { + val value = readField(fieldName, lz) + assert(value != null, s"$fieldName was null") + } + + assert(lz.l0 == 'A'.toInt) + assertNotNull("a") + + assert(lz.l1 == new VCInt('B'.toInt)) + assertNotNull("b") + + assert(lz.l2 == new VCString("C")) + assertNotNull("c") + + assert(lz.l3 == "D") + + assert(lz.l4 == "E") + assertNotNull("e") + + assert(lz.l5 == "F") + assert(lz.l6 == "F") + assertNotNull("f") + + assert(lz.l7 == "G") + assertNotNull("g") + + val inner = new lz.Inner + assert(inner.l8 == "H") + assertNotNull("LazyNotNullable$$h") // fragile: test will break if compiler generated names change + + val fromTrait = new LazyTrait {} + assert(fromTrait.l0 == "A") + assert(readField("LazyTrait$$a", fromTrait) != null) // fragile: test will break if compiler generated names change + + val lz2 = new LazyNotNullable2("Hello") + assert(lz2.y == "Hello") + assert(lz2.x == "Hello") + } + + def readField(fieldName: String, target: Any): Any = { + val field = target.getClass.getDeclaredField(fieldName) + field.setAccessible(true) + field.get(target) + } +} diff --git a/tests/run/i1856.scala b/tests/run/i1856.scala index 9dafc1c1b693..536ccf4c0203 100644 --- a/tests/run/i1856.scala +++ b/tests/run/i1856.scala @@ -1,6 +1,8 @@ +import scala.annotation.threadUnsafe + object Test { var count = 0 - lazy val lzy: Int = { + @threadUnsafe lazy val lzy: Int = { if (count < 10) { println(s"Iteration $count") count += 1 @@ -10,7 +12,7 @@ object Test { def lzy2 = { var countLocal = 0 - lazy val lzyLocal: Int = { + @threadUnsafe lazy val lzyLocal: Int = { if (countLocal < 10) { println(s"Iteration $countLocal") countLocal += 1 diff --git a/tests/run/i2275.scala b/tests/run/i2275.scala index 9ba28a072462..1cbabaab8501 100644 --- a/tests/run/i2275.scala +++ b/tests/run/i2275.scala @@ -1,7 +1,7 @@ object Test { var count = 0 - @volatile lazy val x: Int = { + lazy val x: Int = { if (count < 100) { count += 1 ??? diff --git a/tests/run/i4451.scala b/tests/run/i4451.scala index 6d713bf4b38c..46e9b3ce9c95 100644 --- a/tests/run/i4451.scala +++ b/tests/run/i4451.scala @@ -1,8 +1,10 @@ +import scala.annotation.threadUnsafe + class InitError extends Exception -class Lazy(x: Int) { +class LazyThreadUnsafe(x: Int) { private[this] var init = false - lazy val value = { + @threadUnsafe lazy val value = { if (!init) { init = true throw new InitError @@ -11,9 +13,9 @@ class Lazy(x: Int) { } } -class LazyVolatile(x: Int) { +class Lazy(x: Int) { private[this] var init = false - @volatile lazy val value = { + lazy val value = { if (!init) { init = true throw new InitError @@ -46,8 +48,8 @@ object Test { def main(args: Array[String]) = { val v = 42 - val l0 = new Lazy(v) - val l1 = new LazyVolatile(v) + val l0 = new LazyThreadUnsafe(v) + val l1 = new Lazy(v) assert(tryTwice(l0.value) == v) assert(tryTwice(l1.value) == v) assert(lazyInMethod(v) == v) diff --git a/tests/run/statics.scala b/tests/run/statics.scala index 5d180074d4ad..d4d635400d93 100644 --- a/tests/run/statics.scala +++ b/tests/run/statics.scala @@ -35,6 +35,6 @@ object Test { } class WithLazies{ - @volatile lazy val s = 1 + lazy val s = 1 // 98: getstatic #30 // Field WithLazies$.OFFSET$0:J } From 324683d060924bf6e403a7c05ff54e678fe8decf Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Wed, 29 May 2019 14:14:13 +0200 Subject: [PATCH 3/4] Definitions: use @threadUnsafe lazy vals There does not seem to be a noticeable performance difference compared to thread-safe lazy vals but there is a noticeable impact on bytecode size (Definitions.class goes from 210 to 168K). --- .../tools/backend/sjs/JSDefinitions.scala | 161 ++--- .../dotty/tools/dotc/core/Definitions.scala | 589 +++++++++--------- 2 files changed, 376 insertions(+), 374 deletions(-) diff --git a/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala b/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala index 8dc16ed85231..5f165b82cbf4 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala @@ -2,6 +2,7 @@ package dotty.tools.backend.sjs import dotty.tools.dotc.core._ +import scala.annotation.threadUnsafe import Types._ import Contexts._ import Symbols._ @@ -19,157 +20,157 @@ object JSDefinitions { final class JSDefinitions()(implicit ctx: Context) { - lazy val InlineAnnotType: TypeRef = ctx.requiredClassRef("scala.inline") + @threadUnsafe lazy val InlineAnnotType: TypeRef = ctx.requiredClassRef("scala.inline") def InlineAnnot(implicit ctx: Context) = InlineAnnotType.symbol.asClass - lazy val NoinlineAnnotType: TypeRef = ctx.requiredClassRef("scala.noinline") + @threadUnsafe lazy val NoinlineAnnotType: TypeRef = ctx.requiredClassRef("scala.noinline") def NoinlineAnnot(implicit ctx: Context) = NoinlineAnnotType.symbol.asClass - lazy val JavaLangVoidType: TypeRef = ctx.requiredClassRef("java.lang.Void") + @threadUnsafe lazy val JavaLangVoidType: TypeRef = ctx.requiredClassRef("java.lang.Void") def JavaLangVoidClass(implicit ctx: Context) = JavaLangVoidType.symbol.asClass - lazy val ScalaJSJSPackageVal = ctx.requiredPackage("scala.scalajs.js") - lazy val ScalaJSJSPackageClass = ScalaJSJSPackageVal.moduleClass.asClass - lazy val JSPackage_typeOfR = ScalaJSJSPackageClass.requiredMethodRef("typeOf") + @threadUnsafe lazy val ScalaJSJSPackageVal = ctx.requiredPackage("scala.scalajs.js") + @threadUnsafe lazy val ScalaJSJSPackageClass = ScalaJSJSPackageVal.moduleClass.asClass + @threadUnsafe lazy val JSPackage_typeOfR = ScalaJSJSPackageClass.requiredMethodRef("typeOf") def JSPackage_typeOf(implicit ctx: Context) = JSPackage_typeOfR.symbol - lazy val JSPackage_constructorOfR = ScalaJSJSPackageClass.requiredMethodRef("constructorOf") + @threadUnsafe lazy val JSPackage_constructorOfR = ScalaJSJSPackageClass.requiredMethodRef("constructorOf") def JSPackage_constructorOf(implicit ctx: Context) = JSPackage_constructorOfR.symbol - lazy val JSPackage_nativeR = ScalaJSJSPackageClass.requiredMethodRef("native") + @threadUnsafe lazy val JSPackage_nativeR = ScalaJSJSPackageClass.requiredMethodRef("native") def JSPackage_native(implicit ctx: Context) = JSPackage_nativeR.symbol - lazy val JSNativeAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.native") + @threadUnsafe lazy val JSNativeAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.native") def JSNativeAnnot(implicit ctx: Context) = JSNativeAnnotType.symbol.asClass - lazy val JSAnyType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.Any") + @threadUnsafe lazy val JSAnyType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.Any") def JSAnyClass(implicit ctx: Context) = JSAnyType.symbol.asClass - lazy val JSObjectType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.Object") + @threadUnsafe lazy val JSObjectType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.Object") def JSObjectClass(implicit ctx: Context) = JSObjectType.symbol.asClass - lazy val JSBaseThisFunctionType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.ThisFunction") + @threadUnsafe lazy val JSBaseThisFunctionType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.ThisFunction") def JSBaseThisFunctionClass(implicit ctx: Context) = JSBaseThisFunctionType.symbol.asClass - lazy val JSArrayType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.Array") + @threadUnsafe lazy val JSArrayType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.Array") def JSArrayClass(implicit ctx: Context) = JSArrayType.symbol.asClass - lazy val JSFunctionType = (0 to 22).map(n => ctx.requiredClassRef("scala.scalajs.js.Function" + n)).toArray + @threadUnsafe lazy val JSFunctionType = (0 to 22).map(n => ctx.requiredClassRef("scala.scalajs.js.Function" + n)).toArray def JSFunctionClass(n: Int)(implicit ctx: Context) = JSFunctionType(n).symbol.asClass - lazy val JSThisFunctionType = (0 to 21).map(n => ctx.requiredClassRef("scala.scalajs.js.ThisFunction" + n)).toArray + @threadUnsafe lazy val JSThisFunctionType = (0 to 21).map(n => ctx.requiredClassRef("scala.scalajs.js.ThisFunction" + n)).toArray def JSThisFunctionClass(n: Int)(implicit ctx: Context) = JSThisFunctionType(n).symbol.asClass - lazy val RuntimeExceptionType: TypeRef = ctx.requiredClassRef("java.lang.RuntimeException") + @threadUnsafe lazy val RuntimeExceptionType: TypeRef = ctx.requiredClassRef("java.lang.RuntimeException") def RuntimeExceptionClass(implicit ctx: Context) = RuntimeExceptionType.symbol.asClass - lazy val JavaScriptExceptionType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.JavaScriptException") + @threadUnsafe lazy val JavaScriptExceptionType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.JavaScriptException") def JavaScriptExceptionClass(implicit ctx: Context) = JavaScriptExceptionType.symbol.asClass - lazy val JSGlobalScopeAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSGlobalScope") + @threadUnsafe lazy val JSGlobalScopeAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSGlobalScope") def JSGlobalScopeAnnot(implicit ctx: Context) = JSGlobalScopeAnnotType.symbol.asClass - lazy val JSNameAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSName") + @threadUnsafe lazy val JSNameAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSName") def JSNameAnnot(implicit ctx: Context) = JSNameAnnotType.symbol.asClass - lazy val JSFullNameAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSFullName") + @threadUnsafe lazy val JSFullNameAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSFullName") def JSFullNameAnnot(implicit ctx: Context) = JSFullNameAnnotType.symbol.asClass - lazy val JSBracketAccessAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSBracketAccess") + @threadUnsafe lazy val JSBracketAccessAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSBracketAccess") def JSBracketAccessAnnot(implicit ctx: Context) = JSBracketAccessAnnotType.symbol.asClass - lazy val JSBracketCallAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSBracketCall") + @threadUnsafe lazy val JSBracketCallAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSBracketCall") def JSBracketCallAnnot(implicit ctx: Context) = JSBracketCallAnnotType.symbol.asClass - lazy val JSExportAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSExport") + @threadUnsafe lazy val JSExportAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSExport") def JSExportAnnot(implicit ctx: Context) = JSExportAnnotType.symbol.asClass - lazy val JSExportDescendentObjectsAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSExportDescendentObjects") + @threadUnsafe lazy val JSExportDescendentObjectsAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSExportDescendentObjects") def JSExportDescendentObjectsAnnot(implicit ctx: Context) = JSExportDescendentObjectsAnnotType.symbol.asClass - lazy val JSExportDescendentClassesAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSExportDescendentClasses") + @threadUnsafe lazy val JSExportDescendentClassesAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSExportDescendentClasses") def JSExportDescendentClassesAnnot(implicit ctx: Context) = JSExportDescendentClassesAnnotType.symbol.asClass - lazy val JSExportAllAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSExportAll") + @threadUnsafe lazy val JSExportAllAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSExportAll") def JSExportAllAnnot(implicit ctx: Context) = JSExportAllAnnotType.symbol.asClass - lazy val JSExportNamedAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSExportNamed") + @threadUnsafe lazy val JSExportNamedAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.JSExportNamed") def JSExportNamedAnnot(implicit ctx: Context) = JSExportNamedAnnotType.symbol.asClass - lazy val RawJSTypeAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.RawJSType") + @threadUnsafe lazy val RawJSTypeAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.RawJSType") def RawJSTypeAnnot(implicit ctx: Context) = RawJSTypeAnnotType.symbol.asClass - lazy val ExposedJSMemberAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.ExposedJSMember") + @threadUnsafe lazy val ExposedJSMemberAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.annotation.ExposedJSMember") def ExposedJSMemberAnnot(implicit ctx: Context) = ExposedJSMemberAnnotType.symbol.asClass - lazy val JSAnyModuleRef = ctx.requiredModuleRef("scala.scalajs.js.Any") + @threadUnsafe lazy val JSAnyModuleRef = ctx.requiredModuleRef("scala.scalajs.js.Any") def JSAnyModule(implicit ctx: Context) = JSAnyModuleRef.symbol - lazy val JSAny_fromFunctionR = (0 to 22).map(n => JSAnyModule.requiredMethodRef("fromFunction" + n)).toArray + @threadUnsafe lazy val JSAny_fromFunctionR = (0 to 22).map(n => JSAnyModule.requiredMethodRef("fromFunction" + n)).toArray def JSAny_fromFunction(n: Int)(implicit ctx: Context) = JSAny_fromFunctionR(n).symbol - lazy val JSDynamicModuleRef = ctx.requiredModuleRef("scala.scalajs.js.Dynamic") + @threadUnsafe lazy val JSDynamicModuleRef = ctx.requiredModuleRef("scala.scalajs.js.Dynamic") def JSDynamicModule(implicit ctx: Context) = JSDynamicModuleRef.symbol - lazy val JSDynamic_globalR = JSDynamicModule.requiredMethodRef("global") + @threadUnsafe lazy val JSDynamic_globalR = JSDynamicModule.requiredMethodRef("global") def JSDynamic_global(implicit ctx: Context) = JSDynamic_globalR.symbol - lazy val JSDynamic_newInstanceR = JSDynamicModule.requiredMethodRef("newInstance") + @threadUnsafe lazy val JSDynamic_newInstanceR = JSDynamicModule.requiredMethodRef("newInstance") def JSDynamic_newInstance(implicit ctx: Context) = JSDynamic_newInstanceR.symbol - lazy val JSDynamicLiteralModuleRef = JSDynamicModule.moduleClass.requiredValueRef("literal") + @threadUnsafe lazy val JSDynamicLiteralModuleRef = JSDynamicModule.moduleClass.requiredValueRef("literal") def JSDynamicLiteralModule(implicit ctx: Context) = JSDynamicLiteralModuleRef.symbol - lazy val JSDynamicLiteral_applyDynamicNamedR = JSDynamicLiteralModule.requiredMethodRef("applyDynamicNamed") + @threadUnsafe lazy val JSDynamicLiteral_applyDynamicNamedR = JSDynamicLiteralModule.requiredMethodRef("applyDynamicNamed") def JSDynamicLiteral_applyDynamicNamed(implicit ctx: Context) = JSDynamicLiteral_applyDynamicNamedR.symbol - lazy val JSDynamicLiteral_applyDynamicR = JSDynamicLiteralModule.requiredMethodRef("applyDynamic") + @threadUnsafe lazy val JSDynamicLiteral_applyDynamicR = JSDynamicLiteralModule.requiredMethodRef("applyDynamic") def JSDynamicLiteral_applyDynamic(implicit ctx: Context) = JSDynamicLiteral_applyDynamicR.symbol - lazy val JSObjectModuleRef = ctx.requiredModuleRef("scala.scalajs.js.Object") + @threadUnsafe lazy val JSObjectModuleRef = ctx.requiredModuleRef("scala.scalajs.js.Object") def JSObjectModule(implicit ctx: Context) = JSObjectModuleRef.symbol - lazy val JSArrayModuleRef = ctx.requiredModuleRef("scala.scalajs.js.Array") + @threadUnsafe lazy val JSArrayModuleRef = ctx.requiredModuleRef("scala.scalajs.js.Array") def JSArrayModule(implicit ctx: Context) = JSArrayModuleRef.symbol - lazy val JSArray_applyR = JSArrayModule.requiredMethodRef(nme.apply) + @threadUnsafe lazy val JSArray_applyR = JSArrayModule.requiredMethodRef(nme.apply) def JSArray_apply(implicit ctx: Context) = JSArray_applyR.symbol - lazy val JSThisFunctionModuleRef = ctx.requiredModuleRef("scala.scalajs.js.ThisFunction") + @threadUnsafe lazy val JSThisFunctionModuleRef = ctx.requiredModuleRef("scala.scalajs.js.ThisFunction") def JSThisFunctionModule(implicit ctx: Context) = JSThisFunctionModuleRef.symbol - lazy val JSThisFunction_fromFunctionR = (1 to 22).map(n => JSThisFunctionModule.requiredMethodRef("fromFunction" + n)).toArray + @threadUnsafe lazy val JSThisFunction_fromFunctionR = (1 to 22).map(n => JSThisFunctionModule.requiredMethodRef("fromFunction" + n)).toArray def JSThisFunction_fromFunction(n: Int)(implicit ctx: Context) = JSThisFunction_fromFunctionR(n - 1).symbol - lazy val JSConstructorTagModuleRef = ctx.requiredModuleRef("scala.scalajs.js.ConstructorTag") + @threadUnsafe lazy val JSConstructorTagModuleRef = ctx.requiredModuleRef("scala.scalajs.js.ConstructorTag") def JSConstructorTagModule(implicit ctx: Context) = JSConstructorTagModuleRef.symbol - lazy val JSConstructorTag_materializeR = JSConstructorTagModule.requiredMethodRef("materialize") + @threadUnsafe lazy val JSConstructorTag_materializeR = JSConstructorTagModule.requiredMethodRef("materialize") def JSConstructorTag_materialize(implicit ctx: Context) = JSConstructorTag_materializeR.symbol - lazy val RuntimePackageVal = ctx.requiredPackage("scala.scalajs.runtime") - lazy val RuntimePackageClass = RuntimePackageVal.moduleClass.asClass - lazy val RuntimePackage_wrapJavaScriptExceptionR = RuntimePackageClass.requiredMethodRef("wrapJavaScriptException") + @threadUnsafe lazy val RuntimePackageVal = ctx.requiredPackage("scala.scalajs.runtime") + @threadUnsafe lazy val RuntimePackageClass = RuntimePackageVal.moduleClass.asClass + @threadUnsafe lazy val RuntimePackage_wrapJavaScriptExceptionR = RuntimePackageClass.requiredMethodRef("wrapJavaScriptException") def Runtime_wrapJavaScriptException(implicit ctx: Context) = RuntimePackage_wrapJavaScriptExceptionR.symbol - lazy val Runtime_unwrapJavaScriptExceptionR = RuntimePackageClass.requiredMethodRef("unwrapJavaScriptException") + @threadUnsafe lazy val Runtime_unwrapJavaScriptExceptionR = RuntimePackageClass.requiredMethodRef("unwrapJavaScriptException") def Runtime_unwrapJavaScriptException(implicit ctx: Context) = Runtime_unwrapJavaScriptExceptionR.symbol - lazy val Runtime_toScalaVarArgsR = RuntimePackageClass.requiredMethodRef("toScalaVarArgs") + @threadUnsafe lazy val Runtime_toScalaVarArgsR = RuntimePackageClass.requiredMethodRef("toScalaVarArgs") def Runtime_toScalaVarArgs(implicit ctx: Context) = Runtime_toScalaVarArgsR.symbol - lazy val Runtime_toJSVarArgsR = RuntimePackageClass.requiredMethodRef("toJSVarArgs") + @threadUnsafe lazy val Runtime_toJSVarArgsR = RuntimePackageClass.requiredMethodRef("toJSVarArgs") def Runtime_toJSVarArgs(implicit ctx: Context) = Runtime_toJSVarArgsR.symbol - lazy val Runtime_constructorOfR = RuntimePackageClass.requiredMethodRef("constructorOf") + @threadUnsafe lazy val Runtime_constructorOfR = RuntimePackageClass.requiredMethodRef("constructorOf") def Runtime_constructorOf(implicit ctx: Context) = Runtime_constructorOfR.symbol - lazy val Runtime_newConstructorTagR = RuntimePackageClass.requiredMethodRef("newConstructorTag") + @threadUnsafe lazy val Runtime_newConstructorTagR = RuntimePackageClass.requiredMethodRef("newConstructorTag") def Runtime_newConstructorTag(implicit ctx: Context) = Runtime_newConstructorTagR.symbol - lazy val Runtime_linkingInfoR = RuntimePackageClass.requiredMethodRef("linkingInfo") + @threadUnsafe lazy val Runtime_linkingInfoR = RuntimePackageClass.requiredMethodRef("linkingInfo") def Runtime_linkingInfo(implicit ctx: Context) = Runtime_linkingInfoR.symbol - lazy val SpecialPackageVal = ctx.requiredPackage("scala.scalajs.js.special") - lazy val SpecialPackageClass = SpecialPackageVal.moduleClass.asClass - lazy val Special_debuggerR = SpecialPackageClass.requiredMethodRef("debugger") + @threadUnsafe lazy val SpecialPackageVal = ctx.requiredPackage("scala.scalajs.js.special") + @threadUnsafe lazy val SpecialPackageClass = SpecialPackageVal.moduleClass.asClass + @threadUnsafe lazy val Special_debuggerR = SpecialPackageClass.requiredMethodRef("debugger") def Special_debugger(implicit ctx: Context) = Special_debuggerR.symbol - lazy val Special_deleteR = SpecialPackageClass.requiredMethodRef("delete") + @threadUnsafe lazy val Special_deleteR = SpecialPackageClass.requiredMethodRef("delete") def Special_delete(implicit ctx: Context) = Special_deleteR.symbol - lazy val Special_forinR = SpecialPackageClass.requiredMethodRef("forin") + @threadUnsafe lazy val Special_forinR = SpecialPackageClass.requiredMethodRef("forin") def Special_forin(implicit ctx: Context) = Special_forinR.symbol - lazy val Special_inR = SpecialPackageClass.requiredMethodRef("in") + @threadUnsafe lazy val Special_inR = SpecialPackageClass.requiredMethodRef("in") def Special_in(implicit ctx: Context) = Special_inR.symbol - lazy val Special_instanceofR = SpecialPackageClass.requiredMethodRef("instanceof") + @threadUnsafe lazy val Special_instanceofR = SpecialPackageClass.requiredMethodRef("instanceof") def Special_instanceof(implicit ctx: Context) = Special_instanceofR.symbol - lazy val WrappedArrayType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.WrappedArray") + @threadUnsafe lazy val WrappedArrayType: TypeRef = ctx.requiredClassRef("scala.scalajs.js.WrappedArray") def WrappedArrayClass(implicit ctx: Context) = WrappedArrayType.symbol.asClass - lazy val ScalaRunTime_isArrayR = defn.ScalaRuntimeModule.requiredMethodRef("isArray", List(???, ???)) + @threadUnsafe lazy val ScalaRunTime_isArrayR = defn.ScalaRuntimeModule.requiredMethodRef("isArray", List(???, ???)) def ScalaRunTime_isArray(implicit ctx: Context): Symbol = ScalaRunTime_isArrayR.symbol - lazy val BoxesRunTime_boxToCharacterR = defn.BoxesRunTimeModule.requiredMethodRef("boxToCharacter") + @threadUnsafe lazy val BoxesRunTime_boxToCharacterR = defn.BoxesRunTimeModule.requiredMethodRef("boxToCharacter") def BoxesRunTime_boxToCharacter(implicit ctx: Context): Symbol = BoxesRunTime_boxToCharacterR.symbol - lazy val BoxesRunTime_unboxToCharR = defn.BoxesRunTimeModule.requiredMethodRef("unboxToChar") + @threadUnsafe lazy val BoxesRunTime_unboxToCharR = defn.BoxesRunTimeModule.requiredMethodRef("unboxToChar") def BoxesRunTime_unboxToChar(implicit ctx: Context): Symbol = BoxesRunTime_unboxToCharR.symbol - lazy val EnableReflectiveInstantiationAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.reflect.annotation.EnableReflectiveInstantiation") + @threadUnsafe lazy val EnableReflectiveInstantiationAnnotType: TypeRef = ctx.requiredClassRef("scala.scalajs.reflect.annotation.EnableReflectiveInstantiation") def EnableReflectiveInstantiationAnnot(implicit ctx: Context) = EnableReflectiveInstantiationAnnotType.symbol.asClass - lazy val ReflectModuleRef = ctx.requiredModuleRef("scala.scalajs.reflect.Reflect") + @threadUnsafe lazy val ReflectModuleRef = ctx.requiredModuleRef("scala.scalajs.reflect.Reflect") def ReflectModule(implicit ctx: Context) = ReflectModuleRef.symbol - lazy val Reflect_registerLoadableModuleClassR = ReflectModule.requiredMethodRef("registerLoadableModuleClass") + @threadUnsafe lazy val Reflect_registerLoadableModuleClassR = ReflectModule.requiredMethodRef("registerLoadableModuleClass") def Reflect_registerLoadableModuleClass(implicit ctx: Context) = Reflect_registerLoadableModuleClassR.symbol - lazy val Reflect_registerInstantiatableClassR = ReflectModule.requiredMethodRef("registerInstantiatableClass") + @threadUnsafe lazy val Reflect_registerInstantiatableClassR = ReflectModule.requiredMethodRef("registerInstantiatableClass") def Reflect_registerInstantiatableClass(implicit ctx: Context) = Reflect_registerInstantiatableClassR.symbol /** If `cls` is a class in the scala package, its name, otherwise EmptyTypeName */ @@ -195,37 +196,37 @@ final class JSDefinitions()(implicit ctx: Context) { /** Definitions related to the treatment of JUnit boostrappers. */ object junit { - lazy val TestAnnotType: TypeRef = ctx.requiredClassRef("org.junit.Test") + @threadUnsafe lazy val TestAnnotType: TypeRef = ctx.requiredClassRef("org.junit.Test") def TestAnnotClass(implicit ctx: Context): ClassSymbol = TestAnnotType.symbol.asClass - lazy val BeforeAnnotType: TypeRef = ctx.requiredClassRef("org.junit.Before") + @threadUnsafe lazy val BeforeAnnotType: TypeRef = ctx.requiredClassRef("org.junit.Before") def BeforeAnnotClass(implicit ctx: Context): ClassSymbol = BeforeAnnotType.symbol.asClass - lazy val AfterAnnotType: TypeRef = ctx.requiredClassRef("org.junit.After") + @threadUnsafe lazy val AfterAnnotType: TypeRef = ctx.requiredClassRef("org.junit.After") def AfterAnnotClass(implicit ctx: Context): ClassSymbol = AfterAnnotType.symbol.asClass - lazy val BeforeClassAnnotType: TypeRef = ctx.requiredClassRef("org.junit.BeforeClass") + @threadUnsafe lazy val BeforeClassAnnotType: TypeRef = ctx.requiredClassRef("org.junit.BeforeClass") def BeforeClassAnnotClass(implicit ctx: Context): ClassSymbol = BeforeClassAnnotType.symbol.asClass - lazy val AfterClassAnnotType: TypeRef = ctx.requiredClassRef("org.junit.AfterClass") + @threadUnsafe lazy val AfterClassAnnotType: TypeRef = ctx.requiredClassRef("org.junit.AfterClass") def AfterClassAnnotClass(implicit ctx: Context): ClassSymbol = AfterClassAnnotType.symbol.asClass - lazy val IgnoreAnnotType: TypeRef = ctx.requiredClassRef("org.junit.Ignore") + @threadUnsafe lazy val IgnoreAnnotType: TypeRef = ctx.requiredClassRef("org.junit.Ignore") def IgnoreAnnotClass(implicit ctx: Context): ClassSymbol = IgnoreAnnotType.symbol.asClass - lazy val BootstrapperType: TypeRef = ctx.requiredClassRef("org.scalajs.junit.Bootstrapper") + @threadUnsafe lazy val BootstrapperType: TypeRef = ctx.requiredClassRef("org.scalajs.junit.Bootstrapper") - lazy val TestMetadataType: TypeRef = ctx.requiredClassRef("org.scalajs.junit.TestMetadata") + @threadUnsafe lazy val TestMetadataType: TypeRef = ctx.requiredClassRef("org.scalajs.junit.TestMetadata") - lazy val NoSuchMethodExceptionType: TypeRef = ctx.requiredClassRef("java.lang.NoSuchMethodException") + @threadUnsafe lazy val NoSuchMethodExceptionType: TypeRef = ctx.requiredClassRef("java.lang.NoSuchMethodException") - lazy val FutureType: TypeRef = ctx.requiredClassRef("scala.concurrent.Future") + @threadUnsafe lazy val FutureType: TypeRef = ctx.requiredClassRef("scala.concurrent.Future") def FutureClass(implicit ctx: Context): ClassSymbol = FutureType.symbol.asClass - private lazy val FutureModule_successfulR = ctx.requiredModule("scala.concurrent.Future").requiredMethodRef("successful") + @threadUnsafe private lazy val FutureModule_successfulR = ctx.requiredModule("scala.concurrent.Future").requiredMethodRef("successful") def FutureModule_successful(implicit ctx: Context): Symbol = FutureModule_successfulR.symbol - private lazy val SuccessModule_applyR = ctx.requiredModule("scala.util.Success").requiredMethodRef(nme.apply) + @threadUnsafe private lazy val SuccessModule_applyR = ctx.requiredModule("scala.util.Success").requiredMethodRef(nme.apply) def SuccessModule_apply(implicit ctx: Context): Symbol = SuccessModule_applyR.symbol } diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 060362e6d91c..9bfa280fcc20 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -2,6 +2,7 @@ package dotty.tools package dotc package core +import scala.annotation.threadUnsafe import Types._, Contexts._, Symbols._, SymDenotations._, StdNames._, Names._ import Flags._, Scopes._, Decorators._, NameOps._, Periods._ import unpickleScala2.Scala2Unpickler.ensureConstructor @@ -192,22 +193,22 @@ class Definitions { cls } - lazy val RootClass: ClassSymbol = ctx.newPackageSymbol( + @threadUnsafe lazy val RootClass: ClassSymbol = ctx.newPackageSymbol( NoSymbol, nme.ROOT, (root, rootcls) => ctx.base.rootLoader(root)).moduleClass.asClass - lazy val RootPackage: TermSymbol = ctx.newSymbol( + @threadUnsafe lazy val RootPackage: TermSymbol = ctx.newSymbol( NoSymbol, nme.ROOTPKG, PackageCreationFlags, TypeRef(NoPrefix, RootClass)) - lazy val EmptyPackageVal: TermSymbol = ctx.newPackageSymbol( + @threadUnsafe lazy val EmptyPackageVal: TermSymbol = ctx.newPackageSymbol( RootClass, nme.EMPTY_PACKAGE, (emptypkg, emptycls) => ctx.base.rootLoader(emptypkg)).entered - lazy val EmptyPackageClass: ClassSymbol = EmptyPackageVal.moduleClass.asClass + @threadUnsafe lazy val EmptyPackageClass: ClassSymbol = EmptyPackageVal.moduleClass.asClass /** A package in which we can place all methods that are interpreted specially by the compiler */ - lazy val OpsPackageVal: TermSymbol = ctx.newCompletePackageSymbol(RootClass, nme.OPS_PACKAGE).entered - lazy val OpsPackageClass: ClassSymbol = OpsPackageVal.moduleClass.asClass + @threadUnsafe lazy val OpsPackageVal: TermSymbol = ctx.newCompletePackageSymbol(RootClass, nme.OPS_PACKAGE).entered + @threadUnsafe lazy val OpsPackageClass: ClassSymbol = OpsPackageVal.moduleClass.asClass - lazy val ScalaPackageVal: TermSymbol = ctx.requiredPackage(nme.scala_) - lazy val ScalaMathPackageVal: TermSymbol = ctx.requiredPackage("scala.math") - lazy val ScalaPackageClass: ClassSymbol = { + @threadUnsafe lazy val ScalaPackageVal: TermSymbol = ctx.requiredPackage(nme.scala_) + @threadUnsafe lazy val ScalaMathPackageVal: TermSymbol = ctx.requiredPackage("scala.math") + @threadUnsafe lazy val ScalaPackageClass: ClassSymbol = { val cls = ScalaPackageVal.moduleClass.asClass cls.info.decls.openForMutations.useSynthesizer( name => ctx => @@ -215,23 +216,23 @@ class Definitions { else NoSymbol) cls } - lazy val ScalaPackageObjectRef: TermRef = ctx.requiredModuleRef("scala.package") - lazy val JavaPackageVal: TermSymbol = ctx.requiredPackage(nme.java) - lazy val JavaLangPackageVal: TermSymbol = ctx.requiredPackage(jnme.JavaLang) + @threadUnsafe lazy val ScalaPackageObjectRef: TermRef = ctx.requiredModuleRef("scala.package") + @threadUnsafe lazy val JavaPackageVal: TermSymbol = ctx.requiredPackage(nme.java) + @threadUnsafe lazy val JavaLangPackageVal: TermSymbol = ctx.requiredPackage(jnme.JavaLang) // fundamental modules - lazy val SysPackage: TermSymbol = ctx.requiredModule("scala.sys.package") - lazy val Sys_errorR: TermRef = SysPackage.moduleClass.requiredMethodRef(nme.error) + @threadUnsafe lazy val SysPackage: TermSymbol = ctx.requiredModule("scala.sys.package") + @threadUnsafe lazy val Sys_errorR: TermRef = SysPackage.moduleClass.requiredMethodRef(nme.error) def Sys_error(implicit ctx: Context): Symbol = Sys_errorR.symbol - lazy val ScalaXmlPackageClass: Symbol = ctx.getPackageClassIfDefined("scala.xml") + @threadUnsafe lazy val ScalaXmlPackageClass: Symbol = ctx.getPackageClassIfDefined("scala.xml") - lazy val CompiletimePackageObjectRef: TermRef = ctx.requiredModuleRef("scala.compiletime.package") - lazy val CompiletimePackageObject: Symbol = CompiletimePackageObjectRef.symbol.moduleClass - lazy val Compiletime_errorR: TermRef = CompiletimePackageObjectRef.symbol.requiredMethodRef(nme.error) + @threadUnsafe lazy val CompiletimePackageObjectRef: TermRef = ctx.requiredModuleRef("scala.compiletime.package") + @threadUnsafe lazy val CompiletimePackageObject: Symbol = CompiletimePackageObjectRef.symbol.moduleClass + @threadUnsafe lazy val Compiletime_errorR: TermRef = CompiletimePackageObjectRef.symbol.requiredMethodRef(nme.error) def Compiletime_error(implicit ctx: Context): Symbol = Compiletime_errorR.symbol - lazy val Compiletime_constValueR: TermRef = CompiletimePackageObjectRef.symbol.requiredMethodRef("constValue") + @threadUnsafe lazy val Compiletime_constValueR: TermRef = CompiletimePackageObjectRef.symbol.requiredMethodRef("constValue") def Compiletime_constValue(implicit ctx: Context): Symbol = Compiletime_constValueR.symbol - lazy val Compiletime_constValueOptR: TermRef = CompiletimePackageObjectRef.symbol.requiredMethodRef("constValueOpt") + @threadUnsafe lazy val Compiletime_constValueOptR: TermRef = CompiletimePackageObjectRef.symbol.requiredMethodRef("constValueOpt") def Compiletime_constValueOpt(implicit ctx: Context): Symbol = Compiletime_constValueOptR.symbol /** The `scalaShadowing` package is used to safely modify classes and @@ -241,7 +242,7 @@ class Definitions { * in `scalaShadowing` so they don't clash with the same-named `scala` * members at runtime. */ - lazy val ScalaShadowingPackageVal: TermSymbol = ctx.requiredPackage(nme.scalaShadowing) + @threadUnsafe lazy val ScalaShadowingPackageVal: TermSymbol = ctx.requiredPackage(nme.scalaShadowing) def ScalaShadowingPackageClass(implicit ctx: Context): ClassSymbol = ScalaShadowingPackageVal.moduleClass.asClass /** Note: We cannot have same named methods defined in Object and Any (and AnyVal, for that matter) @@ -266,28 +267,28 @@ class Definitions { * def getClass: java.lang.Class[T] = ??? * } */ - lazy val AnyClass: ClassSymbol = completeClass(enterCompleteClassSymbol(ScalaPackageClass, tpnme.Any, Abstract, Nil), ensureCtor = false) + @threadUnsafe lazy val AnyClass: ClassSymbol = completeClass(enterCompleteClassSymbol(ScalaPackageClass, tpnme.Any, Abstract, Nil), ensureCtor = false) def AnyType: TypeRef = AnyClass.typeRef - lazy val AnyValClass: ClassSymbol = completeClass(enterCompleteClassSymbol(ScalaPackageClass, tpnme.AnyVal, Abstract, List(AnyClass.typeRef))) + @threadUnsafe lazy val AnyValClass: ClassSymbol = completeClass(enterCompleteClassSymbol(ScalaPackageClass, tpnme.AnyVal, Abstract, List(AnyClass.typeRef))) def AnyValType: TypeRef = AnyValClass.typeRef - lazy val Any_== : TermSymbol = enterMethod(AnyClass, nme.EQ, methOfAny(BooleanType), Final) - lazy val Any_!= : TermSymbol = enterMethod(AnyClass, nme.NE, methOfAny(BooleanType), Final) - lazy val Any_equals: TermSymbol = enterMethod(AnyClass, nme.equals_, methOfAny(BooleanType)) - lazy val Any_hashCode: TermSymbol = enterMethod(AnyClass, nme.hashCode_, MethodType(Nil, IntType)) - lazy val Any_toString: TermSymbol = enterMethod(AnyClass, nme.toString_, MethodType(Nil, StringType)) - lazy val Any_## : TermSymbol = enterMethod(AnyClass, nme.HASHHASH, ExprType(IntType), Final) - lazy val Any_getClass: TermSymbol = enterMethod(AnyClass, nme.getClass_, MethodType(Nil, ClassClass.typeRef.appliedTo(TypeBounds.empty)), Final) - lazy val Any_isInstanceOf: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOf_, _ => BooleanType, Final) - lazy val Any_asInstanceOf: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOf_, _.paramRefs(0), Final) - lazy val Any_typeTest: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOfPM, _ => BooleanType, Final | Synthetic | Artifact) - lazy val Any_typeCast: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOfPM, _.paramRefs(0), Final | Synthetic | Artifact | StableRealizable) + @threadUnsafe lazy val Any_== : TermSymbol = enterMethod(AnyClass, nme.EQ, methOfAny(BooleanType), Final) + @threadUnsafe lazy val Any_!= : TermSymbol = enterMethod(AnyClass, nme.NE, methOfAny(BooleanType), Final) + @threadUnsafe lazy val Any_equals: TermSymbol = enterMethod(AnyClass, nme.equals_, methOfAny(BooleanType)) + @threadUnsafe lazy val Any_hashCode: TermSymbol = enterMethod(AnyClass, nme.hashCode_, MethodType(Nil, IntType)) + @threadUnsafe lazy val Any_toString: TermSymbol = enterMethod(AnyClass, nme.toString_, MethodType(Nil, StringType)) + @threadUnsafe lazy val Any_## : TermSymbol = enterMethod(AnyClass, nme.HASHHASH, ExprType(IntType), Final) + @threadUnsafe lazy val Any_getClass: TermSymbol = enterMethod(AnyClass, nme.getClass_, MethodType(Nil, ClassClass.typeRef.appliedTo(TypeBounds.empty)), Final) + @threadUnsafe lazy val Any_isInstanceOf: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOf_, _ => BooleanType, Final) + @threadUnsafe lazy val Any_asInstanceOf: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOf_, _.paramRefs(0), Final) + @threadUnsafe lazy val Any_typeTest: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOfPM, _ => BooleanType, Final | Synthetic | Artifact) + @threadUnsafe lazy val Any_typeCast: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOfPM, _.paramRefs(0), Final | Synthetic | Artifact | StableRealizable) // generated by pattern matcher, eliminated by erasure def AnyMethods: List[TermSymbol] = List(Any_==, Any_!=, Any_equals, Any_hashCode, Any_toString, Any_##, Any_getClass, Any_isInstanceOf, Any_asInstanceOf, Any_typeTest, Any_typeCast) - lazy val ObjectClass: ClassSymbol = { + @threadUnsafe lazy val ObjectClass: ClassSymbol = { val cls = ctx.requiredClass("java.lang.Object") assert(!cls.isCompleted, "race for completing java.lang.Object") cls.info = ClassInfo(cls.owner.thisType, cls, AnyClass.typeRef :: Nil, newScope) @@ -303,25 +304,25 @@ class Definitions { } def ObjectType: TypeRef = ObjectClass.typeRef - lazy val AnyRefAlias: TypeSymbol = enterAliasType(tpnme.AnyRef, ObjectType) + @threadUnsafe lazy val AnyRefAlias: TypeSymbol = enterAliasType(tpnme.AnyRef, ObjectType) def AnyRefType: TypeRef = AnyRefAlias.typeRef - lazy val Object_eq: TermSymbol = enterMethod(ObjectClass, nme.eq, methOfAnyRef(BooleanType), Final) - lazy val Object_ne: TermSymbol = enterMethod(ObjectClass, nme.ne, methOfAnyRef(BooleanType), Final) - lazy val Object_synchronized: TermSymbol = enterPolyMethod(ObjectClass, nme.synchronized_, 1, + @threadUnsafe lazy val Object_eq: TermSymbol = enterMethod(ObjectClass, nme.eq, methOfAnyRef(BooleanType), Final) + @threadUnsafe lazy val Object_ne: TermSymbol = enterMethod(ObjectClass, nme.ne, methOfAnyRef(BooleanType), Final) + @threadUnsafe lazy val Object_synchronized: TermSymbol = enterPolyMethod(ObjectClass, nme.synchronized_, 1, pt => MethodType(List(pt.paramRefs(0)), pt.paramRefs(0)), Final) - lazy val Object_clone: TermSymbol = enterMethod(ObjectClass, nme.clone_, MethodType(Nil, ObjectType), Protected) - lazy val Object_finalize: TermSymbol = enterMethod(ObjectClass, nme.finalize_, MethodType(Nil, UnitType), Protected) - lazy val Object_notify: TermSymbol = enterMethod(ObjectClass, nme.notify_, MethodType(Nil, UnitType), Final) - lazy val Object_notifyAll: TermSymbol = enterMethod(ObjectClass, nme.notifyAll_, MethodType(Nil, UnitType), Final) - lazy val Object_wait: TermSymbol = enterMethod(ObjectClass, nme.wait_, MethodType(Nil, UnitType), Final) - lazy val Object_waitL: TermSymbol = enterMethod(ObjectClass, nme.wait_, MethodType(LongType :: Nil, UnitType), Final) - lazy val Object_waitLI: TermSymbol = enterMethod(ObjectClass, nme.wait_, MethodType(LongType :: IntType :: Nil, UnitType), Final) + @threadUnsafe lazy val Object_clone: TermSymbol = enterMethod(ObjectClass, nme.clone_, MethodType(Nil, ObjectType), Protected) + @threadUnsafe lazy val Object_finalize: TermSymbol = enterMethod(ObjectClass, nme.finalize_, MethodType(Nil, UnitType), Protected) + @threadUnsafe lazy val Object_notify: TermSymbol = enterMethod(ObjectClass, nme.notify_, MethodType(Nil, UnitType), Final) + @threadUnsafe lazy val Object_notifyAll: TermSymbol = enterMethod(ObjectClass, nme.notifyAll_, MethodType(Nil, UnitType), Final) + @threadUnsafe lazy val Object_wait: TermSymbol = enterMethod(ObjectClass, nme.wait_, MethodType(Nil, UnitType), Final) + @threadUnsafe lazy val Object_waitL: TermSymbol = enterMethod(ObjectClass, nme.wait_, MethodType(LongType :: Nil, UnitType), Final) + @threadUnsafe lazy val Object_waitLI: TermSymbol = enterMethod(ObjectClass, nme.wait_, MethodType(LongType :: IntType :: Nil, UnitType), Final) def ObjectMethods: List[TermSymbol] = List(Object_eq, Object_ne, Object_synchronized, Object_clone, Object_finalize, Object_notify, Object_notifyAll, Object_wait, Object_waitL, Object_waitLI) - lazy val AnyKindClass: ClassSymbol = { + @threadUnsafe lazy val AnyKindClass: ClassSymbol = { val cls = ctx.newCompleteClassSymbol(ScalaPackageClass, tpnme.AnyKind, AbstractFinal | Permanent, Nil) if (!ctx.settings.YnoKindPolymorphism.value) { // Enable kind-polymorphism by exposing scala.AnyKind @@ -331,40 +332,40 @@ class Definitions { } def AnyKindType: TypeRef = AnyKindClass.typeRef - lazy val andType: TypeSymbol = enterBinaryAlias(tpnme.AND, AndType(_, _)) - lazy val orType: TypeSymbol = enterBinaryAlias(tpnme.OR, OrType(_, _)) + @threadUnsafe lazy val andType: TypeSymbol = enterBinaryAlias(tpnme.AND, AndType(_, _)) + @threadUnsafe lazy val orType: TypeSymbol = enterBinaryAlias(tpnme.OR, OrType(_, _)) /** Marker method to indicate an argument to a call-by-name parameter. * Created by byNameClosures and elimByName, eliminated by Erasure, */ - lazy val cbnArg: TermSymbol = enterPolyMethod(OpsPackageClass, nme.cbnArg, 1, + @threadUnsafe lazy val cbnArg: TermSymbol = enterPolyMethod(OpsPackageClass, nme.cbnArg, 1, pt => MethodType(List(FunctionOf(Nil, pt.paramRefs(0))), pt.paramRefs(0))) /** Method representing a throw */ - lazy val throwMethod: TermSymbol = enterMethod(OpsPackageClass, nme.THROWkw, + @threadUnsafe lazy val throwMethod: TermSymbol = enterMethod(OpsPackageClass, nme.THROWkw, MethodType(List(ThrowableType), NothingType)) - lazy val NothingClass: ClassSymbol = enterCompleteClassSymbol( + @threadUnsafe lazy val NothingClass: ClassSymbol = enterCompleteClassSymbol( ScalaPackageClass, tpnme.Nothing, AbstractFinal, List(AnyClass.typeRef)) def NothingType: TypeRef = NothingClass.typeRef - lazy val RuntimeNothingModuleRef: TermRef = ctx.requiredModuleRef("scala.runtime.Nothing") - lazy val NullClass: ClassSymbol = enterCompleteClassSymbol( + @threadUnsafe lazy val RuntimeNothingModuleRef: TermRef = ctx.requiredModuleRef("scala.runtime.Nothing") + @threadUnsafe lazy val NullClass: ClassSymbol = enterCompleteClassSymbol( ScalaPackageClass, tpnme.Null, AbstractFinal, List(ObjectClass.typeRef)) def NullType: TypeRef = NullClass.typeRef - lazy val RuntimeNullModuleRef: TermRef = ctx.requiredModuleRef("scala.runtime.Null") + @threadUnsafe lazy val RuntimeNullModuleRef: TermRef = ctx.requiredModuleRef("scala.runtime.Null") - lazy val ImplicitScrutineeTypeSym = + @threadUnsafe lazy val ImplicitScrutineeTypeSym = newSymbol(ScalaPackageClass, tpnme.IMPLICITkw, EmptyFlags, TypeBounds.empty).entered def ImplicitScrutineeTypeRef: TypeRef = ImplicitScrutineeTypeSym.typeRef - lazy val ScalaPredefModuleRef: TermRef = ctx.requiredModuleRef("scala.Predef") + @threadUnsafe lazy val ScalaPredefModuleRef: TermRef = ctx.requiredModuleRef("scala.Predef") def ScalaPredefModule(implicit ctx: Context): Symbol = ScalaPredefModuleRef.symbol - lazy val Predef_conformsR: TermRef = ScalaPredefModule.requiredMethodRef(nme.conforms_) + @threadUnsafe lazy val Predef_conformsR: TermRef = ScalaPredefModule.requiredMethodRef(nme.conforms_) def Predef_conforms(implicit ctx: Context): Symbol = Predef_conformsR.symbol - lazy val Predef_classOfR: TermRef = ScalaPredefModule.requiredMethodRef(nme.classOf) + @threadUnsafe lazy val Predef_classOfR: TermRef = ScalaPredefModule.requiredMethodRef(nme.classOf) def Predef_classOf(implicit ctx: Context): Symbol = Predef_classOfR.symbol - lazy val Predef_undefinedR: TermRef = ScalaPredefModule.requiredMethodRef(nme.???) + @threadUnsafe lazy val Predef_undefinedR: TermRef = ScalaPredefModule.requiredMethodRef(nme.???) def Predef_undefined(implicit ctx: Context): Symbol = Predef_undefinedR.symbol def SubTypeClass(implicit ctx: Context): ClassSymbol = @@ -379,7 +380,7 @@ class Definitions { else ScalaPredefModule.requiredClass("DummyImplicit") - lazy val ScalaRuntimeModuleRef: TermRef = ctx.requiredModuleRef("scala.runtime.ScalaRunTime") + @threadUnsafe lazy val ScalaRuntimeModuleRef: TermRef = ctx.requiredModuleRef("scala.runtime.ScalaRunTime") def ScalaRuntimeModule(implicit ctx: Context): Symbol = ScalaRuntimeModuleRef.symbol def ScalaRuntimeClass(implicit ctx: Context): ClassSymbol = ScalaRuntimeModule.moduleClass.asClass @@ -387,17 +388,17 @@ class Definitions { def ScalaRuntime_dropR(implicit ctx: Context): TermRef = runtimeMethodRef(nme.drop) def ScalaRuntime_drop(implicit ctx: Context): Symbol = ScalaRuntime_dropR.symbol - lazy val BoxesRunTimeModuleRef: TermRef = ctx.requiredModuleRef("scala.runtime.BoxesRunTime") + @threadUnsafe lazy val BoxesRunTimeModuleRef: TermRef = ctx.requiredModuleRef("scala.runtime.BoxesRunTime") def BoxesRunTimeModule(implicit ctx: Context): Symbol = BoxesRunTimeModuleRef.symbol def BoxesRunTimeClass(implicit ctx: Context): ClassSymbol = BoxesRunTimeModule.moduleClass.asClass - lazy val ScalaStaticsModuleRef: TermRef = ctx.requiredModuleRef("scala.runtime.Statics") + @threadUnsafe lazy val ScalaStaticsModuleRef: TermRef = ctx.requiredModuleRef("scala.runtime.Statics") def ScalaStaticsModule(implicit ctx: Context): Symbol = ScalaStaticsModuleRef.symbol def ScalaStaticsClass(implicit ctx: Context): ClassSymbol = ScalaStaticsModule.moduleClass.asClass def staticsMethodRef(name: PreName): TermRef = ScalaStaticsModule.requiredMethodRef(name) def staticsMethod(name: PreName): TermSymbol = ScalaStaticsModule.requiredMethod(name) - // Dotty deviation: we cannot use a lazy val here because lazy vals in dotty + // Dotty deviation: we cannot use a @threadUnsafe lazy val here because @threadUnsafe lazy vals in dotty // will return "null" when called recursively, see #1856. def DottyPredefModuleRef: TermRef = { if (myDottyPredefModuleRef == null) { @@ -410,13 +411,13 @@ class Definitions { def DottyPredefModule(implicit ctx: Context): Symbol = DottyPredefModuleRef.symbol - lazy val DottyArraysModuleRef: TermRef = ctx.requiredModuleRef("dotty.runtime.Arrays") + @threadUnsafe lazy val DottyArraysModuleRef: TermRef = ctx.requiredModuleRef("dotty.runtime.Arrays") def DottyArraysModule(implicit ctx: Context): Symbol = DottyArraysModuleRef.symbol def newGenericArrayMethod(implicit ctx: Context): TermSymbol = DottyArraysModule.requiredMethod("newGenericArray") def newArrayMethod(implicit ctx: Context): TermSymbol = DottyArraysModule.requiredMethod("newArray") // TODO: Remove once we drop support for 2.12 standard library - lazy val isNewCollections: Boolean = ctx.settings.YnewCollections.value + @threadUnsafe lazy val isNewCollections: Boolean = ctx.settings.YnewCollections.value def getWrapVarargsArrayModule: Symbol = if (isNewCollections) ScalaRuntimeModule else ScalaPredefModule @@ -426,386 +427,386 @@ class Definitions { methodNames.map(getWrapVarargsArrayModule.requiredMethodRef(_).symbol) }) - lazy val NilModuleRef: TermRef = ctx.requiredModuleRef("scala.collection.immutable.Nil") + @threadUnsafe lazy val NilModuleRef: TermRef = ctx.requiredModuleRef("scala.collection.immutable.Nil") def NilModule(implicit ctx: Context): Symbol = NilModuleRef.symbol - lazy val SingletonClass: ClassSymbol = + @threadUnsafe lazy val SingletonClass: ClassSymbol = // needed as a synthetic class because Scala 2.x refers to it in classfiles // but does not define it as an explicit class. enterCompleteClassSymbol( ScalaPackageClass, tpnme.Singleton, PureInterfaceCreationFlags | Final, List(AnyClass.typeRef), EmptyScope) - lazy val SingletonType: TypeRef = SingletonClass.typeRef + @threadUnsafe lazy val SingletonType: TypeRef = SingletonClass.typeRef - lazy val SeqType: TypeRef = + @threadUnsafe lazy val SeqType: TypeRef = if (isNewCollections) ctx.requiredClassRef("scala.collection.immutable.Seq") else ctx.requiredClassRef("scala.collection.Seq") def SeqClass(implicit ctx: Context): ClassSymbol = SeqType.symbol.asClass - lazy val Seq_applyR: TermRef = SeqClass.requiredMethodRef(nme.apply) + @threadUnsafe lazy val Seq_applyR: TermRef = SeqClass.requiredMethodRef(nme.apply) def Seq_apply(implicit ctx: Context): Symbol = Seq_applyR.symbol - lazy val Seq_headR: TermRef = SeqClass.requiredMethodRef(nme.head) + @threadUnsafe lazy val Seq_headR: TermRef = SeqClass.requiredMethodRef(nme.head) def Seq_head(implicit ctx: Context): Symbol = Seq_headR.symbol - lazy val Seq_dropR: TermRef = SeqClass.requiredMethodRef(nme.drop) + @threadUnsafe lazy val Seq_dropR: TermRef = SeqClass.requiredMethodRef(nme.drop) def Seq_drop(implicit ctx: Context): Symbol = Seq_dropR.symbol - lazy val Seq_lengthCompareR: TermRef = SeqClass.requiredMethodRef(nme.lengthCompare, List(IntType)) + @threadUnsafe lazy val Seq_lengthCompareR: TermRef = SeqClass.requiredMethodRef(nme.lengthCompare, List(IntType)) def Seq_lengthCompare(implicit ctx: Context): Symbol = Seq_lengthCompareR.symbol - lazy val Seq_lengthR: TermRef = SeqClass.requiredMethodRef(nme.length) + @threadUnsafe lazy val Seq_lengthR: TermRef = SeqClass.requiredMethodRef(nme.length) def Seq_length(implicit ctx: Context): Symbol = Seq_lengthR.symbol - lazy val Seq_toSeqR: TermRef = SeqClass.requiredMethodRef(nme.toSeq) + @threadUnsafe lazy val Seq_toSeqR: TermRef = SeqClass.requiredMethodRef(nme.toSeq) def Seq_toSeq(implicit ctx: Context): Symbol = Seq_toSeqR.symbol - lazy val ArrayType: TypeRef = ctx.requiredClassRef("scala.Array") + @threadUnsafe lazy val ArrayType: TypeRef = ctx.requiredClassRef("scala.Array") def ArrayClass(implicit ctx: Context): ClassSymbol = ArrayType.symbol.asClass - lazy val Array_applyR: TermRef = ArrayClass.requiredMethodRef(nme.apply) + @threadUnsafe lazy val Array_applyR: TermRef = ArrayClass.requiredMethodRef(nme.apply) def Array_apply(implicit ctx: Context): Symbol = Array_applyR.symbol - lazy val Array_updateR: TermRef = ArrayClass.requiredMethodRef(nme.update) + @threadUnsafe lazy val Array_updateR: TermRef = ArrayClass.requiredMethodRef(nme.update) def Array_update(implicit ctx: Context): Symbol = Array_updateR.symbol - lazy val Array_lengthR: TermRef = ArrayClass.requiredMethodRef(nme.length) + @threadUnsafe lazy val Array_lengthR: TermRef = ArrayClass.requiredMethodRef(nme.length) def Array_length(implicit ctx: Context): Symbol = Array_lengthR.symbol - lazy val Array_cloneR: TermRef = ArrayClass.requiredMethodRef(nme.clone_) + @threadUnsafe lazy val Array_cloneR: TermRef = ArrayClass.requiredMethodRef(nme.clone_) def Array_clone(implicit ctx: Context): Symbol = Array_cloneR.symbol - lazy val ArrayConstructorR: TermRef = ArrayClass.requiredMethodRef(nme.CONSTRUCTOR) + @threadUnsafe lazy val ArrayConstructorR: TermRef = ArrayClass.requiredMethodRef(nme.CONSTRUCTOR) def ArrayConstructor(implicit ctx: Context): Symbol = ArrayConstructorR.symbol - lazy val ArrayModuleType: TermRef = ctx.requiredModuleRef("scala.Array") + @threadUnsafe lazy val ArrayModuleType: TermRef = ctx.requiredModuleRef("scala.Array") def ArrayModule(implicit ctx: Context): ClassSymbol = ArrayModuleType.symbol.moduleClass.asClass - lazy val UnitType: TypeRef = valueTypeRef("scala.Unit", java.lang.Void.TYPE, UnitEnc, nme.specializedTypeNames.Void) + @threadUnsafe lazy val UnitType: TypeRef = valueTypeRef("scala.Unit", java.lang.Void.TYPE, UnitEnc, nme.specializedTypeNames.Void) def UnitClass(implicit ctx: Context): ClassSymbol = UnitType.symbol.asClass def UnitModuleClass(implicit ctx: Context): Symbol = UnitType.symbol.asClass.linkedClass - lazy val BooleanType: TypeRef = valueTypeRef("scala.Boolean", java.lang.Boolean.TYPE, BooleanEnc, nme.specializedTypeNames.Boolean) + @threadUnsafe lazy val BooleanType: TypeRef = valueTypeRef("scala.Boolean", java.lang.Boolean.TYPE, BooleanEnc, nme.specializedTypeNames.Boolean) def BooleanClass(implicit ctx: Context): ClassSymbol = BooleanType.symbol.asClass - lazy val Boolean_notR: TermRef = BooleanClass.requiredMethodRef(nme.UNARY_!) + @threadUnsafe lazy val Boolean_notR: TermRef = BooleanClass.requiredMethodRef(nme.UNARY_!) def Boolean_! : Symbol = Boolean_notR.symbol - lazy val Boolean_andR: TermRef = BooleanClass.requiredMethodRef(nme.ZAND) // ### harmonize required... calls + @threadUnsafe lazy val Boolean_andR: TermRef = BooleanClass.requiredMethodRef(nme.ZAND) // ### harmonize required... calls def Boolean_&& : Symbol = Boolean_andR.symbol - lazy val Boolean_orR: TermRef = BooleanClass.requiredMethodRef(nme.ZOR) + @threadUnsafe lazy val Boolean_orR: TermRef = BooleanClass.requiredMethodRef(nme.ZOR) def Boolean_|| : Symbol = Boolean_orR.symbol - lazy val Boolean_eqeqR: SingleDenotation = BooleanClass.info.member(nme.EQ).suchThat(_.info.firstParamTypes match { + @threadUnsafe lazy val Boolean_eqeqR: SingleDenotation = BooleanClass.info.member(nme.EQ).suchThat(_.info.firstParamTypes match { case List(pt) => (pt isRef BooleanClass) case _ => false }) def Boolean_== : Symbol = Boolean_eqeqR.symbol - lazy val Boolean_neqeqR: SingleDenotation = BooleanClass.info.member(nme.NE).suchThat(_.info.firstParamTypes match { + @threadUnsafe lazy val Boolean_neqeqR: SingleDenotation = BooleanClass.info.member(nme.NE).suchThat(_.info.firstParamTypes match { case List(pt) => (pt isRef BooleanClass) case _ => false }) def Boolean_!= : Symbol = Boolean_neqeqR.symbol - lazy val ByteType: TypeRef = valueTypeRef("scala.Byte", java.lang.Byte.TYPE, ByteEnc, nme.specializedTypeNames.Byte) + @threadUnsafe lazy val ByteType: TypeRef = valueTypeRef("scala.Byte", java.lang.Byte.TYPE, ByteEnc, nme.specializedTypeNames.Byte) def ByteClass(implicit ctx: Context): ClassSymbol = ByteType.symbol.asClass - lazy val ShortType: TypeRef = valueTypeRef("scala.Short", java.lang.Short.TYPE, ShortEnc, nme.specializedTypeNames.Short) + @threadUnsafe lazy val ShortType: TypeRef = valueTypeRef("scala.Short", java.lang.Short.TYPE, ShortEnc, nme.specializedTypeNames.Short) def ShortClass(implicit ctx: Context): ClassSymbol = ShortType.symbol.asClass - lazy val CharType: TypeRef = valueTypeRef("scala.Char", java.lang.Character.TYPE, CharEnc, nme.specializedTypeNames.Char) + @threadUnsafe lazy val CharType: TypeRef = valueTypeRef("scala.Char", java.lang.Character.TYPE, CharEnc, nme.specializedTypeNames.Char) def CharClass(implicit ctx: Context): ClassSymbol = CharType.symbol.asClass - lazy val IntType: TypeRef = valueTypeRef("scala.Int", java.lang.Integer.TYPE, IntEnc, nme.specializedTypeNames.Int) + @threadUnsafe lazy val IntType: TypeRef = valueTypeRef("scala.Int", java.lang.Integer.TYPE, IntEnc, nme.specializedTypeNames.Int) def IntClass(implicit ctx: Context): ClassSymbol = IntType.symbol.asClass - lazy val Int_minusR: TermRef = IntClass.requiredMethodRef(nme.MINUS, List(IntType)) + @threadUnsafe lazy val Int_minusR: TermRef = IntClass.requiredMethodRef(nme.MINUS, List(IntType)) def Int_- : Symbol = Int_minusR.symbol - lazy val Int_plusR: TermRef = IntClass.requiredMethodRef(nme.PLUS, List(IntType)) + @threadUnsafe lazy val Int_plusR: TermRef = IntClass.requiredMethodRef(nme.PLUS, List(IntType)) def Int_+ : Symbol = Int_plusR.symbol - lazy val Int_divR: TermRef = IntClass.requiredMethodRef(nme.DIV, List(IntType)) + @threadUnsafe lazy val Int_divR: TermRef = IntClass.requiredMethodRef(nme.DIV, List(IntType)) def Int_/ : Symbol = Int_divR.symbol - lazy val Int_mulR: TermRef = IntClass.requiredMethodRef(nme.MUL, List(IntType)) + @threadUnsafe lazy val Int_mulR: TermRef = IntClass.requiredMethodRef(nme.MUL, List(IntType)) def Int_* : Symbol = Int_mulR.symbol - lazy val Int_eqR: TermRef = IntClass.requiredMethodRef(nme.EQ, List(IntType)) + @threadUnsafe lazy val Int_eqR: TermRef = IntClass.requiredMethodRef(nme.EQ, List(IntType)) def Int_== : Symbol = Int_eqR.symbol - lazy val Int_geR: TermRef = IntClass.requiredMethodRef(nme.GE, List(IntType)) + @threadUnsafe lazy val Int_geR: TermRef = IntClass.requiredMethodRef(nme.GE, List(IntType)) def Int_>= : Symbol = Int_geR.symbol - lazy val Int_leR: TermRef = IntClass.requiredMethodRef(nme.LE, List(IntType)) + @threadUnsafe lazy val Int_leR: TermRef = IntClass.requiredMethodRef(nme.LE, List(IntType)) def Int_<= : Symbol = Int_leR.symbol - lazy val LongType: TypeRef = valueTypeRef("scala.Long", java.lang.Long.TYPE, LongEnc, nme.specializedTypeNames.Long) + @threadUnsafe lazy val LongType: TypeRef = valueTypeRef("scala.Long", java.lang.Long.TYPE, LongEnc, nme.specializedTypeNames.Long) def LongClass(implicit ctx: Context): ClassSymbol = LongType.symbol.asClass - lazy val Long_XOR_Long: Symbol = LongType.member(nme.XOR).requiredSymbol("method", nme.XOR, LongType.denot)( + @threadUnsafe lazy val Long_XOR_Long: Symbol = LongType.member(nme.XOR).requiredSymbol("method", nme.XOR, LongType.denot)( x => (x is Method) && (x.info.firstParamTypes.head isRef defn.LongClass) ) - lazy val Long_LSR_Int: Symbol = LongType.member(nme.LSR).requiredSymbol("method", nme.LSR, LongType.denot)( + @threadUnsafe lazy val Long_LSR_Int: Symbol = LongType.member(nme.LSR).requiredSymbol("method", nme.LSR, LongType.denot)( x => (x is Method) && (x.info.firstParamTypes.head isRef defn.IntClass) ) - lazy val Long_plusR: TermRef = LongClass.requiredMethodRef(nme.PLUS, List(LongType)) + @threadUnsafe lazy val Long_plusR: TermRef = LongClass.requiredMethodRef(nme.PLUS, List(LongType)) def Long_+ : Symbol = Long_plusR.symbol - lazy val Long_mulR: TermRef = LongClass.requiredMethodRef(nme.MUL, List(LongType)) + @threadUnsafe lazy val Long_mulR: TermRef = LongClass.requiredMethodRef(nme.MUL, List(LongType)) def Long_* : Symbol = Long_mulR.symbol - lazy val Long_divR: TermRef = LongClass.requiredMethodRef(nme.DIV, List(LongType)) + @threadUnsafe lazy val Long_divR: TermRef = LongClass.requiredMethodRef(nme.DIV, List(LongType)) def Long_/ : Symbol = Long_divR.symbol - lazy val FloatType: TypeRef = valueTypeRef("scala.Float", java.lang.Float.TYPE, FloatEnc, nme.specializedTypeNames.Float) + @threadUnsafe lazy val FloatType: TypeRef = valueTypeRef("scala.Float", java.lang.Float.TYPE, FloatEnc, nme.specializedTypeNames.Float) def FloatClass(implicit ctx: Context): ClassSymbol = FloatType.symbol.asClass - lazy val DoubleType: TypeRef = valueTypeRef("scala.Double", java.lang.Double.TYPE, DoubleEnc, nme.specializedTypeNames.Double) + @threadUnsafe lazy val DoubleType: TypeRef = valueTypeRef("scala.Double", java.lang.Double.TYPE, DoubleEnc, nme.specializedTypeNames.Double) def DoubleClass(implicit ctx: Context): ClassSymbol = DoubleType.symbol.asClass - lazy val BoxedUnitType: TypeRef = ctx.requiredClassRef("scala.runtime.BoxedUnit") + @threadUnsafe lazy val BoxedUnitType: TypeRef = ctx.requiredClassRef("scala.runtime.BoxedUnit") def BoxedUnitClass(implicit ctx: Context): ClassSymbol = BoxedUnitType.symbol.asClass def BoxedUnit_UNIT(implicit ctx: Context): TermSymbol = BoxedUnitClass.linkedClass.requiredValue("UNIT") - lazy val BoxedBooleanType: TypeRef = ctx.requiredClassRef("java.lang.Boolean") + @threadUnsafe lazy val BoxedBooleanType: TypeRef = ctx.requiredClassRef("java.lang.Boolean") def BoxedBooleanClass(implicit ctx: Context): ClassSymbol = BoxedBooleanType.symbol.asClass - lazy val BoxedByteType: TypeRef = ctx.requiredClassRef("java.lang.Byte") + @threadUnsafe lazy val BoxedByteType: TypeRef = ctx.requiredClassRef("java.lang.Byte") def BoxedByteClass(implicit ctx: Context): ClassSymbol = BoxedByteType.symbol.asClass - lazy val BoxedShortType: TypeRef = ctx.requiredClassRef("java.lang.Short") + @threadUnsafe lazy val BoxedShortType: TypeRef = ctx.requiredClassRef("java.lang.Short") def BoxedShortClass(implicit ctx: Context): ClassSymbol = BoxedShortType.symbol.asClass - lazy val BoxedCharType: TypeRef = ctx.requiredClassRef("java.lang.Character") + @threadUnsafe lazy val BoxedCharType: TypeRef = ctx.requiredClassRef("java.lang.Character") def BoxedCharClass(implicit ctx: Context): ClassSymbol = BoxedCharType.symbol.asClass - lazy val BoxedIntType: TypeRef = ctx.requiredClassRef("java.lang.Integer") + @threadUnsafe lazy val BoxedIntType: TypeRef = ctx.requiredClassRef("java.lang.Integer") def BoxedIntClass(implicit ctx: Context): ClassSymbol = BoxedIntType.symbol.asClass - lazy val BoxedLongType: TypeRef = ctx.requiredClassRef("java.lang.Long") + @threadUnsafe lazy val BoxedLongType: TypeRef = ctx.requiredClassRef("java.lang.Long") def BoxedLongClass(implicit ctx: Context): ClassSymbol = BoxedLongType.symbol.asClass - lazy val BoxedFloatType: TypeRef = ctx.requiredClassRef("java.lang.Float") + @threadUnsafe lazy val BoxedFloatType: TypeRef = ctx.requiredClassRef("java.lang.Float") def BoxedFloatClass(implicit ctx: Context): ClassSymbol = BoxedFloatType.symbol.asClass - lazy val BoxedDoubleType: TypeRef = ctx.requiredClassRef("java.lang.Double") + @threadUnsafe lazy val BoxedDoubleType: TypeRef = ctx.requiredClassRef("java.lang.Double") def BoxedDoubleClass(implicit ctx: Context): ClassSymbol = BoxedDoubleType.symbol.asClass - lazy val BoxedBooleanModule: TermSymbol = ctx.requiredModule("java.lang.Boolean") - lazy val BoxedByteModule: TermSymbol = ctx.requiredModule("java.lang.Byte") - lazy val BoxedShortModule: TermSymbol = ctx.requiredModule("java.lang.Short") - lazy val BoxedCharModule: TermSymbol = ctx.requiredModule("java.lang.Character") - lazy val BoxedIntModule: TermSymbol = ctx.requiredModule("java.lang.Integer") - lazy val BoxedLongModule: TermSymbol = ctx.requiredModule("java.lang.Long") - lazy val BoxedFloatModule: TermSymbol = ctx.requiredModule("java.lang.Float") - lazy val BoxedDoubleModule: TermSymbol = ctx.requiredModule("java.lang.Double") - lazy val BoxedUnitModule: TermSymbol = ctx.requiredModule("java.lang.Void") + @threadUnsafe lazy val BoxedBooleanModule: TermSymbol = ctx.requiredModule("java.lang.Boolean") + @threadUnsafe lazy val BoxedByteModule: TermSymbol = ctx.requiredModule("java.lang.Byte") + @threadUnsafe lazy val BoxedShortModule: TermSymbol = ctx.requiredModule("java.lang.Short") + @threadUnsafe lazy val BoxedCharModule: TermSymbol = ctx.requiredModule("java.lang.Character") + @threadUnsafe lazy val BoxedIntModule: TermSymbol = ctx.requiredModule("java.lang.Integer") + @threadUnsafe lazy val BoxedLongModule: TermSymbol = ctx.requiredModule("java.lang.Long") + @threadUnsafe lazy val BoxedFloatModule: TermSymbol = ctx.requiredModule("java.lang.Float") + @threadUnsafe lazy val BoxedDoubleModule: TermSymbol = ctx.requiredModule("java.lang.Double") + @threadUnsafe lazy val BoxedUnitModule: TermSymbol = ctx.requiredModule("java.lang.Void") - lazy val ByNameParamClass2x: ClassSymbol = enterSpecialPolyClass(tpnme.BYNAME_PARAM_CLASS, Covariant, Seq(AnyType)) + @threadUnsafe lazy val ByNameParamClass2x: ClassSymbol = enterSpecialPolyClass(tpnme.BYNAME_PARAM_CLASS, Covariant, Seq(AnyType)) - lazy val RepeatedParamClass: ClassSymbol = enterSpecialPolyClass(tpnme.REPEATED_PARAM_CLASS, Covariant, Seq(ObjectType, SeqType)) + @threadUnsafe lazy val RepeatedParamClass: ClassSymbol = enterSpecialPolyClass(tpnme.REPEATED_PARAM_CLASS, Covariant, Seq(ObjectType, SeqType)) // fundamental classes - lazy val StringClass: ClassSymbol = ctx.requiredClass("java.lang.String") + @threadUnsafe lazy val StringClass: ClassSymbol = ctx.requiredClass("java.lang.String") def StringType: Type = StringClass.typeRef - lazy val StringModule: Symbol = StringClass.linkedClass + @threadUnsafe lazy val StringModule: Symbol = StringClass.linkedClass - lazy val String_+ : TermSymbol = enterMethod(StringClass, nme.raw.PLUS, methOfAny(StringType), Final) - lazy val String_valueOf_Object: Symbol = StringModule.info.member(nme.valueOf).suchThat(_.info.firstParamTypes match { + @threadUnsafe lazy val String_+ : TermSymbol = enterMethod(StringClass, nme.raw.PLUS, methOfAny(StringType), Final) + @threadUnsafe lazy val String_valueOf_Object: Symbol = StringModule.info.member(nme.valueOf).suchThat(_.info.firstParamTypes match { case List(pt) => (pt isRef AnyClass) || (pt isRef ObjectClass) case _ => false }).symbol - lazy val JavaCloneableClass: ClassSymbol = ctx.requiredClass("java.lang.Cloneable") - lazy val NullPointerExceptionClass: ClassSymbol = ctx.requiredClass("java.lang.NullPointerException") - lazy val IndexOutOfBoundsException: ClassSymbol = ctx.requiredClass("java.lang.IndexOutOfBoundsException") - lazy val ClassClass: ClassSymbol = ctx.requiredClass("java.lang.Class") - lazy val BoxedNumberClass: ClassSymbol = ctx.requiredClass("java.lang.Number") - lazy val ClassCastExceptionClass: ClassSymbol = ctx.requiredClass("java.lang.ClassCastException") - lazy val ClassCastExceptionClass_stringConstructor: TermSymbol = ClassCastExceptionClass.info.member(nme.CONSTRUCTOR).suchThat(_.info.firstParamTypes match { + @threadUnsafe lazy val JavaCloneableClass: ClassSymbol = ctx.requiredClass("java.lang.Cloneable") + @threadUnsafe lazy val NullPointerExceptionClass: ClassSymbol = ctx.requiredClass("java.lang.NullPointerException") + @threadUnsafe lazy val IndexOutOfBoundsException: ClassSymbol = ctx.requiredClass("java.lang.IndexOutOfBoundsException") + @threadUnsafe lazy val ClassClass: ClassSymbol = ctx.requiredClass("java.lang.Class") + @threadUnsafe lazy val BoxedNumberClass: ClassSymbol = ctx.requiredClass("java.lang.Number") + @threadUnsafe lazy val ClassCastExceptionClass: ClassSymbol = ctx.requiredClass("java.lang.ClassCastException") + @threadUnsafe lazy val ClassCastExceptionClass_stringConstructor: TermSymbol = ClassCastExceptionClass.info.member(nme.CONSTRUCTOR).suchThat(_.info.firstParamTypes match { case List(pt) => (pt isRef StringClass) case _ => false }).symbol.asTerm - lazy val ArithmeticExceptionClass: ClassSymbol = ctx.requiredClass("java.lang.ArithmeticException") - lazy val ArithmeticExceptionClass_stringConstructor: TermSymbol = ArithmeticExceptionClass.info.member(nme.CONSTRUCTOR).suchThat(_.info.firstParamTypes match { + @threadUnsafe lazy val ArithmeticExceptionClass: ClassSymbol = ctx.requiredClass("java.lang.ArithmeticException") + @threadUnsafe lazy val ArithmeticExceptionClass_stringConstructor: TermSymbol = ArithmeticExceptionClass.info.member(nme.CONSTRUCTOR).suchThat(_.info.firstParamTypes match { case List(pt) => (pt isRef StringClass) case _ => false }).symbol.asTerm - lazy val JavaSerializableClass: ClassSymbol = ctx.requiredClass("java.io.Serializable") + @threadUnsafe lazy val JavaSerializableClass: ClassSymbol = ctx.requiredClass("java.io.Serializable") - lazy val ComparableClass: ClassSymbol = ctx.requiredClass("java.lang.Comparable") + @threadUnsafe lazy val ComparableClass: ClassSymbol = ctx.requiredClass("java.lang.Comparable") - lazy val SystemClass: ClassSymbol = ctx.requiredClass("java.lang.System") - lazy val SystemModule: Symbol = SystemClass.linkedClass + @threadUnsafe lazy val SystemClass: ClassSymbol = ctx.requiredClass("java.lang.System") + @threadUnsafe lazy val SystemModule: Symbol = SystemClass.linkedClass // in scalac modified to have Any as parent - lazy val ThrowableType: TypeRef = ctx.requiredClassRef("java.lang.Throwable") + @threadUnsafe lazy val ThrowableType: TypeRef = ctx.requiredClassRef("java.lang.Throwable") def ThrowableClass(implicit ctx: Context): ClassSymbol = ThrowableType.symbol.asClass - lazy val SerializableType: TypeRef = + @threadUnsafe lazy val SerializableType: TypeRef = if (isNewCollections) JavaSerializableClass.typeRef else ctx.requiredClassRef("scala.Serializable") def SerializableClass(implicit ctx: Context): ClassSymbol = SerializableType.symbol.asClass - lazy val StringBuilderType: TypeRef = ctx.requiredClassRef("scala.collection.mutable.StringBuilder") + @threadUnsafe lazy val StringBuilderType: TypeRef = ctx.requiredClassRef("scala.collection.mutable.StringBuilder") def StringBuilderClass(implicit ctx: Context): ClassSymbol = StringBuilderType.symbol.asClass - lazy val MatchErrorType: TypeRef = ctx.requiredClassRef("scala.MatchError") + @threadUnsafe lazy val MatchErrorType: TypeRef = ctx.requiredClassRef("scala.MatchError") def MatchErrorClass(implicit ctx: Context): ClassSymbol = MatchErrorType.symbol.asClass - lazy val ConversionType: TypeRef = ctx.requiredClass("scala.Conversion").typeRef + @threadUnsafe lazy val ConversionType: TypeRef = ctx.requiredClass("scala.Conversion").typeRef def ConversionClass(implicit ctx: Context): ClassSymbol = ConversionType.symbol.asClass - lazy val StringAddType: TypeRef = ctx.requiredClassRef("scala.runtime.StringAdd") + @threadUnsafe lazy val StringAddType: TypeRef = ctx.requiredClassRef("scala.runtime.StringAdd") def StringAddClass(implicit ctx: Context): ClassSymbol = StringAddType.symbol.asClass - lazy val StringAdd_plusR: TermRef = StringAddClass.requiredMethodRef(nme.raw.PLUS) + @threadUnsafe lazy val StringAdd_plusR: TermRef = StringAddClass.requiredMethodRef(nme.raw.PLUS) def StringAdd_+(implicit ctx: Context): Symbol = StringAdd_plusR.symbol - lazy val StringContextType: TypeRef = ctx.requiredClassRef("scala.StringContext") + @threadUnsafe lazy val StringContextType: TypeRef = ctx.requiredClassRef("scala.StringContext") def StringContextClass(implicit ctx: Context): ClassSymbol = StringContextType.symbol.asClass - lazy val StringContextSR: TermRef = StringContextClass.requiredMethodRef(nme.s) + @threadUnsafe lazy val StringContextSR: TermRef = StringContextClass.requiredMethodRef(nme.s) def StringContextS(implicit ctx: Context): Symbol = StringContextSR.symbol - lazy val StringContextRawR: TermRef = StringContextClass.requiredMethodRef(nme.raw_) + @threadUnsafe lazy val StringContextRawR: TermRef = StringContextClass.requiredMethodRef(nme.raw_) def StringContextRaw(implicit ctx: Context): Symbol = StringContextRawR.symbol - lazy val StringContext_fR: TermRef = StringContextClass.requiredMethodRef(nme.f) + @threadUnsafe lazy val StringContext_fR: TermRef = StringContextClass.requiredMethodRef(nme.f) def StringContext_f(implicit ctx: Context): Symbol = StringContext_fR.symbol def StringContextModule(implicit ctx: Context): Symbol = StringContextClass.companionModule - lazy val StringContextModule_applyR: TermRef = StringContextModule.requiredMethodRef(nme.apply) + @threadUnsafe lazy val StringContextModule_applyR: TermRef = StringContextModule.requiredMethodRef(nme.apply) def StringContextModule_apply(implicit ctx: Context): Symbol = StringContextModule_applyR.symbol - lazy val InternalStringContextMacroModuleR: TermRef = ctx.requiredModuleRef("dotty.internal.StringContextMacro") + @threadUnsafe lazy val InternalStringContextMacroModuleR: TermRef = ctx.requiredModuleRef("dotty.internal.StringContextMacro") def InternalStringContextMacroModule(implicit ctx: Context): Symbol = InternalStringContextMacroModuleR.termSymbol - lazy val InternalStringContextMacroModule_fR: TermRef = InternalStringContextMacroModule.requiredMethodRef(nme.f) + @threadUnsafe lazy val InternalStringContextMacroModule_fR: TermRef = InternalStringContextMacroModule.requiredMethodRef(nme.f) def InternalStringContextMacroModule_f(implicit ctx: Context): Symbol = InternalStringContextMacroModule_fR.symbol - lazy val PartialFunctionType: TypeRef = ctx.requiredClassRef("scala.PartialFunction") + @threadUnsafe lazy val PartialFunctionType: TypeRef = ctx.requiredClassRef("scala.PartialFunction") def PartialFunctionClass(implicit ctx: Context): ClassSymbol = PartialFunctionType.symbol.asClass - lazy val PartialFunction_isDefinedAtR: TermRef = PartialFunctionClass.requiredMethodRef(nme.isDefinedAt) + @threadUnsafe lazy val PartialFunction_isDefinedAtR: TermRef = PartialFunctionClass.requiredMethodRef(nme.isDefinedAt) def PartialFunction_isDefinedAt(implicit ctx: Context): Symbol = PartialFunction_isDefinedAtR.symbol - lazy val PartialFunction_applyOrElseR: TermRef = PartialFunctionClass.requiredMethodRef(nme.applyOrElse) + @threadUnsafe lazy val PartialFunction_applyOrElseR: TermRef = PartialFunctionClass.requiredMethodRef(nme.applyOrElse) def PartialFunction_applyOrElse(implicit ctx: Context): Symbol = PartialFunction_applyOrElseR.symbol - lazy val AbstractPartialFunctionType: TypeRef = ctx.requiredClassRef("scala.runtime.AbstractPartialFunction") + @threadUnsafe lazy val AbstractPartialFunctionType: TypeRef = ctx.requiredClassRef("scala.runtime.AbstractPartialFunction") def AbstractPartialFunctionClass(implicit ctx: Context): ClassSymbol = AbstractPartialFunctionType.symbol.asClass - lazy val FunctionXXLType: TypeRef = ctx.requiredClassRef("scala.FunctionXXL") + @threadUnsafe lazy val FunctionXXLType: TypeRef = ctx.requiredClassRef("scala.FunctionXXL") def FunctionXXLClass(implicit ctx: Context): ClassSymbol = FunctionXXLType.symbol.asClass - lazy val ScalaSymbolType: TypeRef = ctx.requiredClassRef("scala.Symbol") + @threadUnsafe lazy val ScalaSymbolType: TypeRef = ctx.requiredClassRef("scala.Symbol") def ScalaSymbolClass(implicit ctx: Context): ClassSymbol = ScalaSymbolType.symbol.asClass def ScalaSymbolModule(implicit ctx: Context): Symbol = ScalaSymbolClass.companionModule - lazy val ScalaSymbolModule_applyR: TermRef = ScalaSymbolModule.requiredMethodRef(nme.apply, List(StringType)) + @threadUnsafe lazy val ScalaSymbolModule_applyR: TermRef = ScalaSymbolModule.requiredMethodRef(nme.apply, List(StringType)) def ScalaSymbolModule_apply(implicit ctx: Context): Symbol = ScalaSymbolModule_applyR.symbol - lazy val DynamicType: TypeRef = ctx.requiredClassRef("scala.Dynamic") + @threadUnsafe lazy val DynamicType: TypeRef = ctx.requiredClassRef("scala.Dynamic") def DynamicClass(implicit ctx: Context): ClassSymbol = DynamicType.symbol.asClass - lazy val OptionType: TypeRef = ctx.requiredClassRef("scala.Option") + @threadUnsafe lazy val OptionType: TypeRef = ctx.requiredClassRef("scala.Option") def OptionClass(implicit ctx: Context): ClassSymbol = OptionType.symbol.asClass - lazy val SomeType: TypeRef = ctx.requiredClassRef("scala.Some") + @threadUnsafe lazy val SomeType: TypeRef = ctx.requiredClassRef("scala.Some") def SomeClass(implicit ctx: Context): ClassSymbol = SomeType.symbol.asClass - lazy val NoneModuleRef: TermRef = ctx.requiredModuleRef("scala.None") + @threadUnsafe lazy val NoneModuleRef: TermRef = ctx.requiredModuleRef("scala.None") def NoneClass(implicit ctx: Context): ClassSymbol = NoneModuleRef.symbol.moduleClass.asClass - lazy val EnumType: TypeRef = ctx.requiredClassRef("scala.Enum") + @threadUnsafe lazy val EnumType: TypeRef = ctx.requiredClassRef("scala.Enum") def EnumClass(implicit ctx: Context): ClassSymbol = EnumType.symbol.asClass - lazy val JEnumType: TypeRef = ctx.requiredClassRef("scala.compat.JEnum") + @threadUnsafe lazy val JEnumType: TypeRef = ctx.requiredClassRef("scala.compat.JEnum") def JEnumClass(implicit ctx: Context): ClassSymbol = JEnumType.symbol.asClass - lazy val EnumValuesType: TypeRef = ctx.requiredClassRef("scala.runtime.EnumValues") + @threadUnsafe lazy val EnumValuesType: TypeRef = ctx.requiredClassRef("scala.runtime.EnumValues") def EnumValuesClass(implicit ctx: Context): ClassSymbol = EnumValuesType.symbol.asClass - lazy val ProductType: TypeRef = ctx.requiredClassRef("scala.Product") + @threadUnsafe lazy val ProductType: TypeRef = ctx.requiredClassRef("scala.Product") def ProductClass(implicit ctx: Context): ClassSymbol = ProductType.symbol.asClass - lazy val Product_canEqualR: TermRef = ProductClass.requiredMethodRef(nme.canEqual_) + @threadUnsafe lazy val Product_canEqualR: TermRef = ProductClass.requiredMethodRef(nme.canEqual_) def Product_canEqual(implicit ctx: Context): Symbol = Product_canEqualR.symbol - lazy val Product_productArityR: TermRef = ProductClass.requiredMethodRef(nme.productArity) + @threadUnsafe lazy val Product_productArityR: TermRef = ProductClass.requiredMethodRef(nme.productArity) def Product_productArity(implicit ctx: Context): Symbol = Product_productArityR.symbol - lazy val Product_productElementR: TermRef = ProductClass.requiredMethodRef(nme.productElement) + @threadUnsafe lazy val Product_productElementR: TermRef = ProductClass.requiredMethodRef(nme.productElement) def Product_productElement(implicit ctx: Context): Symbol = Product_productElementR.symbol - lazy val Product_productPrefixR: TermRef = ProductClass.requiredMethodRef(nme.productPrefix) + @threadUnsafe lazy val Product_productPrefixR: TermRef = ProductClass.requiredMethodRef(nme.productPrefix) def Product_productPrefix(implicit ctx: Context): Symbol = Product_productPrefixR.symbol - lazy val IteratorType: TypeRef = ctx.requiredClassRef("scala.collection.Iterator") + @threadUnsafe lazy val IteratorType: TypeRef = ctx.requiredClassRef("scala.collection.Iterator") def IteratorClass(implicit ctx: Context): ClassSymbol = IteratorType.symbol.asClass def IteratorModule(implicit ctx: Context): Symbol = IteratorClass.companionModule - lazy val ModuleSerializationProxyType: TypeRef = ctx.requiredClassRef("scala.runtime.ModuleSerializationProxy") + @threadUnsafe lazy val ModuleSerializationProxyType: TypeRef = ctx.requiredClassRef("scala.runtime.ModuleSerializationProxy") def ModuleSerializationProxyClass(implicit ctx: Context): ClassSymbol = ModuleSerializationProxyType.symbol.asClass - lazy val ModuleSerializationProxyConstructor: TermSymbol = + @threadUnsafe lazy val ModuleSerializationProxyConstructor: TermSymbol = ModuleSerializationProxyClass.requiredMethod(nme.CONSTRUCTOR, List(ClassType(TypeBounds.empty))) - lazy val MirrorType: TypeRef = ctx.requiredClassRef("scala.deriving.Mirror") + @threadUnsafe lazy val MirrorType: TypeRef = ctx.requiredClassRef("scala.deriving.Mirror") def MirrorClass(implicit ctx: Context): ClassSymbol = MirrorType.symbol.asClass - lazy val Mirror_ProductType: TypeRef = ctx.requiredClassRef("scala.deriving.Mirror.Product") + @threadUnsafe lazy val Mirror_ProductType: TypeRef = ctx.requiredClassRef("scala.deriving.Mirror.Product") def Mirror_ProductClass(implicit ctx: Context): ClassSymbol = Mirror_ProductType.symbol.asClass - lazy val Mirror_Product_fromProductR: TermRef = Mirror_ProductClass.requiredMethodRef(nme.fromProduct) + @threadUnsafe lazy val Mirror_Product_fromProductR: TermRef = Mirror_ProductClass.requiredMethodRef(nme.fromProduct) def Mirror_Product_fromProduct(implicit ctx: Context): Symbol = Mirror_Product_fromProductR.symbol - lazy val Mirror_SumType: TypeRef = ctx.requiredClassRef("scala.deriving.Mirror.Sum") + @threadUnsafe lazy val Mirror_SumType: TypeRef = ctx.requiredClassRef("scala.deriving.Mirror.Sum") def Mirror_SumClass(implicit ctx: Context): ClassSymbol = Mirror_SumType.symbol.asClass - lazy val Mirror_SingletonType: TypeRef = ctx.requiredClassRef("scala.deriving.Mirror.Singleton") + @threadUnsafe lazy val Mirror_SingletonType: TypeRef = ctx.requiredClassRef("scala.deriving.Mirror.Singleton") def Mirror_SingletonClass(implicit ctx: Context): ClassSymbol = Mirror_SingletonType.symbol.asClass - lazy val Mirror_SingletonProxyType: TypeRef = ctx.requiredClassRef("scala.deriving.Mirror.SingletonProxy") + @threadUnsafe lazy val Mirror_SingletonProxyType: TypeRef = ctx.requiredClassRef("scala.deriving.Mirror.SingletonProxy") def Mirror_SingletonProxyClass(implicit ctx: Context): ClassSymbol = Mirror_SingletonProxyType.symbol.asClass - lazy val LanguageModuleRef: TermSymbol = ctx.requiredModule("scala.language") + @threadUnsafe lazy val LanguageModuleRef: TermSymbol = ctx.requiredModule("scala.language") def LanguageModuleClass(implicit ctx: Context): ClassSymbol = LanguageModuleRef.moduleClass.asClass - lazy val NonLocalReturnControlType: TypeRef = ctx.requiredClassRef("scala.runtime.NonLocalReturnControl") - lazy val SelectableType: TypeRef = ctx.requiredClassRef("scala.Selectable") + @threadUnsafe lazy val NonLocalReturnControlType: TypeRef = ctx.requiredClassRef("scala.runtime.NonLocalReturnControl") + @threadUnsafe lazy val SelectableType: TypeRef = ctx.requiredClassRef("scala.Selectable") - lazy val ClassTagType: TypeRef = ctx.requiredClassRef("scala.reflect.ClassTag") + @threadUnsafe lazy val ClassTagType: TypeRef = ctx.requiredClassRef("scala.reflect.ClassTag") def ClassTagClass(implicit ctx: Context): ClassSymbol = ClassTagType.symbol.asClass def ClassTagModule(implicit ctx: Context): Symbol = ClassTagClass.companionModule - lazy val QuotedExprType: TypeRef = ctx.requiredClassRef("scala.quoted.Expr") + @threadUnsafe lazy val QuotedExprType: TypeRef = ctx.requiredClassRef("scala.quoted.Expr") def QuotedExprClass(implicit ctx: Context): ClassSymbol = QuotedExprType.symbol.asClass - lazy val InternalQuotedModuleRef: TermRef = ctx.requiredModuleRef("scala.internal.Quoted") + @threadUnsafe lazy val InternalQuotedModuleRef: TermRef = ctx.requiredModuleRef("scala.internal.Quoted") def InternalQuotedModule: Symbol = InternalQuotedModuleRef.symbol - lazy val InternalQuoted_exprQuoteR: TermRef = InternalQuotedModule.requiredMethodRef("exprQuote") + @threadUnsafe lazy val InternalQuoted_exprQuoteR: TermRef = InternalQuotedModule.requiredMethodRef("exprQuote") def InternalQuoted_exprQuote(implicit ctx: Context): Symbol = InternalQuoted_exprQuoteR.symbol - lazy val InternalQuoted_exprSpliceR: TermRef = InternalQuotedModule.requiredMethodRef("exprSplice") + @threadUnsafe lazy val InternalQuoted_exprSpliceR: TermRef = InternalQuotedModule.requiredMethodRef("exprSplice") def InternalQuoted_exprSplice(implicit ctx: Context): Symbol = InternalQuoted_exprSpliceR.symbol - lazy val InternalQuoted_typeQuoteR: TermRef = InternalQuotedModule.requiredMethodRef("typeQuote") + @threadUnsafe lazy val InternalQuoted_typeQuoteR: TermRef = InternalQuotedModule.requiredMethodRef("typeQuote") def InternalQuoted_typeQuote(implicit ctx: Context): Symbol = InternalQuoted_typeQuoteR.symbol - lazy val InternalQuoted_patternHoleR: TermRef = InternalQuotedModule.requiredMethodRef("patternHole") + @threadUnsafe lazy val InternalQuoted_patternHoleR: TermRef = InternalQuotedModule.requiredMethodRef("patternHole") def InternalQuoted_patternHole(implicit ctx: Context): Symbol = InternalQuoted_patternHoleR.symbol - lazy val InternalQuoted_patternBindHoleAnnot: ClassSymbol = InternalQuotedModule.requiredClass("patternBindHole") + @threadUnsafe lazy val InternalQuoted_patternBindHoleAnnot: ClassSymbol = InternalQuotedModule.requiredClass("patternBindHole") - lazy val InternalQuotedMatcherModuleRef: TermRef = ctx.requiredModuleRef("scala.internal.quoted.Matcher") + @threadUnsafe lazy val InternalQuotedMatcherModuleRef: TermRef = ctx.requiredModuleRef("scala.internal.quoted.Matcher") def InternalQuotedMatcherModule(implicit ctx: Context): Symbol = InternalQuotedMatcherModuleRef.symbol - lazy val InternalQuotedMatcher_unapplyR: TermRef = InternalQuotedMatcherModule.requiredMethodRef(nme.unapply) + @threadUnsafe lazy val InternalQuotedMatcher_unapplyR: TermRef = InternalQuotedMatcherModule.requiredMethodRef(nme.unapply) def InternalQuotedMatcher_unapply(implicit ctx: Context) = InternalQuotedMatcher_unapplyR.symbol - lazy val QuotedTypeType: TypeRef = ctx.requiredClassRef("scala.quoted.Type") + @threadUnsafe lazy val QuotedTypeType: TypeRef = ctx.requiredClassRef("scala.quoted.Type") def QuotedTypeClass(implicit ctx: Context): ClassSymbol = QuotedTypeType.symbol.asClass - lazy val QuotedType_spliceR: TypeRef = QuotedTypeClass.requiredType(tpnme.splice).typeRef + @threadUnsafe lazy val QuotedType_spliceR: TypeRef = QuotedTypeClass.requiredType(tpnme.splice).typeRef def QuotedType_splice : Symbol = QuotedType_spliceR.symbol - lazy val QuotedTypeModuleRef: TermRef = ctx.requiredModuleRef("scala.quoted.Type") + @threadUnsafe lazy val QuotedTypeModuleRef: TermRef = ctx.requiredModuleRef("scala.quoted.Type") def QuotedTypeModule(implicit ctx: Context): Symbol = QuotedTypeModuleRef.symbol - lazy val QuotedMatchingBindingType: TypeRef = ctx.requiredClassRef("scala.quoted.matching.Bind") + @threadUnsafe lazy val QuotedMatchingBindingType: TypeRef = ctx.requiredClassRef("scala.quoted.matching.Bind") def QuotedMatchingBindingClass(implicit ctx: Context): ClassSymbol = QuotedMatchingBindingType.symbol.asClass def Unpickler_unpickleExpr: TermSymbol = ctx.requiredMethod("scala.runtime.quoted.Unpickler.unpickleExpr") def Unpickler_liftedExpr: TermSymbol = ctx.requiredMethod("scala.runtime.quoted.Unpickler.liftedExpr") def Unpickler_unpickleType: TermSymbol = ctx.requiredMethod("scala.runtime.quoted.Unpickler.unpickleType") - lazy val TastyReflectionType: TypeRef = ctx.requiredClassRef("scala.tasty.Reflection") + @threadUnsafe lazy val TastyReflectionType: TypeRef = ctx.requiredClassRef("scala.tasty.Reflection") def TastyReflectionClass(implicit ctx: Context): ClassSymbol = TastyReflectionType.symbol.asClass - lazy val TastyReflectionModule: TermSymbol = ctx.requiredModule("scala.tasty.Reflection") - lazy val TastyReflection_macroContext: TermSymbol = TastyReflectionModule.requiredMethod("macroContext") + @threadUnsafe lazy val TastyReflectionModule: TermSymbol = ctx.requiredModule("scala.tasty.Reflection") + @threadUnsafe lazy val TastyReflection_macroContext: TermSymbol = TastyReflectionModule.requiredMethod("macroContext") - lazy val EqlType: TypeRef = ctx.requiredClassRef("scala.Eql") + @threadUnsafe lazy val EqlType: TypeRef = ctx.requiredClassRef("scala.Eql") def EqlClass(implicit ctx: Context): ClassSymbol = EqlType.symbol.asClass def EqlModule(implicit ctx: Context): Symbol = EqlClass.companionModule def Eql_eqlAny(implicit ctx: Context): TermSymbol = EqlModule.requiredMethod(nme.eqlAny) - lazy val TypeBoxType: TypeRef = ctx.requiredClassRef("scala.internal.TypeBox") + @threadUnsafe lazy val TypeBoxType: TypeRef = ctx.requiredClassRef("scala.internal.TypeBox") - lazy val TypeBox_CAP: TypeSymbol = TypeBoxType.symbol.requiredType(tpnme.CAP) + @threadUnsafe lazy val TypeBox_CAP: TypeSymbol = TypeBoxType.symbol.requiredType(tpnme.CAP) - lazy val MatchCaseType: TypeRef = ctx.requiredClassRef("scala.internal.MatchCase") + @threadUnsafe lazy val MatchCaseType: TypeRef = ctx.requiredClassRef("scala.internal.MatchCase") def MatchCaseClass(implicit ctx: Context): ClassSymbol = MatchCaseType.symbol.asClass - lazy val NotType: TypeRef = ctx.requiredClassRef("scala.implicits.Not") + @threadUnsafe lazy val NotType: TypeRef = ctx.requiredClassRef("scala.implicits.Not") def NotClass(implicit ctx: Context): ClassSymbol = NotType.symbol.asClass def NotModule(implicit ctx: Context): Symbol = NotClass.companionModule def Not_value(implicit ctx: Context): TermSymbol = NotModule.requiredMethod(nme.value) - lazy val ValueOfType: TypeRef = ctx.requiredClassRef("scala.ValueOf") + @threadUnsafe lazy val ValueOfType: TypeRef = ctx.requiredClassRef("scala.ValueOf") def ValueOfClass(implicit ctx: Context): ClassSymbol = ValueOfType.symbol.asClass - lazy val StatsModule = ctx.requiredModule("dotty.tools.dotc.util.Stats") + @threadUnsafe lazy val StatsModule = ctx.requiredModule("dotty.tools.dotc.util.Stats") def Stats_doRecord(implicit ctx: Context): TermSymbol = StatsModule.requiredMethod("doRecord") - lazy val XMLTopScopeModuleRef: TermRef = ctx.requiredModuleRef("scala.xml.TopScope") + @threadUnsafe lazy val XMLTopScopeModuleRef: TermRef = ctx.requiredModuleRef("scala.xml.TopScope") - lazy val TupleTypeRef: TypeRef = ctx.requiredClassRef("scala.Tuple") + @threadUnsafe lazy val TupleTypeRef: TypeRef = ctx.requiredClassRef("scala.Tuple") def TupleClass(implicit ctx: Context): ClassSymbol = TupleTypeRef.symbol.asClass - lazy val Tuple_consR: TermRef = TupleClass.requiredMethod("*:").termRef + @threadUnsafe lazy val Tuple_consR: TermRef = TupleClass.requiredMethod("*:").termRef def Tuple_cons: Symbol = Tuple_consR.symbol - lazy val NonEmptyTupleTypeRef: TypeRef = ctx.requiredClassRef("scala.NonEmptyTuple") + @threadUnsafe lazy val NonEmptyTupleTypeRef: TypeRef = ctx.requiredClassRef("scala.NonEmptyTuple") def NonEmptyTupleClass(implicit ctx: Context): ClassSymbol = NonEmptyTupleTypeRef.symbol.asClass lazy val NonEmptyTuple_tailR: TermRef = NonEmptyTupleClass.requiredMethod("tail").termRef def NonEmptyTuple_tail: Symbol = NonEmptyTuple_tailR.symbol - lazy val PairType: TypeRef = ctx.requiredClassRef("scala.*:") + @threadUnsafe lazy val PairType: TypeRef = ctx.requiredClassRef("scala.*:") def PairClass(implicit ctx: Context): ClassSymbol = PairType.symbol.asClass - lazy val TupleXXLType: TypeRef = ctx.requiredClassRef("scala.TupleXXL") + @threadUnsafe lazy val TupleXXLType: TypeRef = ctx.requiredClassRef("scala.TupleXXL") def TupleXXLClass(implicit ctx: Context): ClassSymbol = TupleXXLType.symbol.asClass def TupleXXLModule(implicit ctx: Context): Symbol = TupleXXLClass.companionModule @@ -833,97 +834,97 @@ class Definitions { def InternalTupleFunctionModule(implicit ctx: Context): Symbol = ctx.requiredModule("scala.internal.TupledFunction") // Annotation base classes - lazy val AnnotationType: TypeRef = ctx.requiredClassRef("scala.annotation.Annotation") + @threadUnsafe lazy val AnnotationType: TypeRef = ctx.requiredClassRef("scala.annotation.Annotation") def AnnotationClass(implicit ctx: Context): ClassSymbol = AnnotationType.symbol.asClass - lazy val ClassfileAnnotationType: TypeRef = ctx.requiredClassRef("scala.annotation.ClassfileAnnotation") + @threadUnsafe lazy val ClassfileAnnotationType: TypeRef = ctx.requiredClassRef("scala.annotation.ClassfileAnnotation") def ClassfileAnnotationClass(implicit ctx: Context): ClassSymbol = ClassfileAnnotationType.symbol.asClass - lazy val StaticAnnotationType: TypeRef = ctx.requiredClassRef("scala.annotation.StaticAnnotation") + @threadUnsafe lazy val StaticAnnotationType: TypeRef = ctx.requiredClassRef("scala.annotation.StaticAnnotation") def StaticAnnotationClass(implicit ctx: Context): ClassSymbol = StaticAnnotationType.symbol.asClass - lazy val RefiningAnnotationType: TypeRef = ctx.requiredClassRef("scala.annotation.RefiningAnnotation") + @threadUnsafe lazy val RefiningAnnotationType: TypeRef = ctx.requiredClassRef("scala.annotation.RefiningAnnotation") def RefiningAnnotationClass(implicit ctx: Context): ClassSymbol = RefiningAnnotationType.symbol.asClass // Annotation classes - lazy val AliasAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.Alias") + @threadUnsafe lazy val AliasAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.Alias") def AliasAnnot(implicit ctx: Context): ClassSymbol = AliasAnnotType.symbol.asClass - lazy val AnnotationDefaultAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.AnnotationDefault") + @threadUnsafe lazy val AnnotationDefaultAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.AnnotationDefault") def AnnotationDefaultAnnot(implicit ctx: Context): ClassSymbol = AnnotationDefaultAnnotType.symbol.asClass - lazy val BodyAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.Body") + @threadUnsafe lazy val BodyAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.Body") def BodyAnnot(implicit ctx: Context): ClassSymbol = BodyAnnotType.symbol.asClass - lazy val ChildAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.Child") + @threadUnsafe lazy val ChildAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.Child") def ChildAnnot(implicit ctx: Context): ClassSymbol = ChildAnnotType.symbol.asClass - lazy val CovariantBetweenAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.CovariantBetween") + @threadUnsafe lazy val CovariantBetweenAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.CovariantBetween") def CovariantBetweenAnnot(implicit ctx: Context): ClassSymbol = CovariantBetweenAnnotType.symbol.asClass - lazy val ContravariantBetweenAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.ContravariantBetween") + @threadUnsafe lazy val ContravariantBetweenAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.ContravariantBetween") def ContravariantBetweenAnnot(implicit ctx: Context): ClassSymbol = ContravariantBetweenAnnotType.symbol.asClass - lazy val DeprecatedAnnotType: TypeRef = ctx.requiredClassRef("scala.deprecated") + @threadUnsafe lazy val DeprecatedAnnotType: TypeRef = ctx.requiredClassRef("scala.deprecated") def DeprecatedAnnot(implicit ctx: Context): ClassSymbol = DeprecatedAnnotType.symbol.asClass - lazy val ImplicitAmbiguousAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.implicitAmbiguous") + @threadUnsafe lazy val ImplicitAmbiguousAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.implicitAmbiguous") def ImplicitAmbiguousAnnot(implicit ctx: Context): ClassSymbol = ImplicitAmbiguousAnnotType.symbol.asClass - lazy val ImplicitNotFoundAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.implicitNotFound") + @threadUnsafe lazy val ImplicitNotFoundAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.implicitNotFound") def ImplicitNotFoundAnnot(implicit ctx: Context): ClassSymbol = ImplicitNotFoundAnnotType.symbol.asClass - lazy val ForceInlineAnnotType: TypeRef = ctx.requiredClassRef("scala.forceInline") + @threadUnsafe lazy val ForceInlineAnnotType: TypeRef = ctx.requiredClassRef("scala.forceInline") def ForceInlineAnnot(implicit ctx: Context): ClassSymbol = ForceInlineAnnotType.symbol.asClass - lazy val InlineParamAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.InlineParam") + @threadUnsafe lazy val InlineParamAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.InlineParam") def InlineParamAnnot(implicit ctx: Context): ClassSymbol = InlineParamAnnotType.symbol.asClass - lazy val InvariantBetweenAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.InvariantBetween") + @threadUnsafe lazy val InvariantBetweenAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.InvariantBetween") def InvariantBetweenAnnot(implicit ctx: Context): ClassSymbol = InvariantBetweenAnnotType.symbol.asClass - lazy val MigrationAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.migration") + @threadUnsafe lazy val MigrationAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.migration") def MigrationAnnot(implicit ctx: Context): ClassSymbol = MigrationAnnotType.symbol.asClass - lazy val NativeAnnotType: TypeRef = ctx.requiredClassRef("scala.native") + @threadUnsafe lazy val NativeAnnotType: TypeRef = ctx.requiredClassRef("scala.native") def NativeAnnot(implicit ctx: Context): ClassSymbol = NativeAnnotType.symbol.asClass - lazy val RepeatedAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.Repeated") + @threadUnsafe lazy val RepeatedAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.Repeated") def RepeatedAnnot(implicit ctx: Context): ClassSymbol = RepeatedAnnotType.symbol.asClass - lazy val SourceFileAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.SourceFile") + @threadUnsafe lazy val SourceFileAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.SourceFile") def SourceFileAnnot(implicit ctx: Context): ClassSymbol = SourceFileAnnotType.symbol.asClass - lazy val ScalaSignatureAnnotType: TypeRef = ctx.requiredClassRef("scala.reflect.ScalaSignature") + @threadUnsafe lazy val ScalaSignatureAnnotType: TypeRef = ctx.requiredClassRef("scala.reflect.ScalaSignature") def ScalaSignatureAnnot(implicit ctx: Context): ClassSymbol = ScalaSignatureAnnotType.symbol.asClass - lazy val ScalaLongSignatureAnnotType: TypeRef = ctx.requiredClassRef("scala.reflect.ScalaLongSignature") + @threadUnsafe lazy val ScalaLongSignatureAnnotType: TypeRef = ctx.requiredClassRef("scala.reflect.ScalaLongSignature") def ScalaLongSignatureAnnot(implicit ctx: Context): ClassSymbol = ScalaLongSignatureAnnotType.symbol.asClass - lazy val ScalaStrictFPAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.strictfp") + @threadUnsafe lazy val ScalaStrictFPAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.strictfp") def ScalaStrictFPAnnot(implicit ctx: Context): ClassSymbol = ScalaStrictFPAnnotType.symbol.asClass - lazy val ScalaStaticAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.static") + @threadUnsafe lazy val ScalaStaticAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.static") def ScalaStaticAnnot(implicit ctx: Context): ClassSymbol = ScalaStaticAnnotType.symbol.asClass - lazy val SerialVersionUIDAnnotType: TypeRef = ctx.requiredClassRef("scala.SerialVersionUID") + @threadUnsafe lazy val SerialVersionUIDAnnotType: TypeRef = ctx.requiredClassRef("scala.SerialVersionUID") def SerialVersionUIDAnnot(implicit ctx: Context): ClassSymbol = SerialVersionUIDAnnotType.symbol.asClass - lazy val TASTYSignatureAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.TASTYSignature") + @threadUnsafe lazy val TASTYSignatureAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.TASTYSignature") def TASTYSignatureAnnot(implicit ctx: Context): ClassSymbol = TASTYSignatureAnnotType.symbol.asClass - lazy val TASTYLongSignatureAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.TASTYLongSignature") + @threadUnsafe lazy val TASTYLongSignatureAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.internal.TASTYLongSignature") def TASTYLongSignatureAnnot(implicit ctx: Context): ClassSymbol = TASTYLongSignatureAnnotType.symbol.asClass - lazy val TailrecAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.tailrec") + @threadUnsafe lazy val TailrecAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.tailrec") def TailrecAnnot(implicit ctx: Context): ClassSymbol = TailrecAnnotType.symbol.asClass - lazy val ThreadUnsafeAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.threadUnsafe") + @threadUnsafe lazy val ThreadUnsafeAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.threadUnsafe") def ThreadUnsafeAnnot(implicit ctx: Context): ClassSymbol = ThreadUnsafeAnnotType.symbol.asClass - lazy val TransientParamAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.constructorOnly") + @threadUnsafe lazy val TransientParamAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.constructorOnly") def TransientParamAnnot(implicit ctx: Context): ClassSymbol = TransientParamAnnotType.symbol.asClass - lazy val CompileTimeOnlyAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.compileTimeOnly") + @threadUnsafe lazy val CompileTimeOnlyAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.compileTimeOnly") def CompileTimeOnlyAnnot(implicit ctx: Context): ClassSymbol = CompileTimeOnlyAnnotType.symbol.asClass - lazy val SwitchAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.switch") + @threadUnsafe lazy val SwitchAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.switch") def SwitchAnnot(implicit ctx: Context): ClassSymbol = SwitchAnnotType.symbol.asClass - lazy val ThrowsAnnotType: TypeRef = ctx.requiredClassRef("scala.throws") + @threadUnsafe lazy val ThrowsAnnotType: TypeRef = ctx.requiredClassRef("scala.throws") def ThrowsAnnot(implicit ctx: Context): ClassSymbol = ThrowsAnnotType.symbol.asClass - lazy val TransientAnnotType: TypeRef = ctx.requiredClassRef("scala.transient") + @threadUnsafe lazy val TransientAnnotType: TypeRef = ctx.requiredClassRef("scala.transient") def TransientAnnot(implicit ctx: Context): ClassSymbol = TransientAnnotType.symbol.asClass - lazy val UncheckedAnnotType: TypeRef = ctx.requiredClassRef("scala.unchecked") + @threadUnsafe lazy val UncheckedAnnotType: TypeRef = ctx.requiredClassRef("scala.unchecked") def UncheckedAnnot(implicit ctx: Context): ClassSymbol = UncheckedAnnotType.symbol.asClass - lazy val UncheckedStableAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.unchecked.uncheckedStable") + @threadUnsafe lazy val UncheckedStableAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.unchecked.uncheckedStable") def UncheckedStableAnnot(implicit ctx: Context): ClassSymbol = UncheckedStableAnnotType.symbol.asClass - lazy val UncheckedVarianceAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.unchecked.uncheckedVariance") + @threadUnsafe lazy val UncheckedVarianceAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.unchecked.uncheckedVariance") def UncheckedVarianceAnnot(implicit ctx: Context): ClassSymbol = UncheckedVarianceAnnotType.symbol.asClass - lazy val VolatileAnnotType: TypeRef = ctx.requiredClassRef("scala.volatile") + @threadUnsafe lazy val VolatileAnnotType: TypeRef = ctx.requiredClassRef("scala.volatile") def VolatileAnnot(implicit ctx: Context): ClassSymbol = VolatileAnnotType.symbol.asClass - lazy val FieldMetaAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.meta.field") + @threadUnsafe lazy val FieldMetaAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.meta.field") def FieldMetaAnnot(implicit ctx: Context): ClassSymbol = FieldMetaAnnotType.symbol.asClass - lazy val GetterMetaAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.meta.getter") + @threadUnsafe lazy val GetterMetaAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.meta.getter") def GetterMetaAnnot(implicit ctx: Context): ClassSymbol = GetterMetaAnnotType.symbol.asClass - lazy val SetterMetaAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.meta.setter") + @threadUnsafe lazy val SetterMetaAnnotType: TypeRef = ctx.requiredClassRef("scala.annotation.meta.setter") def SetterMetaAnnot(implicit ctx: Context): ClassSymbol = SetterMetaAnnotType.symbol.asClass - lazy val ShowAsInfixAnotType: TypeRef = ctx.requiredClassRef("scala.annotation.showAsInfix") + @threadUnsafe lazy val ShowAsInfixAnotType: TypeRef = ctx.requiredClassRef("scala.annotation.showAsInfix") def ShowAsInfixAnnot(implicit ctx: Context): ClassSymbol = ShowAsInfixAnotType.symbol.asClass - lazy val FunctionalInterfaceAnnotType = ctx.requiredClassRef("java.lang.FunctionalInterface") + @threadUnsafe lazy val FunctionalInterfaceAnnotType = ctx.requiredClassRef("java.lang.FunctionalInterface") def FunctionalInterfaceAnnot(implicit ctx: Context) = FunctionalInterfaceAnnotType.symbol.asClass - lazy val InfixAnnotType = ctx.requiredClassRef("scala.annotation.infix") + @threadUnsafe lazy val InfixAnnotType = ctx.requiredClassRef("scala.annotation.infix") def InfixAnnot(implicit ctx: Context) = InfixAnnotType.symbol.asClass - lazy val AlphaAnnotType = ctx.requiredClassRef("scala.annotation.alpha") + @threadUnsafe lazy val AlphaAnnotType = ctx.requiredClassRef("scala.annotation.alpha") def AlphaAnnot(implicit ctx: Context) = AlphaAnnotType.symbol.asClass // convenient one-parameter method types @@ -1032,10 +1033,10 @@ class Definitions { // ----- Symbol sets --------------------------------------------------- - lazy val AbstractFunctionType: Array[TypeRef] = mkArityArray("scala.runtime.AbstractFunction", MaxImplementedFunctionArity, 0) + @threadUnsafe lazy val AbstractFunctionType: Array[TypeRef] = mkArityArray("scala.runtime.AbstractFunction", MaxImplementedFunctionArity, 0) val AbstractFunctionClassPerRun: PerRun[Array[Symbol]] = new PerRun(implicit ctx => AbstractFunctionType.map(_.symbol.asClass)) def AbstractFunctionClass(n: Int)(implicit ctx: Context): Symbol = AbstractFunctionClassPerRun()(ctx)(n) - private lazy val ImplementedFunctionType = mkArityArray("scala.Function", MaxImplementedFunctionArity, 0) + @threadUnsafe private lazy val ImplementedFunctionType = mkArityArray("scala.Function", MaxImplementedFunctionArity, 0) def FunctionClassPerRun: PerRun[Array[Symbol]] = new PerRun(implicit ctx => ImplementedFunctionType.map(_.symbol.asClass)) val LazyHolder: PerRun[Map[Symbol, Symbol]] = new PerRun({ implicit ctx => @@ -1053,7 +1054,7 @@ class Definitions { .withDefaultValue(holderImpl("LazyRef")) }) - lazy val TupleType: Array[TypeRef] = mkArityArray("scala.Tuple", MaxTupleArity, 1) + @threadUnsafe lazy val TupleType: Array[TypeRef] = mkArityArray("scala.Tuple", MaxTupleArity, 1) def FunctionClass(n: Int, isContextual: Boolean = false, isErased: Boolean = false)(implicit ctx: Context): Symbol = if (isContextual && isErased) @@ -1067,7 +1068,7 @@ class Definitions { else ctx.requiredClass("scala.Function" + n.toString) - lazy val Function0_applyR: TermRef = ImplementedFunctionType(0).symbol.requiredMethodRef(nme.apply) + @threadUnsafe lazy val Function0_applyR: TermRef = ImplementedFunctionType(0).symbol.requiredMethodRef(nme.apply) def Function0_apply(implicit ctx: Context): Symbol = Function0_applyR.symbol def FunctionType(n: Int, isContextual: Boolean = false, isErased: Boolean = false)(implicit ctx: Context): TypeRef = @@ -1193,19 +1194,19 @@ class Definitions { () => DottyPredefModuleRef ) - lazy val RootImportFns: List[() => TermRef] = + @threadUnsafe lazy val RootImportFns: List[() => TermRef] = if (ctx.settings.YnoImports.value) List.empty[() => TermRef] else if (ctx.settings.YnoPredef.value) StaticRootImportFns else StaticRootImportFns ++ PredefImportFns - lazy val ShadowableImportNames: Set[TermName] = Set("Predef", "DottyPredef").map(_.toTermName) - lazy val RootImportTypes: List[TermRef] = RootImportFns.map(_()) + @threadUnsafe lazy val ShadowableImportNames: Set[TermName] = Set("Predef", "DottyPredef").map(_.toTermName) + @threadUnsafe lazy val RootImportTypes: List[TermRef] = RootImportFns.map(_()) /** Modules whose members are in the default namespace and their module classes */ - lazy val UnqualifiedOwnerTypes: Set[NamedType] = + @threadUnsafe lazy val UnqualifiedOwnerTypes: Set[NamedType] = RootImportTypes.toSet[NamedType] ++ RootImportTypes.map(_.symbol.moduleClass.typeRef) - lazy val NotRuntimeClasses: Set[Symbol] = Set(AnyClass, AnyValClass, NullClass, NothingClass) + @threadUnsafe lazy val NotRuntimeClasses: Set[Symbol] = Set(AnyClass, AnyValClass, NullClass, NothingClass) /** Classes that are known not to have an initializer irrespective of * whether NoInits is set. Note: FunctionXXLClass is in this set @@ -1217,7 +1218,7 @@ class Definitions { * trait gets screwed up. Therefore, it is mandatory that FunctionXXL * is treated as a NoInit trait. */ - lazy val NoInitClasses: Set[Symbol] = NotRuntimeClasses + FunctionXXLClass + @threadUnsafe lazy val NoInitClasses: Set[Symbol] = NotRuntimeClasses + FunctionXXLClass def isPolymorphicAfterErasure(sym: Symbol): Boolean = (sym eq Any_isInstanceOf) || (sym eq Any_asInstanceOf) || (sym eq Object_synchronized) @@ -1265,26 +1266,26 @@ class Definitions { isNonRefinedFunction(tp.dropDependentRefinement) // Specialized type parameters defined for scala.Function{0,1,2}. - lazy val Function1SpecializedParamTypes: collection.Set[TypeRef] = + @threadUnsafe lazy val Function1SpecializedParamTypes: collection.Set[TypeRef] = Set(IntType, LongType, FloatType, DoubleType) - lazy val Function2SpecializedParamTypes: collection.Set[TypeRef] = + @threadUnsafe lazy val Function2SpecializedParamTypes: collection.Set[TypeRef] = Set(IntType, LongType, DoubleType) - lazy val Function0SpecializedReturnTypes: collection.Set[TypeRef] = + @threadUnsafe lazy val Function0SpecializedReturnTypes: collection.Set[TypeRef] = ScalaNumericValueTypeList.toSet + UnitType + BooleanType - lazy val Function1SpecializedReturnTypes: collection.Set[TypeRef] = + @threadUnsafe lazy val Function1SpecializedReturnTypes: collection.Set[TypeRef] = Set(UnitType, BooleanType, IntType, FloatType, LongType, DoubleType) - lazy val Function2SpecializedReturnTypes: collection.Set[TypeRef] = + @threadUnsafe lazy val Function2SpecializedReturnTypes: collection.Set[TypeRef] = Function1SpecializedReturnTypes - lazy val Function1SpecializedParamClasses: PerRun[collection.Set[Symbol]] = + @threadUnsafe lazy val Function1SpecializedParamClasses: PerRun[collection.Set[Symbol]] = new PerRun(implicit ctx => Function1SpecializedParamTypes.map(_.symbol)) - lazy val Function2SpecializedParamClasses: PerRun[collection.Set[Symbol]] = + @threadUnsafe lazy val Function2SpecializedParamClasses: PerRun[collection.Set[Symbol]] = new PerRun(implicit ctx => Function2SpecializedParamTypes.map(_.symbol)) - lazy val Function0SpecializedReturnClasses: PerRun[collection.Set[Symbol]] = + @threadUnsafe lazy val Function0SpecializedReturnClasses: PerRun[collection.Set[Symbol]] = new PerRun(implicit ctx => Function0SpecializedReturnTypes.map(_.symbol)) - lazy val Function1SpecializedReturnClasses: PerRun[collection.Set[Symbol]] = + @threadUnsafe lazy val Function1SpecializedReturnClasses: PerRun[collection.Set[Symbol]] = new PerRun(implicit ctx => Function1SpecializedReturnTypes.map(_.symbol)) - lazy val Function2SpecializedReturnClasses: PerRun[collection.Set[Symbol]] = + @threadUnsafe lazy val Function2SpecializedReturnClasses: PerRun[collection.Set[Symbol]] = new PerRun(implicit ctx => Function2SpecializedReturnTypes.map(_.symbol)) def isSpecializableFunction(cls: ClassSymbol, paramTypes: List[Type], retType: Type)(implicit ctx: Context): Boolean = @@ -1358,11 +1359,11 @@ class Definitions { } } - lazy val ScalaNumericValueTypeList: List[TypeRef] = List( + @threadUnsafe lazy val ScalaNumericValueTypeList: List[TypeRef] = List( ByteType, ShortType, CharType, IntType, LongType, FloatType, DoubleType) - private lazy val ScalaNumericValueTypes: collection.Set[TypeRef] = ScalaNumericValueTypeList.toSet - private lazy val ScalaValueTypes: collection.Set[TypeRef] = ScalaNumericValueTypes + UnitType + BooleanType + @threadUnsafe private lazy val ScalaNumericValueTypes: collection.Set[TypeRef] = ScalaNumericValueTypeList.toSet + @threadUnsafe private lazy val ScalaValueTypes: collection.Set[TypeRef] = ScalaNumericValueTypes + UnitType + BooleanType val ScalaNumericValueClasses: PerRun[collection.Set[Symbol]] = new PerRun(implicit ctx => ScalaNumericValueTypes.map(_.symbol)) val ScalaValueClasses: PerRun[collection.Set[Symbol]] = new PerRun(implicit ctx => ScalaValueTypes.map(_.symbol)) @@ -1427,7 +1428,7 @@ class Definitions { def isValueSubClass(sym1: Symbol, sym2: Symbol): Boolean = valueTypeEnc(sym2.asClass.name) % valueTypeEnc(sym1.asClass.name) == 0 - lazy val specialErasure: SimpleIdentityMap[Symbol, ClassSymbol] = + @threadUnsafe lazy val specialErasure: SimpleIdentityMap[Symbol, ClassSymbol] = SimpleIdentityMap.Empty[Symbol] .updated(AnyClass, ObjectClass) .updated(AnyValClass, ObjectClass) @@ -1438,7 +1439,7 @@ class Definitions { // ----- Initialization --------------------------------------------------- /** Lists core classes that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */ - lazy val syntheticScalaClasses: List[TypeSymbol] = List( + @threadUnsafe lazy val syntheticScalaClasses: List[TypeSymbol] = List( AnyClass, AnyRefAlias, AnyKindClass, @@ -1451,15 +1452,15 @@ class Definitions { NothingClass, SingletonClass) - lazy val syntheticCoreClasses: List[Symbol] = syntheticScalaClasses ++ List( + @threadUnsafe lazy val syntheticCoreClasses: List[Symbol] = syntheticScalaClasses ++ List( EmptyPackageVal, OpsPackageClass) /** Lists core methods that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */ - lazy val syntheticCoreMethods: List[TermSymbol] = + @threadUnsafe lazy val syntheticCoreMethods: List[TermSymbol] = AnyMethods ++ ObjectMethods ++ List(String_+, throwMethod) - lazy val reservedScalaClassNames: Set[Name] = syntheticScalaClasses.map(_.name).toSet + @threadUnsafe lazy val reservedScalaClassNames: Set[Name] = syntheticScalaClasses.map(_.name).toSet private[this] var isInitialized = false From a73b8306d40618c3f8a4b123d44c066d4374fc4d Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Thu, 30 May 2019 16:25:56 +0200 Subject: [PATCH 4/4] Mark some more lazy vals as @threadUnsafe --- .../tools/backend/jvm/BTypesFromSymbols.scala | 5 +++-- .../tools/backend/jvm/BackendInterface.scala | 1 - .../backend/jvm/DottyBackendInterface.scala | 17 +++++++++-------- .../tools/backend/jvm/scalaPrimitives.scala | 3 ++- compiler/src/dotty/tools/dotc/core/Types.scala | 3 ++- .../dotty/tools/dotc/typer/Applications.scala | 10 +++++----- .../src/dotty/tools/dotc/typer/Implicits.scala | 7 ++++--- .../dotty/tools/dotc/typer/Inferencing.scala | 3 ++- .../dotty/tools/dotc/typer/TypeAssigner.scala | 4 +++- 9 files changed, 30 insertions(+), 23 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index 44e7055c22e0..897537df047d 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -3,6 +3,7 @@ package backend package jvm import scala.tools.asm +import scala.annotation.threadUnsafe /** * This class mainly contains the method classBTypeFromSymbol, which extracts the necessary @@ -30,14 +31,14 @@ class BTypesFromSymbols[I <: BackendInterface](val int: I) extends BTypes { coreBTypes.setBTypes(new CoreBTypes[this.type](this)) } - protected lazy val classBTypeFromInternalNameMap = { + @threadUnsafe protected lazy val classBTypeFromInternalNameMap = { perRunCaches.recordCache(collection.concurrent.TrieMap.empty[String, ClassBType]) } /** * Cache for the method classBTypeFromSymbol. */ - private lazy val convertedClasses = perRunCaches.newMap[Symbol, ClassBType]() + @threadUnsafe private lazy val convertedClasses = perRunCaches.newMap[Symbol, ClassBType]() /** * The ClassBType for a class symbol `sym`. diff --git a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala index a6af1bf203a2..66fda62641c6 100644 --- a/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/BackendInterface.scala @@ -8,7 +8,6 @@ import dotty.tools.io.AbstractFile import scala.language.implicitConversions import scala.tools.asm - /* Interface to abstract over frontend inside backend. * Intended to be implemented by both scalac and dotc */ diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 66a59cd3eafc..3cd668e1fc38 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -8,6 +8,7 @@ import dotty.tools.dotc.transform.{Erasure, GenericSignatures} import dotty.tools.dotc.transform.SymUtils._ import java.io.{File => _} +import scala.annotation.threadUnsafe import scala.collection.generic.Clearable import scala.collection.mutable import scala.reflect.ClassTag @@ -104,8 +105,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma val nme_EQEQ_LOCAL_VAR: Name = StdNames.nme.EQEQ_LOCAL_VAR // require LambdaMetafactory: scalac uses getClassIfDefined, but we need those always. - override lazy val LambdaMetaFactory: ClassSymbol = ctx.requiredClass("java.lang.invoke.LambdaMetafactory") - override lazy val MethodHandle: ClassSymbol = ctx.requiredClass("java.lang.invoke.MethodHandle") + @threadUnsafe override lazy val LambdaMetaFactory: ClassSymbol = ctx.requiredClass("java.lang.invoke.LambdaMetafactory") + @threadUnsafe override lazy val MethodHandle: ClassSymbol = ctx.requiredClass("java.lang.invoke.MethodHandle") val nme_valueOf: Name = StdNames.nme.valueOf val nme_apply: TermName = StdNames.nme.apply @@ -145,13 +146,13 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma val PartialFunctionClass: Symbol = defn.PartialFunctionClass val AbstractPartialFunctionClass: Symbol = defn.AbstractPartialFunctionClass val String_valueOf: Symbol = defn.String_valueOf_Object - lazy val Predef_classOf: Symbol = defn.ScalaPredefModule.requiredMethod(nme.classOf) + @threadUnsafe lazy val Predef_classOf: Symbol = defn.ScalaPredefModule.requiredMethod(nme.classOf) - lazy val AnnotationRetentionAttr: ClassSymbol = ctx.requiredClass("java.lang.annotation.Retention") - lazy val AnnotationRetentionSourceAttr: TermSymbol = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("SOURCE") - lazy val AnnotationRetentionClassAttr: TermSymbol = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("CLASS") - lazy val AnnotationRetentionRuntimeAttr: TermSymbol = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("RUNTIME") - lazy val JavaAnnotationClass: ClassSymbol = ctx.requiredClass("java.lang.annotation.Annotation") + @threadUnsafe lazy val AnnotationRetentionAttr: ClassSymbol = ctx.requiredClass("java.lang.annotation.Retention") + @threadUnsafe lazy val AnnotationRetentionSourceAttr: TermSymbol = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("SOURCE") + @threadUnsafe lazy val AnnotationRetentionClassAttr: TermSymbol = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("CLASS") + @threadUnsafe lazy val AnnotationRetentionRuntimeAttr: TermSymbol = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("RUNTIME") + @threadUnsafe lazy val JavaAnnotationClass: ClassSymbol = ctx.requiredClass("java.lang.annotation.Annotation") def boxMethods: Map[Symbol, Symbol] = defn.ScalaValueClasses().map{x => // @darkdimius Are you sure this should be a def? (x, Erasure.Boxing.boxMethod(x.asClass)) diff --git a/compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala b/compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala index 29ff56d34bd9..ebb09d6cfc38 100644 --- a/compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala +++ b/compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala @@ -14,6 +14,7 @@ import Names.TermName, StdNames._ import Types.{JavaArrayType, UnspecifiedErrorType, Type} import Symbols.{Symbol, NoSymbol} +import scala.annotation.threadUnsafe import scala.collection.immutable @@ -37,7 +38,7 @@ import scala.collection.immutable class DottyPrimitives(ctx: Context) { import dotty.tools.backend.ScalaPrimitivesOps._ - private lazy val primitives: immutable.Map[Symbol, Int] = init + @threadUnsafe private lazy val primitives: immutable.Map[Symbol, Int] = init /** Return the code for the given symbol. */ def getPrimitive(sym: Symbol): Int = { diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 493f7d1fd8e4..a7ab3fad44f3 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -35,6 +35,7 @@ import reporting.trace import java.lang.ref.WeakReference import scala.annotation.internal.sharable +import scala.annotation.threadUnsafe object Types { @@ -3325,7 +3326,7 @@ object Types { def newParamRef(n: Int): TypeParamRef = new TypeParamRefImpl(this, n) - lazy val typeParams: List[LambdaParam] = + @threadUnsafe lazy val typeParams: List[LambdaParam] = paramNames.indices.toList.map(new LambdaParam(this, _)) def derivedLambdaAbstraction(paramNames: List[TypeName], paramInfos: List[TypeBounds], resType: Type)(implicit ctx: Context): Type = diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index c9b930b37bbb..b9b76ef846f5 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -32,7 +32,7 @@ import reporting.trace import Constants.{Constant, IntTag, LongTag} import dotty.tools.dotc.reporting.diagnostic.messages.{UnapplyInvalidReturnType, NotAnExtractor, UnapplyInvalidNumberOfArguments} import Denotations.SingleDenotation -import annotation.constructorOnly +import annotation.{constructorOnly, threadUnsafe} object Applications { import tpd._ @@ -311,13 +311,13 @@ trait Applications extends Compatibility { self: Typer with Dynamic => /** The function's type after widening and instantiating polytypes * with TypeParamRefs in constraint set */ - lazy val methType: Type = liftedFunType.widen match { + @threadUnsafe lazy val methType: Type = liftedFunType.widen match { case funType: MethodType => funType case funType: PolyType => constrained(funType).resultType case tp => tp //was: funType } - lazy val liftedFunType: Type = + @threadUnsafe lazy val liftedFunType: Type = if (needLiftFun) { liftFun() normalizedFun.tpe @@ -327,7 +327,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic => /** The arguments re-ordered so that each named argument matches the * same-named formal parameter. */ - lazy val orderedArgs: List[Arg] = + @threadUnsafe lazy val orderedArgs: List[Arg] = if (hasNamedArg(args)) reorder(args.asInstanceOf[List[untpd.Tree]]).asInstanceOf[List[Arg]] else @@ -618,7 +618,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic => def fail(msg: => Message): Unit = ok = false def appPos: SourcePosition = NoSourcePosition - lazy val normalizedFun: Tree = ref(methRef) + @threadUnsafe lazy val normalizedFun: Tree = ref(methRef) init() } diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index b1c4ec04dd1f..6af31f6f2bf1 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -39,6 +39,7 @@ import reporting.trace import annotation.tailrec import scala.annotation.internal.sharable +import scala.annotation.threadUnsafe /** Implicit resolution */ object Implicits { @@ -231,14 +232,14 @@ object Implicits { */ class OfTypeImplicits(tp: Type, val companionRefs: TermRefSet)(initctx: Context) extends ImplicitRefs(initctx) { assert(initctx.typer != null) - lazy val refs: List[ImplicitRef] = { + @threadUnsafe lazy val refs: List[ImplicitRef] = { val buf = new mutable.ListBuffer[TermRef] for (companion <- companionRefs) buf ++= companion.implicitMembers(ImplicitOrImpliedOrGiven) buf.toList } /** The candidates that are eligible for expected type `tp` */ - lazy val eligible: List[Candidate] = + @threadUnsafe lazy val eligible: List[Candidate] = /*>|>*/ track("eligible in tpe") /*<|<*/ { /*>|>*/ trace(i"eligible($tp), companions = ${companionRefs.toList}%, %", implicitsDetailed, show = true) /*<|<*/ { if (refs.nonEmpty && monitored) record(s"check eligible refs in tpe", refs.length) @@ -1302,7 +1303,7 @@ trait Implicits { self: Typer => private def isCoherent = pt.isRef(defn.EqlClass) /** The expected type for the searched implicit */ - lazy val fullProto: Type = implicitProto(pt, identity) + @threadUnsafe lazy val fullProto: Type = implicitProto(pt, identity) /** The expected type where parameters and uninstantiated typevars are replaced by wildcard types */ val wildProto: Type = implicitProto(pt, wildApprox(_)) diff --git a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala index 1f697678f6ff..9941f2662ad6 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala @@ -17,6 +17,7 @@ import reporting._ import collection.mutable import scala.annotation.internal.sharable +import scala.annotation.threadUnsafe object Inferencing { @@ -53,7 +54,7 @@ object Inferencing { */ def instantiateDependent(tp: Type, tparams: List[Symbol], vparamss: List[List[Symbol]])(implicit ctx: Context): Unit = { val dependentVars = new TypeAccumulator[Set[TypeVar]] { - lazy val params = (tparams :: vparamss).flatten + @threadUnsafe lazy val params = (tparams :: vparamss).flatten def apply(tvars: Set[TypeVar], tp: Type) = tp match { case tp: TypeVar if !tp.isInstantiated && diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala index 4f140a109827..b0f3242f83f2 100644 --- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -15,6 +15,8 @@ import collection.mutable import reporting.diagnostic.messages._ import Checking.{checkNoPrivateLeaks, checkNoWildcard} +import scala.annotation.threadUnsafe + trait TypeAssigner { import tpd._ @@ -91,7 +93,7 @@ trait TypeAssigner { */ def avoid(tp: Type, symsToAvoid: => List[Symbol])(implicit ctx: Context): Type = { val widenMap = new ApproximatingTypeMap { - lazy val forbidden = symsToAvoid.toSet + @threadUnsafe lazy val forbidden = symsToAvoid.toSet def toAvoid(sym: Symbol) = !sym.isStatic && forbidden.contains(sym) def partsToAvoid = new NamedPartsAccumulator(tp => toAvoid(tp.symbol)) def apply(tp: Type): Type = tp match {