Skip to content

exception while typing def <init>(): Unit of class class dotty.tools.dotc.ast.Trees$DefDef # 1088 #8425

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

Closed
ohze opened this issue Mar 3, 2020 · 4 comments · Fixed by #8433

Comments

@ohze
Copy link

ohze commented Mar 3, 2020

minimized code

import java.io.{ OutputStream, PrintStream }

trait Test {
  new PrintStream(new OutputStream {
    def write(b: Int) = ???
  }) {
    override def println(x: Any) = ???
  }
}

Crash output (click arrow to expand)

compile
[info] Compiling 1 Scala source to /Users/thanhbv/ohze/dotty-example/target/scala-0.22/classes ...
exception while typing def <init>(): Unit of class class dotty.tools.dotc.ast.Trees$DefDef # 1088
exception while typing final class $anon() extends java.io.PrintStream($anon$superArg$1()) {
  override def println(x: Any): Unit = ???
  private def $outer: Test
  final def Test$_$$anon$$$outer: Test = $outer
} of class class dotty.tools.dotc.ast.Trees$TypeDef # 1397
exception while typing {
  final class $anon() extends java.io.PrintStream($anon$superArg$1()) {
    override def println(x: Any): Unit = ???
    private def $outer: Test
    final def Test$_$$anon$$$outer: Test = $outer
  }
  private def $anon$superArg$1(): java.io.OutputStream = 
    {
      final class $anon() extends java.io.OutputStream() {
        def write(b: Int): Unit = ???
      }
      new java.io.OutputStream {...}():java.io.OutputStream
    }
  new java.io.PrintStream {...}():java.io.PrintStream
} of class class dotty.tools.dotc.ast.Trees$Block # 1398
exception while typing @scala.annotation.internal.SourceFile(
  "/Users/thanhbv/ohze/dotty-example/src/main/scala/Test.scala"
) trait Test() extends Object {
  {
    final class $anon() extends java.io.PrintStream($anon$superArg$1()) {
      override def println(x: Any): Unit = ???
      private def $outer: Test
      final def Test$_$$anon$$$outer: Test = $outer
    }
    private def $anon$superArg$1(): java.io.OutputStream = 
      {
        final class $anon() extends java.io.OutputStream() {
          def write(b: Int): Unit = ???
        }
        new java.io.OutputStream {...}():java.io.OutputStream
      }
    new java.io.PrintStream {...}():java.io.PrintStream
  }
} of class class dotty.tools.dotc.ast.Trees$TypeDef # 1400
exception while typing package <empty> {
  @scala.annotation.internal.SourceFile(
    "/Users/thanhbv/ohze/dotty-example/src/main/scala/Test.scala"
  ) trait Test() extends Object {
    {
      final class $anon() extends java.io.PrintStream($anon$superArg$1()) {
        override def println(x: Any): Unit = ???
        private def $outer: Test
        final def Test$_$$anon$$$outer: Test = $outer
      }
      private def $anon$superArg$1(): java.io.OutputStream = 
        {
          final class $anon() extends java.io.OutputStream() {
            def write(b: Int): Unit = ???
          }
          new java.io.OutputStream {...}():java.io.OutputStream
        }
      new java.io.PrintStream {...}():java.io.PrintStream
    }
  }
} of class class dotty.tools.dotc.ast.Trees$PackageDef # 1401
[info] exception occurred while compiling /Users/thanhbv/ohze/dotty-example/src/main/scala/Test.scala
scala.MatchError: MethodType(List(), List(), TypeRef(NoPrefix,class $anon)) (of class dotty.tools.dotc.core.Types$CachedMethodType) while compiling /Users/thanhbv/ohze/dotty-example/src/main/scala/Test.scala
[error] ## Exception when compiling 1 sources to /Users/thanhbv/ohze/dotty-example/target/scala-0.22/classes
[error] scala.MatchError: MethodType(List(), List(), TypeRef(NoPrefix,class $anon)) (of class dotty.tools.dotc.core.Types$CachedMethodType)
[error] dotty.tools.dotc.transform.ExplicitOuter$OuterOps$.paramDefs$extension(ExplicitOuter.scala:413)
[error] dotty.tools.dotc.transform.Erasure$Typer.typedDefDef(Erasure.scala:615)
[error] dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2138)
[error] dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2208)
[error] dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:123)
[error] dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2247)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2256)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2259)
[error] dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:1801)
[error] dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2141)
[error] dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2208)
[error] dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:123)
[error] dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2247)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2256)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2259)
[error] dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2281)
[error] dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:2325)
[error] dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:747)
[error] dotty.tools.dotc.typer.Typer.typedBlockStats(Typer.scala:796)
[error] dotty.tools.dotc.typer.Typer.typedBlock(Typer.scala:800)
[error] dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2159)
[error] dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2209)
[error] dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:123)
[error] dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2247)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2256)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2259)
[error] dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2303)
[error] dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:2325)
[error] dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:747)
[error] dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:1812)
[error] dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:2141)
[error] dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2208)
[error] dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:123)
[error] dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2247)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2256)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2259)
[error] dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:2281)
[error] dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:2325)
[error] dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:747)
[error] dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:1938)
[error] dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:2182)
[error] dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:2209)
[error] dotty.tools.dotc.typer.ReTyper.typedUnadapted(ReTyper.scala:123)
[error] dotty.tools.dotc.typer.Typer.op$1(Typer.scala:2247)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2256)
[error] dotty.tools.dotc.typer.Typer.typed(Typer.scala:2259)
[error] dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:2367)
[error] dotty.tools.dotc.transform.Erasure.run(Erasure.scala:100)
[error] dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:315)
[error] scala.collection.immutable.List.map(List.scala:219)
[error] dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:316)
[error] dotty.tools.dotc.Run.runPhases$4$$anonfun$4(Run.scala:167)
[error] dotty.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] dotty.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
[error] dotty.tools.dotc.Run.runPhases$5(Run.scala:177)
[error] dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:185)
[error] dotty.runtime.function.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
[error] dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:64)
[error] dotty.tools.dotc.Run.compileUnits(Run.scala:192)
[error] dotty.tools.dotc.Run.compileSources(Run.scala:129)
[error] dotty.tools.dotc.Run.compile(Run.scala:112)
[error] dotty.tools.dotc.Driver.doCompile(Driver.scala:36)
[error] dotty.tools.dotc.Driver.process(Driver.scala:189)
[error] dotty.tools.dotc.Main.process(Main.scala)
[error] xsbt.CachedCompilerImpl.run(CachedCompilerImpl.java:69)
[error] xsbt.CompilerInterface.run(CompilerInterface.java:41)
[error] sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error] sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[error] sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error] java.lang.reflect.Method.invoke(Method.java:498)
[error] sbt.internal.inc.AnalyzingCompiler.call(AnalyzingCompiler.scala:248)
[error] sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:122)
[error] sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:95)
[error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4(MixedAnalyzingCompiler.scala:91)
[error] scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
[error] sbt.internal.inc.MixedAnalyzingCompiler.timed(MixedAnalyzingCompiler.scala:186)
[error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$3(MixedAnalyzingCompiler.scala:82)
[error] sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$3$adapted(MixedAnalyzingCompiler.scala:77)
[error] sbt.internal.inc.JarUtils$.withPreviousJar(JarUtils.scala:215)
[error] sbt.internal.inc.MixedAnalyzingCompiler.compileScala$1(MixedAnalyzingCompiler.scala:77)
[error] sbt.internal.inc.MixedAnalyzingCompiler.compile(MixedAnalyzingCompiler.scala:146)
[error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1(IncrementalCompilerImpl.scala:343)
[error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1$adapted(IncrementalCompilerImpl.scala:343)
[error] sbt.internal.inc.Incremental$.doCompile(Incremental.scala:120)
[error] sbt.internal.inc.Incremental$.$anonfun$compile$4(Incremental.scala:100)
[error] sbt.internal.inc.IncrementalCommon.recompileClasses(IncrementalCommon.scala:180)
[error] sbt.internal.inc.IncrementalCommon.cycle(IncrementalCommon.scala:98)
[error] sbt.internal.inc.Incremental$.$anonfun$compile$3(Incremental.scala:102)
[error] sbt.internal.inc.Incremental$.manageClassfiles(Incremental.scala:155)
[error] sbt.internal.inc.Incremental$.compile(Incremental.scala:92)
[error] sbt.internal.inc.IncrementalCompile$.apply(Compile.scala:75)
[error] sbt.internal.inc.IncrementalCompilerImpl.compileInternal(IncrementalCompilerImpl.scala:348)
[error] sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileIncrementally$1(IncrementalCompilerImpl.scala:301)
[error] sbt.internal.inc.IncrementalCompilerImpl.handleCompilationError(IncrementalCompilerImpl.scala:168)
[error] sbt.internal.inc.IncrementalCompilerImpl.compileIncrementally(IncrementalCompilerImpl.scala:248)
[error] sbt.internal.inc.IncrementalCompilerImpl.compile(IncrementalCompilerImpl.scala:74)
[error] sbt.Defaults$.compileIncrementalTaskImpl(Defaults.scala:1762)
[error] sbt.Defaults$.$anonfun$compileIncrementalTask$1(Defaults.scala:1735)
[error] scala.Function1.$anonfun$compose$1(Function1.scala:49)
[error] sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62)
[error] sbt.std.Transform$$anon$4.work(Transform.scala:67)
[error] sbt.Execute.$anonfun$submit$2(Execute.scala:281)
[error] sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:19)
[error] sbt.Execute.work(Execute.scala:290)
[error] sbt.Execute.$anonfun$submit$1(Execute.scala:281)
[error] sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:178)
[error] sbt.CompletionService$$anon$2.call(CompletionService.scala:37)
[error] java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error] java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[error] java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error] java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[error] java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[error] java.lang.Thread.run(Thread.java:748)
[error]            
[error] stack trace is suppressed; run last Compile / compileIncremental for the full output
[error] (Compile / compileIncremental) scala.MatchError: MethodType(List(), List(), TypeRef(NoPrefix,class $anon)) (of class dotty.tools.dotc.core.Types$CachedMethodType)
[error] Total time: 3 s, completed Mar 3, 2020 7:03:23 PM
[IJ]sbt:dotty-example> 
@smarter

