@@ -47,7 +47,7 @@ object Matcher {
47
47
}
48
48
49
49
/** 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 =
51
51
matchLists(scrutinees, patterns)(_ =#= _)
52
52
53
53
/** Check that the trees match and return the contents from the pattern holes.
@@ -58,7 +58,17 @@ object Matcher {
58
58
* @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`.
59
59
* @return `None` if it did not match or `Some(tup: Tuple)` if it matched where `tup` contains the contents of the holes.
60
60
*/
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)
62
72
63
73
/** Check that both are `val` or both are `lazy val` or both are `var` **/
64
74
def checkValFlags (): Boolean = {
@@ -80,14 +90,7 @@ object Matcher {
80
90
def hasBindAnnotation (sym : Symbol ) =
81
91
sym.annots.exists { case Apply (Select (New (TypeIdent (" patternBindHole" ))," <init>" ),List ()) => true ; case _ => true }
82
92
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 {
91
94
92
95
// Match a scala.internal.Quoted.patternHole typed as a repeated argument and return the scrutinee tree
93
96
case (IsTerm (scrutinee @ Typed (s, tpt1)), Typed (TypeApply (patternHole, tpt :: Nil ), tpt2))
@@ -112,6 +115,9 @@ object Matcher {
112
115
case (Typed (expr1, tpt1), Typed (expr2, tpt2)) =>
113
116
expr1 =#= expr2 && tpt1 =#= tpt2
114
117
118
+ case (scrutinee, Typed (expr2, _)) =>
119
+ scrutinee =#= expr2
120
+
115
121
case (Ident (_), Ident (_)) if scrutinee.symbol == pattern.symbol || the[Env ].apply((scrutinee.symbol, pattern.symbol)) =>
116
122
matched
117
123
@@ -144,9 +150,6 @@ object Matcher {
144
150
case (While (cond1, body1), While (cond2, body2)) =>
145
151
cond1 =#= cond2 && body1 =#= body2
146
152
147
- case (NamedArg (name1, expr1), NamedArg (name2, expr2)) if name1 == name2 =>
148
- expr1 =#= expr2
149
-
150
153
case (New (tpt1), New (tpt2)) =>
151
154
tpt1 =#= tpt2
152
155
@@ -159,10 +162,11 @@ object Matcher {
159
162
case (Repeated (elems1, _), Repeated (elems2, _)) if elems1.size == elems2.size =>
160
163
elems1 =##= elems2
161
164
165
+ // TODO is this case required
162
166
case (IsTypeTree (scrutinee @ TypeIdent (_)), IsTypeTree (pattern @ TypeIdent (_))) if scrutinee.symbol == pattern.symbol =>
163
167
matched
164
168
165
- case (IsInferred (scrutinee), IsInferred (pattern)) if scrutinee.tpe <:< pattern.tpe =>
169
+ case (IsTypeTree (scrutinee), IsTypeTree (pattern)) if scrutinee.tpe <:< pattern.tpe =>
166
170
matched
167
171
168
172
case (Applied (tycon1, args1), Applied (tycon2, args2)) =>
@@ -173,7 +177,7 @@ object Matcher {
173
177
if (hasBindAnnotation(pattern.symbol) || hasBindTypeAnnotation(tpt2)) bindingMatch(scrutinee.symbol)
174
178
else matched
175
179
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) )
177
181
178
182
case (DefDef (_, typeParams1, paramss1, tpt1, Some (rhs1)), DefDef (_, typeParams2, paramss2, tpt2, Some (rhs2))) =>
179
183
val bindMatch =
@@ -229,15 +233,15 @@ object Matcher {
229
233
}
230
234
}
231
235
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 = {
233
237
(scrutinee, pattern) match {
234
238
case (Some (x), Some (y)) => x =#= y
235
239
case (None , None ) => matched
236
240
case _ => notMatched
237
241
}
238
242
}
239
243
240
- def caseMatches (scrutinee : CaseDef , pattern : CaseDef ) given Env : Matching = {
244
+ def caseMatches (scrutinee : CaseDef , pattern : CaseDef ) given Context , Env : Matching = {
241
245
val (caseEnv, patternMatch) = scrutinee.pattern =%= pattern.pattern
242
246
withEnv(caseEnv) {
243
247
patternMatch &&
@@ -256,7 +260,7 @@ object Matcher {
256
260
* @return The new environment containing the bindings defined in this pattern tuppled with
257
261
* `None` if it did not match or `Some(tup: Tuple)` if it matched where `tup` contains the contents of the holes.
258
262
*/
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 {
260
264
case (Pattern .Value (v1), Pattern .Unapply (TypeApply (Select (patternHole @ Ident (" patternHole" ), " unapply" ), List (tpt)), Nil , Nil ))
261
265
if patternHole.symbol.owner.fullName == " scala.runtime.quoted.Matcher$" =>
262
266
(the[Env ], matched(v1.seal))
@@ -266,7 +270,7 @@ object Matcher {
266
270
267
271
case (Pattern .Bind (name1, body1), Pattern .Bind (name2, body2)) =>
268
272
val bindEnv = the[Env ] + (scrutinee.symbol -> pattern.symbol)
269
- (body1 =%= body2) given bindEnv
273
+ (body1 =%= body2) given (the[ Context ], bindEnv)
270
274
271
275
case (Pattern .Unapply (fun1, implicits1, patterns1), Pattern .Unapply (fun2, implicits2, patterns2)) =>
272
276
val (patEnv, patternsMatch) = foldPatterns(patterns1, patterns2)
@@ -302,16 +306,33 @@ object Matcher {
302
306
(the[Env ], notMatched)
303
307
}
304
308
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 ) = {
306
310
if (patterns1.size != patterns2.size) (the[Env ], notMatched)
307
311
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)
309
313
(env, acc._2 && res)
310
314
}
311
315
}
312
316
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
+
313
323
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 ]]
315
336
}
316
337
317
338
/** Result of matching a part of an expression */
0 commit comments