@@ -1114,27 +1114,34 @@ object Denotations {
11141114 type AsSeenFromResult = SingleDenotation
11151115 protected def computeAsSeenFrom (pre : Type )(implicit ctx : Context ): SingleDenotation = {
11161116 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
11241120 }
1121+ def derived (info : Type ) = derivedSingleDenotation(symbol, info.asSeenFrom(pre, owner))
11251122 pre match {
11261123 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
11271134 symbol.normalizeOpaque()
1128- def findRefined (tp : Type , name : Name ): SingleDenotation = tp match {
1135+ def findRefined (tp : Type , name : Name ): Type = tp match {
11291136 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)
11321138 case _ =>
1133- derived
1139+ symbol.info
11341140 }
1135- findRefined(pre.underlying, symbol.name)
1141+ derived( findRefined(pre.underlying, symbol.name) )
11361142 case _ =>
1137- derived
1143+ if (! owner.membersNeedAsSeenFrom(pre) || symbol.is(NonMember )) this
1144+ else derived(symbol.info)
11381145 }
11391146 }
11401147
0 commit comments