Skip to content

Commit 8a7522c

Browse files
committed
Add explanations
1 parent e4fe509 commit 8a7522c

File tree

1 file changed

+20
-13
lines changed

1 file changed

+20
-13
lines changed

compiler/src/dotty/tools/dotc/core/Denotations.scala

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)