@@ -33,17 +33,19 @@ object Matcher {
3333 def unapply [Tup <: Tuple ](scrutineeExpr : Expr [_])(implicit patternExpr : Expr [_], reflection : Reflection ): Option [Tup ] = {
3434 import reflection .{Bind => BindPattern , _ }
3535
36+ type Env = Set [(Symbol , Symbol )]
37+
3638 // TODO improve performance
3739
3840 /** Check that the trees match and return the contents from the pattern holes.
3941 * Return None if the trees do not match otherwise return Some of a tuple containing all the contents in the holes.
4042 *
4143 * @param scrutinee The tree beeing matched
4244 * @param pattern The pattern tree that the scrutinee should match. Contains `patternHole` holes.
43- * @param env Set of tuples containing pairs of symbols (s, p) where s defines a symbol in `scrutinee` which corresponds to symbol p in `pattern`.
45+ * @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`.
4446 * @return `None` if it did not match or `Some(tup: Tuple)` if it matched where `tup` contains the contents of the holes.
4547 */
46- def treeMatches (scrutinee : Tree , pattern : Tree )( implicit env : Set [( Symbol , Symbol )]) : Option [Tuple ] = {
48+ def treeMatches (scrutinee : Tree , pattern : Tree ) given Env : Option [Tuple ] = {
4749
4850 /** Check that both are `val` or both are `lazy val` or both are `var` **/
4951 def checkValFlags (): Boolean = {
@@ -101,7 +103,7 @@ object Matcher {
101103 case (Typed (expr1, tpt1), Typed (expr2, tpt2)) =>
102104 foldMatchings(treeMatches(expr1, expr2), treeMatches(tpt1, tpt2))
103105
104- case (Ident (_), Ident (_)) if scrutinee.symbol == pattern.symbol || env ((scrutinee.symbol, pattern.symbol)) =>
106+ case (Ident (_), Ident (_)) if scrutinee.symbol == pattern.symbol || the[ Env ].apply ((scrutinee.symbol, pattern.symbol)) =>
105107 Some (())
106108
107109 case (Select (qual1, _), Select (qual2, _)) if scrutinee.symbol == pattern.symbol =>
@@ -160,8 +162,8 @@ object Matcher {
160162 if (hasBindAnnotation(pattern.symbol) || hasBindTypeAnnotation(tpt2)) bindingMatch(scrutinee.symbol)
161163 else Some (())
162164 val returnTptMatch = treeMatches(tpt1, tpt2)
163- val rhsEnv = env + (scrutinee.symbol -> pattern.symbol)
164- val rhsMatchings = treeOptMatches(rhs1, rhs2)( rhsEnv)
165+ val rhsEnv = the[ Env ] + (scrutinee.symbol -> pattern.symbol)
166+ val rhsMatchings = treeOptMatches(rhs1, rhs2) given rhsEnv
165167 foldMatchings(bindMatch, returnTptMatch, rhsMatchings)
166168
167169 case (DefDef (_, typeParams1, paramss1, tpt1, Some (rhs1)), DefDef (_, typeParams2, paramss2, tpt2, Some (rhs2))) =>
@@ -174,10 +176,10 @@ object Matcher {
174176 else Some (())
175177 val tptMatch = treeMatches(tpt1, tpt2)
176178 val rhsEnv =
177- env + (scrutinee.symbol -> pattern.symbol) ++
179+ the[ Env ] + (scrutinee.symbol -> pattern.symbol) ++
178180 typeParams1.zip(typeParams2).map((tparam1, tparam2) => tparam1.symbol -> tparam2.symbol) ++
179181 paramss1.flatten.zip(paramss2.flatten).map((param1, param2) => param1.symbol -> param2.symbol)
180- val rhsMatch = treeMatches(rhs1, rhs2)( rhsEnv)
182+ val rhsMatch = treeMatches(rhs1, rhs2) given rhsEnv
181183
182184 foldMatchings(bindMatch, typeParmasMatch, paramssMatch, tptMatch, rhsMatch)
183185
@@ -227,19 +229,23 @@ object Matcher {
227229 }
228230 }
229231
230- def treeOptMatches (scrutinee : Option [Tree ], pattern : Option [Tree ])( implicit env : Set [( Symbol , Symbol )]) : Option [Tuple ] = {
232+ def treeOptMatches (scrutinee : Option [Tree ], pattern : Option [Tree ]) given Env : Option [Tuple ] = {
231233 (scrutinee, pattern) match {
232234 case (Some (x), Some (y)) => treeMatches(x, y)
233235 case (None , None ) => Some (())
234236 case _ => None
235237 }
236238 }
237239
238- def caseMatches (scrutinee : CaseDef , pattern : CaseDef )( implicit env : Set [( Symbol , Symbol )]) : Option [Tuple ] = {
240+ def caseMatches (scrutinee : CaseDef , pattern : CaseDef ) given Env : Option [Tuple ] = {
239241 val (caseEnv, patternMatch) = patternMatches(scrutinee.pattern, pattern.pattern)
240- val guardMatch = treeOptMatches(scrutinee.guard, pattern.guard)(caseEnv)
241- val rhsMatch = treeMatches(scrutinee.rhs, pattern.rhs)(caseEnv)
242- foldMatchings(patternMatch, guardMatch, rhsMatch)
242+
243+ {
244+ implied for Env = caseEnv
245+ val guardMatch = treeOptMatches(scrutinee.guard, pattern.guard)
246+ val rhsMatch = treeMatches(scrutinee.rhs, pattern.rhs)
247+ foldMatchings(patternMatch, guardMatch, rhsMatch)
248+ }
243249 }
244250
245251 /** Check that the pattern trees match and return the contents from the pattern holes.
@@ -248,21 +254,21 @@ object Matcher {
248254 *
249255 * @param scrutinee The pattern tree beeing matched
250256 * @param pattern The pattern tree that the scrutinee should match. Contains `patternHole` holes.
251- * @param env Set of tuples containing pairs of symbols (s, p) where s defines a symbol in `scrutinee` which corresponds to symbol p in `pattern`.
257+ * @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`.
252258 * @return The new environment containing the bindings defined in this pattern tuppled with
253259 * `None` if it did not match or `Some(tup: Tuple)` if it matched where `tup` contains the contents of the holes.
254260 */
255- def patternMatches (scrutinee : Pattern , pattern : Pattern )( implicit env : Set [( Symbol , Symbol )]) : (Set [( Symbol , Symbol )] , Option [Tuple ]) = (scrutinee, pattern) match {
261+ def patternMatches (scrutinee : Pattern , pattern : Pattern ) given Env : (Env , Option [Tuple ]) = (scrutinee, pattern) match {
256262 case (Pattern .Value (v1), Pattern .Unapply (TypeApply (Select (patternHole @ Ident (" patternHole" ), " unapply" ), List (tpt)), Nil , Nil ))
257263 if patternHole.symbol.owner.fullName == " scala.runtime.quoted.Matcher$" =>
258- (env , Some (Tuple1 (v1.seal)))
264+ (the[ Env ] , Some (Tuple1 (v1.seal)))
259265
260266 case (Pattern .Value (v1), Pattern .Value (v2)) =>
261- (env , treeMatches(v1, v2))
267+ (the[ Env ] , treeMatches(v1, v2))
262268
263269 case (Pattern .Bind (name1, body1), Pattern .Bind (name2, body2)) =>
264- val bindEnv = env + (scrutinee.symbol -> pattern.symbol)
265- patternMatches(body1, body2)( bindEnv)
270+ val bindEnv = the[ Env ] + (scrutinee.symbol -> pattern.symbol)
271+ patternMatches(body1, body2) given bindEnv
266272
267273 case (Pattern .Unapply (fun1, implicits1, patterns1), Pattern .Unapply (fun2, implicits2, patterns2)) =>
268274 val funMatch = treeMatches(fun1, fun2)
@@ -276,10 +282,10 @@ object Matcher {
276282 foldPatterns(patterns1, patterns2)
277283
278284 case (Pattern .TypeTest (tpt1), Pattern .TypeTest (tpt2)) =>
279- (env , treeMatches(tpt1, tpt2))
285+ (the[ Env ] , treeMatches(tpt1, tpt2))
280286
281287 case (Pattern .WildcardPattern (), Pattern .WildcardPattern ()) =>
282- (env , Some (()))
288+ (the[ Env ] , Some (()))
283289
284290 case _ =>
285291 if (debug)
@@ -299,18 +305,19 @@ object Matcher {
299305 |
300306 |
301307 | """ .stripMargin)
302- (env , None )
308+ (the[ Env ] , None )
303309 }
304310
305- def foldPatterns (patterns1 : List [Pattern ], patterns2 : List [Pattern ])( implicit env : Set [( Symbol , Symbol )]) : (Set [( Symbol , Symbol )] , Option [Tuple ]) = {
306- if (patterns1.size != patterns2.size) (env , None )
307- else patterns1.zip(patterns2).foldLeft((env , Option [Tuple ](()))) { (acc, x) =>
308- val (env, res) = patternMatches(x._1, x._2)( acc._1)
311+ def foldPatterns (patterns1 : List [Pattern ], patterns2 : List [Pattern ]) given Env : (Env , Option [Tuple ]) = {
312+ if (patterns1.size != patterns2.size) (the[ Env ] , None )
313+ else patterns1.zip(patterns2).foldLeft((the[ Env ] , Option [Tuple ](()))) { (acc, x) =>
314+ val (env, res) = patternMatches(x._1, x._2) given acc ._1
309315 (env, foldMatchings(acc._2, res))
310316 }
311317 }
312318
313- treeMatches(scrutineeExpr.unseal, patternExpr.unseal)(Set .empty).asInstanceOf [Option [Tup ]]
319+ implied for Env = Set .empty
320+ treeMatches(scrutineeExpr.unseal, patternExpr.unseal).asInstanceOf [Option [Tup ]]
314321 }
315322
316323 /** Joins the mattchings into a single matching. If any matching is `None` the result is `None`.
0 commit comments