@@ -3,6 +3,7 @@ package scala.internal.quoted
33import scala .annotation .internal .sharable
44
55import scala .quoted ._
6+ import scala .quoted .matching .Binding
67import scala .tasty ._
78
89object Matcher {
@@ -51,6 +52,18 @@ object Matcher {
5152 sFlags.is(Lazy ) == pFlags.is(Lazy ) && sFlags.is(Mutable ) == pFlags.is(Mutable )
5253 }
5354
55+ def bindingMatch (sym : Symbol ) =
56+ Some (Tuple1 (new Binding (sym.name, sym)))
57+
58+ def hasBindingTypeAnnotation (tpt : TypeTree ): Boolean = tpt match {
59+ case Annotated (tpt2, Apply (Select (New (TypeIdent (" patternBindHole" )), " <init>" ), Nil )) => true
60+ case Annotated (tpt2, _) => hasBindingTypeAnnotation(tpt2)
61+ case _ => false
62+ }
63+
64+ def hasBindingAnnotation (sym : Symbol ) =
65+ sym.annots.exists { case Apply (Select (New (TypeIdent (" patternBindHole" ))," <init>" ),List ()) => true ; case _ => true }
66+
5467 def treesMatch (scrutinees : List [Tree ], patterns : List [Tree ]): Option [Tuple ] =
5568 if (scrutinees.size != patterns.size) None
5669 else foldMatchings(scrutinees.zip(patterns).map(treeMatches): _* )
@@ -134,24 +147,30 @@ object Matcher {
134147 foldMatchings(treeMatches(tycon1, tycon2), treesMatch(args1, args2))
135148
136149 case (ValDef (_, tpt1, rhs1), ValDef (_, tpt2, rhs2)) if checkValFlags() =>
150+ val bindMatch =
151+ if (hasBindingAnnotation(pattern.symbol) || hasBindingTypeAnnotation(tpt2)) bindingMatch(scrutinee.symbol)
152+ else Some (())
137153 val returnTptMatch = treeMatches(tpt1, tpt2)
138154 val rhsEnv = env + (scrutinee.symbol -> pattern.symbol)
139155 val rhsMatchings = treeOptMatches(rhs1, rhs2)(rhsEnv)
140- foldMatchings(returnTptMatch, rhsMatchings)
156+ foldMatchings(bindMatch, returnTptMatch, rhsMatchings)
141157
142158 case (DefDef (_, typeParams1, paramss1, tpt1, Some (rhs1)), DefDef (_, typeParams2, paramss2, tpt2, Some (rhs2))) =>
143159 val typeParmasMatch = treesMatch(typeParams1, typeParams2)
144160 val paramssMatch =
145161 if (paramss1.size != paramss2.size) None
146162 else foldMatchings(paramss1.zip(paramss2).map { (params1, params2) => treesMatch(params1, params2) }: _* )
163+ val bindMatch =
164+ if (hasBindingAnnotation(pattern.symbol)) bindingMatch(scrutinee.symbol)
165+ else Some (())
147166 val tptMatch = treeMatches(tpt1, tpt2)
148167 val rhsEnv =
149168 env + (scrutinee.symbol -> pattern.symbol) ++
150- typeParams1.zip(typeParams2).map((tparam1, tparam2) => tparam1.symbol -> tparam2.symbol) ++
151- paramss1.flatten.zip(paramss2.flatten).map((param1, param2) => param1.symbol -> param2.symbol)
169+ typeParams1.zip(typeParams2).map((tparam1, tparam2) => tparam1.symbol -> tparam2.symbol) ++
170+ paramss1.flatten.zip(paramss2.flatten).map((param1, param2) => param1.symbol -> param2.symbol)
152171 val rhsMatch = treeMatches(rhs1, rhs2)(rhsEnv)
153172
154- foldMatchings(typeParmasMatch, paramssMatch, tptMatch, rhsMatch)
173+ foldMatchings(bindMatch, typeParmasMatch, paramssMatch, tptMatch, rhsMatch)
155174
156175 case (Lambda (_, tpt1), Lambda (_, tpt2)) =>
157176 // TODO match tpt1 with tpt2?
@@ -172,6 +191,10 @@ object Matcher {
172191 val finalizerMatch = treeOptMatches(finalizer1, finalizer2)
173192 foldMatchings(bodyMacth, casesMatch, finalizerMatch)
174193
194+ // Ignore type annotations
195+ case (Annotated (tpt, _), _) => treeMatches(tpt, pattern)
196+ case (_, Annotated (tpt, _)) => treeMatches(scrutinee, tpt)
197+
175198 // No Match
176199 case _ =>
177200 if (debug)
0 commit comments