From a6137d19b6ec7c63fbbae274de3c78e310bba4ae Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Fri, 1 Feb 2013 14:36:14 +0100 Subject: Fix SI-6578. Deprecated `askType` because of possible race conditions in type checker. AskType triggers type-checks the given source and returns a typed tree. If that source is already loaded (a precondition), the background compilation loop may actually be compiling that same source. The new type checker run may then get into an inconsistent state and try to add twice the same synthetic members, like `canEqual`. Most of the times, `askLoadedTyped` (that waits for the type checker to finish, and returns the most recent typed tree) *is* the right way to go. Removed occurrences of the deprecated method in tests and interactive.REPL. @reviewby @huitseeker,@odersky --- .../scala/tools/nsc/interactive/CompilerControl.scala | 5 +++++ src/compiler/scala/tools/nsc/interactive/REPL.scala | 9 +-------- .../tools/nsc/interactive/tests/InteractiveTest.scala | 1 - .../tools/nsc/interactive/tests/core/AskCommand.scala | 17 ----------------- 4 files changed, 6 insertions(+), 26 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala index b4af8f00d6..7dc0b786a7 100644 --- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala +++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala @@ -139,7 +139,12 @@ trait CompilerControl { self: Global => /** Sets sync var `response` to the fully attributed & typechecked tree contained in `source`. * @pre `source` needs to be loaded. + * + * @note Deprecated because of race conditions in the typechecker when the background compiler + * is interrupted while typing the same `source`. + * @see SI-6578 */ + @deprecated("Use `askLoadedTyped` instead to avoid race conditions in the typechecker", "2.10.1") def askType(source: SourceFile, forceReload: Boolean, response: Response[Tree]) = postWorkItem(new AskTypeItem(source, forceReload, response)) diff --git a/src/compiler/scala/tools/nsc/interactive/REPL.scala b/src/compiler/scala/tools/nsc/interactive/REPL.scala index dacfa679dd..7b89d5b0aa 100644 --- a/src/compiler/scala/tools/nsc/interactive/REPL.scala +++ b/src/compiler/scala/tools/nsc/interactive/REPL.scala @@ -110,11 +110,6 @@ object REPL { show(completeResult) } - def doTypedTree(file: String) { - comp.askType(toSourceFile(file), true, typedResult) - show(typedResult) - } - def doStructure(file: String) { comp.askParsedEntered(toSourceFile(file), false, structureResult) show(structureResult) @@ -175,10 +170,8 @@ object REPL { comp.askReload(List(toSourceFile(file)), reloadResult) Thread.sleep(millis.toInt) println("ask type now") - comp.askType(toSourceFile(file), false, typedResult) + comp.askLoadedTyped(toSourceFile(file), typedResult) typedResult.get - case List("typed", file) => - doTypedTree(file) case List("typeat", file, off1, off2) => doTypeAt(makePos(file, off1, off2)) case List("typeat", file, off1) => diff --git a/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala b/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala index 62d274bc70..597b9012ce 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala +++ b/src/compiler/scala/tools/nsc/interactive/tests/InteractiveTest.scala @@ -55,7 +55,6 @@ abstract class InteractiveTest with AskShutdown with AskReload with AskLoadedTyped - with AskType with PresentationCompilerInstance with CoreTestDefs with InteractiveTestSettings { self => diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/AskCommand.scala b/src/compiler/scala/tools/nsc/interactive/tests/core/AskCommand.scala index eb902e3e6c..8d446cbbf8 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/AskCommand.scala +++ b/src/compiler/scala/tools/nsc/interactive/tests/core/AskCommand.scala @@ -97,23 +97,6 @@ trait AskTypeAt extends AskCommand { } } - -trait AskType extends AskCommand { - import compiler.Tree - - protected def askType(source: SourceFile, forceReload: Boolean)(implicit reporter: Reporter): Response[Tree] = { - ask { - compiler.askType(source, forceReload, _) - } - } - - protected def askType(sources: Seq[SourceFile], forceReload: Boolean)(implicit reporter: Reporter): Seq[Response[Tree]] = { - for(source <- sources) yield - askType(source, forceReload) - } -} - - trait AskLoadedTyped extends AskCommand { import compiler.Tree -- cgit v1.2.3