@@ -490,7 +490,7 @@ object Denotations {
490490 // compare with way merge is performed in SymDenotation#computeMembersNamed
491491 else throw new MergeError (ex.sym1, ex.sym2, ex.tp1, ex.tp2, pre)
492492 }
493- new JointRefDenotation (sym, jointInfo, denot1.validFor & denot2.validFor)
493+ new JointRefDenotation (sym, jointInfo, denot1.validFor & denot2.validFor, pre )
494494 }
495495 }
496496 }
@@ -543,7 +543,7 @@ object Denotations {
543543 lubSym(sym1.allOverriddenSymbols, NoSymbol )
544544 }
545545 new JointRefDenotation (
546- jointSym, infoJoin(info1, info2, sym1, sym2), denot1.validFor & denot2.validFor)
546+ jointSym, infoJoin(info1, info2, sym1, sym2), denot1.validFor & denot2.validFor, pre )
547547 }
548548 }
549549 else NoDenotation
@@ -716,10 +716,15 @@ object Denotations {
716716
717717 /** A non-overloaded denotation */
718718 abstract class SingleDenotation (symbol : Symbol , initInfo : Type ) extends Denotation (symbol, initInfo) {
719- protected def newLikeThis (symbol : Symbol , info : Type ): SingleDenotation
719+ protected def newLikeThis (symbol : Symbol , info : Type , pre : Type ): SingleDenotation
720720
721721 final def name (implicit ctx : Context ): Name = symbol.name
722722
723+ /** If this is not a SymDenotation: The prefix under which the denotation was constructed.
724+ * NoPrefix for SymDenotations.
725+ */
726+ def prefix : Type = NoPrefix
727+
723728 final def signature (implicit ctx : Context ): Signature =
724729 if (isType) Signature .NotAMethod // don't force info if this is a type SymDenotation
725730 else info match {
@@ -733,9 +738,9 @@ object Denotations {
733738 case _ => Signature .NotAMethod
734739 }
735740
736- def derivedSingleDenotation (symbol : Symbol , info : Type )(implicit ctx : Context ): SingleDenotation =
737- if ((symbol eq this .symbol) && (info eq this .info)) this
738- else newLikeThis(symbol, info)
741+ def derivedSingleDenotation (symbol : Symbol , info : Type , pre : Type = this .prefix )(implicit ctx : Context ): SingleDenotation =
742+ if ((symbol eq this .symbol) && (info eq this .info) && (pre eq this .prefix) ) this
743+ else newLikeThis(symbol, info, pre )
739744
740745 def mapInfo (f : Type => Type )(implicit ctx : Context ): SingleDenotation =
741746 derivedSingleDenotation(symbol, f(info))
@@ -1126,9 +1131,26 @@ object Denotations {
11261131 case thisd : SymDenotation => thisd.owner
11271132 case _ => if (symbol.exists) symbol.owner else NoSymbol
11281133 }
1129- def derived (info : Type ) = derivedSingleDenotation(symbol, info.asSeenFrom(pre, owner))
1134+
1135+ /** The derived denotation with the given `info` transformed with `asSeenFrom`.
1136+ * The prefix of the derived denotation is the new prefix `pre` if the type is
1137+ * abstract or opaque, or if the current prefix is already different from `NoPrefix`.
1138+ * That leaves SymDenotations (which have NoPrefix as the prefix), which are left
1139+ * as SymDenotations unless the type is abstract or opaque. This special case
1140+ * is not ideal, and we should see whether we can drop it.
1141+ * Currently dropping the special case fails the bootstrap. There's also a concern
1142+ * that without the special case we'd create more denotation objects, at a price
1143+ * in performance.
1144+ */
1145+ def derived (info : Type ) =
1146+ derivedSingleDenotation(
1147+ symbol,
1148+ info.asSeenFrom(pre, owner),
1149+ if (symbol.isOneOf(Opaque | Deferred ) || this .prefix != NoPrefix ) pre
1150+ else /* special case, see above */ this .prefix)
1151+
11301152 pre match {
1131- case pre : ThisType if symbol.isOpaqueAlias && pre.cls == symbol. owner =>
1153+ case pre : ThisType if symbol.isOpaqueAlias && pre.cls == owner =>
11321154 // This code is necessary to compensate for a "window of vulnerability" with
11331155 // opaque types. The problematic sequence is as follows.
11341156 // 1. Type a selection `m.this.T` where `T` is an opaque type alias in `m`
@@ -1164,34 +1186,39 @@ object Denotations {
11641186 }
11651187 }
11661188
1167- abstract class NonSymSingleDenotation (symbol : Symbol , initInfo : Type ) extends SingleDenotation (symbol, initInfo) {
1189+ abstract class NonSymSingleDenotation (symbol : Symbol , initInfo : Type , override val prefix : Type ) extends SingleDenotation (symbol, initInfo) {
11681190 def infoOrCompleter : Type = initInfo
11691191 def isType : Boolean = infoOrCompleter.isInstanceOf [TypeType ]
11701192 }
11711193
11721194 class UniqueRefDenotation (
11731195 symbol : Symbol ,
11741196 initInfo : Type ,
1175- initValidFor : Period ) extends NonSymSingleDenotation (symbol, initInfo) {
1197+ initValidFor : Period ,
1198+ prefix : Type ) extends NonSymSingleDenotation (symbol, initInfo, prefix) {
11761199 validFor = initValidFor
11771200 override def hasUniqueSym : Boolean = true
1178- protected def newLikeThis (s : Symbol , i : Type ): SingleDenotation = new UniqueRefDenotation (s, i, validFor)
1201+ protected def newLikeThis (s : Symbol , i : Type , pre : Type ): SingleDenotation =
1202+ new UniqueRefDenotation (s, i, validFor, pre)
11791203 }
11801204
11811205 class JointRefDenotation (
11821206 symbol : Symbol ,
11831207 initInfo : Type ,
1184- initValidFor : Period ) extends NonSymSingleDenotation (symbol, initInfo) {
1208+ initValidFor : Period ,
1209+ prefix : Type ) extends NonSymSingleDenotation (symbol, initInfo, prefix) {
11851210 validFor = initValidFor
11861211 override def hasUniqueSym : Boolean = false
1187- protected def newLikeThis (s : Symbol , i : Type ): SingleDenotation = new JointRefDenotation (s, i, validFor)
1212+ protected def newLikeThis (s : Symbol , i : Type , pre : Type ): SingleDenotation =
1213+ new JointRefDenotation (s, i, validFor, pre)
11881214 }
11891215
1190- class ErrorDenotation (implicit ctx : Context ) extends NonSymSingleDenotation (NoSymbol , NoType ) {
1216+ class ErrorDenotation (implicit ctx : Context ) extends NonSymSingleDenotation (NoSymbol , NoType , NoType ) {
11911217 override def exists : Boolean = false
11921218 override def hasUniqueSym : Boolean = false
11931219 validFor = Period .allInRun(ctx.runId)
1194- protected def newLikeThis (s : Symbol , i : Type ): SingleDenotation = this
1220+ protected def newLikeThis (s : Symbol , i : Type , pre : Type ): SingleDenotation =
1221+ this
11951222 }
11961223
11971224 /** An error denotation that provides more info about the missing reference.
0 commit comments