@@ -27,17 +27,18 @@ object Matcher {
2727 *
2828 * @param scrutineeExpr `Expr[_]` on which we are pattern matching
2929 * @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)
3031 * @param reflection instance of the reflection API (implicitly provided by the macro)
3132 * @return None if it did not match, `Some(tup)` if it matched where `tup` contains `Expr[Ti]``
3233 */
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 ] = {
3435 // TODO improve performance
3536 import reflection .{Bind => BindPattern , _ }
3637 import Matching ._
3738
3839 type Env = Set [(Symbol , Symbol )]
3940
40- class SymBinding (val sym : Symbol )
41+ class SymBinding (val sym : Symbol , val fromBellow : Boolean )
4142
4243 inline def withEnv [T ](env : Env )(body : => given Env => T ): T = body given env
4344
@@ -140,7 +141,8 @@ object Matcher {
140141
141142 case (Block (stats1, expr1), Block (binding :: stats2, expr2)) if isTypeBinding(binding) =>
142143 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)
144146
145147 case (Block (stat1 :: stats1, expr1), Block (stat2 :: stats2, expr2)) =>
146148 withEnv(the[Env ] + (stat1.symbol -> stat2.symbol)) {
@@ -150,7 +152,8 @@ object Matcher {
150152 case (scrutinee, Block (typeBindings, expr2)) if typeBindings.forall(isTypeBinding) =>
151153 val bindingSymbols = typeBindings.map(_.symbol)
152154 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)
154157
155158 case (If (cond1, thenp1, elsep1), If (cond2, thenp2, elsep2)) =>
156159 cond1 =#= cond2 && thenp1 =#= thenp2 && elsep1 =#= elsep2
@@ -335,18 +338,24 @@ object Matcher {
335338
336339 implied for Env = Set .empty
337340
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
347356 }
348- res.asInstanceOf [Option [Tup ]]
349357 }
358+ res.asInstanceOf [Option [Tup ]]
350359 }
351360
352361 /** Result of matching a part of an expression */
0 commit comments