This comment has been minimized.

@smarter

This comment has been minimized.

@smarter
Copy link
Member

smarter commented Mar 3, 2020

This is a problem with the interaction between ExplicitOuter, Erasure and time-travelling:

  1. In RefChecks#hasJavaErasedOverriding, we run some code with ctx.atPhase(ctx.erasurePhase.next)
  2. This triggers the completion of the denotation transformer for the anonymous class new PrintStream(...), which runs this code: https://github.com/lampepfl/dotty/blob/aea5f3cc5230adabf11ff902e95df2c2035b0bb4/compiler/src/dotty/tools/dotc/core/TypeErasure.scala#L198
  3. OuterOps#addParam in turn relies on ExplicitOuter.hasOuterParam, which lists a very relevant pre-condition: https://github.com/lampepfl/dotty/blob/aea5f3cc5230adabf11ff902e95df2c2035b0bb4/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala#L242-L244
    This is only going to return the correct result after the ExplicitOuter tree transformer has been run (because that's when outer accessors are actually created), but recall that we're inside RefChecks currently, which happens before ExplicitOuter!
  4. The end result is that the denotaiton at phase Erasure we create for the anonymous class constructor is incorrect: it's missing the outer parameter, and this leads to a crash later on.

There's no easy fix here. The only thing I can imagine is that we could disallow forward time-travelling from a phase before ExplicitOuter to a phase at or after Erasure. I think that would only impact the RefEchsk#hasJavaErasedOverriding check which would need to be done later somehow. /cc @odersky

odersky added a commit to dotty-staging/dotty that referenced this issue Mar 4, 2020
@odersky
Copy link
Contributor

odersky commented Mar 4, 2020

I don't have a fix that could solve all possible races between explicit outer and erasure. But I do have two fixes for this particular problem:

  • we can compensate for missing outer parameters in erasure
  • we can call hasJavaErasedOverriding a lot less often than we do now

Each of these two fixes the problem at hand. #8433 implements both of them.

odersky added a commit to dotty-staging/dotty that referenced this issue Mar 6, 2020
smarter added a commit that referenced this issue Mar 6, 2020
Fix #8425: Avoid race between erasure and explicit outer
giabao added a commit to ohze/akka that referenced this issue Mar 21, 2020
giabao added a commit to ohze/akka that referenced this issue Mar 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants