@@ -126,6 +126,19 @@ object Types {
126126 false
127127 }
128128
129+ /** Does this type refer exactly to class symbol `sym`, instead of to a subclass of `sym`?
130+ * Implemented like `isRef`, but follows more types: all type proxies as well as and- and or-types
131+ */
132+ private [Types ] def isTightPrefix (sym : Symbol )(implicit ctx : Context ): Boolean = stripTypeVar match {
133+ case tp : NamedType => tp.info.isTightPrefix(sym)
134+ case tp : ClassInfo => tp.cls eq sym
135+ case tp : Types .ThisType => tp.cls eq sym
136+ case tp : TypeProxy => tp.underlying.isTightPrefix(sym)
137+ case tp : AndType => tp.tp1.isTightPrefix(sym) && tp.tp2.isTightPrefix(sym)
138+ case tp : OrType => tp.tp1.isTightPrefix(sym) || tp.tp2.isTightPrefix(sym)
139+ case _ => false
140+ }
141+
129142 /** Is this type an instance of a non-bottom subclass of the given class `cls`? */
130143 final def derivesFrom (cls : Symbol )(implicit ctx : Context ): Boolean = this match {
131144 case tp : TypeRef =>
@@ -1221,27 +1234,17 @@ object Types {
12211234 val sym = lastSymbol
12221235 if (sym == null ) loadDenot else denotOfSym(sym)
12231236 case d : SymDenotation =>
1224- if ( d.validFor.runId == ctx.runId
1225- || ctx.stillValid(d)
1226- || this .isInstanceOf [WithFixedSym ]) d.current
1237+ if (this .isInstanceOf [WithFixedSym ]) d.current
1238+ else if (d.validFor.runId == ctx.runId || ctx.stillValid(d))
1239+ if (prefix.isTightPrefix(d.owner) || d.isConstructor) d.current
1240+ else recomputeMember(d) // symbol could have been overridden, recompute membership
12271241 else {
12281242 val newd = loadDenot
12291243 if (newd.exists) newd else d.staleSymbolError
12301244 }
12311245 case d =>
1232- if (d.validFor.runId != ctx.period.runId)
1233- loadDenot
1234- // The following branch was used to avoid an assertErased error.
1235- // It's idea was to void keeping non-sym denotations after erasure
1236- // since they violate the assertErased contract. But the problem is
1237- // that when seen again in an earlier phase the denotation is
1238- // still seen as a SymDenotation, whereas it should be a SingleDenotation.
1239- // That's why the branch is disabled.
1240- //
1241- // else if (ctx.erasedTypes && lastSymbol != null)
1242- // denotOfSym(lastSymbol)
1243- else
1244- d.current
1246+ if (d.validFor.runId != ctx.period.runId) loadDenot
1247+ else d.current
12451248 }
12461249 if (ctx.typerState.ephemeral) record(" ephemeral cache miss: loadDenot" )
12471250 else if (d.exists) {
@@ -1250,14 +1253,25 @@ object Types {
12501253 // phase but a defined denotation earlier (e.g. a TypeRef to an abstract type
12511254 // is undefined after erasure.) We need to be able to do time travel back and
12521255 // forth also in these cases.
1253- setDenot(d)
1256+
1257+ // Don't use setDenot here; double binding checks can give spurious failures after erasure
1258+ lastDenotation = d
1259+ lastSymbol = d.symbol
12541260 checkedPeriod = ctx.period
12551261 }
12561262 d
12571263 }
12581264 finally ctx.typerState.ephemeral |= savedEphemeral
12591265 }
12601266
1267+ /** A member of `prefix` (disambiguated by `d.signature`) or, if none was found, `d.current`. */
1268+ private def recomputeMember (d : SymDenotation )(implicit ctx : Context ): Denotation =
1269+ asMemberOf(prefix) match {
1270+ case NoDenotation => d.current
1271+ case newd : SingleDenotation => newd
1272+ case newd => newd.atSignature(d.signature).orElse(d.current)
1273+ }
1274+
12611275 private def denotOfSym (sym : Symbol )(implicit ctx : Context ): Denotation = {
12621276 val d = sym.denot
12631277 val owner = d.owner
@@ -1276,11 +1290,9 @@ object Types {
12761290 (lastDefRunId == NoRunId )
12771291 } ||
12781292 (lastSymbol.infoOrCompleter == ErrorType ||
1279- defn.overriddenBySynthetic.contains(lastSymbol)
1280- // for overriddenBySynthetic symbols a TermRef such as SomeCaseClass.this.hashCode
1281- // might be rewritten from Object#hashCode to the hashCode generated at SyntheticMethods
1293+ sym.owner.derivesFrom(lastSymbol.owner) && sym.owner != lastSymbol.owner
12821294 ),
1283- s " data race? overwriting symbol of ${this .show} / $this / ${this .getClass} / ${lastSymbol.id} / ${sym.id}" )
1295+ s " data race? overwriting symbol of ${this .show} / $this / ${this .getClass} / ${lastSymbol.id} / ${sym.id} / ${sym.owner} / ${lastSymbol.owner} / ${ctx.phase} " )
12841296
12851297 protected def sig : Signature = Signature .NotAMethod
12861298
0 commit comments