Skip to content

Fix #7618: Remove QuoteContext.macroContext #7681

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
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
2 changes: 0 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -645,8 +645,6 @@ class Definitions {
@tu lazy val QuotedExprModule_unitExpr: Symbol = QuotedExprModule.requiredMethod(nme.unitExpr)

@tu lazy val QuoteContextClass: ClassSymbol = ctx.requiredClass("scala.quoted.QuoteContext")
@tu lazy val QuoteContextModule: Symbol = QuoteContextClass.companionModule
@tu lazy val QuoteContext_macroContext: Symbol = QuoteContextModule.requiredMethod("macroContext")

@tu lazy val LiftableModule: Symbol = ctx.requiredModule("scala.quoted.Liftable")
@tu lazy val LiftableModule_BooleanIsLiftable: Symbol = LiftableModule.requiredMethod("BooleanIsLiftable")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,6 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
case Some(l) =>
l == level ||
level == -1 && (
sym == defn.QuoteContext_macroContext ||
// here we assume that Splicer.canBeSpliced was true before going to level -1,
// this implies that all non-inline arguments are quoted and that the following two cases are checked
// on inline parameters or type parameters.
Expand Down
9 changes: 0 additions & 9 deletions compiler/src/dotty/tools/dotc/transform/Splicer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,6 @@ object Splicer {
case Literal(Constant(value)) =>
// OK

case _ if tree.symbol == defn.QuoteContext_macroContext =>
// OK

case Call(fn, args)
if (fn.symbol.isConstructor && fn.symbol.owner.owner.is(Package)) ||
fn.symbol.is(Module) || fn.symbol.isStatic ||
Expand Down Expand Up @@ -191,9 +188,6 @@ object Splicer {
case Literal(Constant(value)) =>
interpretLiteral(value)

case _ if tree.symbol == defn.QuoteContext_macroContext =>
interpretQuoteContext()

// TODO disallow interpreted method calls as arguments
case Call(fn, args) =>
if (fn.symbol.isConstructor && fn.symbol.owner.owner.is(Package))
Expand Down Expand Up @@ -263,9 +257,6 @@ object Splicer {
private def interpretVarargs(args: List[Object])(implicit env: Env): Object =
args.toSeq

private def interpretQuoteContext()(implicit env: Env): Object =
QuoteContext()

private def interpretedStaticMethodCall(moduleClass: Symbol, fn: Symbol)(implicit env: Env): List[Object] => Object = {
val (inst, clazz) =
if (moduleClass.name.startsWith(str.REPL_SESSION_LINE))
Expand Down
7 changes: 0 additions & 7 deletions compiler/src/dotty/tools/dotc/typer/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -732,11 +732,6 @@ trait Implicits { self: Typer =>
}
}

lazy val synthesizedQuoteContext: SpecialHandler =
(formal, span) => implicit ctx =>
if (ctx.inMacro || enclosingInlineds.nonEmpty) ref(defn.QuoteContext_macroContext)
else EmptyTree

lazy val synthesizedTupleFunction: SpecialHandler =
(formal, span) => implicit ctx => formal match {
case AppliedType(_, funArgs @ fun :: tupled :: Nil) =>
Expand Down Expand Up @@ -1082,7 +1077,6 @@ trait Implicits { self: Typer =>
mySpecialHandlers = List(
defn.ClassTagClass -> synthesizedClassTag,
defn.QuotedTypeClass -> synthesizedTypeTag,
defn.QuoteContextClass -> synthesizedQuoteContext,
defn.EqlClass -> synthesizedEq,
defn.TupledFunctionClass -> synthesizedTupleFunction,
defn.ValueOfClass -> synthesizedValueOf,
Expand Down Expand Up @@ -1464,7 +1458,6 @@ trait Implicits { self: Typer =>
case alt1: SearchSuccess =>
var diff = compareCandidate(alt1, alt2.ref, alt2.level)
assert(diff <= 0) // diff > 0 candidates should already have been eliminated in `rank`

if diff == 0 then
// Fall back: if both results are extension method applications,
// compare the extension methods instead of their wrappers.
Expand Down
4 changes: 0 additions & 4 deletions library/src/scala/quoted/QuoteContext.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,3 @@ class QuoteContext(val tasty: scala.tasty.Reflection) {
}

}

object QuoteContext {
def macroContext: QuoteContext = throw new Exception("Not in inline macro.")
}
36 changes: 36 additions & 0 deletions tests/neg/i7618.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package macros

import scala.quoted.{given, _}

enum Exp {
case Num(n: Int)
case Plus(e1: Exp, e2: Exp)
case Var(x: String)
case Let(x: String, e: Exp, in: Exp)
}

object Compiler {
import Exp._

inline def compile(e: Exp, env: Map[String, Expr[Int]])(given ctx: QuoteContext): Expr[Int] = inline e match { // error
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may conflict with #7684. One of the PRs needs to be rebased on the other one.

case Num(n) =>
Expr(n)
case Plus(e1, e2) =>
'{ ${ compile(e1, env) } + ${ compile(e2, env) } }
case Var(x) =>
env(x)
case Let(x, e, body) =>
'{ val y = ${ compile(e, env) }; ${ compile(body, env + (x -> 'y)) } }
}
}

object Example {
def run(): Unit = {
import Exp._

val exp = Plus(Plus(Num(2), Var("x")), Num(4))
val letExp = Let("x", Num(3), exp)

Compiler.compile(letExp, Map.empty)(given QuoteContext.macroContext) // error
}
}
36 changes: 36 additions & 0 deletions tests/neg/i7618b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package macros

import scala.quoted.{given, _}

enum Exp {
case Num(n: Int)
case Plus(e1: Exp, e2: Exp)
case Var(x: String)
case Let(x: String, e: Exp, in: Exp)
}

object Compiler {
import Exp._

inline def compile(e: Exp, env: Map[String, Expr[Int]])(given ctx: QuoteContext): Expr[Int] = inline e match { // error
case Num(n) =>
Expr(n)
case Plus(e1, e2) =>
'{ ${ compile(e1, env) } + ${ compile(e2, env) } }
case Var(x) =>
env(x)
case Let(x, e, body) =>
'{ val y = ${ compile(e, env) }; ${ compile(body, env + (x -> 'y)) } }
}
}

