Skip to content

Match error in backend using Java defined annotation with default parameters #2704

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
olafurpg opened this issue Jun 7, 2017 · 12 comments
Closed

Comments

@olafurpg
Copy link
Contributor

olafurpg commented Jun 7, 2017

While trying to compile the compiler-benchmark with Dotty I hit on a match error in the backend

[error] Error while emitting ColdDotcBenchmark.scala
[error] Block(List(ValDef(warmups$1,TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,scala)),Nothing)],Select(Ident(Fork),$lessinit$greater$default$2)), ValDef(jvm$1,TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,scala)),Nothing)],Select(Ident(Fork),$lessinit$greater$default$3)), ValDef(jvmArgs$1,TypeTree[RefinedType(TypeRef(ThisType(TypeRef(NoPrefix,scala)),Array), scala$Array$$T, TypeAlias(TypeRef(ThisType(TypeRef(NoPrefix,lang)),String), 0))],Apply(Apply(TypeApply(Select(Ident(Array),apply),List(TypeTree[TypeVar(ParamRef(scala$Array$apply$$T) -> TypeRef(ThisType(TypeRef(NoPrefix,lang)),String))])),List(SeqLiteral(List(Literal(Constant(-XX:CICompilerCount=2))),TypeTree[TypeVar(ParamRef(scala$Array$apply$$T) -> TypeRef(ThisType(TypeRef(NoPrefix,lang)),String))]))),List(Apply(TypeApply(Select(Ident(ClassTag),apply),List(TypeTree[TypeVar(ParamRef(scala$Array$apply$$T) -> TypeRef(ThisType(TypeRef(NoPrefix,lang)),String))])),List(Literal(Constant(TypeRef(ThisType(TypeRef(NoPrefix,lang)),String)))))))), ValDef(jvmArgsPrepend$1,TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,scala)),Nothing)],Select(Ident(Fork),$lessinit$greater$default$5))),Apply(Select(New(TypeTree[TypeRef(TermRef(TermRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix,<root>)),org)/withSig(Signature(List(),)),openjdk)/withSig(Signature(List(),)),jmh)/withSig(Signature(List(),)),annotations)/withSig(Signature(List(),)),Fork)]),<init>),List(Literal(Constant(16)), Select(This(Ident(ColdDotcBenchmark)),warmups$1), Select(This(Ident(ColdDotcBenchmark)),jvm$1), Select(This(Ident(ColdDotcBenchmark)),jvmArgs$1), Select(This(Ident(ColdDotcBenchmark)),jvmArgsPrepend$1), Select(Ident(Fork),$lessinit$greater$default$6)))) (of class dotty.tools.dotc.ast.Trees$Block)
scala.MatchError: Block(List(ValDef(warmups$3,TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,scala)),Nothing)],Select(Ident(Fork),$lessinit$greater$default$2)), ValDef(jvm$3,TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,scala)),Nothing)],Select(Ident(Fork),$lessinit$greater$default$3)), ValDef(jvmArgs$3,TypeTree[RefinedType(TypeRef(ThisType(TypeRef(NoPrefix,scala)),Array), scala$Array$$T, TypeAlias(TypeRef(ThisType(TypeRef(NoPrefix,lang)),String), 0))],Apply(Apply(TypeApply(Select(Ident(Array),apply),List(TypeTree[TypeVar(ParamRef(scala$Array$apply$$T) -> TypeRef(ThisType(TypeRef(NoPrefix,lang)),String))])),List(SeqLiteral(List(Literal(Constant(-XX:CICompilerCount=2))),TypeTree[TypeVar(ParamRef(scala$Array$apply$$T) -> TypeRef(ThisType(TypeRef(NoPrefix,lang)),String))]))),List(Apply(TypeApply(Select(Ident(ClassTag),apply),List(TypeTree[TypeVar(ParamRef(scala$Array$apply$$T) -> TypeRef(ThisType(TypeRef(NoPrefix,lang)),String))])),List(Literal(Constant(TypeRef(ThisType(TypeRef(NoPrefix,lang)),String)))))))), ValDef(jvmArgsPrepend$3,TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,scala)),Nothing)],Select(Ident(Fork),$lessinit$greater$default$5))),Apply(Select(New(TypeTree[TypeRef(TermRef(TermRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix,<root>)),org)/withSig(Signature(List(),)),openjdk)/withSig(Signature(List(),)),jmh)/withSig(Signature(List(),)),annotations)/withSig(Signature(List(),)),Fork)]),<init>),List(Literal(Constant(16)), Select(This(Ident(ColdScalacBenchmark)),warmups$3), Select(This(Ident(ColdScalacBenchmark)),jvm$3), Select(This(Ident(ColdScalacBenchmark)),jvmArgs$3), Select(This(Ident(ColdScalacBenchmark)),jvmArgsPrepend$3), Select(Ident(Fork),$lessinit$greater$default$6)))) (of class dotty.tools.dotc.ast.Trees$Block)
    at dotty.tools.backend.jvm.DottyBackendInterface.assocsFromApply(DottyBackendInterface.scala:530)
    at dotty.tools.backend.jvm.DottyBackendInterface$$anon$10.assocs(DottyBackendInterface.scala:521)
    at dotty.tools.backend.jvm.DottyBackendInterface.emitAnnotations$$anonfun$6(DottyBackendInterface.scala:306)

