Skip to content

Commit 311a576

Browse files
authored
Merge pull request scala#6008 from retronym/ticket/sd409
Fix race condition in quasiquotes in runtime reflection
2 parents 8510479 + fe1e3a0 commit 311a576

File tree

5 files changed

+27
-5
lines changed

5 files changed

+27
-5
lines changed

src/reflect/mima-filters/2.12.0.backwards.excludes

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ ProblemFilters.exclude[Problem]("scala.reflect.internal.*")
33
ProblemFilters.exclude[IncompatibleMethTypeProblem]("scala.reflect.runtime.JavaMirrors#JavaMirror.unpickleClass")
44
ProblemFilters.exclude[IncompatibleMethTypeProblem]("scala.reflect.runtime.SymbolLoaders#TopClassCompleter.this")
55

6-
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.reflect.runtime.SynchronizedOps#SynchronizedBaseTypeSeq.lateMap")
6+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.reflect.runtime.SynchronizedOps#SynchronizedBaseTypeSeq.lateMap")
7+
8+
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.reflect.runtime.SynchronizedSymbols#SynchronizedSymbol.scala$reflect$runtime$SynchronizedSymbols$SynchronizedSymbol$$super$exists")

src/reflect/mima-filters/2.12.0.forwards.excludes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ ProblemFilters.exclude[DirectMissingMethodProblem]("scala.reflect.runtime.JavaUn
1212
ProblemFilters.exclude[MissingClassProblem]("scala.reflect.io.FileZipArchive$LazyEntry")
1313
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.reflect.io.ZipArchive.closeZipFile")
1414
ProblemFilters.exclude[MissingClassProblem]("scala.reflect.io.FileZipArchive$LeakyEntry")
15+
16+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.reflect.runtime.SynchronizedSymbols#SynchronizedSymbol.exists")

src/reflect/scala/reflect/internal/ReificationSupport.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ trait ReificationSupport { self: SymbolTable =>
427427

428428
object SyntacticTuple extends SyntacticTupleExtractor {
429429
def apply(args: List[Tree]): Tree = {
430-
require(args.isEmpty || TupleClass(args.length).exists, s"Tuples with ${args.length} arity aren't supported")
430+
require(args.isEmpty || (TupleClass(args.length) != NoSymbol), s"Tuples with ${args.length} arity aren't supported")
431431
gen.mkTuple(args)
432432
}
433433

@@ -447,7 +447,7 @@ trait ReificationSupport { self: SymbolTable =>
447447

448448
object SyntacticTupleType extends SyntacticTupleExtractor {
449449
def apply(args: List[Tree]): Tree = {
450-
require(args.isEmpty || TupleClass(args.length).exists, s"Tuples with ${args.length} arity aren't supported")
450+
require(args.isEmpty || (TupleClass(args.length) != NoSymbol), s"Tuples with ${args.length} arity aren't supported")
451451
gen.mkTupleType(args)
452452
}
453453

@@ -466,7 +466,7 @@ trait ReificationSupport { self: SymbolTable =>
466466

467467
object SyntacticFunctionType extends SyntacticFunctionTypeExtractor {
468468
def apply(argtpes: List[Tree], restpe: Tree): Tree = {
469-
require(FunctionClass(argtpes.length).exists, s"Function types with ${argtpes.length} arity aren't supported")
469+
require(FunctionClass(argtpes.length) != NoSymbol, s"Function types with ${argtpes.length} arity aren't supported")
470470
gen.mkFunctionTypeTree(argtpes, restpe)
471471
}
472472

src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb
118118
override def markFlagsCompleted(mask: Long): this.type = { _initializationMask = _initializationMask & ~mask; this }
119119
override def markAllCompleted(): this.type = { _initializationMask = 0L; _initialized = true; this }
120120

121-
def gilSynchronizedIfNotThreadsafe[T](body: => T): T = {
121+
@inline final def gilSynchronizedIfNotThreadsafe[T](body: => T): T = {
122122
// TODO: debug and fix the race that doesn't allow us uncomment this optimization
123123
// if (isCompilerUniverse || isThreadsafe(purpose = AllOps)) body
124124
// else gilSynchronized { body }
@@ -128,6 +128,7 @@ private[reflect] trait SynchronizedSymbols extends internal.Symbols { self: Symb
128128
override def validTo = gilSynchronizedIfNotThreadsafe { super.validTo }
129129
override def info = gilSynchronizedIfNotThreadsafe { super.info }
130130
override def rawInfo: Type = gilSynchronizedIfNotThreadsafe { super.rawInfo }
131+
override def exists: Boolean = gilSynchronizedIfNotThreadsafe(super.exists)
131132
override def typeSignature: Type = gilSynchronizedIfNotThreadsafe { super.typeSignature }
132133
override def typeSignatureIn(site: Type): Type = gilSynchronizedIfNotThreadsafe { super.typeSignatureIn(site) }
133134

test/files/run/sd409.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import reflect.runtime.universe._
2+
3+
object Test {
4+
def main(args: Array[String]): Unit = {
5+
val threads = collection.mutable.Buffer[Thread]()
6+
for (i <- 1 to 22; j <- 1 to 8) {
7+
val t = new Thread {
8+
override def run(): Unit = {
9+
internal.reificationSupport.SyntacticTuple.apply(List.fill(i)(EmptyTree))
10+
}
11+
}
12+
threads += t
13+
t.start()
14+
}
15+
threads.foreach(_.join())
16+
}
17+
}

0 commit comments

Comments
 (0)