-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add regression test #18300
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
Add regression test #18300
Conversation
It seems that type parameter inference #18169 could help reduce some of the syntactic overhead in some of the examples. |
This add a prototype implementation for providing precise types without the overhead of quote pattern matching.
29f87fc
to
4743d9c
Compare
type X <: T | ||
val exprX = expr.asInstanceOf[Expr[X]] | ||
val tpeX = expr.asTerm.tpe.asType.asInstanceOf[Type[X]] | ||
body[X](using tpeX)(exprX) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not pass T
to body and avoid the casts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to be able to refine the type of T
to the precise type of the expression. For example if T is of type Any but the expression is of type Int, we can use that type in the generated code in a type safe way. Note that the cast would only be required in the stdlib method that provides this functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but body is not inlined so I don't understand how this would change anything to the code we generate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is about the code generated inbody
. For example
def foo[T: Type](expr: Expr[T])(using Quotes) = '{ val y: T = $x }
def bar[T: Type](expr: Expr[T])(using Quotes) =
exprWithPreciseType(a) { [X] => _ ?=> x =>
'{ val y: X = $x }
}
val a: Expr[Int] = '{ 1 }
foo(a) // generates '{ val y: Int = 1 }
foo[Any](a) // generates '{ val y: Any = 1 } // boxing
foo(b) // generates '{ val y: Any = 1 } // boxing
val b: Expr[Any] = '{ 2 }
bar(a) // generates '{ val y: Int = 2 }
bar[Any](a) // generates '{ val y: Int = 2 }
bar(b) // generates '{ val y: Int = 2 }
Other uses involve getting the precise type to inspect it.
In general it is equivalent but will always be more efficient than
def baz[T: Type](expr: Expr[T])(using Quotes) =
expr match
case '{ $x: t } => '{ val y: t = $x }
Though the main use case will probably be when we get a term or type from reflection and want to recover/name its precise type.
....
exprWithPreciseType(term.asExpr/*: Expr[Any]*/) { [T] => _ ?=> x =>
'{ val y: T= $x; ... }
}
withType(tpe.asType/*: Type[? <: AnyKind]*/) { [T] => _ ?=>
someFunction[T]//(using Type.of[T])
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still confused, if I make the following change:
diff --git tests/pos-macros/quoted-with-precise-types.scala tests/pos-macros/quoted-with-precise-types.scala
index e9620810377..ddfc5dfefa7 100644
--- tests/pos-macros/quoted-with-precise-types.scala
+++ tests/pos-macros/quoted-with-precise-types.scala
@@ -20,10 +20,8 @@ def test1(t1: Type[?], t2: Type[? <: Any])(using Quotes) =
def exprWithPreciseType[T, U](expr: Expr[T])(body: [X <: T] => Type[X] ?=> Expr[X] => U)(using Quotes): U =
import quotes.reflect.*
- type X <: T
- val exprX = expr.asInstanceOf[Expr[X]]
- val tpeX = expr.asTerm.tpe.asType.asInstanceOf[Type[X]]
- body[X](using tpeX)(exprX)
+ val tpe = expr.asTerm.tpe.asType.asInstanceOf[Type[T]]
+ body[T](using tpe)(expr)
def test2(x: Expr[Any])(using Quotes) =
// exprWithPreciseType(x) { [T] => x => // Inference limitation: x is assumed to be the Type[T] instead of the Expr[T]
Then the test still compiles, will it generate different code?
This add a prototype implementation for providing precise types without the overhead of quote pattern matching.