@@ -33,7 +33,7 @@ object Matcher {
3333 def unapply [TypeBindings <: Tuple , Tup <: Tuple ](scrutineeExpr : Expr [_])(implicit patternExpr : Expr [_],
3434 hasTypeSplices : Boolean , qctx : QuoteContext ): Option [Tup ] = {
3535 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 ]]
3737 }
3838
3939 private class QuoteMatcher [QCtx <: QuoteContext & Singleton ] given (val qctx : QCtx ) {
@@ -48,7 +48,7 @@ object Matcher {
4848
4949 class SymBinding (val sym : Symbol )
5050
51- def matches (scrutineeTerm : Term , patternTerm : Term , hasTypeSplices : Boolean ): Option [Tuple ] = {
51+ def termMatch (scrutineeTerm : Term , patternTerm : Term , hasTypeSplices : Boolean ): Option [Tuple ] = {
5252 implicit val env : Env = Set .empty
5353 if (hasTypeSplices) {
5454 implicit val ctx : Context = internal.Context_GADT_setFreshGADTBounds (rootContext)
@@ -67,6 +67,26 @@ object Matcher {
6767 }
6868 }
6969
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+
7090 private def hasBindTypeAnnotation (tpt : TypeTree ): Boolean = tpt match {
7191 case Annotated (tpt2, annot) => isBindAnnotation(annot) || hasBindTypeAnnotation(tpt2)
7292 case _ => false
0 commit comments