Skip to content

Commit a5374ae

Browse files
committed
WIP
1 parent 5501e37 commit a5374ae

File tree

3 files changed

+25
-15
lines changed

3 files changed

+25
-15
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: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,18 @@ 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._
3738

3839
type Env = Set[(Symbol, Symbol)]
3940

40-
class SymBinding(val sym: Symbol)
41+
class SymBinding(val sym: Symbol, val fromBellow: Boolean)
4142

4243
inline def withEnv[T](env: Env)(body: => given Env => T): T = body given env
4344

@@ -140,7 +141,8 @@ object Matcher {
140141

141142
case (Block(stats1, expr1), Block(binding :: stats2, expr2)) if isTypeBinding(binding) =>
142143
reflection.kernel.Context_GADT_addToConstraint(the[Context])(binding.symbol :: Nil)
143-
matched(new SymBinding(binding.symbol)) && Block(stats1, expr1) =#= Block(stats2, expr2)
144+
val fromBellow = true // TODO
145+
matched(new SymBinding(binding.symbol, fromBellow)) && Block(stats1, expr1) =#= Block(stats2, expr2)
144146

145147
case (Block(stat1 :: stats1, expr1), Block(stat2 :: stats2, expr2)) =>
146148
withEnv(the[Env] + (stat1.symbol -> stat2.symbol)) {
@@ -150,7 +152,8 @@ object Matcher {
150152
case (scrutinee, Block(typeBindings, expr2)) if typeBindings.forall(isTypeBinding) =>
151153
val bindingSymbols = typeBindings.map(_.symbol)
152154
reflection.kernel.Context_GADT_addToConstraint(the[Context])(bindingSymbols)
153-
bindingSymbols.foldRight(scrutinee =#= expr2)((x, acc) => matched(new SymBinding(x)) && acc)
155+
val fromBellow = true // TODO
156+
bindingSymbols.foldRight(scrutinee =#= expr2)((x, acc) => matched(new SymBinding(x, fromBellow)) && acc)
154157

155158
case (If(cond1, thenp1, elsep1), If(cond2, thenp2, elsep2)) =>
156159
cond1 =#= cond2 && thenp1 =#= thenp2 && elsep1 =#= elsep2
@@ -335,18 +338,24 @@ object Matcher {
335338

336339
implied for Env = Set.empty
337340

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-
})
341+
val res = {
342+
if (hasTypeSplices) {
343+
implied for Context = reflection.kernel.Context_GADT_setFreshGADTBounds(rootContext)
344+
val matchings = scrutineeExpr.unseal.underlyingArgument =#= patternExpr.unseal.underlyingArgument
345+
// After matching and doing all subtype check, we have to aproximate all the type bindings
346+
// that we have found and seal them in a quoted.Type
347+
matchings.asOptionOfTuple.map { tup =>
348+
Tuple.fromArray(tup.toArray.map { // TODO improve performace
349+
case x: SymBinding => kernel.Context_GADT_approximation(the[Context])(x.sym, x.fromBellow).seal
350+
case x => x
351+
})
352+
}
353+
}
354+
else {
355+
scrutineeExpr.unseal.underlyingArgument =#= patternExpr.unseal.underlyingArgument
347356
}
348-
res.asInstanceOf[Option[Tup]]
349357
}
358+
res.asInstanceOf[Option[Tup]]
350359
}
351360

352361
/** 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)