Open deusaquilus opened 1 year ago
Also, is it necessary to do import ctx._
for every method or should this also work?
class Repo[T]:
val ctx = new Context
import ctx._ // move to here
inline def summonEncoder = {
summonMyEncoder[T]
}
object Use:
val repo = new Repo[String]
val v = repo.summonEncoder
// [error] -- Error: /home/git/encoder-typing-reproduction/src/main/scala/org/deusaquilus/Use.scala:12:15
// [error] 12 | val v = repo.summonEncoder
// [error] | ^^^^^^^^^^^^^^^^^^
// [error] | can't do it
When I do this, no encoder is found and the report.throwError("can't do it")
happens.
One other thing, when I move the context variable to be passed in via a parameter it also throws an error.
class Repo[T]:
inline def summonEncoder(ctx: Context) = { // Pass it in as a parameter
import ctx._ // ... then import it!
summonMyEncoder[T]
}
object Use:
val repo = new Repo[String]
val v = repo.summonEncoder(new Context)
Then the following error happens:
java.lang.IllegalArgumentException: Could not find proxy for ctx: org.deusaquilus.Context in [parameter ctx, method summonEncoder, class Repo, package org.deusaquilus, package org, package <root>], encl = package org.deusaquilus, owners = package org.deusaquilus, package org, package <root>; enclosures = package org.deusaquilus, package org, package <root> while compiling /home/alexi/git/encoder-typing-reproduction/src/main/scala/org/deusaquilus/Use.scala
[error] ## Exception when compiling 3 sources to /home/git/encoder-typing-reproduction/target/scala-3.2.0/classes
[error] java.lang.IllegalArgumentException: Could not find proxy for ctx: org.deusaquilus.Context in [parameter ctx, method summonEncoder, class Repo, package org.deusaquilus, package org, package <root>], encl = package org.deusaquilus, owners = package org.deusaquilus, package org, package <root>; enclosures = package org.deusaquilus, package org, package <root>
[error] dotty.tools.dotc.transform.LambdaLift$Lifter.searchIn$1(LambdaLift.scala:135)
[error] dotty.tools.dotc.transform.LambdaLift$Lifter.proxy(LambdaLift.scala:148)
[error] dotty.tools.dotc.transform.LambdaLift$Lifter.proxyRef(LambdaLift.scala:166)
[error] dotty.tools.dotc.transform.LambdaLift$Lifter.addFreeArgs$$anonfun$1(LambdaLift.scala:172)
When inlining the repo.summonEncoder(new Context)
context we first expand to
{
import Repo_this.ctx.*
Repo_this.ctx.summonMyEncoder[String]
}
But when we expand summonMyEncoder[String]
we get this:
{
import Repo_this.ctx.*
Repo.this.ctx.encoderInstance.encode
}
It looks to me that the implicit search is made in the context of class Repo
, so we get a prefix Repo.this
. It should have been the proxy Repo_this
instead.
I noted the same problem happens when the inline methods are transparent
.
Compiler version
Error happens in 3.2.0 as well as latest nightly
3.2.2-RC1-bin-20221006-a6a3385-NIGHTLY
.Minimized code
Let's create a context object that has an encoder instance:
Then let's make the macro
SummonEncoder.impl
summon that instance:Then let's create a 'Repo' object that internally uses the context to summon an encoder for a particular type, ...and then use that summoning function.
Output
Long
exception while typing Repo.this...
error happens:Expectation
It should work and summon the encoder property.
Github Example:
You can find an example of the codebase here: https://github.com/deusaquilus/encoder-typing-reproduction The exact same problem happens if you change the encoder to a
given
and change the import toimport ctx.{given, _}
.Why this is Important
I would really like to use Scala 3 inline to be able to create DAO repository patterns. That would look something like this:
Only I can't do this because the above error will happen in my encoders and decoders.