Skip to content

Commit d9fd1f0

Browse files
committed
WIP
1 parent 5501e37 commit d9fd1f0

File tree

3 files changed

+20
-12
lines changed

3 files changed

+20
-12
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,6 +2009,7 @@ class Typer extends Namer
20092009
fun = ref(defn.InternalQuotedMatcher_unapplyR).appliedToTypeTrees(typeBindingsTuple :: TypeTree(patType) :: Nil),
20102010
implicits =
20112011
ref(defn.InternalQuoted_exprQuoteR).appliedToType(shape.tpe).appliedTo(shape) ::
2012+
Literal(Constant(typeBindings.nonEmpty)) ::
20122013
implicitArgTree(defn.TastyReflectionType, tree.span) :: Nil,
20132014
patterns = splicePat :: Nil,
20142015
proto = pt)

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

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@ object Matcher {
2727
*
2828
* @param scrutineeExpr `Expr[_]` on which we are pattern matching
2929
* @param patternExpr `Expr[_]` containing the pattern tree
30+
* @param hasTypeSplices `Boolean` notify if the pattern has type splices (if so we use a GADT context)
3031
* @param reflection instance of the reflection API (implicitly provided by the macro)
3132
* @return None if it did not match, `Some(tup)` if it matched where `tup` contains `Expr[Ti]``
3233
*/
33-
def unapply[TypeBindings <: Tuple, Tup <: Tuple](scrutineeExpr: Expr[_])(implicit patternExpr: Expr[_], reflection: Reflection): Option[Tup] = {
34+
def unapply[TypeBindings <: Tuple, Tup <: Tuple](scrutineeExpr: Expr[_])(implicit patternExpr: Expr[_], hasTypeSplices: Boolean, reflection: Reflection): Option[Tup] = {
3435
// TODO improve performance
3536
import reflection.{Bind => BindPattern, _}
3637
import Matching._
@@ -335,18 +336,24 @@ object Matcher {
335336

336337
implied for Env = Set.empty
337338

338-
{
339-
// TODO only set GADT context when needed
340-
implicit val ctx2 = reflection.kernel.Context_GADT_setFreshGADTBounds(rootContext)
341-
val matchings = scrutineeExpr.unseal.underlyingArgument =#= patternExpr.unseal.underlyingArgument
342-
val res = matchings.asOptionOfTuple.map { tup =>
343-
Tuple.fromArray(tup.toArray.map { // TODO improve code
344-
case x: SymBinding => reflection.kernel.Context_GADT_approximation(ctx2)(x.sym, true).seal
345-
case x => x
346-
})
339+
val res = {
340+
if (hasTypeSplices) {
341+
implied for Context = reflection.kernel.Context_GADT_setFreshGADTBounds(rootContext)
342+
val matchings = scrutineeExpr.unseal.underlyingArgument =#= patternExpr.unseal.underlyingArgument
343+
// After matching and doing all subtype check, we have to aproximate all the type bindings
344+
// that we have found and seal them in a quoted.Type
345+
matchings.asOptionOfTuple.map { tup =>
346+
Tuple.fromArray(tup.toArray.map { // TODO improve performace
347+
case x: SymBinding => kernel.Context_GADT_approximation(the[Context])(x.sym, true).seal
348+
case x => x
349+
})
350+
}
351+
}
352+
else {
353+
scrutineeExpr.unseal.underlyingArgument =#= patternExpr.unseal.underlyingArgument
347354
}
348-
res.asInstanceOf[Option[Tup]]
349355
}
356+
res.asInstanceOf[Option[Tup]]
350357
}
351358

352359
/** Result of matching a part of an expression */

tests/run-macros/quote-matcher-runtime/quoted_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ object Macros {
1010
private def impl[A, B](a: Expr[A], b: Expr[B])(implicit reflect: Reflection): Expr[Unit] = {
1111
import reflect.{Bind => _, _}
1212

13-
val res = scala.internal.quoted.Matcher.unapply[Tuple, Tuple](a)(b, reflect).map { tup =>
13+
val res = scala.internal.quoted.Matcher.unapply[Tuple, Tuple](a)(b, true, reflect).map { tup =>
1414
tup.toArray.toList.map {
1515
case r: Expr[_] =>
1616
s"Expr(${r.unseal.show})"

0 commit comments

Comments
 (0)