@@ -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,29 @@ 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+ * 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 opaque. The treatment of opaque types
1140+ * is needed, without it i7159.scala fails in from-tasty. Without the treatment,
1141+ * opaque type denotations in subclasses are kept as SymDenotations, which means
1142+ * that the transform in `ElimOpaque` will return the symbol's opaque alias without
1143+ * adding the needed asSeenFrom.
1144+ *
1145+ * Logically, the right thing to do would be to extend the same treatment to all denotations
1146+ * Currently this fails the bootstrap. There's also a concern that this generalization
1147+ * would create more denotation objects, at a price in performance.
1148+ */
1149+ def derived (info : Type ) =
1150+ derivedSingleDenotation(
1151+ symbol,
1152+ info.asSeenFrom(pre, owner),
1153+ if (symbol.is(Opaque ) || this .prefix != NoPrefix ) pre else this .prefix)
1154+
11301155 pre match {
1131- case pre : ThisType if symbol.isOpaqueAlias && pre.cls == symbol. owner =>
1156+ case pre : ThisType if symbol.isOpaqueAlias && pre.cls == owner =>
11321157 // This code is necessary to compensate for a "window of vulnerability" with
11331158 // opaque types. The problematic sequence is as follows.
11341159 // 1. Type a selection `m.this.T` where `T` is an opaque type alias in `m`
@@ -1164,34 +1189,39 @@ object Denotations {
11641189 }
11651190 }
11661191
1167- abstract class NonSymSingleDenotation (symbol : Symbol , initInfo : Type ) extends SingleDenotation (symbol, initInfo) {
1192+ abstract class NonSymSingleDenotation (symbol : Symbol , initInfo : Type , override val prefix : Type ) extends SingleDenotation (symbol, initInfo) {
11681193 def infoOrCompleter : Type = initInfo
11691194 def isType : Boolean = infoOrCompleter.isInstanceOf [TypeType ]
11701195 }
11711196
11721197 class UniqueRefDenotation (
11731198 symbol : Symbol ,
11741199 initInfo : Type ,
1175- initValidFor : Period ) extends NonSymSingleDenotation (symbol, initInfo) {
1200+ initValidFor : Period ,
1201+ prefix : Type ) extends NonSymSingleDenotation (symbol, initInfo, prefix) {
11761202 validFor = initValidFor
11771203 override def hasUniqueSym : Boolean = true
1178- protected def newLikeThis (s : Symbol , i : Type ): SingleDenotation = new UniqueRefDenotation (s, i, validFor)
1204+ protected def newLikeThis (s : Symbol , i : Type , pre : Type ): SingleDenotation =
1205+ new UniqueRefDenotation (s, i, validFor, pre)
11791206 }
11801207
11811208 class JointRefDenotation (
11821209 symbol : Symbol ,
11831210 initInfo : Type ,
1184- initValidFor : Period ) extends NonSymSingleDenotation (symbol, initInfo) {
1211+ initValidFor : Period ,
1212+ prefix : Type ) extends NonSymSingleDenotation (symbol, initInfo, prefix) {
11851213 validFor = initValidFor
11861214 override def hasUniqueSym : Boolean = false
1187- protected def newLikeThis (s : Symbol , i : Type ): SingleDenotation = new JointRefDenotation (s, i, validFor)
1215+ protected def newLikeThis (s : Symbol , i : Type , pre : Type ): SingleDenotation =
1216+ new JointRefDenotation (s, i, validFor, pre)
11881217 }
11891218
1190- class ErrorDenotation (implicit ctx : Context ) extends NonSymSingleDenotation (NoSymbol , NoType ) {
1219+ class ErrorDenotation (implicit ctx : Context ) extends NonSymSingleDenotation (NoSymbol , NoType , NoType ) {
11911220 override def exists : Boolean = false
11921221 override def hasUniqueSym : Boolean = false
11931222 validFor = Period .allInRun(ctx.runId)
1194- protected def newLikeThis (s : Symbol , i : Type ): SingleDenotation = this
1223+ protected def newLikeThis (s : Symbol , i : Type , pre : Type ): SingleDenotation =
1224+ this
11951225 }
11961226
11971227 /** An error denotation that provides more info about the missing reference.
0 commit comments