@@ -126,6 +126,17 @@ object Types {
126
126
false
127
127
}
128
128
129
+ /** Same as `isRef`, but follows more types: all type proxies as well as and- and or-types */
130
+ private [Types ] def isWeakRef (sym : Symbol )(implicit ctx : Context ): Boolean = stripTypeVar match {
131
+ case tp : NamedType => tp.info.isWeakRef(sym)
132
+ case tp : ClassInfo => tp.cls eq sym
133
+ case tp : Types .ThisType => tp.cls eq sym
134
+ case tp : TypeProxy => tp.underlying.isWeakRef(sym)
135
+ case tp : AndType => tp.tp1.isWeakRef(sym) && tp.tp2.isWeakRef(sym)
136
+ case tp : OrType => tp.tp1.isWeakRef(sym) || tp.tp2.isWeakRef(sym)
137
+ case _ => false
138
+ }
139
+
129
140
/** Is this type an instance of a non-bottom subclass of the given class `cls`? */
130
141
final def derivesFrom (cls : Symbol )(implicit ctx : Context ): Boolean = this match {
131
142
case tp : TypeRef =>
@@ -1216,27 +1227,17 @@ object Types {
1216
1227
val sym = lastSymbol
1217
1228
if (sym == null ) loadDenot else denotOfSym(sym)
1218
1229
case d : SymDenotation =>
1219
- if ( d.validFor.runId == ctx.runId
1220
- || ctx.stillValid(d)
1221
- || this .isInstanceOf [WithFixedSym ]) d.current
1230
+ if (this .isInstanceOf [WithFixedSym ]) d.current
1231
+ else if (d.validFor.runId == ctx.runId || ctx.stillValid(d))
1232
+ if (prefix.isWeakRef(d.owner) || d.isConstructor) d.current
1233
+ else recomputeMember(d) // symbol could have been overridden, recompute membership
1222
1234
else {
1223
1235
val newd = loadDenot
1224
1236
if (newd.exists) newd else d.staleSymbolError
1225
1237
}
1226
1238
case d =>
1227
- if (d.validFor.runId != ctx.period.runId)
1228
- loadDenot
1229
- // The following branch was used to avoid an assertErased error.
1230
- // It's idea was to void keeping non-sym denotations after erasure
1231
- // since they violate the assertErased contract. But the problem is
1232
- // that when seen again in an earlier phase the denotation is
1233
- // still seen as a SymDenotation, whereas it should be a SingleDenotation.
1234
- // That's why the branch is disabled.
1235
- //
1236
- // else if (ctx.erasedTypes && lastSymbol != null)
1237
- // denotOfSym(lastSymbol)
1238
- else
1239
- d.current
1239
+ if (d.validFor.runId != ctx.period.runId) loadDenot
1240
+ else d.current
1240
1241
}
1241
1242
if (ctx.typerState.ephemeral) record(" ephemeral cache miss: loadDenot" )
1242
1243
else if (d.exists) {
@@ -1245,14 +1246,25 @@ object Types {
1245
1246
// phase but a defined denotation earlier (e.g. a TypeRef to an abstract type
1246
1247
// is undefined after erasure.) We need to be able to do time travel back and
1247
1248
// forth also in these cases.
1248
- setDenot(d)
1249
+
1250
+ // Don't use setDenot here; double binding checks can give spurious failures after erasure
1251
+ lastDenotation = d
1252
+ lastSymbol = d.symbol
1249
1253
checkedPeriod = ctx.period
1250
1254
}
1251
1255
d
1252
1256
}
1253
1257
finally ctx.typerState.ephemeral |= savedEphemeral
1254
1258
}
1255
1259
1260
+ /** A member of `prefix` (disambiguated by `d.signature`) or, if none was found, `d.current`. */
1261
+ private def recomputeMember (d : SymDenotation )(implicit ctx : Context ): Denotation =
1262
+ asMemberOf(prefix) match {
1263
+ case NoDenotation => d.current
1264
+ case newd : SingleDenotation => newd
1265
+ case newd => newd.atSignature(d.signature).orElse(d.current)
1266
+ }
1267
+
1256
1268
private def denotOfSym (sym : Symbol )(implicit ctx : Context ): Denotation = {
1257
1269
val d = sym.denot
1258
1270
val owner = d.owner
@@ -1275,7 +1287,7 @@ object Types {
1275
1287
// for overriddenBySynthetic symbols a TermRef such as SomeCaseClass.this.hashCode
1276
1288
// might be rewritten from Object#hashCode to the hashCode generated at SyntheticMethods
1277
1289
),
1278
- s " data race? overwriting symbol of ${this .show} / $this / ${this .getClass} / ${lastSymbol.id} / ${sym.id}" )
1290
+ s " data race? overwriting symbol of ${this .show} / $this / ${this .getClass} / ${lastSymbol.id} / ${sym.id} / ${sym.owner} / ${lastSymbol.owner} / ${ctx.phase} " )
1279
1291
1280
1292
protected def sig : Signature = Signature .NotAMethod
1281
1293
0 commit comments