@@ -365,6 +365,23 @@ object SymDenotations {
365365 case _ => unforcedDecls.openForMutations
366366 }
367367
368+ /** If this is a synthetic opaque type alias, mark it as Deferred with empty bounds
369+ */
370+ final def normalizeOpaque ()(implicit ctx : Context ) = {
371+ def abstractRHS (tp : Type ): Type = tp match {
372+ case tp : HKTypeLambda => tp.derivedLambdaType(resType = abstractRHS(tp.resType))
373+ case _ => defn.AnyType
374+ }
375+ if (isOpaqueHelper) {
376+ info match {
377+ case TypeAlias (alias) =>
378+ info = TypeBounds (defn.NothingType , abstractRHS(alias))
379+ setFlag(Deferred )
380+ case _ =>
381+ }
382+ }
383+ }
384+
368385 // ------ Names ----------------------------------------------
369386
370387 /** The expanded name of this denotation. */
@@ -517,10 +534,19 @@ object SymDenotations {
517534 /** Is this symbol an abstract type or type parameter? */
518535 final def isAbstractOrParamType (implicit ctx : Context ): Boolean = this is DeferredOrTypeParam
519536
537+ /** Is this symbol a user-defined opaque alias type? */
538+ def isOpaqueAlias (implicit ctx : Context ): Boolean = is(Opaque , butNot = Synthetic )
539+
540+ /** Is this symbol the companion of an opaque alias type? */
541+ def isOpaqueCompanion (implicit ctx : Context ): Boolean = is(OpaqueModule )
542+
543+ /** Is this symbol a synthetic opaque type inside an opaque companion object? */
544+ def isOpaqueHelper (implicit ctx : Context ): Boolean = is(SyntheticOpaque , butNot = Module )
545+
520546 /** Can this symbol have a companion module?
521547 * This is the case if it is a class or an opaque type alias.
522548 */
523- final def canHaveCompanion (implicit ctx : Context ) = isClass
549+ final def canHaveCompanion (implicit ctx : Context ) = isClass || isOpaqueAlias
524550
525551 /** Is this the denotation of a self symbol of some class?
526552 * This is the case if one of two conditions holds:
@@ -830,10 +856,12 @@ object SymDenotations {
830856 /** The module implemented by this module class, NoSymbol if not applicable. */
831857 final def sourceModule (implicit ctx : Context ): Symbol = myInfo match {
832858 case ClassInfo (_, _, _, _, selfType) if this is ModuleClass =>
833- selfType match {
834- case selfType : TermRef => selfType.symbol
835- case selfType : Symbol => selfType.info.asInstanceOf [TermRef ].symbol
859+ def sourceOfSelf (tp : Any ): Symbol = tp match {
860+ case tp : TermRef => tp.symbol
861+ case tp : Symbol => sourceOfSelf(tp.info)
862+ case tp : RefinedType => sourceOfSelf(tp.parent)
836863 }
864+ sourceOfSelf(selfType)
837865 case info : LazyType =>
838866 info.sourceModule
839867 case _ =>
@@ -954,6 +982,10 @@ object SymDenotations {
954982 */
955983 final def companionModule (implicit ctx : Context ): Symbol =
956984 if (is(Module )) sourceModule
985+ else if (isOpaqueAlias)
986+ info match {
987+ case TypeAlias (TypeRef (TermRef (prefix, _), _)) => prefix.termSymbol
988+ }
957989 else registeredCompanion.sourceModule
958990
959991 private def companionType (implicit ctx : Context ): Symbol =
@@ -968,6 +1000,13 @@ object SymDenotations {
9681000 final def companionClass (implicit ctx : Context ): Symbol =
9691001 companionType.suchThat(_.isClass).symbol
9701002
1003+ /** The opaque type with the same (type-) name as this module or module class,
1004+ * and which is also defined in the same scope and compilation unit.
1005+ * NoSymbol if this type does not exist.
1006+ */
1007+ final def companionOpaqueType (implicit ctx : Context ): Symbol =
1008+ companionType.suchThat(_.isOpaqueAlias).symbol
1009+
9711010 final def scalacLinkedClass (implicit ctx : Context ): Symbol =
9721011 if (this is ModuleClass ) companionNamed(effectiveName.toTypeName)
9731012 else if (this .isClass) companionNamed(effectiveName.moduleClassName).sourceModule.moduleClass
@@ -1017,6 +1056,24 @@ object SymDenotations {
10171056 final def enclosingSubClass (implicit ctx : Context ): Symbol =
10181057 ctx.owner.ownersIterator.findSymbol(_.isSubClass(symbol))
10191058
1059+ /** The alias of a synthetic opaque type that's stored in the self type of the
1060+ * containing object.
1061+ */
1062+ def opaqueAlias (implicit ctx : Context ): Type = {
1063+ if (isOpaqueHelper) {
1064+ owner.asClass.classInfo.selfType match {
1065+ case RefinedType (_, _, TypeBounds (lo, _)) =>
1066+ def extractAlias (tp : Type ): Type = tp match {
1067+ case OrType (alias, _) => alias
1068+ case HKTypeLambda (tparams, tp) =>
1069+ HKTypeLambda (tparams.map(_.paramInfo), extractAlias(tp))
1070+ }
1071+ extractAlias(lo)
1072+ }
1073+ }
1074+ else NoType
1075+ }
1076+
10201077 /** The non-private symbol whose name and type matches the type of this symbol
10211078 * in the given class.
10221079 * @param inClass The class containing the result symbol's definition
@@ -1653,15 +1710,16 @@ object SymDenotations {
16531710
16541711 def computeTypeRef = {
16551712 btrCache.put(tp, NoPrefix )
1656- tp.symbol.denot match {
1713+ val tpSym = tp.symbol
1714+ tpSym.denot match {
16571715 case clsd : ClassDenotation =>
16581716 def isOwnThis = prefix match {
16591717 case prefix : ThisType => prefix.cls `eq` clsd.owner
16601718 case NoPrefix => true
16611719 case _ => false
16621720 }
16631721 val baseTp =
1664- if (tp.symbol eq symbol)
1722+ if (tpSym eq symbol)
16651723 tp
16661724 else if (isOwnThis)
16671725 if (clsd.baseClassSet.contains(symbol))
0 commit comments