-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Type the quoted patterns as precisely as possible
In a pattern match where the contents of the quote are statically known we want to propagate the type inside the pattern the the binding. For example `e` will not only be an `Expr[T]` but also an `Expr[Some[Int]]`. ```scala (s: Expr[T]) match { case e @ '{ Some($x: Int) } => // e: Expr[T & Some[Int]] // x: Expr[Int] } ``` If the expression in the pattern contains a spliced expression, possibly typed, we also need to propagate the type of the scrutinee down into the pattern. For example `x` will not only be an `Expr[Boolean]` but also an `Expr[T]`. ```scala (s: Expr[T]) match { case e @ '{ $x: Boolean } => // e: Expr[T & Boolean] // x: Expr[T & Boolean] } ```
- Loading branch information
1 parent
0e5e541
commit 1a1e8f6
Showing
7 changed files
with
138 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import scala.quoted._ | ||
import scala.tasty.Reflection | ||
|
||
object Lib { | ||
|
||
def impl[T: Type](arg: Expr[T])(implicit refl: Reflection): Expr[T] = { | ||
arg match { | ||
case e @ '{ $x: Boolean } => | ||
e: Expr[T & Boolean] | ||
x: Expr[T & Boolean] | ||
e | ||
|
||
case e @ '{ println("hello"); $x } => | ||
e: Expr[T] | ||
x: Expr[T] | ||
e | ||
|
||
case e @ '{ println("hello"); $x: T } => | ||
e: Expr[T] | ||
x: Expr[T] | ||
e | ||
|
||
case e @ '{ Some($x: Int) } => | ||
e: Expr[T & Some[Int]] | ||
x: Expr[Int] | ||
e | ||
|
||
case e @ '{ if ($x) ($y: Boolean) else ($z: Int) } => | ||
e: Expr[T & (Boolean | Int)] | ||
y: Expr[T & Boolean] | ||
z: Expr[T & Int] | ||
e | ||
|
||
case e @ '{ if ($x) $y else $z } => | ||
e: Expr[T] | ||
y: Expr[T] | ||
z: Expr[T] | ||
e | ||
|
||
case e @ '{ if ($x) $y else ($z: Int) } => | ||
e: Expr[T & (T | Int)] | ||
y: Expr[T] | ||
z: Expr[T & Int] | ||
e | ||
|
||
case e @ '{ ($x: Boolean) match { case _ => $y: Int } } => | ||
e: Expr[T & Int] | ||
y: Expr[T & Int] | ||
e | ||
|
||
case e @ '{ ($x: Boolean) match { case _ => $y } } => | ||
e: Expr[T] | ||
y: Expr[T] | ||
e | ||
|
||
case e @ '{ try ($x: Boolean) catch { case _ => $y: Int } } => | ||
e: Expr[T & (Boolean | Int)] | ||
x: Expr[T & Boolean] | ||
y: Expr[T & Int] | ||
e | ||
|
||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Boolean: true | ||
Int: 4 | ||
Printed hello and returned world | ||
Printed world and returned hello | ||
Some: 5 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import scala.quoted._ | ||
import scala.tasty.Reflection | ||
|
||
object Lib { | ||
|
||
inline def foo[T](arg: => T): T = ${ impl('arg) } | ||
|
||
private def impl[T: Type](arg: Expr[T])(implicit refl: Reflection): Expr[T] = { | ||
arg match { | ||
case e @ '{ $x: Boolean } => '{ println("Boolean: " + $e); $e } | ||
case e @ '{ $x: Int } => '{ println("Int: " + $x); $x } | ||
case '{ println("hello"); $arg } => '{ println("Printed hello and returned " + $arg); $arg } | ||
case '{ println("world"); $arg: T } => '{ println("Printed world and returned " + $arg); $arg } | ||
case e @ '{ Some($x: Int) } => '{ println("Some: " + $x); $e } | ||
case arg => '{ ??? } | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
object Test { | ||
import Lib._ | ||
|
||
def main(args: Array[String]): Unit = { | ||
foo(true) | ||
foo(4) | ||
foo { println("hello"); "world" } | ||
foo { println("world"); "hello" } | ||
foo(Some(5)) | ||
} | ||
} |