object Example {
def run(): Unit = {
import Exp._

val exp = Plus(Plus(Num(2), Var("x")), Num(4))
val letExp = Let("x", Num(3), exp)

Compiler.compile(letExp, Map.empty)(given (??? : QuoteContext))
}
}
4 changes: 2 additions & 2 deletions tests/pos/i7358.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package test
import scala.quoted._
import scala.compiletime._

inline def summonT[Tp <: Tuple] <: Tuple = inline erasedValue[Tp] match {
inline def summonT[Tp <: Tuple](given QuoteContext) <: Tuple = inline erasedValue[Tp] match {
case _ : Unit => ()
case _ : (hd *: tl) => {
type H = hd
Expand All @@ -13,4 +13,4 @@ inline def summonT[Tp <: Tuple] <: Tuple = inline erasedValue[Tp] match {
}
}

def test[T : Type] = summonT[Tuple1[List[T]]]
def test[T : Type](given QuoteContext) = summonT[Tuple1[List[T]]]
5 changes: 1 addition & 4 deletions tests/run-staging/quote-macro-in-splice/quoted_2.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,11 @@ object Test {
val x = '{
val y = 1
${
// FIXME remove context when $ will provide one
// Currently we would accidentally capture the one from withQuoteContext
inline def a(z: Int): Int = ${ impl('z)(given QuoteContext.macroContext) }
inline def a(z: Int): Int = ${ impl('z) }
val b = Expr(a(7))
'{ y + $b }
}
}
println(x.show)
}

}