You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[experimental feature] Support HOAS pattern with type variables for quote pattern matching (#18271)
This PR extends higher-order patterns inside quote patterns to allow
type parameters. When this PR is merged, we'll be able to write quote
patterns like the following example with an experimental flag
`experimental.quotedPatternsWithPolymorphicFunctions`.
```scala
def decomposePoly(x: Expr[Any])(using Quotes): Expr[Int] =
x match
case '{ [A] => (x: List[A]) => $y[A](x) : Int } =>
'{ $y[Int](List(1, 2, 3)) }
case _ => Expr(0)
```
You can see that the higher-order pattern `$y[A](x)` carries an type
parameter `A`. It states that this pattern matches a code fragment with
occurrences of `A`, and `y` is assigned a polymorphic function type `[A]
=> List[A] => x`.
This PR mainly changes two parts: type checker and quote pattern
matcher. Those changes are based on the formalized type system defined
in [Nicolas Stucki's thesis](https://github.com/nicolasstucki#thesis),
and one can expect the soundness of the implementation.
## Type Dependency
If a higher-order pattern carries a value parameter with a type that has
type parameters defined in the quoted pattern, those type parameters
should also be captured in the higher-order pattern. For example, the
following pattern will not be typed.
```
case '{ [A] => (x: List[A]) => $y(x) : Int } =>
```
In this case, `x` has the type `List[A]`, which includes a type variable
`A` that is defined in the pattern. However, the higher-order pattern
`$y(x)` does not have any type parameters. This should be ill-typed. One
can always avoid this kind of type errors by adding type parameters,
like `$y[A](x)`
## Implementation Restriction
Current implementation only allows type parameters that do not have
bounds, because sound typing rules for such pattern is not clear yet.
```scala
case '{ [A] => (x: List[A]) => $y(x) : Int } => // Allowed
case '{ [A <: Int] => (x: List[A]) => $y(x) : Int } => // Disallowed
Copy file name to clipboardExpand all lines: compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
+1-2
Original file line number
Diff line number
Diff line change
@@ -1668,8 +1668,7 @@ class TreeUnpickler(reader: TastyReader,
1668
1668
valpat= readTree()
1669
1669
valpatType= readType()
1670
1670
val (targs, args) = until(end)(readTree()).span(_.isType)
1671
-
assert(targs.isEmpty, "unexpected type arguments in SPLICEPATTERN") // `targs` will be needed for #18271. Until this fearure is added they should be empty.
0 commit comments