@@ -1114,27 +1114,34 @@ object Denotations {
1114
1114
type AsSeenFromResult = SingleDenotation
1115
1115
protected def computeAsSeenFrom (pre : Type )(implicit ctx : Context ): SingleDenotation = {
1116
1116
val symbol = this .symbol
1117
- def derived = {
1118
- val owner = this match {
1119
- case thisd : SymDenotation => thisd.owner
1120
- case _ => if (symbol.exists) symbol.owner else NoSymbol
1121
- }
1122
- if (! owner.membersNeedAsSeenFrom(pre) || symbol.is(NonMember )) this
1123
- else derivedSingleDenotation(symbol, symbol.info.asSeenFrom(pre, owner))
1117
+ val owner = this match {
1118
+ case thisd : SymDenotation => thisd.owner
1119
+ case _ => if (symbol.exists) symbol.owner else NoSymbol
1124
1120
}
1121
+ def derived (info : Type ) = derivedSingleDenotation(symbol, info.asSeenFrom(pre, owner))
1125
1122
pre match {
1126
1123
case pre : ThisType if symbol.isOpaqueAlias && pre.cls == symbol.owner =>
1124
+ // This code is necessary to compensate for a "window of vulnerability" with
1125
+ // opaque types. The problematic sequence is as follows.
1126
+ // 1. Type a selection `m.this.T` where `T` is an opaque type alias in `m`
1127
+ // and this is the first access
1128
+ // 2. `T` will normalize to an abstract type on completion.
1129
+ // 3. At that time, the default logic in the second case is wrong: `T`'s new info
1130
+ // is now an abstract type and running it through an asSeenFrom gives nothing.
1131
+ // We fix this as follows:
1132
+ // 1. Force opaque normalization as first step
1133
+ // 2. Read the info from the enclosing object's refinement
1127
1134
symbol.normalizeOpaque()
1128
- def findRefined (tp : Type , name : Name ): SingleDenotation = tp match {
1135
+ def findRefined (tp : Type , name : Name ): Type = tp match {
1129
1136
case RefinedType (parent, rname, rinfo) =>
1130
- if (rname == name) derivedSingleDenotation(symbol, rinfo)
1131
- else findRefined(parent, name)
1137
+ if (rname == name) rinfo else findRefined(parent, name)
1132
1138
case _ =>
1133
- derived
1139
+ symbol.info
1134
1140
}
1135
- findRefined(pre.underlying, symbol.name)
1141
+ derived( findRefined(pre.underlying, symbol.name) )
1136
1142
case _ =>
1137
- derived
1143
+ if (! owner.membersNeedAsSeenFrom(pre) || symbol.is(NonMember )) this
1144
+ else derived(symbol.info)
1138
1145
}
1139
1146
}
1140
1147
0 commit comments