Skip to content

Commit a7fc7ac

Browse files
committed
wip
1 parent 3da6139 commit a7fc7ac

File tree

4 files changed

+50
-12
lines changed

4 files changed

+50
-12
lines changed

library/src-bootstrapped/scala/internal/Quoted.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@ object Quoted {
2121
def patternHole[T]: T =
2222
throw new Error("Internal error: this method call should have been replaced by the compiler")
2323

24-
/** A splice of a name in a quoted pattern is desugared by wrapping getting this annotation */
24+
/** A splice of a name in a quoted pattern is desugared by adding this annotation */
2525
class patternBindHole extends Annotation
2626

27+
/** A splice of a name in a quoted pattern in pattern position is desugared by wrapping it in this extractor */
28+
object patternMatchBindHole {
29+
def unapply(x: Any): Some[x.type] =
30+
throw new Error("Internal error: this method call should have been replaced by the compiler")
31+
}
32+
2733
}

library/src-bootstrapped/scala/internal/quoted/Matcher.scala

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ object Matcher {
3434
import reflection._
3535
// TODO improve performance
3636

37+
/** Create a new matching with the resulting binding for the symbol */
38+
def bindingMatched(sym: Symbol) =
39+
Some(Tuple1(new Binding(sym.name, sym)))
40+
3741
/** Check that the trees match and return the contents from the pattern holes.
3842
* Return None if the trees do not match otherwise return Some of a tuple containing all the contents in the holes.
3943
*
@@ -52,9 +56,6 @@ object Matcher {
5256
sFlags.is(Lazy) == pFlags.is(Lazy) && sFlags.is(Mutable) == pFlags.is(Mutable)
5357
}
5458

55-
def bindingMatch(sym: Symbol) =
56-
Some(Tuple1(new Binding(sym.name, sym)))
57-
5859
def hasBindingTypeAnnotation(tpt: TypeTree): Boolean = tpt match {
5960
case Annotated(tpt2, Apply(Select(New(TypeIdent("patternBindHole")), "<init>"), Nil)) => true
6061
case Annotated(tpt2, _) => hasBindingTypeAnnotation(tpt2)
@@ -148,7 +149,7 @@ object Matcher {
148149

149150
case (ValDef(_, tpt1, rhs1), ValDef(_, tpt2, rhs2)) if checkValFlags() =>
150151
val bindMatch =
151-
if (hasBindingAnnotation(pattern.symbol) || hasBindingTypeAnnotation(tpt2)) bindingMatch(scrutinee.symbol)
152+
if (hasBindingAnnotation(pattern.symbol) || hasBindingTypeAnnotation(tpt2)) bindingMatched(scrutinee.symbol)
152153
else Some(())
153154
val returnTptMatch = treeMatches(tpt1, tpt2)
154155
val rhsEnv = env + (scrutinee.symbol -> pattern.symbol)
@@ -161,7 +162,7 @@ object Matcher {
161162
if (paramss1.size != paramss2.size) None
162163
else foldMatchings(paramss1.zip(paramss2).map { (params1, params2) => treesMatch(params1, params2) }: _*)
163164
val bindMatch =
164-
if (hasBindingAnnotation(pattern.symbol)) bindingMatch(scrutinee.symbol)
165+
if (hasBindingAnnotation(pattern.symbol)) bindingMatched(scrutinee.symbol)
165166
else Some(())
166167
val tptMatch = treeMatches(tpt1, tpt2)
167168
val rhsEnv =
@@ -244,13 +245,24 @@ object Matcher {
244245
* `None` if it did not match or `Some(tup: Tuple)` if it matched where `tup` contains the contents of the holes.
245246
*/
246247
def patternMatches(scrutinee: Pattern, pattern: Pattern)(implicit env: Set[(Symbol, Symbol)]): (Set[(Symbol, Symbol)], Option[Tuple]) = (scrutinee, pattern) match {
247-
case (Pattern.Value(v1), Pattern.Unapply(TypeApply(Select(patternHole @ Ident("patternHole"), "unapply"), List(tpt)), Nil, Nil))
248-
if patternHole.symbol.owner.fullName == "scala.runtime.quoted.Matcher$" =>
249-
(env, Some(Tuple1(v1.seal)))
248+
// case (Pattern.Value(v1), Pattern.Unapply(TypeApply(Select(patternHole @ Ident("patternHole"), "unapply"), List(tpt)), Nil, Nil))
249+
// if patternHole.symbol.owner.fullName == "scala.runtime.quoted.Matcher$" =>
250+
// (env, Some(Tuple1(v1.seal)))
251+
252+
case (Pattern.Bind(name1, pat1), Pattern.Unapply(Select(Ident("patternMatchBindHole"), "unapply"), Nil, List(Pattern.Bind(name2, pat2))))
253+
// TODO if pattern.symbol == ... =>
254+
=>
255+
val (env1, patMatch) = patternMatches(pat1, pat2)
256+
(env1, foldMatchings(bindingMatched(scrutinee.symbol), patMatch))
257+
258+
case (Pattern.Value(Ident("_")), Pattern.Value(Ident("_"))) => // TODO add Wildcard to patterns
259+
val bindEnv = env + (scrutinee.symbol -> pattern.symbol)
260+
(bindEnv, Some(()))
250261

251262
case (Pattern.Value(v1), Pattern.Value(v2)) =>
252263
(env, treeMatches(v1, v2))
253264

265+
254266
case (Pattern.Bind(name1, body1), Pattern.Bind(name2, body2)) =>
255267
val bindEnv = env + (scrutinee.symbol -> pattern.symbol)
256268
patternMatches(body1, body2)(bindEnv)

tests/run-with-compiler/quote-matcher-runtime.check

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,26 @@ Pattern: scala.Predef.??? match {
622622
}
623623
Result: Some(List())
624624

625+
Scrutinee: scala.Predef.??? match {
626+
case scala.Some(n) =>
627+
2
628+
}
629+
Pattern: scala.Predef.??? match {
630+
case scala.Some(scala.internal.Quoted.patternMatchBindHole(n)) =>
631+
2
632+
}
633+
Result: Some(List(Binding(n)))
634+
635+
Scrutinee: scala.Predef.??? match {
636+
case scala.Some(n @ scala.Some(m)) =>
637+
2
638+
}
639+
Pattern: scala.Predef.??? match {
640+
case scala.Some(scala.internal.Quoted.patternMatchBindHole(n @ scala.Some(scala.internal.Quoted.patternMatchBindHole(m)))) =>
641+
2
642+
}
643+
Result: Some(List(Binding(n), Binding(m)))
644+
625645
Scrutinee: try 1 catch {
626646
case _ =>
627647
2

tests/run-with-compiler/quote-matcher-runtime/quoted_2.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Macros._
33

44
import scala.internal.quoted.Matcher._
55

6-
import scala.internal.Quoted.{patternHole, patternBindHole}
6+
import scala.internal.Quoted.{patternHole, patternBindHole, patternMatchBindHole}
77

88
object Test {
99

@@ -123,8 +123,8 @@ object Test {
123123
matches(??? match { case None => 2 }, ??? match { case None => 2 })
124124
matches(??? match { case Some(1) => 2 }, ??? match { case Some(1) => 2 })
125125
// matches(??? match { case Some(1) => 2 }, ??? match { case Some(patternMatchHole()) => 2 })
126-
// matches(??? match { case Some(n) => 2 }, ??? match { case Some(patternMatchBindHole(n)) => 2 })
127-
// matches(??? match { case Some(n @ Some(m)) => 2 }, ??? match { case Some(patterMatchBindHole(n @ Some(patternMatchBindHole(m)))) => 2 })
126+
matches(??? match { case Some(n) => 2 }, ??? match { case Some(patternMatchBindHole(n)) => 2 })
127+
matches(??? match { case Some(n @ Some(m)) => 2 }, ??? match { case Some(patternMatchBindHole(n @ Some(patternMatchBindHole(m)))) => 2 })
128128
matches(try 1 catch { case _ => 2 }, try 1 catch { case _ => 2 })
129129
matches(try 1 finally 2, try 1 finally 2)
130130
matches(try 1 catch { case _ => 2 }, try patternHole[Int] catch { case _ => patternHole[Int] })

0 commit comments

Comments
 (0)