Skip to content

Commit 8ddba1b

Browse files
Merge pull request #6401 from dotty-staging/use-same-logic-to-match-over-all-lists
Use same logic to match over all lists
2 parents cab020d + 20f5c5c commit 8ddba1b

File tree

1 file changed

+23
-39
lines changed

1 file changed

+23
-39
lines changed

library/src-3.x/scala/internal/quoted/Matcher.scala

Lines changed: 23 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,17 @@ object Matcher {
3939

4040
inline def withEnv[T](env: Env)(body: => given Env => T): T = body given env
4141

42-
/** Check that all trees match with =#= and concatenate the results with && */
43-
def (scrutinees: List[Tree]) =##= (patterns: List[Tree]) given Env: Matching = {
44-
def rec(l1: List[Tree], l2: List[Tree]): Matching = (l1, l2) match {
45-
case (x :: xs, y :: ys) => x =#= y && rec(xs, ys)
46-
case (Nil, Nil) => matched
47-
case _ => notMatched
48-
}
49-
rec(scrutinees, patterns)
42+
/** Check that all trees match with `mtch` and concatenate the results with && */
43+
def matchLists[T](l1: List[T], l2: List[T])(mtch: (T, T) => Matching): Matching = (l1, l2) match {
44+
case (x :: xs, y :: ys) => mtch(x, y) && matchLists(xs, ys)(mtch)
45+
case (Nil, Nil) => matched
46+
case _ => notMatched
5047
}
5148

49+
/** Check that all trees match with =#= and concatenate the results with && */
50+
def (scrutinees: List[Tree]) =##= (patterns: List[Tree]) given Env: Matching =
51+
matchLists(scrutinees, patterns)(_ =#= _)
52+
5253
/** Check that the trees match and return the contents from the pattern holes.
5354
* Return None if the trees do not match otherwise return Some of a tuple containing all the contents in the holes.
5455
*
@@ -171,46 +172,33 @@ object Matcher {
171172
val bindMatch =
172173
if (hasBindAnnotation(pattern.symbol) || hasBindTypeAnnotation(tpt2)) bindingMatch(scrutinee.symbol)
173174
else matched
174-
val returnTptMatch = tpt1 =#= tpt2
175-
val rhsEnv = the[Env] + (scrutinee.symbol -> pattern.symbol)
176-
val rhsMatchings = treeOptMatches(rhs1, rhs2) given rhsEnv
177-
bindMatch && returnTptMatch && rhsMatchings
175+
def rhsEnv = the[Env] + (scrutinee.symbol -> pattern.symbol)
176+
bindMatch && tpt1 =#= tpt2 && (treeOptMatches(rhs1, rhs2) given rhsEnv)
178177

179178
case (DefDef(_, typeParams1, paramss1, tpt1, Some(rhs1)), DefDef(_, typeParams2, paramss2, tpt2, Some(rhs2))) =>
180-
val typeParmasMatch = typeParams1 =##= typeParams2
181-
val paramssMatch =
182-
if (paramss1.size != paramss2.size) notMatched
183-
else foldMatchings(paramss1.zip(paramss2).map { (params1, params2) => params1 =##= params2 }: _*)
184179
val bindMatch =
185180
if (hasBindAnnotation(pattern.symbol)) bindingMatch(scrutinee.symbol)
186181
else matched
187-
val tptMatch = tpt1 =#= tpt2
188-
val rhsEnv =
182+
def rhsEnv =
189183
the[Env] + (scrutinee.symbol -> pattern.symbol) ++
190184
typeParams1.zip(typeParams2).map((tparam1, tparam2) => tparam1.symbol -> tparam2.symbol) ++
191185
paramss1.flatten.zip(paramss2.flatten).map((param1, param2) => param1.symbol -> param2.symbol)
192-
val rhsMatch = (rhs1 =#= rhs2) given rhsEnv
193186

194-
bindMatch && typeParmasMatch && paramssMatch && tptMatch && rhsMatch
187+
bindMatch &&
188+
typeParams1 =##= typeParams2 &&
189+
matchLists(paramss1, paramss2)(_ =##= _) &&
190+
tpt1 =#= tpt2 &&
191+
withEnv(rhsEnv)(rhs1 =#= rhs2)
195192

196193
case (Lambda(_, tpt1), Lambda(_, tpt2)) =>
197194
// TODO match tpt1 with tpt2?
198195
matched
199196

200197
case (Match(scru1, cases1), Match(scru2, cases2)) =>
201-
val scrutineeMacth = scru1 =#= scru2
202-
val casesMatch =
203-
if (cases1.size != cases2.size) notMatched
204-
else foldMatchings(cases1.zip(cases2).map(caseMatches): _*)
205-
scrutineeMacth && casesMatch
198+
scru1 =#= scru2 && matchLists(cases1, cases2)(caseMatches)
206199

207200
case (Try(body1, cases1, finalizer1), Try(body2, cases2, finalizer2)) =>
208-
val bodyMacth = body1 =#= body2
209-
val casesMatch =
210-
if (cases1.size != cases2.size) notMatched
211-
else foldMatchings(cases1.zip(cases2).map(caseMatches): _*)
212-
val finalizerMatch = treeOptMatches(finalizer1, finalizer2)
213-
bodyMacth && casesMatch && finalizerMatch
201+
body1 =#= body2 && matchLists(cases1, cases2)(caseMatches) && treeOptMatches(finalizer1, finalizer2)
214202

215203
// Ignore type annotations
216204
case (Annotated(tpt, _), _) =>
@@ -252,9 +240,9 @@ object Matcher {
252240
def caseMatches(scrutinee: CaseDef, pattern: CaseDef) given Env: Matching = {
253241
val (caseEnv, patternMatch) = scrutinee.pattern =%= pattern.pattern
254242
withEnv(caseEnv) {
255-
val guardMatch = treeOptMatches(scrutinee.guard, pattern.guard)
256-
val rhsMatch = scrutinee.rhs =#= pattern.rhs
257-
patternMatch && guardMatch && rhsMatch
243+
patternMatch &&
244+
treeOptMatches(scrutinee.guard, pattern.guard) &&
245+
scrutinee.rhs =#= pattern.rhs
258246
}
259247
}
260248

@@ -281,12 +269,8 @@ object Matcher {
281269
(body1 =%= body2) given bindEnv
282270

283271
case (Pattern.Unapply(fun1, implicits1, patterns1), Pattern.Unapply(fun2, implicits2, patterns2)) =>
284-
val funMatch = fun1 =#= fun2
285-
val implicitsMatch =
286-
if (implicits1.size != implicits2.size) notMatched
287-
else foldMatchings(implicits1.zip(implicits2).map((i1, i2) => i1 =#= i2): _*)
288272
val (patEnv, patternsMatch) = foldPatterns(patterns1, patterns2)
289-
(patEnv, funMatch && implicitsMatch && patternsMatch)
273+
(patEnv, fun1 =#= fun2 && implicits1 =##= implicits2 && patternsMatch)
290274

291275
case (Pattern.Alternatives(patterns1), Pattern.Alternatives(patterns2)) =>
292276
foldPatterns(patterns1, patterns2)

0 commit comments

Comments
 (0)