Skip to content

Opaque type with cyclic bound: assertion error #8337

Closed
@Jasper-M

Description

@Jasper-M

minimized code

trait Foo[F <: Foo[F]]
class Bar extends Foo[Bar]

object Q {
  opaque type X <: Foo[X] = Bar
}

Crash output (click arrow to expand)

-- Error: test.scala:5:19 ------------------------------------------------------
5 |  opaque type X <: Foo[X] = Bar
  |                   ^^^^^^^^^^^^
  |                   type Bar outside bounds  <: Foo[Q.X]
exception occurred while typechecking test.scala
exception occurred while compiling test.scala
java.lang.AssertionError: assertion failed while compiling test.scala
Exception in thread "main" java.lang.AssertionError: assertion failed
	at dotty.DottyPredef$.assertFail(DottyPredef.scala:16)
	at dotty.tools.dotc.core.Types$LazyRef.update(Types.scala:2598)
	at dotty.tools.dotc.core.SymDenotations$SymDenotation.recur$3(SymDenotations.scala:445)
	at dotty.tools.dotc.core.SymDenotations$SymDenotation.setAlias$1(SymDenotations.scala:448)
	at dotty.tools.dotc.core.SymDenotations$SymDenotation.opaqueToBounds(SymDenotations.scala:462)
	at dotty.tools.dotc.typer.Namer$TypeDefCompleter.typeSig(Namer.scala:1006)
	at dotty.tools.dotc.typer.Namer$Completer.completeInCreationContext(Namer.scala:932)
	at dotty.tools.dotc.typer.Namer$Completer.complete(Namer.scala:840)
	at dotty.tools.dotc.core.SymDenotations$SymDenotation.completeFrom(SymDenotations.scala:260)
	at dotty.tools.dotc.core.Denotations$Denotation.completeInfo$1(Denotations.scala:185)
	at dotty.tools.dotc.core.Denotations$Denotation.info(Denotations.scala:187)
	at dotty.tools.dotc.core.Denotations$SingleDenotation.computeAsSeenFrom(Denotations.scala:1169)
	at dotty.tools.dotc.core.Denotations$SingleDenotation.computeAsSeenFrom(Denotations.scala:1141)
	at dotty.tools.dotc.core.Denotations$PreDenotation.asSeenFrom(Denotations.scala:132)
	at dotty.tools.dotc.core.SymDenotations$ClassDenotation.findMember(SymDenotations.scala:1851)
	at dotty.tools.dotc.core.Types$Type.go$1(Types.scala:580)
	at dotty.tools.dotc.core.Types$Type.findMember(Types.scala:741)
	at dotty.tools.dotc.core.Types$Type.memberBasedOnFlags(Types.scala:563)
	at dotty.tools.dotc.core.Types$Type.member(Types.scala:547)
	at dotty.tools.dotc.typer.Typer.memberInSelfButNotThis$2(Typer.scala:1794)
	at dotty.tools.dotc.typer.Typer.classExistsOnSelf$4$$anonfun$3(Typer.scala:1796)
	at dotty.tools.dotc.typer.Typer.classExistsOnSelf$5$$anonfun$adapted$1(Typer.scala:1801)
	at scala.collection.IterableOnceOps.foldLeft(IterableOnce.scala:636)
	at scala.collection.IterableOnceOps.foldLeft$(IterableOnce.scala:632)
	at scala.collection.AbstractIterator.foldLeft(Iterator.scala:1274)
	at dotty.tools.dotc.typer.Typer.classExistsOnSelf$1(Typer.scala:1801)
	at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:1812)
	at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2141)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2208)
	at dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2247)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2256)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2259)
	at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2281)
	at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:2325)
	at dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:1944)
	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2182)
	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2209)
	at dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2247)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2256)
	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:2259)
	at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:2367)
	at dotty.tools.dotc.typer.FrontEnd.liftedTree1$2(FrontEnd.scala:78)
	at dotty.tools.dotc.typer.FrontEnd.typeCheck$$anonfun$1(FrontEnd.scala:83)
	at dotty.runtime.function.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
	at dotty.tools.dotc.typer.FrontEnd.monitor(FrontEnd.scala:42)
	at dotty.tools.dotc.typer.FrontEnd.typeCheck(FrontEnd.scala:84)
	at dotty.tools.dotc.typer.FrontEnd.runOn$$anonfun$3(FrontEnd.scala:114)
	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:15)
	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:10)
	at scala.collection.immutable.List.foreach(List.scala:305)
	at dotty.tools.dotc.typer.FrontEnd.runOn(FrontEnd.scala:114)
	at dotty.tools.dotc.Run.runPhases$4$$anonfun$4(Run.scala:167)
	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:15)
	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:10)
	at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
	at dotty.tools.dotc.Run.runPhases$5(Run.scala:177)
	at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:185)
	at dotty.runtime.function.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
	at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:64)
	at dotty.tools.dotc.Run.compileUnits(Run.scala:192)
	at dotty.tools.dotc.Run.compileSources(Run.scala:129)
	at dotty.tools.dotc.Run.compile(Run.scala:112)
	at dotty.tools.dotc.Driver.doCompile(Driver.scala:36)
	at dotty.tools.dotc.Driver.process(Driver.scala:189)
	at dotty.tools.dotc.Driver.process(Driver.scala:158)
	at dotty.tools.dotc.Driver.process(Driver.scala:170)
	at dotty.tools.dotc.Driver.main(Driver.scala:197)
	at dotty.tools.dotc.Main.main(Main.scala)

Besides the crash, I think it should be possible to define this type without errors, given that X =:= Bar and Bar <: Foo[Bar].

Also consider the following which already (or still?) works:

scala> trait Foo[F <: Foo[F]] { this: F => def self: F = this }
// defined trait Foo

scala> class Bar extends Foo[Bar]
// defined class Bar

scala> trait Q { type X <: Foo[X]; def mkX(b: Bar): X }
// defined trait Q

scala> val XMaker: Q = new Q { type X  = Bar; def mkX(b: Bar) = b }
val XMaker: Q = anon$1@67671db1

scala> val x = XMaker.mkX(new Bar)
val x: XMaker.X = Bar@8e77c5b

scala> x.self                                                                   
val res2: LazyRef(XMaker.X) = Bar@8e77c5b

And also notice the strange LazyRef(XMaker.X) type.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions