-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Cannot Refer to Path Dependent Type inside of type-quote #8887
Comments
FYI, I was using this functionality to implement Quill's |
How would this work? Maybe the macro API could provide a |
@deusaquilus could you provide a small self contained example that show from where you get the context in those cases? |
@nicolasstucki The attached code sums it up. I have removed everything extraneous. The idea is:
trait Context {
type RowType
implicit def stringDecoder: Decoder[RowType, String]
def serve[T](decoder: Decoder[RowType, T]): T
}
val tpe = '[Decoder[$context.RowType, T]]
val decoderExpr =
Expr.summon(using tpe) match {
case Some(decoder) => decoder
case None => qctx.throwError(s"Cannot find decoder for: ${tpe.show}")
}
'{ $context.serve[T]($decoderExpr) } That's basically it! |
@deusaquilus it looks like this can be encoded as import scala.quoted._
import scala.quoted.matching._
trait Decoder[RowType, T] {
def decode(row:RowType): T
}
trait Context {
type RowType
implicit def stringDecoder: Decoder[RowType, String]
def serve[T](decoder: Decoder[RowType, T]): T
}
object Macro {
inline def serveDecoder[T](context: Context): T = ${ serveDecoderImpl('context) }
def serveDecoderImpl[T: Type, U: Type, C <: Context { type RowType = U }: Type](context: Expr[C])(using qctx: QuoteContext): Expr[T] = {
import qctx.tasty._
val tpe = '[Decoder[U, T]]
val decoderExpr =
Expr.summon(using tpe) match {
case Some(decoder) => decoder
case None => qctx.throwError(s"Cannot find decoder for: ${tpe.show}")
}
'{ $context.serve[T]($decoderExpr) }
}
} I have not tried to expand the macro. |
@nicolasstucki I'll give that a try. My context (in the real Quill) itself has parameters. Should I encode that like this? def serveDecoderImpl[T: Type, U: Type, CN <: Naming, C <: Context[CN] { type RowType = U }: Type](context: Expr[C])(using qctx: QuoteContext): Expr[T] Or like this? def serveDecoderImpl[T: Type, U: Type, CN <: Naming, C <: Context[_] { type RowType = U }: Type](context: Expr[C[CN]])(using qctx: QuoteContext): Expr[T] |
The first one looks better |
Edit: Removing my previous comments as they were incorrect. @nicolasstucki Okay, so your example above does not actually work because you need the type T in order to know type of [error] 20 | println( serveDecoder[String](ctx) )
[error] | ^^^^^^^^^^^^^^^^^^^^^^^^^
[error] | Cannot find decoder for: bug.Decoder[ctx.RowType, scala.Nothing]
[error] | This location contains code that was inlined from Test.scala:20 You can have a look at that here: |
However, if I add a parameter to specify T as a specific type (e.g. via inline def serveDecoder[T](context: Context, cls: Class[T]): T = ${ serveDecoderImpl('context, 'cls) }
def serveDecoderImpl[T: Type, U: Type, C <: Context { type RowType = U }: Type](context: Expr[C], cls: Expr[Class[T]])(using qctx: QuoteContext): Expr[T] = { You can see it in this branch: |
If I want to manually type the inline inline def serveDecoder[T](context: Context): T = ${ serveDecoderImpl[T, context.RowType, Context]('context) } ... and I get: [error] -- [E057] Type Mismatch Error: /home/alexander/git/dotty/pdt_typesummon/src/main/scala/bug/Macro.scala:18:92
[error] 18 | inline def serveDecoder[T](context: Context): T = ${ serveDecoderImpl[T, context.RowType, Context]('context) }
[error] | ^
[error] |Type argument bug.Context does not conform to upper bound bug.Context{RowType = context.RowType} I tried adding inline def serveDecoder[T](context: Context): T = ${ serveDecoderImpl[T, context.RowType, Context { type RowType = context.RowType }]('context) } ... but then this error happens:
Code here: |
That seems to be another bug. I will investigate it. The context type parameter should probably be |
Just tried that. That causes this error: [error] 21 | inline def serveDecoder[T](context: Context): T = ${ serveDecoderImpl[T, context.RowType, context.type]('context) }
[error] | ^^^^^^^
[error] | access to value context from wrong staging level:
[error] | - the definition is at level 0,
[error] | - but the access is at level -1. Just checked that into the following branch: |
That should be allowed. |
Minimized to import scala.quoted._
inline def foo(x: Any): Any = ${ expr[x.type] }
def expr[X](using Quotes): Expr[Any] = ???
|
Minimized code
Let's say we want to create a class with a PDT for example:
Then inside of a macro, I want to be able to use this PDT (i.e.
RowType
) inside of a type-quoteI would want to do this for many reasons... for example to summon an object with it:
Only it doesn't work...
Output
The compiler fails with the following error:
Expectation
The code should compile and run properly. Statements like
'[$foo.Bar]
should be possible.Code
A full code sample of this issue and a minimized version of my use-case is available here:
https://github.com/deusaquilus/pdt_typesummon
The text was updated successfully, but these errors were encountered: