-
Notifications
You must be signed in to change notification settings - Fork 1.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
NamedTuples: Error compiling macro that selects an argument #22863
Comments
I think the arguments need to be inline as well |
Tried it, same error message, see below: //> using scala 3.7.0-RC1
//> using jvm temurin:23
import scala.quoted.*
import scala.deriving.*
object MacroNamedTuple:
inline def tupleStringArg[T](inline t: T, inline arg: String) = ${tupleArg('t,'arg)}
def tupleArg[T](t: Expr[T], arg: Expr[String])(using Quotes) =
import quotes.reflect.*
val sel = Select.unique(t.asTerm, arg.valueOrAbort)
sel.asExprOf[String] //> using scala 3.7.0-RC1
//> using jvm temurin:23
object Example:
def main(args:Array[String]): Unit =
val t = (name = "abc", v = 123)
val str = MacroNamedTuple.tupleStringArg(t, "name")
println(str)
|
Normally,
My nitpick is that there are a dozen |
The same behaviour can be observed with the named tuples import |
if you expect this to work, (and not require manually resolving to //> using scala 3.7.0-RC1
//> using jvm temurin:23
class Record extends Selectable:
def selectDynamic(s: String): Any = ???
object Example:
def main(args:Array[String]): Unit =
val t: Record { val name: String }
val str = MacroNamedTuple.tupleStringArg(t, "name")
println(str) does this work? i would assume the same behavior accross all fake selections. so therefore extensions and implicit conversions should also resolve. My thought was that Select.unique was a low level operation that requires a real member to exist there is |
I had also tried |
Following @som-snytt advice I compiled using -Vprint:all options. These are my findings: The line: val str = MacroNamedTuple.tupleStringArg(t, "name") Is correctly expanded to: val str: String = t.name:String But it's done in the latest compilation stage, when the compiler doesn't know anything about tuple names. The compiler desugars val n: String = NamedTuple.apply[(("name" : String), ("v" : String)), (String, Int)](t)(0) To find a solution I replicated something similar using Macros. This works: //> using scala 3.7.0-RC1
//> using jvm temurin:23
import scala.quoted.*
import scala.deriving.*
object Helper:
def valueAt[V](t: Tuple, pos:Int): V = t(pos).asInstanceOf[V]
object MacroNamedTuple:
inline def tupleAnyArg[T](inline t: T, inline arg: String) = ${tupleArg('t,'arg)}
def tupleArg[T: Type](t: Expr[T], arg: Expr[String])(using Quotes) =
import quotes.reflect.*
val tt = TypeRepr.of[T]
val tp = Typed(t.asTerm, TypeTree.of[Tuple])
val names = tt.typeArgs(0).typeArgs.map{case c:ConstantType => c.constant.value.toString}
val pos = names.indexOf(arg.valueOrAbort)
val tpa = tt.typeArgs(1).typeArgs(pos).asType
val app = tpa match
case '[t] =>
'{
Helper.valueAt[t](${tp.asExprOf[Tuple]}, ${Expr(pos)})
}
app //> using scala 3.7.0-RC1
//> using jvm temurin:23
object Example:
def main(args:Array[String]): Unit =
val t = (name = "abc", v = 123)
val n1 = MacroNamedTuple.tupleAnyArg(t, "v")
println(n1)
val n2 = MacroNamedTuple.tupleAnyArg(t, "name")
println(n2)
Not sure if this is the desired behavior dealing with NamedTuples in macros, if that's the case please close this issue. |
Compiler version
3.7.0-RC1
Minimized code
MacroNamedTuple.scala
Example.scala
Output
Running with:
Expectation
Should print "abc"
Changing Example to regular tuples works fine:
The text was updated successfully, but these errors were encountered: