@@ -45,7 +45,7 @@ object Matcher {
4545 }
4646
4747 /** Check that all trees match with =#= and concatenate the results with && */
48- def (scrutinees : List [Tree ]) =##= (patterns : List [Tree ]) given Env : Matching =
48+ def (scrutinees : List [Tree ]) =##= (patterns : List [Tree ]) given Context , Env : Matching =
4949 matchLists(scrutinees, patterns)(_ =#= _)
5050
5151 /** Check that the trees match and return the contents from the pattern holes.
@@ -56,7 +56,17 @@ object Matcher {
5656 * @param `the[Env]` Set of tuples containing pairs of symbols (s, p) where s defines a symbol in `scrutinee` which corresponds to symbol p in `pattern`.
5757 * @return `None` if it did not match or `Some(tup: Tuple)` if it matched where `tup` contains the contents of the holes.
5858 */
59- def (scrutinee : Tree ) =#= (pattern : Tree ) given Env : Matching = {
59+ def (scrutinee0 : Tree ) =#= (pattern0 : Tree ) given Context , Env : Matching = {
60+
61+ /** Normalieze the tree */
62+ def normalize (tree : Tree ): Tree = tree match {
63+ case Block (Nil , expr) => normalize(expr)
64+ case Inlined (_, Nil , expr) => normalize(expr)
65+ case _ => tree
66+ }
67+
68+ val scrutinee = normalize(scrutinee0)
69+ val pattern = normalize(pattern0)
6070
6171 /** Check that both are `val` or both are `lazy val` or both are `var` **/
6272 def checkValFlags (): Boolean = {
@@ -78,14 +88,7 @@ object Matcher {
7888 def hasBindAnnotation (sym : Symbol ) =
7989 sym.annots.exists { case Apply (Select (New (TypeIdent (" patternBindHole" ))," <init>" ),List ()) => true ; case _ => true }
8090
81- /** Normalieze the tree */
82- def normalize (tree : Tree ): Tree = tree match {
83- case Block (Nil , expr) => normalize(expr)
84- case Inlined (_, Nil , expr) => normalize(expr)
85- case _ => tree
86- }
87-
88- (normalize(scrutinee), normalize(pattern)) match {
91+ (scrutinee, pattern) match {
8992
9093 // Match a scala.internal.Quoted.patternHole typed as a repeated argument and return the scrutinee tree
9194 case (IsTerm (scrutinee @ Typed (s, tpt1)), Typed (TypeApply (patternHole, tpt :: Nil ), tpt2))
@@ -110,6 +113,9 @@ object Matcher {
110113 case (Typed (expr1, tpt1), Typed (expr2, tpt2)) =>
111114 expr1 =#= expr2 && tpt1 =#= tpt2
112115
116+ case (scrutinee, Typed (expr2, _)) =>
117+ scrutinee =#= expr2
118+
113119 case (Ident (_), Ident (_)) if scrutinee.symbol == pattern.symbol || the[Env ].apply((scrutinee.symbol, pattern.symbol)) =>
114120 matched
115121
@@ -142,9 +148,6 @@ object Matcher {
142148 case (While (cond1, body1), While (cond2, body2)) =>
143149 cond1 =#= cond2 && body1 =#= body2
144150
145- case (NamedArg (name1, expr1), NamedArg (name2, expr2)) if name1 == name2 =>
146- expr1 =#= expr2
147-
148151 case (New (tpt1), New (tpt2)) =>
149152 tpt1 =#= tpt2
150153
@@ -157,10 +160,11 @@ object Matcher {
157160 case (Repeated (elems1, _), Repeated (elems2, _)) if elems1.size == elems2.size =>
158161 elems1 =##= elems2
159162
163+ // TODO is this case required
160164 case (IsTypeTree (scrutinee @ TypeIdent (_)), IsTypeTree (pattern @ TypeIdent (_))) if scrutinee.symbol == pattern.symbol =>
161165 matched
162166
163- case (IsInferred (scrutinee), IsInferred (pattern)) if scrutinee.tpe <:< pattern.tpe =>
167+ case (IsTypeTree (scrutinee), IsTypeTree (pattern)) if scrutinee.tpe <:< pattern.tpe =>
164168 matched
165169
166170 case (Applied (tycon1, args1), Applied (tycon2, args2)) =>
@@ -171,7 +175,7 @@ object Matcher {
171175 if (hasBindAnnotation(pattern.symbol) || hasBindTypeAnnotation(tpt2)) bindingMatch(scrutinee.symbol)
172176 else matched
173177 def rhsEnv = the[Env ] + (scrutinee.symbol -> pattern.symbol)
174- bindMatch && tpt1 =#= tpt2 && (treeOptMatches(rhs1, rhs2) given rhsEnv )
178+ bindMatch && tpt1 =#= tpt2 && (treeOptMatches(rhs1, rhs2) given (the[ Context ], rhsEnv) )
175179
176180 case (DefDef (_, typeParams1, paramss1, tpt1, Some (rhs1)), DefDef (_, typeParams2, paramss2, tpt2, Some (rhs2))) =>
177181 val bindMatch =
@@ -227,15 +231,15 @@ object Matcher {
227231 }
228232 }
229233
230- def treeOptMatches (scrutinee : Option [Tree ], pattern : Option [Tree ]) given Env : Matching = {
234+ def treeOptMatches (scrutinee : Option [Tree ], pattern : Option [Tree ]) given Context , Env : Matching = {
231235 (scrutinee, pattern) match {
232236 case (Some (x), Some (y)) => x =#= y
233237 case (None , None ) => matched
234238 case _ => notMatched
235239 }
236240 }
237241
238- def caseMatches (scrutinee : CaseDef , pattern : CaseDef ) given Env : Matching = {
242+ def caseMatches (scrutinee : CaseDef , pattern : CaseDef ) given Context , Env : Matching = {
239243 val (caseEnv, patternMatch) = scrutinee.pattern =%= pattern.pattern
240244 withEnv(caseEnv) {
241245 patternMatch &&
@@ -254,7 +258,7 @@ object Matcher {
254258 * @return The new environment containing the bindings defined in this pattern tuppled with
255259 * `None` if it did not match or `Some(tup: Tuple)` if it matched where `tup` contains the contents of the holes.
256260 */
257- def (scrutinee : Pattern ) =%= (pattern : Pattern ) given Env : (Env , Matching ) = (scrutinee, pattern) match {
261+ def (scrutinee : Pattern ) =%= (pattern : Pattern ) given Context , Env : (Env , Matching ) = (scrutinee, pattern) match {
258262 case (Pattern .Value (v1), Pattern .Unapply (TypeApply (Select (patternHole @ Ident (" patternHole" ), " unapply" ), List (tpt)), Nil , Nil ))
259263 if patternHole.symbol.owner.fullName == " scala.runtime.quoted.Matcher$" =>
260264 (the[Env ], matched(v1.seal))
@@ -264,7 +268,7 @@ object Matcher {
264268
265269 case (Pattern .Bind (name1, body1), Pattern .Bind (name2, body2)) =>
266270 val bindEnv = the[Env ] + (scrutinee.symbol -> pattern.symbol)
267- (body1 =%= body2) given bindEnv
271+ (body1 =%= body2) given (the[ Context ], bindEnv)
268272
269273 case (Pattern .Unapply (fun1, implicits1, patterns1), Pattern .Unapply (fun2, implicits2, patterns2)) =>
270274 val (patEnv, patternsMatch) = foldPatterns(patterns1, patterns2)
@@ -300,16 +304,33 @@ object Matcher {
300304 (the[Env ], notMatched)
301305 }
302306
303- def foldPatterns (patterns1 : List [Pattern ], patterns2 : List [Pattern ]) given Env : (Env , Matching ) = {
307+ def foldPatterns (patterns1 : List [Pattern ], patterns2 : List [Pattern ]) given Context , Env : (Env , Matching ) = {
304308 if (patterns1.size != patterns2.size) (the[Env ], notMatched)
305309 else patterns1.zip(patterns2).foldLeft((the[Env ], matched)) { (acc, x) =>
306- val (env, res) = (x._1 =%= x._2) given acc ._1
310+ val (env, res) = (x._1 =%= x._2) given (the[ Context ], acc._1)
307311 (env, acc._2 && res)
308312 }
309313 }
310314
315+ def isTypeBinding (tree : Tree ): Boolean = tree match {
316+ case IsTypeDef (tree) =>
317+ tree.symbol.annots.exists(_.symbol.owner.fullName == " scala.internal.Quoted$.patternType" )
318+ case _ => false
319+ }
320+
311321 implicit val env : Env = Set .empty
312- (scrutineeExpr.unseal =#= patternExpr.unseal).asOptionOfTuple.asInstanceOf [Option [Tup ]]
322+ val res = patternExpr.unseal.underlyingArgument match {
323+ case Block (typeBindings, pattern) if typeBindings.forall(isTypeBinding) =>
324+ implicit val ctx2 = reflection.kernel.Context_GADT_setFreshGADTBounds (rootContext)
325+ val bindingSymbols = typeBindings.map(_.symbol(ctx2))
326+ reflection.kernel.Context_GADT_addToConstraint (ctx2)(bindingSymbols)
327+ val matchings = scrutineeExpr.unseal.underlyingArgument =#= pattern
328+ val constainedTypes = bindingSymbols.map(s => reflection.kernel.Context_GADT_approximation (ctx2)(s, true ))
329+ constainedTypes.foldRight(matchings)((x, acc) => matched(x.seal) && acc)
330+ case pattern =>
331+ scrutineeExpr.unseal.underlyingArgument =#= pattern
332+ }
333+ res.asOptionOfTuple.asInstanceOf [Option [Tup ]]
313334 }
314335
315336 /** Result of matching a part of an expression */
0 commit comments