aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-11-25 15:30:05 +0100
committerMartin Odersky <odersky@gmail.com>2014-11-26 09:29:25 +0100
commit3e7d63e7331807d3b92921fc4b1bc2bcfbf30d83 (patch)
tree2c771e2afc1f4a21b4980a1a8bdb17e93dd8d461 /src/dotty
parent03ec379926f1f900f09c50dd038fba86feae70f6 (diff)
downloaddotty-3e7d63e7331807d3b92921fc4b1bc2bcfbf30d83.tar.gz
dotty-3e7d63e7331807d3b92921fc4b1bc2bcfbf30d83.tar.bz2
dotty-3e7d63e7331807d3b92921fc4b1bc2bcfbf30d83.zip
Fixed data race in ResolveSuper
The datarace happened because for method "transform" implemented by ResolveSuper which disambiguated overridden methods. Previously, there was a reference FirstTransform.this.transform of type termRefWithSig to the method implemented in a super trait. Now the same reference points to the newly implemented method. Solved because ResolveSuper now generates symbolic references.
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/core/Phases.scala15
-rw-r--r--src/dotty/tools/dotc/core/Types.scala10
2 files changed, 15 insertions, 10 deletions
diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala
index 348789e14..8476ae601 100644
--- a/src/dotty/tools/dotc/core/Phases.scala
+++ b/src/dotty/tools/dotc/core/Phases.scala
@@ -220,6 +220,7 @@ object Phases {
private var myErasedTypes = false
private var myFlatClasses = false
private var myRefChecked = false
+ private var mySymbolicRefs = false
/** The sequence position of this phase in the given context where 0
* is reserved for NoPhase and the first real phase is at position 1.
@@ -231,18 +232,20 @@ object Phases {
def start = myPeriod.firstPhaseId
def end = myPeriod.lastPhaseId
- final def erasedTypes = myErasedTypes
- final def flatClasses = myFlatClasses
- final def refChecked = myRefChecked
+ final def erasedTypes = myErasedTypes // Phase is after erasure
+ final def flatClasses = myFlatClasses // Phase is after flatten
+ final def refChecked = myRefChecked // Phase is after RefChecks
+ final def symbolicRefs = mySymbolicRefs // Phase is after ResolveSuper, newly generated TermRefs should be symbolic
protected[Phases] def init(base: ContextBase, start: Int, end:Int): Unit = {
if (start >= FirstPhaseId)
assert(myPeriod == Periods.InvalidPeriod, s"phase $this has already been used once; cannot be reused")
myBase = base
myPeriod = Period(start, end)
- myErasedTypes = prev.getClass == classOf[Erasure] || prev.erasedTypes
- myFlatClasses = prev.getClass == classOf[Flatten] || prev.flatClasses
- myRefChecked = prev.getClass == classOf[RefChecks] || prev.refChecked
+ myErasedTypes = prev.getClass == classOf[Erasure] || prev.erasedTypes
+ myFlatClasses = prev.getClass == classOf[Flatten] || prev.flatClasses
+ myRefChecked = prev.getClass == classOf[RefChecks] || prev.refChecked
+ mySymbolicRefs = prev.getClass == classOf[ResolveSuper] || prev.symbolicRefs
}
protected[Phases] def init(base: ContextBase, id: Int): Unit = init(base, id, id)
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index feee05d86..017b7cadc 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -1542,6 +1542,8 @@ object Types {
object TermRef {
+ private def symbolicRefs(implicit ctx: Context) = ctx.phase.symbolicRefs
+
/** Create term ref with given name, without specifying a signature.
* Its meaning is the (potentially multi-) denotation of the member(s)
* of prefix with given name.
@@ -1562,7 +1564,7 @@ object Types {
* signature, if denotation is not yet completed.
*/
def apply(prefix: Type, name: TermName, denot: Denotation)(implicit ctx: Context): TermRef = {
- if ((prefix eq NoPrefix) || denot.symbol.isFresh || ctx.erasedTypes)
+ if ((prefix eq NoPrefix) || denot.symbol.isFresh || symbolicRefs)
apply(prefix, denot.symbol.asTerm)
else denot match {
case denot: SymDenotation if denot.isCompleted => withSig(prefix, name, denot.signature)
@@ -1584,7 +1586,7 @@ object Types {
* (2) The name in the term ref need not be the same as the name of the Symbol.
*/
def withSymAndName(prefix: Type, sym: TermSymbol, name: TermName)(implicit ctx: Context): TermRef =
- if ((prefix eq NoPrefix) || sym.isFresh || ctx.erasedTypes)
+ if ((prefix eq NoPrefix) || sym.isFresh || symbolicRefs)
withFixedSym(prefix, name, sym)
else if (sym.defRunId != NoRunId && sym.isCompleted)
withSig(prefix, name, sym.signature) withSym (sym, sym.signature)
@@ -1595,7 +1597,7 @@ object Types {
* (which must be completed).
*/
def withSig(prefix: Type, sym: TermSymbol)(implicit ctx: Context): TermRef =
- if ((prefix eq NoPrefix) || sym.isFresh || ctx.erasedTypes) withFixedSym(prefix, sym.name, sym)
+ if ((prefix eq NoPrefix) || sym.isFresh || symbolicRefs) withFixedSym(prefix, sym.name, sym)
else withSig(prefix, sym.name, sym.signature).withSym(sym, sym.signature)
/** Create a term ref with given prefix, name and signature */
@@ -1604,7 +1606,7 @@ object Types {
/** Create a term ref with given prefix, name, signature, and initial denotation */
def withSigAndDenot(prefix: Type, name: TermName, sig: Signature, denot: Denotation)(implicit ctx: Context): TermRef = {
- if ((prefix eq NoPrefix) || denot.symbol.isFresh || ctx.erasedTypes)
+ if ((prefix eq NoPrefix) || denot.symbol.isFresh || symbolicRefs)
withFixedSym(prefix, denot.symbol.asTerm.name, denot.symbol.asTerm)
else
withSig(prefix, name, sig)