With -Xprint:all

[info] result of /Users/ollie/dev/compiler-benchmark/compilation/src/main/scala/dotty/tools/dotc/ColdDotcBenchmark.scala after genBCode:
[info]
[info] package dotty.tools.dotc {
[info]   @scala.annotation.internal.SourceFile(
[info]     "/Users/ollie/dev/compiler-benchmark/compilation/src/main/scala/dotty/tools/dotc/ColdDotcBenchmark.scala"
[info]   ) @{
[info]     <accessor> val warmups$1: Nothing =
[info]       org.openjdk.jmh.annotations.Fork.$lessinit$greater$default$2
[info]     <accessor> val jvm$1: Nothing =
[info]       org.openjdk.jmh.annotations.Fork.$lessinit$greater$default$3
[info]     <accessor> val jvmArgs$1: Array{scala$Array$$T = String} =
[info]       Array.apply[String^](["-XX:CICompilerCount=2" : String^])(
[info]         scala.reflect.ClassTag.apply[String^](classOf[class String])
[info]       )
[info]     <accessor> val jvmArgsPrepend$1: Nothing =
[info]       org.openjdk.jmh.annotations.Fork.$lessinit$greater$default$5
[info]     new org.openjdk.jmh.annotations.Fork(16,
[info]       dotty.tools.dotc.ColdDotcBenchmark.this.warmups$1
[info]     , dotty.tools.dotc.ColdDotcBenchmark.this.jvm$1,
[info]       dotty.tools.dotc.ColdDotcBenchmark.this.jvmArgs$1
[info]     , dotty.tools.dotc.ColdDotcBenchmark.this.jvmArgsPrepend$1,
[info]       org.openjdk.jmh.annotations.Fork.$lessinit$greater$default$6
[info]     )
[info]   } @org.openjdk.jmh.annotations.OutputTimeUnit(MILLISECONDS) @
[info]     org.openjdk.jmh.annotations.BenchmarkMode
[info]   (
[info]     Array.apply[org.openjdk.jmh.annotations.Mode^](
[info]       [SingleShotTime : org.openjdk.jmh.annotations.Mode^]
[info]     )(
[info]       scala.reflect.ClassTag.apply[org.openjdk.jmh.annotations.Mode^](
[info]         classOf[class Mode]
[info]       )
[info]     )
[info]   ) @org.openjdk.jmh.annotations.State(Benchmark) class ColdDotcBenchmark
[info]      extends
[info]    base.BaseDotcBenchmark {
[info]     def <init>(): Unit =
[info]       {
[info]         super()
[info]         ()
[info]       }
[info]     @org.openjdk.jmh.annotations.Benchmark() override def compile(): Unit =
[info]       super.compile()
[info]   }
[info] }
[info]

The source file where the error happens ColdDotcBenchmark.scala: https://github.com/lampepfl/compiler-benchmark/blob/82392bc30df11946cb489d45afc2698e3b48bced/compilation/src/main/scala/dotty/tools/dotc/ColdDotcBenchmark.scala#L10-L18

The @Fork annotations is defined in Java from the JMH project, https://github.com/jacek-lewandowski/jmh-jl/blob/fc92780b525f6376b2433518b3dc90a5f511feef/jmh-core/src/main/java/org/openjdk/jmh/annotations/Fork.java#L44

I made several attempts to minimize the error with Fork.java and a tiny Foo.scala but didn't manage to reproduce. To reproduce in the environment I hit the error:

@olafurpg
Copy link
Contributor Author

I managed to minimize the error into something that scalac compiles OK but dotc reports an error

// bench.scala
package foo

@Fork(value = 16)
class Bar

// fork.java
package foo;

public @interface Fork {
    int value() default -1;
    int warmups() default -1;
}

Running dotc bench.scala fork.java reports

-- Error: bench.scala:3:0 ------------------------------------------------------
3 |@Fork(value = 16)
  |^^^^^^^^^^^^^^^^
  |missing argument for parameter warmups of constructor Fork: (value: Int, warmups: Int)foo.Fork

one error found

I didn't manage to minimize a repro for the match error, but this might be a good start.

@DarkDimius
Copy link
Contributor

@olafurpg, thanks for a nice minimization, but is this the same error?
It looks like in your minimization doesn't crash the compiler, but instead reports an error.

@olafurpg
Copy link
Contributor Author

Correct, that minimization does not crash the compiler. I can open another issue if that makes more sense.

olafurpg added a commit to olafurpg/compiler-benchmark that referenced this issue Jun 14, 2017
Note, the benchmarks currently don't actually run with Dotty because of
scala/scala3#2704.

- scalac and dotc driver separated in src/main/{scalac,dotc}.
- unit tests for rapic local iteration without the need to remember cli args.
- `fork in run` is necessary for -usejavacp to work with compilation/run
- `FileVisitOption.FOLLOW_LINKS` produces duplicate filenames, which
  causes "X is already compiled in this run" errors in Dotty.
olafurpg added a commit to olafurpg/compiler-benchmark that referenced this issue Jun 14, 2017
Note, the benchmarks currently don't actually run with Dotty because of
scala/scala3#2704.

- scalac and dotc driver separated in src/main/{scalac,dotc}.
- unit tests for rapic local iteration without the need to remember cli args.
- `fork in run` is necessary for -usejavacp to work with compilation/run
- `FileVisitOption.FOLLOW_LINKS` produces duplicate filenames, which
  causes "X is already compiled in this run" errors in Dotty.
olafurpg added a commit to olafurpg/compiler-benchmark that referenced this issue Jun 14, 2017
Note, the benchmarks currently don't actually run with Dotty because of
scala/scala3#2704.

- scalac and dotc driver separated in src/main/{scalac,dotc}.
- unit tests for rapic local iteration without the need to remember cli args.
- `fork in run` is necessary for -usejavacp to work with compilation/run
- `FileVisitOption.FOLLOW_LINKS` produces duplicate filenames, which
  causes "X is already compiled in this run" errors in Dotty.
olafurpg added a commit to olafurpg/compiler-benchmark that referenced this issue Jun 14, 2017
Note, the benchmarks currently don't actually run with Dotty because of
scala/scala3#2704.

- scalac and dotc driver separated in src/main/{scalac,dotc}.
- unit tests for rapic local iteration without the need to remember cli args.
- `fork in run` is necessary for -usejavacp to work with compilation/run
- `FileVisitOption.FOLLOW_LINKS` produces duplicate filenames, which
  causes "X is already compiled in this run" errors in Dotty.
olafurpg added a commit to olafurpg/compiler-benchmark that referenced this issue Jun 14, 2017
Note, the benchmarks currently don't actually run with Dotty because of
scala/scala3#2704.

- When `scalaVersion := "0.x"`, then "src/main/dotc" is  added to
  unmanagedSourceDirectories, otherwise "src/main/scalac" is added.
- compilation/test checks the setup is OK without the need to remember cli args.
- `fork in run` is necessary for -usejavacp to work with compilation/run
- `FileVisitOption.FOLLOW_LINKS` produces duplicate filenames, which
  causes "X is already compiled in this run" errors in Dotty.
@olafurpg
Copy link
Contributor Author

The PR to compile scala/compiler-benchmark with Dotty, scala/compiler-benchmark#31, is currently blocked by this issue (MatchError).

@DarkDimius I opened #2760 for the "missing argument" error.

@DarkDimius
Copy link
Contributor

@olafurpg, I'll prepare a fix to unblock you.

@olafurpg
Copy link
Contributor Author

Thanks @DarkDimius To reproduce the MatchError, you can clone this branch https://github.com/olafurpg/compiler-benchmark/tree/dotty2 (commit c30610306e9bc7b5ed0609f0f24ca1054a48d26f) and run

> ++0.2.0-bin-20170614-8ddfcaf-NIGHTLY
> compilation/test
...
[error] Error while emitting ScalacBenchmark.scala
[error] Block(List(ValDef(warmups$3,TypeTree[TypeRef(ThisType(TypeRef(NoPrefix,scala)),Nothing)]

DarkDimius added a commit to dotty-staging/dotty that referenced this issue Jun 15, 2017
This is not a proper fix, it just fixes the crash.
We need to figure out why this happens and handle it correctly.
DarkDimius added a commit to dotty-staging/dotty that referenced this issue Jun 15, 2017
DarkDimius added a commit to dotty-staging/dotty that referenced this issue Jun 16, 2017
OlivierBlanvillain added a commit to dotty-staging/dotty that referenced this issue Jun 22, 2017
I guess this is what you went in your previous commit?
DarkDimius added a commit that referenced this issue Jun 23, 2017
@smarter
Copy link
Member

smarter commented Jun 23, 2017

@DarkDimius Is the issue really closed or should it stay open?

@olafurpg
Copy link
Contributor Author

@smarter I tested the fix locally and was no longer able to reproduce the match error, #2762 (comment)

@DarkDimius
Copy link
Contributor

@smarter I've added logic to backed that tries to figure out what happened to a tree inside an annotation(made it more robust). I didn't investigate who restructured the tree in the first place.
It would be nice to make whoever restructured annotations not do it anymore.

@smarter
Copy link
Member

smarter commented Jun 23, 2017

Ok, so let's keep this open until we've done that

@smarter smarter reopened this Jun 23, 2017
olafurpg added a commit to olafurpg/compiler-benchmark that referenced this issue Jul 12, 2017
Note, the benchmarks currently don't actually run with Dotty because of
scala/scala3#2704.

- When `scalaVersion := "0.x"`, then "src/main/dotc" is  added to
  unmanagedSourceDirectories, otherwise "src/main/scalac" is added.
- compilation/test checks the setup is OK without the need to remember cli args.
- `fork in run` is necessary for -usejavacp to work with compilation/run
- `FileVisitOption.FOLLOW_LINKS` produces duplicate filenames, which
  causes "X is already compiled in this run" errors in Dotty.
@olafurpg
Copy link
Contributor Author

Fixed in #2819 ?

@smarter
Copy link
Member

smarter commented Jul 12, 2017

Yes

@smarter smarter closed this as completed Jul 12, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants