@@ -27,17 +27,18 @@ object Matcher {
27
27
*
28
28
* @param scrutineeExpr `Expr[_]` on which we are pattern matching
29
29
* @param patternExpr `Expr[_]` containing the pattern tree
30
+ * @param hasTypeSplices `Boolean` notify if the pattern has type splices (if so we use a GADT context)
30
31
* @param reflection instance of the reflection API (implicitly provided by the macro)
31
32
* @return None if it did not match, `Some(tup)` if it matched where `tup` contains `Expr[Ti]``
32
33
*/
33
- def unapply [TypeBindings <: Tuple , Tup <: Tuple ](scrutineeExpr : Expr [_])(implicit patternExpr : Expr [_], reflection : Reflection ): Option [Tup ] = {
34
+ def unapply [TypeBindings <: Tuple , Tup <: Tuple ](scrutineeExpr : Expr [_])(implicit patternExpr : Expr [_], hasTypeSplices : Boolean , reflection : Reflection ): Option [Tup ] = {
34
35
// TODO improve performance
35
36
import reflection .{Bind => BindPattern , _ }
36
37
import Matching ._
37
38
38
39
type Env = Set [(Symbol , Symbol )]
39
40
40
- class SymBinding (val sym : Symbol )
41
+ class SymBinding (val sym : Symbol , val fromBellow : Boolean )
41
42
42
43
inline def withEnv [T ](env : Env )(body : => given Env => T ): T = body given env
43
44
@@ -140,7 +141,8 @@ object Matcher {
140
141
141
142
case (Block (stats1, expr1), Block (binding :: stats2, expr2)) if isTypeBinding(binding) =>
142
143
reflection.kernel.Context_GADT_addToConstraint (the[Context ])(binding.symbol :: Nil )
143
- matched(new SymBinding (binding.symbol)) && Block (stats1, expr1) =#= Block (stats2, expr2)
144
+ val fromBellow = true // TODO
145
+ matched(new SymBinding (binding.symbol, fromBellow)) && Block (stats1, expr1) =#= Block (stats2, expr2)
144
146
145
147
case (Block (stat1 :: stats1, expr1), Block (stat2 :: stats2, expr2)) =>
146
148
withEnv(the[Env ] + (stat1.symbol -> stat2.symbol)) {
@@ -150,7 +152,8 @@ object Matcher {
150
152
case (scrutinee, Block (typeBindings, expr2)) if typeBindings.forall(isTypeBinding) =>
151
153
val bindingSymbols = typeBindings.map(_.symbol)
152
154
reflection.kernel.Context_GADT_addToConstraint (the[Context ])(bindingSymbols)
153
- bindingSymbols.foldRight(scrutinee =#= expr2)((x, acc) => matched(new SymBinding (x)) && acc)
155
+ val fromBellow = true // TODO
156
+ bindingSymbols.foldRight(scrutinee =#= expr2)((x, acc) => matched(new SymBinding (x, fromBellow)) && acc)
154
157
155
158
case (If (cond1, thenp1, elsep1), If (cond2, thenp2, elsep2)) =>
156
159
cond1 =#= cond2 && thenp1 =#= thenp2 && elsep1 =#= elsep2
@@ -335,18 +338,24 @@ object Matcher {
335
338
336
339
implied for Env = Set .empty
337
340
338
- {
339
- // TODO only set GADT context when needed
340
- implicit val ctx2 = reflection.kernel.Context_GADT_setFreshGADTBounds (rootContext)
341
- val matchings = scrutineeExpr.unseal.underlyingArgument =#= patternExpr.unseal.underlyingArgument
342
- val res = matchings.asOptionOfTuple.map { tup =>
343
- Tuple .fromArray(tup.toArray.map { // TODO improve code
344
- case x : SymBinding => reflection.kernel.Context_GADT_approximation (ctx2)(x.sym, true ).seal
345
- case x => x
346
- })
341
+ val res = {
342
+ if (hasTypeSplices) {
343
+ implied for Context = reflection.kernel.Context_GADT_setFreshGADTBounds (rootContext)
344
+ val matchings = scrutineeExpr.unseal.underlyingArgument =#= patternExpr.unseal.underlyingArgument
345
+ // After matching and doing all subtype check, we have to aproximate all the type bindings
346
+ // that we have found and seal them in a quoted.Type
347
+ matchings.asOptionOfTuple.map { tup =>
348
+ Tuple .fromArray(tup.toArray.map { // TODO improve performace
349
+ case x : SymBinding => kernel.Context_GADT_approximation (the[Context ])(x.sym, x.fromBellow).seal
350
+ case x => x
351
+ })
352
+ }
353
+ }
354
+ else {
355
+ scrutineeExpr.unseal.underlyingArgument =#= patternExpr.unseal.underlyingArgument
347
356
}
348
- res.asInstanceOf [Option [Tup ]]
349
357
}
358
+ res.asInstanceOf [Option [Tup ]]
350
359
}
351
360
352
361
/** Result of matching a part of an expression */
0 commit comments