diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2013-02-01 14:36:14 +0100 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2013-02-01 14:36:14 +0100 |
commit | a6137d19b6ec7c63fbbae274de3c78e310bba4ae (patch) | |
tree | d0411389ee939c1beabea1a699d1ed5c354038b6 | |
parent | 309ff57ba62b6a6ec1a9c1b28b8bbabfd1b47b72 (diff) | |
download | scala-a6137d19b6ec7c63fbbae274de3c78e310bba4ae.tar.gz scala-a6137d19b6ec7c63fbbae274de3c78e310bba4ae.tar.bz2 scala-a6137d19b6ec7c63fbbae274de3c78e310bba4ae.zip |
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
4 files changed, 6 insertions, 26 deletions
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 |