@@ -33,7 +33,7 @@ object Matcher {
33
33
def unapply [TypeBindings <: Tuple , Tup <: Tuple ](scrutineeExpr : Expr [_])(implicit patternExpr : Expr [_],
34
34
hasTypeSplices : Boolean , qctx : QuoteContext ): Option [Tup ] = {
35
35
import qctx .tasty ._
36
- new QuoteMatcher [qctx.type ].matches (scrutineeExpr.unseal, patternExpr.unseal, hasTypeSplices).asInstanceOf [Option [Tup ]]
36
+ new QuoteMatcher [qctx.type ].termMatch (scrutineeExpr.unseal, patternExpr.unseal, hasTypeSplices).asInstanceOf [Option [Tup ]]
37
37
}
38
38
39
39
private class QuoteMatcher [QCtx <: QuoteContext & Singleton ] given (val qctx : QCtx ) {
@@ -48,7 +48,7 @@ object Matcher {
48
48
49
49
class SymBinding (val sym : Symbol )
50
50
51
- def matches (scrutineeTerm : Term , patternTerm : Term , hasTypeSplices : Boolean ): Option [Tuple ] = {
51
+ def termMatch (scrutineeTerm : Term , patternTerm : Term , hasTypeSplices : Boolean ): Option [Tuple ] = {
52
52
implicit val env : Env = Set .empty
53
53
if (hasTypeSplices) {
54
54
implicit val ctx : Context = internal.Context_GADT_setFreshGADTBounds (rootContext)
@@ -67,6 +67,26 @@ object Matcher {
67
67
}
68
68
}
69
69
70
+ // TODO factor out common logic with `termMatch`
71
+ def typeTreeMatch (scrutineeTypeTree : Term , patternTypeTree : Term , hasTypeSplices : Boolean ): Option [Tuple ] = {
72
+ implicit val env : Env = Set .empty
73
+ if (hasTypeSplices) {
74
+ implicit val ctx : Context = internal.Context_GADT_setFreshGADTBounds (rootContext)
75
+ val matchings = scrutineeTypeTree =#= patternTypeTree
76
+ // After matching and doing all subtype check, we have to aproximate all the type bindings
77
+ // that we have found and seal them in a quoted.Type
78
+ matchings.asOptionOfTuple.map { tup =>
79
+ Tuple .fromArray(tup.toArray.map { // TODO improve performace
80
+ case x : SymBinding => internal.Context_GADT_approximation (the[Context ])(x.sym, true ).seal
81
+ case x => x
82
+ })
83
+ }
84
+ }
85
+ else {
86
+ scrutineeTypeTree =#= patternTypeTree
87
+ }
88
+ }
89
+
70
90
private def hasBindTypeAnnotation (tpt : TypeTree ): Boolean = tpt match {
71
91
case Annotated (tpt2, annot) => isBindAnnotation(annot) || hasBindTypeAnnotation(tpt2)
72
92
case _ => false
0 commit comments