Skip to content

Commit 2d56d6e

Browse files
Merge pull request #6380 from dotty-staging/use-contextual-types-in-quote-matcher
Use contextual types in quote matcher
2 parents 345a6d3 + 4d8f7f3 commit 2d56d6e

File tree

1 file changed

+33
-26
lines changed

1 file changed

+33
-26
lines changed

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

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)