diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index a5bf09325c29..12a1dc697cc4 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1410,6 +1410,37 @@ object SymDenotations { def namedType(using Context): NamedType = if (isType) typeRef else termRef + /** Like typeRef, but objects in the prefix are represented by their singleton type, + * this means we output `pre.O.member` rather than `pre.O$.this.member`. + * + * This is required to avoid owner crash in ExplicitOuter. + * See tests/pos/i10769.scala + */ + def reachableTypeRef(using Context) = + TypeRef(owner.reachableThisType, symbol) + + /** Like termRef, but objects in the prefix are represented by their singleton type, + * this means we output `pre.O.member` rather than `pre.O$.this.member`. + * + * This is required to avoid owner crash in ExplicitOuter. + * See tests/pos/i10769.scala + */ + def reachableTermRef(using Context) = + TermRef(owner.reachableThisType, symbol) + + /** Like thisType, but objects in the type are represented by their singleton type, + * this means we output `pre.O.member` rather than `pre.O$.this.member`. + */ + def reachableThisType(using Context): Type = + if this.is(Package) then + symbol.thisType + else if this.isTerm then + NoPrefix + else if this.is(Module) then + TermRef(owner.reachableThisType, this.sourceModule) + else + ThisType.raw(TypeRef(owner.reachableThisType, symbol.asType)) + /** The variance of this type parameter or type member as a subset of * {Covariant, Contravariant} */ diff --git a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala index ecea13e5b8ee..c2377467a226 100644 --- a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala +++ b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala @@ -223,9 +223,9 @@ object SymUtils: else owner.isLocal } - /** The typeRef with wildcard arguments for each type parameter */ - def rawTypeRef(using Context) = - self.typeRef.appliedTo(self.typeParams.map(_ => TypeBounds.emptyPolyKind)) + /** The reachable typeRef with wildcard arguments for each type parameter */ + def reachableRawTypeRef(using Context) = + self.reachableTypeRef.appliedTo(self.typeParams.map(_ => TypeBounds.emptyPolyKind)) /** Is symbol a quote operation? */ def isQuote(using Context): Boolean = diff --git a/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala b/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala index 22841a5cf1a0..558122b52865 100644 --- a/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala +++ b/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala @@ -521,7 +521,7 @@ class SyntheticMembers(thisPhase: DenotTransformer) { else { val cases = for ((child, idx) <- cls.children.zipWithIndex) yield { - val patType = if (child.isTerm) child.termRef else child.rawTypeRef + val patType = if (child.isTerm) child.reachableTermRef else child.reachableRawTypeRef val pat = Typed(untpd.Ident(nme.WILDCARD).withType(patType), TypeTree(patType)) CaseDef(pat, EmptyTree, Literal(Constant(idx))) } @@ -563,7 +563,7 @@ class SyntheticMembers(thisPhase: DenotTransformer) { if (existing.exists && !existing.is(Deferred)) existing else { val monoType = - newSymbol(clazz, tpnme.MirroredMonoType, Synthetic, TypeAlias(linked.rawTypeRef), coord = clazz.coord) + newSymbol(clazz, tpnme.MirroredMonoType, Synthetic, TypeAlias(linked.reachableRawTypeRef), coord = clazz.coord) newBody = newBody :+ TypeDef(monoType).withSpan(ctx.owner.span.focus) monoType.entered } diff --git a/tests/pos/i10769.scala b/tests/pos/i10769.scala new file mode 100644 index 000000000000..5c63d2c807d0 --- /dev/null +++ b/tests/pos/i10769.scala @@ -0,0 +1,16 @@ +package stm + +trait STMLike[F[_]] { + import Internals._ + + sealed abstract class Txn[+A] {} + + object Txn { + def abort[A](e: Throwable): Txn[A] = Abort(e) + } + + object Internals { + case class Abort(error: Throwable) extends Txn[Nothing] + case object Noop extends Txn[Nothing] + } +} diff --git a/tests/pos/i10769b.scala b/tests/pos/i10769b.scala new file mode 100644 index 000000000000..2e097460b5bf --- /dev/null +++ b/tests/pos/i10769b.scala @@ -0,0 +1,21 @@ +package stm + +trait STMLike[F[_]] { + import Internals._ + + sealed abstract class Txn[+A] {} + + object Txn { + def abort[A](e: Throwable): Txn[A] = Abort(e) + } + + object Internals { + case class Abort(error: Throwable) extends Txn[Nothing] + case object Noop extends Txn[Nothing] + } + + class Foo { + case class Abort(error: Throwable) extends Txn[Nothing] + case object Noop extends Txn[Nothing] + } +}