Skip to content

Commit cc500c9

Browse files
liufengyunsmarter
andcommitted
Fix #10769: change synthesized type in def ordinal
As pointed out by @smarter in #10769, for the following code: 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] } } The compiler synthesized the following code for the object `Txn`: object Txn { type MirroredMonoType = STMLike.this.Txn[?] def ordinal(x: Txn.MirroredMonoType): Int = x match { case _:stm.STMLike.Internals.Abort => 0 } def abort[A](e: Throwable): Txn[A] = Abort(e) } In the method `ordinal`, the type for `Internals.Abort` is TypeRef(ThisType(TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class stm)),trait STMLike)),module class Internals$)),class Abort) This type is incorrect, as we are not in the object `Internals`. The explicit outer can only handle such types if it's static. In this case, the object is not static, thus it crashes the explicit outer. Co-authored-by: Guillaume Martres <[email protected]>
1 parent fc8f8fb commit cc500c9

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

compiler/src/dotty/tools/dotc/transform/SymUtils.scala

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,20 @@ object SymUtils:
225225

226226
/** The typeRef with wildcard arguments for each type parameter */
227227
def rawTypeRef(using Context) =
228-
self.typeRef.appliedTo(self.typeParams.map(_ => TypeBounds.emptyPolyKind))
228+
// Change `pre.O.this` to `pre.O` if `O` is an object
229+
// This is required to avoid owner crash in ExplicitOuter.
230+
// See tests/pos/i10769.scala
231+
val fixPrefix = new TypeMap {
232+
def apply(tp: Type): Type = tp match {
233+
case ThisType(tref: TypeRef)
234+
if !tref.symbol.isStaticOwner && tref.symbol.is(Module) =>
235+
TermRef(this(tref.prefix), tref.symbol.sourceModule)
236+
237+
case tp => mapOver(tp)
238+
}
239+
}
240+
241+
fixPrefix(self.typeRef).appliedTo(self.typeParams.map(_ => TypeBounds.emptyPolyKind))
229242

230243
/** Is symbol a quote operation? */
231244
def isQuote(using Context): Boolean =

tests/pos/i10769.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package stm
2+
3+
trait STMLike[F[_]] {
4+
import Internals._
5+
6+
sealed abstract class Txn[+A] {}
7+
8+
object Txn {
9+
def abort[A](e: Throwable): Txn[A] = Abort(e)
10+
}
11+
12+
object Internals {
13+
case class Abort(error: Throwable) extends Txn[Nothing]
14+
}
15+
16+
}

0 commit comments

Comments
 (0)