Skip to content

Remove constraints abstraction from Context #9710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,15 @@ class ReflectionCompilerInterface(val rootContext: Context) extends CompilerInte
// Constraints //
/////////////////

def Constraints_init(self: Context): Context =
self.fresh.setFreshGADTBounds.addMode(Mode.GadtConstraintInference)
def Constraints_context[T]: scala.quoted.QuoteContext =
val ctx1 = ctx.fresh.setFreshGADTBounds.addMode(Mode.GadtConstraintInference)
dotty.tools.dotc.quoted.QuoteContextImpl()(using ctx1)

def Constraints_add(self: Context)(syms: List[Symbol]): Boolean =
self.gadt.addToConstraint(syms)
def Constraints_add(syms: List[Symbol]): Boolean =
ctx.gadt.addToConstraint(syms)

def Constraints_approximation(self: Context)(sym: Symbol, fromBelow: Boolean): Type =
self.gadt.approximation(sym, fromBelow)
def Constraints_approximation(sym: Symbol, fromBelow: Boolean): Type =
ctx.gadt.approximation(sym, fromBelow)

////////////
// Source //
Expand Down
5 changes: 4 additions & 1 deletion library/src-bootstrapped/scala/internal/quoted/Expr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ object Expr {
*/
def unapply[TypeBindings <: Tuple, Tup <: Tuple](scrutineeExpr: scala.quoted.Expr[Any])(using patternExpr: scala.quoted.Expr[Any],
hasTypeSplices: Boolean, qctx: QuoteContext): Option[Tup] = {
new Matcher.QuoteMatcher[qctx.type](qctx).termMatch(scrutineeExpr.unseal, patternExpr.unseal, hasTypeSplices).asInstanceOf[Option[Tup]]
val qctx1 = quoteContextWithCompilerInterface(qctx)
val qctx2 = if hasTypeSplices then qctx1.tasty.Constraints_context else qctx1
given qctx2.type = qctx2
new Matcher.QuoteMatcher[qctx2.type](qctx2).termMatch(scrutineeExpr.unseal, patternExpr.unseal, hasTypeSplices).asInstanceOf[Option[Tup]]
}

/** Returns a null expresssion equivalent to `'{null}` */
Expand Down
30 changes: 11 additions & 19 deletions library/src-bootstrapped/scala/internal/quoted/Matcher.scala
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ object Matcher {

// TODO improve performance

// TODO use flag from qctx.tasty.rootContext. Maybe -debug or add -debug-macros
// TODO use flag from qctx.tasty. Maybe -debug or add -debug-macros
private final val debug = false

import qctx.tasty._
Expand All @@ -149,43 +149,35 @@ object Matcher {

def termMatch(scrutineeTerm: Term, patternTerm: Term, hasTypeSplices: Boolean): Option[Tuple] = {
given Env = Map.empty
if (hasTypeSplices) {
val ctx: Context = qctx.tasty.Constraints_init(rootContext)
given Context = ctx
val matchings = scrutineeTerm =?= patternTerm
val matchings = scrutineeTerm =?= patternTerm
if !hasTypeSplices then matchings
else {
// After matching and doing all subtype checks, we have to approximate all the type bindings
// that we have found and seal them in a quoted.Type
matchings.asOptionOfTuple.map { tup =>
Tuple.fromArray(tup.toArray.map { // TODO improve performance
case x: SymBinding => qctx.tasty.Constraints_approximation(summon[Context])(x.sym, !x.fromAbove).seal
case x: SymBinding => qctx.tasty.Constraints_approximation(x.sym, !x.fromAbove).seal
case x => x
})
}
}
else {
scrutineeTerm =?= patternTerm
}
}

// TODO factor out common logic with `termMatch`
def typeTreeMatch(scrutineeTypeTree: TypeTree, patternTypeTree: TypeTree, hasTypeSplices: Boolean): Option[Tuple] = {
given Env = Map.empty
if (hasTypeSplices) {
val ctx: Context = qctx.tasty.Constraints_init(rootContext)
given Context = ctx
val matchings = scrutineeTypeTree =?= patternTypeTree
val matchings = scrutineeTypeTree =?= patternTypeTree
if !hasTypeSplices then matchings
else {
// After matching and doing all subtype checks, we have to approximate all the type bindings
// that we have found and seal them in a quoted.Type
matchings.asOptionOfTuple.map { tup =>
Tuple.fromArray(tup.toArray.map { // TODO improve performance
case x: SymBinding => qctx.tasty.Constraints_approximation(summon[Context])(x.sym, !x.fromAbove).seal
case x: SymBinding => qctx.tasty.Constraints_approximation(x.sym, !x.fromAbove).seal
case x => x
})
}
}
else {
scrutineeTypeTree =?= patternTypeTree
}
}

private def hasPatternTypeAnnotation(sym: Symbol) = sym.annots.exists(isPatternTypeAnnotation)
Expand Down Expand Up @@ -326,7 +318,7 @@ object Matcher {
fn1 =?= fn2 &&& args1 =?= args2

case (Block(stats1, expr1), Block(binding :: stats2, expr2)) if isTypeBinding(binding) =>
qctx.tasty.Constraints_add(summon[Context])(binding.symbol :: Nil)
qctx.tasty.Constraints_add(binding.symbol :: Nil)
matched(new SymBinding(binding.symbol, hasFromAboveAnnotation(binding.symbol))) &&& Block(stats1, expr1) =?= Block(stats2, expr2)

/* Match block */
Expand All @@ -343,7 +335,7 @@ object Matcher {

case (scrutinee, Block(typeBindings, expr2)) if typeBindings.forall(isTypeBinding) =>
val bindingSymbols = typeBindings.map(_.symbol)
qctx.tasty.Constraints_add(summon[Context])(bindingSymbols)
qctx.tasty.Constraints_add(bindingSymbols)
bindingSymbols.foldRight(scrutinee =?= expr2)((x, acc) => matched(new SymBinding(x, hasFromAboveAnnotation(x))) &&& acc)

/* Match if */
Expand Down
5 changes: 4 additions & 1 deletion library/src-bootstrapped/scala/internal/quoted/Type.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ object Type {
*/
def unapply[TypeBindings <: Tuple, Tup <: Tuple](scrutineeType: scala.quoted.Type[_])(using patternType: scala.quoted.Type[_],
hasTypeSplices: Boolean, qctx: QuoteContext): Option[Tup] = {
new Matcher.QuoteMatcher[qctx.type](qctx).typeTreeMatch(scrutineeType.unseal, patternType.unseal, hasTypeSplices).asInstanceOf[Option[Tup]]
val qctx1 = quoteContextWithCompilerInterface(qctx)
val qctx2 = if hasTypeSplices then qctx1.tasty.Constraints_context else qctx1
given qctx2.type = qctx2
new Matcher.QuoteMatcher[qctx2.type](qctx2).typeTreeMatch(scrutineeType.unseal, patternType.unseal, hasTypeSplices).asInstanceOf[Option[Tup]]
}

def Unit: QuoteContext ?=> quoted.Type[Unit] =
Expand Down
6 changes: 3 additions & 3 deletions library/src/scala/internal/tasty/CompilerInterface.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ trait CompilerInterface extends scala.tasty.reflect.Types {
// Constraints //
/////////////////

def Constraints_init(self: Context): Context
def Constraints_add(self: Context)(syms: List[Symbol]): Boolean
def Constraints_approximation(self: Context)(sym: Symbol, fromBelow: Boolean): Type
def Constraints_context[T]: scala.quoted.QuoteContext
def Constraints_add(syms: List[Symbol]): Boolean
def Constraints_approximation(sym: Symbol, fromBelow: Boolean): Type

////////////
// Source //
Expand Down