@@ -126,6 +126,19 @@ object Types {
126
126
false
127
127
}
128
128
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
+
129
142
/** Is this type an instance of a non-bottom subclass of the given class `cls`? */
130
143
final def derivesFrom (cls : Symbol )(implicit ctx : Context ): Boolean = this match {
131
144
case tp : TypeRef =>
@@ -1221,27 +1234,17 @@ object Types {
1221
1234
val sym = lastSymbol
1222
1235
if (sym == null ) loadDenot else denotOfSym(sym)
1223
1236
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
1227
1241
else {
1228
1242
val newd = loadDenot
1229
1243
if (newd.exists) newd else d.staleSymbolError
1230
1244
}
1231
1245
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
1245
1248
}
1246
1249
if (ctx.typerState.ephemeral) record(" ephemeral cache miss: loadDenot" )
1247
1250
else if (d.exists) {
@@ -1250,14 +1253,25 @@ object Types {
1250
1253
// phase but a defined denotation earlier (e.g. a TypeRef to an abstract type
1251
1254
// is undefined after erasure.) We need to be able to do time travel back and
1252
1255
// 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
1254
1260
checkedPeriod = ctx.period
1255
1261
}
1256
1262
d
1257
1263
}
1258
1264
finally ctx.typerState.ephemeral |= savedEphemeral
1259
1265
}
1260
1266
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
+
1261
1275
private def denotOfSym (sym : Symbol )(implicit ctx : Context ): Denotation = {
1262
1276
val d = sym.denot
1263
1277
val owner = d.owner
@@ -1276,11 +1290,9 @@ object Types {
1276
1290
(lastDefRunId == NoRunId )
1277
1291
} ||
1278
1292
(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
1282
1294
),
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} " )
1284
1296
1285
1297
protected def sig : Signature = Signature .NotAMethod
1286
1298
0 commit comments