Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler crash when trying to use object with self reference in multi stage compilation #16437

Closed
WojciechMazur opened this issue Nov 29, 2022 · 2 comments · Fixed by #16441
Closed
Assignees
Labels
area:desugar Desugaring happens after parsing but before typing, see desugar.scala good first issue Perfect for someone who wants to get started contributing itype:bug itype:crash
Milestone

Comments

@WojciechMazur
Copy link
Contributor

WojciechMazur commented Nov 29, 2022

Self types in objects are prohibited in Scala 3 so probably this is an unhandled corner case. Adding type annotation results in compilation error

Compiler version

3.2.1
3.3.0-RC1-bin-20221128-8fba321-NIGHTLY

Minimized code

// definition_1.scala
class OU {
  def dn: String = ""
}

class Inventory() {
  object NODES extends OU { nodes =>
    val x = nodes.dn
  }
}
// usage_2.scala
@main def Test =
  new Inventory().NODES.dn

Output (click arrow to expand)

exception while typing new Inventory().NODES.dn of class class dotty.tools.dotc.ast.Trees$Select # -1
exception while typing @main def Test: String = new Inventory().NODES.dn of class class dotty.tools.dotc.ast.Trees$DefDef # -1
exception while typing @SourceFile("tests/run/custom-sandbox/usage_2.scala") final module class usage_2$package() extends Object() {
  private def writeReplace(): AnyRef = new scala.runtime.ModuleSerializationProxy(classOf[usage_2$package.type])
  @main def Test: String = new Inventory().NODES.dn
} of class class dotty.tools.dotc.ast.Trees$TypeDef # -1
exception while typing package <empty> {
  final lazy module val usage_2$package: usage_2$package = new usage_2$package()
  @SourceFile("tests/run/custom-sandbox/usage_2.scala") final module class usage_2$package() extends Object() {
    private def writeReplace(): AnyRef = new scala.runtime.ModuleSerializationProxy(classOf[usage_2$package.type])
    @main def Test: String = new Inventory().NODES.dn
  }
  @SourceFile("tests/run/custom-sandbox/usage_2.scala") final class Test() extends Object() {
    <static> def main(args: Array[String]): Unit =
      try
        {
          Test
          ()
        }
       catch
        {
          case error @ _:scala.util.CommandLineParser.ParseError => scala.util.CommandLineParser.showError(error)
        }
  }
} of class class dotty.tools.dotc.ast.Trees$PackageDef # -1
scala.MatchError: ThisType(TypeRef(ThisType(TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <root>)),module class <empty>)),class Inventory)),module class NODES$)) (of class dotty.tools.dotc.core.Types$CachedThisType) while running erasure on tests/run/custom-sandbox/usage_2.scala
scala.MatchError: ThisType(TypeRef(ThisType(TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <root>)),module class <empty>)),class Inventory)),module class NODES$)) (of class dotty.tools.dotc.core.Types$CachedThisType) while compiling tests/run/custom-sandbox/usage_2.scala
Fatal compiler crash when compiling: tests/run/custom-sandbox:
ThisType(TypeRef(ThisType(TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <root>)),module class <empty>)),class Inventory)),module class NODES$)) (of class dotty.tools.dotc.core.Types$CachedThisType)
        at dotty.tools.dotc.core.SymDenotations$SymDenotation.sourceOfSelf$1(SymDenotations.scala:1055)
        at dotty.tools.dotc.core.SymDenotations$SymDenotation.sourceModule(SymDenotations.scala:1057)
        at dotty.tools.dotc.core.TypeErasure.dotty$tools$dotc$core$TypeErasure$$apply(TypeErasure.scala:680)
        at dotty.tools.dotc.core.TypeErasure.eraseInfo(TypeErasure.scala:745)
        at dotty.tools.dotc.core.TypeErasure$.transformInfo(TypeErasure.scala:244)
        at dotty.tools.dotc.transform.Erasure.transform(Erasure.scala:97)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.goForward$1(Denotations.scala:833)
        at dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:882)
        at dotty.tools.dotc.core.Symbols$Symbol.recomputeDenot(Symbols.scala:120)
        at dotty.tools.dotc.core.Symbols$Symbol.computeDenot(Symbols.scala:114)
        at dotty.tools.dotc.core.Symbols$Symbol.denot(Symbols.scala:107)
        at dotty.tools.dotc.core.Symbols$.toDenot(Symbols.scala:494)
        at dotty.tools.dotc.transform.TypeUtils$.isErasedClass(TypeUtils.scala:27)
        at dotty.tools.dotc.transform.Erasure$Typer.checkNotErasedClass(Erasure.scala:579)
        at dotty.tools.dotc.transform.Erasure$Typer.checkNotErasedClass(Erasure.scala:587)
        at dotty.tools.dotc.transform.Erasure$Typer.checkNotErased(Erasure.scala:572)
        at dotty.tools.dotc.transform.Erasure$Typer.typedSelect(Erasure.scala:789)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2869)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2962)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:126)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3030)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3034)
        at dotty.tools.dotc.transform.Erasure$Typer.typedSelect(Erasure.scala:667)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2869)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2962)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:126)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3030)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3034)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3150)
        at dotty.tools.dotc.typer.Typer.$anonfun$51(Typer.scala:2358)
        at dotty.tools.dotc.inlines.PrepareInlineable$.dropInlineIfError(PrepareInlineable.scala:249)
        at dotty.tools.dotc.typer.Typer.typedDefDef(Typer.scala:2358)
        at dotty.tools.dotc.transform.Erasure$Typer.typedDefDef(Erasure.scala:944)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2876)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2962)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:126)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3030)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3034)
        at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3056)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3106)
        at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1043)
        at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:2534)
        at dotty.tools.dotc.transform.Erasure$Typer.typedClassDef(Erasure.scala:1032)
        at dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$1(Typer.scala:2888)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2892)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2962)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:126)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3030)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3034)
        at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3056)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3106)
        at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1043)
        at dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:2664)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2933)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2963)
        at dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:126)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3030)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3034)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3150)
        at dotty.tools.dotc.transform.Erasure.run(Erasure.scala:144)
        at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:324)
        at scala.collection.immutable.List.map(List.scala:246)
        at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:328)
        at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:244)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
        at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
        at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1321)
        at dotty.tools.dotc.Run.runPhases$1(Run.scala:260)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:268)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:277)
        at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:68)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:277)
        at dotty.tools.dotc.Run.compileSources(Run.scala:195)
        at dotty.tools.dotc.Run.compile(Run.scala:179)
        at dotty.tools.dotc.Driver.doCompile(Driver.scala:35)
        at dotty.tools.dotc.Driver.process(Driver.scala:195)
        at dotty.tools.dotc.Driver.process(Driver.scala:163)
        at dotty.tools.vulpix.ParallelTesting$Test.compile(ParallelTesting.scala:533)
        at dotty.tools.vulpix.ParallelTesting$CompilationLogic.compileTestSource$$anonfun$1$$anonfun$1(ParallelTesting.scala:236)
        at scala.collection.immutable.List.map(List.scala:250)
        at dotty.tools.vulpix.ParallelTesting$CompilationLogic.compileTestSource$$anonfun$1(ParallelTesting.scala:238)
        at scala.util.Try$.apply(Try.scala:210)
        at dotty.tools.vulpix.ParallelTesting$CompilationLogic.dotty$tools$vulpix$ParallelTesting$CompilationLogic$$compileTestSource(ParallelTesting.scala:239)
        at dotty.tools.vulpix.ParallelTesting$$anon$4.checkTestSource$$anonfun$1(ParallelTesting.scala:285)
        at dotty.tools.vulpix.ParallelTesting$$anon$4.checkTestSource$$anonfun$adapted$1(ParallelTesting.scala:288)
        at scala.Function0.apply$mcV$sp(Function0.scala:42)
        at dotty.tools.vulpix.ParallelTesting$Test.tryCompile(ParallelTesting.scala:462)
        at dotty.tools.vulpix.ParallelTesting$$anon$4.checkTestSource(ParallelTesting.scala:288)
        at dotty.tools.vulpix.ParallelTesting$Test$LoggedRunnable.run(ParallelTesting.scala:358)
        at dotty.tools.vulpix.ParallelTesting$Test$LoggedRunnable.run$(ParallelTesting.scala:340)
        at dotty.tools.vulpix.ParallelTesting$$anon$4.run(ParallelTesting.scala:283)
        at java.base/java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1407)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)```

Adding type annotation would result in compilation error:

-- [E013] Syntax Error: /home/wmazur/projects/virtuslab/normation/rudder/webapp/sources/test.sc:15:28 --------------------------------------------------------------------------------------------------------------------------------------------------
15 |  object NODES extends OU { servers: OU =>
   |                            ^^^^^^^^^^^^^^
   |                            objects must not have a self type
@WojciechMazur WojciechMazur added itype:bug itype:crash stat:needs triage Every issue needs to have an "area" and "itype" label labels Nov 29, 2022
@Kordyjan Kordyjan added area:desugar Desugaring happens after parsing but before typing, see desugar.scala good first issue Perfect for someone who wants to get started contributing and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Nov 30, 2022
@Kordyjan
Copy link
Contributor

@dwijnand
Copy link
Member

dwijnand commented Nov 30, 2022

I'd say constraining an object's self type is prohibited. Every object, every class instance in general, has a self type, called this be default. So I wouldn't make that code not compile. I'd look to handling this in the match that blows up (in sourceOfSelf). case tp: ThisType => tp.cls I think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:desugar Desugaring happens after parsing but before typing, see desugar.scala good first issue Perfect for someone who wants to get started contributing itype:bug itype:crash
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants