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

[macwire 2.5.7][scala 3.1.2][jdk 17.0.3.1+2-LTS-6 (Hotspot)]: Compiler error when generating/compiling wire macro. #215

Open
ALPSMAC opened this issue Jun 10, 2022 · 4 comments

Comments

@ALPSMAC
Copy link

ALPSMAC commented Jun 10, 2022

I've been working on a new project in Scala 3 and trying the Scala 3 support in Macwire and ran into a blocker.

I have the following:

import com.softwaremill.macwire.*

trait ProductionServicesModule extends ServicesModule { self: ConfigModule with
  PoolsModule with
  DatabasesModule with
  CacheModule with
  DAOModule =>

  // Dependencies
  private lazy val theConfigProvider: ConfigProvider = self.configProvider
  private lazy val theForkJoin: ForkJoinThreadPool = self.forkJoin
  private lazy val theIO: IOThreadPool = self.io
  private lazy val theSystemProvider: ActorSystemProvider = self.systemProvider
  private lazy val theCassandraDatabase: CassandraDatabase = self.cassandra
  private lazy val theAsyncCache: AsyncCache = self.asyncCache
  private lazy val theAssocObsDAO: AssociatedObservationsDAO = self.associatedObservationsDAO
  private lazy val theHistoryDAO: HistoryDAO = self.historyDAO
  private lazy val theObsDAO: ObservationsDAO = self.observationsDAO
  private lazy val theObsTypesDAO: ObservationTypesDAO = self.observationTypesDAO

  // Wired Instances - TODO: Compiler bug - can't get macro working here:
  override lazy val observationsService: ObservationsService = wire[ProductionObservationsService]
  override lazy val observationTypesService: ObservationTypesService = wire[ObservationTypesService]

}

Where the ServicesModule looks like:

trait ServicesModule { self: ConfigModule with
  PoolsModule with
  DatabasesModule with
  CacheModule with
  DAOModule =>

  def observationsService: ObservationsService
  def observationTypesService: ObservationTypesService

}

and the other modules that are in scope from the self-typing look very similar (i.e. ConfigModule, PoolsModule, DatabasesModule, etc.).

Note how I've declared the required dependencies into local scope since macwire in Scala 3 can't yet look up dependencies in parent scope. This seemed to work well for the other modules on which ServicesModule depends, but not in ServicesModule itself evidently.

In ServicesModule, the call to wire breaks with a cryptic compiler bug:

[error] java.lang.AssertionError: assertion failed: 'new' call to non-constructor: $init$
[error] 	at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
[error] 	at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genApply(BCodeBodyBuilder.scala:725)
[error] 	at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoad(BCodeBodyBuilder.scala:361)
[error] 	at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoad(BCodeBodyBuilder.scala:436)
[error] 	at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.emitNormalMethodBody$1(BCodeSkelBuilder.scala:766)
[error] 	at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.genDefDef(BCodeSkelBuilder.scala:801)
[error] 	at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.gen(BCodeSkelBuilder.scala:607)
[error] 	at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.gen$$anonfun$1(BCodeSkelBuilder.scala:615)
[error] 	at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] 	at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] 	at scala.collection.immutable.List.foreach(List.scala:333)
[error] 	at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.gen(BCodeSkelBuilder.scala:615)
[error] 	at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.genPlainClass(BCodeSkelBuilder.scala:230)
[error] 	at dotty.tools.backend.jvm.GenBCodePipeline$Worker1.visit(GenBCode.scala:259)
[error] 	at dotty.tools.backend.jvm.GenBCodePipeline$Worker1.run(GenBCode.scala:224)
[error] 	at dotty.tools.backend.jvm.GenBCodePipeline.buildAndSendToDisk(GenBCode.scala:559)
[error] 	at dotty.tools.backend.jvm.GenBCodePipeline.run(GenBCode.scala:525)
[error] 	at dotty.tools.backend.jvm.GenBCode.run(GenBCode.scala:63)
[error] 	at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:308)
[error] 	at scala.collection.immutable.List.map(List.scala:246)
[error] 	at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:309)
[error] 	at dotty.tools.backend.jvm.GenBCode.runOn(GenBCode.scala:71)
[error] 	at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:259)
[error] 	at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] 	at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] 	at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1328)
[error] 	at dotty.tools.dotc.Run.runPhases$1(Run.scala:270)
[error] 	at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:278)
[error] 	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
[error] 	at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:68)
[error] 	at dotty.tools.dotc.Run.compileUnits(Run.scala:287)
[error] 	at dotty.tools.dotc.Run.compileSources(Run.scala:220)
[error] 	at dotty.tools.dotc.Run.compile(Run.scala:204)
[error] 	at dotty.tools.dotc.Driver.doCompile(Driver.scala:39)
[error] 	at dotty.tools.xsbt.CompilerBridgeDriver.run(CompilerBridgeDriver.java:88)
[error] 	at dotty.tools.xsbt.CompilerBridge.run(CompilerBridge.java:22)
[error] 	at sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:91)
[error] 	at sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$7(MixedAnalyzingCompiler.scala:192)
[error] 	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
[error] 	at sbt.internal.inc.MixedAnalyzingCompiler.timed(MixedAnalyzingCompiler.scala:247)
[error] 	at sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4(MixedAnalyzingCompiler.scala:182)
[error] 	at sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4$adapted(MixedAnalyzingCompiler.scala:163)
[error] 	at sbt.internal.inc.JarUtils$.withPreviousJar(JarUtils.scala:239)
[error] 	at sbt.internal.inc.MixedAnalyzingCompiler.compileScala$1(MixedAnalyzingCompiler.scala:163)
[error] 	at sbt.internal.inc.MixedAnalyzingCompiler.compile(MixedAnalyzingCompiler.scala:210)
[error] 	at sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1(IncrementalCompilerImpl.scala:528)
[error] 	at sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1$adapted(IncrementalCompilerImpl.scala:528)
[error] 	at sbt.internal.inc.Incremental$.$anonfun$apply$5(Incremental.scala:177)
[error] 	at sbt.internal.inc.Incremental$.$anonfun$apply$5$adapted(Incremental.scala:175)
[error] 	at sbt.internal.inc.Incremental$$anon$2.run(Incremental.scala:461)
[error] 	at sbt.internal.inc.IncrementalCommon$CycleState.next(IncrementalCommon.scala:116)
[error] 	at sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:56)
[error] 	at sbt.internal.inc.IncrementalCommon$$anon$1.next(IncrementalCommon.scala:52)
[error] 	at sbt.internal.inc.IncrementalCommon.cycle(IncrementalCommon.scala:263)
[error] 	at sbt.internal.inc.Incremental$.$anonfun$incrementalCompile$8(Incremental.scala:416)
[error] 	at sbt.internal.inc.Incremental$.withClassfileManager(Incremental.scala:503)
[error] 	at sbt.internal.inc.Incremental$.incrementalCompile(Incremental.scala:403)
[error] 	at sbt.internal.inc.Incremental$.apply(Incremental.scala:169)
[error] 	at sbt.internal.inc.IncrementalCompilerImpl.compileInternal(IncrementalCompilerImpl.scala:528)
[error] 	at sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileIncrementally$1(IncrementalCompilerImpl.scala:482)
[error] 	at sbt.internal.inc.IncrementalCompilerImpl.handleCompilationError(IncrementalCompilerImpl.scala:332)
[error] 	at sbt.internal.inc.IncrementalCompilerImpl.compileIncrementally(IncrementalCompilerImpl.scala:420)
[error] 	at sbt.internal.inc.IncrementalCompilerImpl.compile(IncrementalCompilerImpl.scala:137)
[error] 	at sbt.Defaults$.compileIncrementalTaskImpl(Defaults.scala:2366)
[error] 	at sbt.Defaults$.$anonfun$compileIncrementalTask$2(Defaults.scala:2316)
[error] 	at sbt.internal.server.BspCompileTask$.$anonfun$compute$1(BspCompileTask.scala:30)
[error] 	at sbt.internal.io.Retry$.apply(Retry.scala:46)
[error] 	at sbt.internal.io.Retry$.apply(Retry.scala:28)
[error] 	at sbt.internal.io.Retry$.apply(Retry.scala:23)
[error] 	at sbt.internal.server.BspCompileTask$.compute(BspCompileTask.scala:30)
[error] 	at sbt.Defaults$.$anonfun$compileIncrementalTask$1(Defaults.scala:2314)
[error] 	at scala.Function1.$anonfun$compose$1(Function1.scala:49)
[error] 	at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62)
[error] 	at sbt.std.Transform$$anon$4.work(Transform.scala:68)
[error] 	at sbt.Execute.$anonfun$submit$2(Execute.scala:282)
[error] 	at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:23)
[error] 	at sbt.Execute.work(Execute.scala:291)
[error] 	at sbt.Execute.$anonfun$submit$1(Execute.scala:282)
[error] 	at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265)
[error] 	at sbt.CompletionService$$anon$2.call(CompletionService.scala:64)
[error] 	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error] 	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
[error] 	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error] 	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
[error] 	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
[error] 	at java.base/java.lang.Thread.run(Thread.java:833)

Wasn't sure whether the best place to post this was here (since y'all are the experts on your macro generation) or the dotty github... but perhaps you can work with the dotty maintainers if you're able to reproduce - or perhaps you'll know what "-isms" to avoid to fix this error?

I tried making sure each class I was wiring had at least an empty constructor (i.e. class ABC() vs class ABC - although I'm not sure if at compile time the difference matters...) since 'new' call to non-constructor: $init$ kind-of sounds like maybe macwire called new on a companion object or something? No luck though... and that's about where I ran out of ideas.

Kind Regards,
Andy

@ALPSMAC
Copy link
Author

ALPSMAC commented Jun 10, 2022

Interestingly https://github.com/yakivy/jam yields the same compiler error...

@ALPSMAC
Copy link
Author

ALPSMAC commented Jun 10, 2022

🤦 figured it out...

 override lazy val observationTypesService: ObservationTypesService = wire[ObservationTypesService]

should have been:

 override lazy val observationTypesService: ObservationTypesService = wire[ProductionObservationTypesService]

Still - error message isn't particularly helpful today... not sure if it's easy or possible to provide a more meaningful error message.

@ALPSMAC ALPSMAC closed this as completed Jun 10, 2022
@adamw adamw reopened this Jun 15, 2022
@adamw
Copy link
Member

adamw commented Jun 15, 2022

Let's keep this open, the compiler error should definitely be better

@ALPSMAC
Copy link
Author

ALPSMAC commented Jun 16, 2022

I appreicate that... I lost more time than I care to admit to my missing the recursive reference.

Also - macwire has been my go-to for Scala DI frameworks that are easy to teach to developers familiar with Java but new to Scala. It's great work and I hope that it will be as easy to use in Scala 3 as it has been for us in Scala 2! 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants