@@ -47,7 +47,7 @@ object Matcher {
4747 }
4848
4949 /** Check that all trees match with =#= and concatenate the results with && */
50- def (scrutinees : List [Tree ]) =##= (patterns : List [Tree ]) given Env : Matching =
50+ def (scrutinees : List [Tree ]) =##= (patterns : List [Tree ]) given Context , Env : Matching =
5151 matchLists(scrutinees, patterns)(_ =#= _)
5252
5353 /** Check that the trees match and return the contents from the pattern holes.
@@ -58,7 +58,17 @@ object Matcher {
5858 * @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`.
5959 * @return `None` if it did not match or `Some(tup: Tuple)` if it matched where `tup` contains the contents of the holes.
6060 */
61- def (scrutinee : Tree ) =#= (pattern : Tree ) given Env : Matching = {
61+ def (scrutinee0 : Tree ) =#= (pattern0 : Tree ) given Context , Env : Matching = {
62+
63+ /** Normalieze the tree */
64+ def normalize (tree : Tree ): Tree = tree match {
65+ case Block (Nil , expr) => normalize(expr)
66+ case Inlined (_, Nil , expr) => normalize(expr)
67+ case _ => tree
68+ }
69+
70+ val scrutinee = normalize(scrutinee0)
71+ val pattern = normalize(pattern0)
6272
6373 /** Check that both are `val` or both are `lazy val` or both are `var` **/
6474 def checkValFlags (): Boolean = {
@@ -80,14 +90,7 @@ object Matcher {
8090 def hasBindAnnotation (sym : Symbol ) =
8191 sym.annots.exists { case Apply (Select (New (TypeIdent (" patternBindHole" ))," <init>" ),List ()) => true ; case _ => true }
8292
83- /** Normalieze the tree */
84- def normalize (tree : Tree ): Tree = tree match {
85- case Block (Nil , expr) => normalize(expr)
86- case Inlined (_, Nil , expr) => normalize(expr)
87- case _ => tree
88- }
89-
90- (normalize(scrutinee), normalize(pattern)) match {
93+ (scrutinee, pattern) match {
9194
9295 // Match a scala.internal.Quoted.patternHole typed as a repeated argument and return the scrutinee tree
9396 case (IsTerm (scrutinee @ Typed (s, tpt1)), Typed (TypeApply (patternHole, tpt :: Nil ), tpt2))
@@ -112,6 +115,9 @@ object Matcher {
112115 case (Typed (expr1, tpt1), Typed (expr2, tpt2)) =>
113116 expr1 =#= expr2 && tpt1 =#= tpt2
114117
118+ case (scrutinee, Typed (expr2, _)) =>
119+ scrutinee =#= expr2
120+
115121 case (Ident (_), Ident (_)) if scrutinee.symbol == pattern.symbol || the[Env ].apply((scrutinee.symbol, pattern.symbol)) =>
116122 matched
117123
@@ -144,9 +150,6 @@ object Matcher {
144150 case (While (cond1, body1), While (cond2, body2)) =>
145151 cond1 =#= cond2 && body1 =#= body2
146152
147- case (NamedArg (name1, expr1), NamedArg (name2, expr2)) if name1 == name2 =>
148- expr1 =#= expr2
149-
150153 case (New (tpt1), New (tpt2)) =>
151154 tpt1 =#= tpt2
152155
@@ -159,10 +162,11 @@ object Matcher {
159162 case (Repeated (elems1, _), Repeated (elems2, _)) if elems1.size == elems2.size =>
160163 elems1 =##= elems2
161164
165+ // TODO is this case required
162166 case (IsTypeTree (scrutinee @ TypeIdent (_)), IsTypeTree (pattern @ TypeIdent (_))) if scrutinee.symbol == pattern.symbol =>
163167 matched
164168
165- case (IsInferred (scrutinee), IsInferred (pattern)) if scrutinee.tpe <:< pattern.tpe =>
169+ case (IsTypeTree (scrutinee), IsTypeTree (pattern)) if scrutinee.tpe <:< pattern.tpe =>
166170 matched
167171
168172 case (Applied (tycon1, args1), Applied (tycon2, args2)) =>
@@ -173,7 +177,7 @@ object Matcher {
173177 if (hasBindAnnotation(pattern.symbol) || hasBindTypeAnnotation(tpt2)) bindingMatch(scrutinee.symbol)
174178 else matched
175179 def rhsEnv = the[Env ] + (scrutinee.symbol -> pattern.symbol)
176- bindMatch && tpt1 =#= tpt2 && (treeOptMatches(rhs1, rhs2) given rhsEnv )
180+ bindMatch && tpt1 =#= tpt2 && (treeOptMatches(rhs1, rhs2) given (the[ Context ], rhsEnv) )
177181
178182 case (DefDef (_, typeParams1, paramss1, tpt1, Some (rhs1)), DefDef (_, typeParams2, paramss2, tpt2, Some (rhs2))) =>
179183 val bindMatch =
@@ -229,15 +233,15 @@ object Matcher {
229233 }
230234 }
231235
232- def treeOptMatches (scrutinee : Option [Tree ], pattern : Option [Tree ]) given Env : Matching = {
236+ def treeOptMatches (scrutinee : Option [Tree ], pattern : Option [Tree ]) given Context , Env : Matching = {
233237 (scrutinee, pattern) match {
234238 case (Some (x), Some (y)) => x =#= y
235239 case (None , None ) => matched
236240 case _ => notMatched
237241 }
238242 }
239243
240- def caseMatches (scrutinee : CaseDef , pattern : CaseDef ) given Env : Matching = {
244+ def caseMatches (scrutinee : CaseDef , pattern : CaseDef ) given Context , Env : Matching = {
241245 val (caseEnv, patternMatch) = scrutinee.pattern =%= pattern.pattern
242246 withEnv(caseEnv) {
243247 patternMatch &&
@@ -256,7 +260,7 @@ object Matcher {
256260 * @return The new environment containing the bindings defined in this pattern tuppled with
257261 * `None` if it did not match or `Some(tup: Tuple)` if it matched where `tup` contains the contents of the holes.
258262 */
259- def (scrutinee : Pattern ) =%= (pattern : Pattern ) given Env : (Env , Matching ) = (scrutinee, pattern) match {
263+ def (scrutinee : Pattern ) =%= (pattern : Pattern ) given Context , Env : (Env , Matching ) = (scrutinee, pattern) match {
260264 case (Pattern .Value (v1), Pattern .Unapply (TypeApply (Select (patternHole @ Ident (" patternHole" ), " unapply" ), List (tpt)), Nil , Nil ))
261265 if patternHole.symbol.owner.fullName == " scala.runtime.quoted.Matcher$" =>
262266 (the[Env ], matched(v1.seal))
@@ -266,7 +270,7 @@ object Matcher {
266270
267271 case (Pattern .Bind (name1, body1), Pattern .Bind (name2, body2)) =>
268272 val bindEnv = the[Env ] + (scrutinee.symbol -> pattern.symbol)
269- (body1 =%= body2) given bindEnv
273+ (body1 =%= body2) given (the[ Context ], bindEnv)
270274
271275 case (Pattern .Unapply (fun1, implicits1, patterns1), Pattern .Unapply (fun2, implicits2, patterns2)) =>
272276 val (patEnv, patternsMatch) = foldPatterns(patterns1, patterns2)
@@ -302,16 +306,33 @@ object Matcher {
302306 (the[Env ], notMatched)
303307 }
304308
305- def foldPatterns (patterns1 : List [Pattern ], patterns2 : List [Pattern ]) given Env : (Env , Matching ) = {
309+ def foldPatterns (patterns1 : List [Pattern ], patterns2 : List [Pattern ]) given Context , Env : (Env , Matching ) = {
306310 if (patterns1.size != patterns2.size) (the[Env ], notMatched)
307311 else patterns1.zip(patterns2).foldLeft((the[Env ], matched)) { (acc, x) =>
308- val (env, res) = (x._1 =%= x._2) given acc ._1
312+ val (env, res) = (x._1 =%= x._2) given (the[ Context ], acc._1)
309313 (env, acc._2 && res)
310314 }
311315 }
312316
317+ def isTypeBinding (tree : Tree ): Boolean = tree match {
318+ case IsTypeDef (tree) =>
319+ tree.symbol.annots.exists(_.symbol.owner.fullName == " scala.internal.Quoted$.patternType" )
320+ case _ => false
321+ }
322+
313323 implied for Env = Set .empty
314- (scrutineeExpr.unseal =#= patternExpr.unseal).asOptionOfTuple.asInstanceOf [Option [Tup ]]
324+ val res = patternExpr.unseal.underlyingArgument match {
325+ case Block (typeBindings, pattern) if typeBindings.forall(isTypeBinding) =>
326+ implicit val ctx2 = reflection.kernel.Context_GADT_setFreshGADTBounds (rootContext)
327+ val bindingSymbols = typeBindings.map(_.symbol(ctx2))
328+ reflection.kernel.Context_GADT_addToConstraint (ctx2)(bindingSymbols)
329+ val matchings = scrutineeExpr.unseal.underlyingArgument =#= pattern
330+ val constainedTypes = bindingSymbols.map(s => reflection.kernel.Context_GADT_approximation (ctx2)(s, true ))
331+ constainedTypes.foldRight(matchings)((x, acc) => matched(x.seal) && acc)
332+ case pattern =>
333+ scrutineeExpr.unseal.underlyingArgument =#= pattern
334+ }
335+ res.asOptionOfTuple.asInstanceOf [Option [Tup ]]
315336 }
316337
317338 /** Result of matching a part of an expression */
0 commit comments