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