Skip to content

Move let to ValDef and fix signature #10175

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 1 commit into from
Nov 6, 2020
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
10 changes: 10 additions & 0 deletions compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,16 @@ class QuoteContextImpl private (ctx: Context) extends QuoteContext, scala.intern
tpd.cpy.ValDef(original)(name.toTermName, tpt, rhs.getOrElse(tpd.EmptyTree))
def unapply(vdef: ValDef): Option[(String, TypeTree, Option[Term])] =
Some((vdef.name.toString, vdef.tpt, optional(vdef.rhs)))

def let(name: String, rhs: Term)(body: Ident => Term): Term =
val vdef = tpd.SyntheticValDef(name.toTermName, rhs)
val ref = tpd.ref(vdef.symbol).asInstanceOf[Ident]
Block(List(vdef), body(ref))

def let(terms: List[Term])(body: List[Ident] => Term): Term =
val vdefs = terms.map(term => tpd.SyntheticValDef("x".toTermName, term))
val refs = vdefs.map(vdef => tpd.ref(vdef.symbol).asInstanceOf[Ident])
Block(vdefs, body(refs))
end ValDef

object ValDefMethodsImpl extends ValDefMethods:
Expand Down
27 changes: 9 additions & 18 deletions library/src/scala/tasty/Reflection.scala
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,15 @@ trait Reflection { reflection =>
def apply(symbol: Symbol, rhs: Option[Term]): ValDef
def copy(original: Tree)(name: String, tpt: TypeTree, rhs: Option[Term]): ValDef
def unapply(vdef: ValDef): Option[(String, TypeTree, Option[Term])]

/** Creates a block `{ val <name> = <rhs: Term>; <body(x): Term> }` */
def let(name: String, rhs: Term)(body: Ident => Term): Term

/** Creates a block `{ val x = <rhs: Term>; <body(x): Term> }` */
def let(rhs: Term)(body: Ident => Term): Term = let("x", rhs)(body)

/** Creates a block `{ val x1 = <terms(0): Term>; ...; val xn = <terms(n-1): Term>; <body(List(x1, ..., xn)): Term> }` */
def let(terms: List[Term])(body: List[Ident] => Term): Term
}

given ValDefMethods as ValDefMethods = ValDefMethodsImpl
Expand Down Expand Up @@ -3603,22 +3612,4 @@ trait Reflection { reflection =>

end TreeMap

// TODO: extract from Reflection

/** Bind the `rhs` to a `val` and use it in `body` */
def let(rhs: Term)(body: Ident => Term): Term = {
val sym = Symbol.newVal(Symbol.currentOwner, "x", rhs.tpe.widen, Flags.EmptyFlags, Symbol.noSymbol)
Block(List(ValDef(sym, Some(rhs))), body(Ref(sym).asInstanceOf[Ident]))
}

/** Bind the given `terms` to names and use them in the `body` */
def lets(terms: List[Term])(body: List[Term] => Term): Term = {
def rec(xs: List[Term], acc: List[Term]): Term = xs match {
case Nil => body(acc)
case x :: xs => let(x) { (x: Term) => rec(xs, x :: acc) }
}
rec(terms, Nil)
}


}
1 change: 1 addition & 0 deletions tests/pos-macros/i6535/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ object scalatest {
def assertImpl(cond: Expr[Boolean])(using qctx: QuoteContext) : Expr[Unit] = {
import qctx.reflect._
import util._
import ValDef.let

cond.unseal.underlyingArgument match {
case t @ Apply(Select(lhs, op), rhs :: Nil) =>
Expand Down
2 changes: 1 addition & 1 deletion tests/pos-macros/i8866/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ object Macro {
def impl(using qctx: QuoteContext): Expr[Int] = {
import qctx.reflect._

let(
ValDef.let(
Select.unique(
'{ OtherMacro }.unseal,
"apply"
Expand Down
2 changes: 1 addition & 1 deletion tests/pos-macros/i8866b/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ object Macro {
def impl(using qctx: QuoteContext): Expr[Int] = {
import qctx.reflect._

let(
ValDef.let(
Select.unique(
'{ Other }.unseal,
"apply"
Expand Down
12 changes: 6 additions & 6 deletions tests/run-macros/i6171/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ object scalatest {

cond.unseal.underlyingArgument match {
case t @ Apply(Select(lhs, op), rhs :: Nil) =>
let(lhs) { left =>
let(rhs) { right =>
ValDef.let(lhs) { left =>
ValDef.let(rhs) { right =>
val app = Select.overloaded(left, op, Nil, right :: Nil)
let(app) { result =>
ValDef.let(app) { result =>
val l = left.seal
val r = right.seal
val b = result.seal.cast[Boolean]
Expand All @@ -28,10 +28,10 @@ object scalatest {
}.seal.cast[Unit]
case Apply(f @ Apply(Select(Apply(qual, lhs :: Nil), op), rhs :: Nil), implicits)
if isImplicitMethodType(f.tpe) =>
let(lhs) { left =>
let(rhs) { right =>
ValDef.let(lhs) { left =>
ValDef.let(rhs) { right =>
val app = Select.overloaded(Apply(qual, left :: Nil), op, Nil, right :: Nil)
let(Apply(app, implicits)) { result =>
ValDef.let(Apply(app, implicits)) { result =>
val l = left.seal
val r = right.seal
val b = result.seal.cast[Boolean]
Expand Down
12 changes: 6 additions & 6 deletions tests/run-macros/reflect-dsl/assert_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ object scalatest {

cond.unseal.underlyingArgument match {
case t @ Apply(sel @ Select(lhs, op), rhs :: Nil) =>
let(lhs) { left =>
let(rhs) { right =>
ValDef.let(lhs) { left =>
ValDef.let(rhs) { right =>
val app = left.select(sel.symbol).appliedTo(right)
let(app) { result =>
ValDef.let(app) { result =>
val l = left.seal
val r = right.seal
val b = result.seal.cast[Boolean]
Expand All @@ -28,10 +28,10 @@ object scalatest {
}.seal.cast[Unit]
case Apply(f @ Apply(sel @ Select(Apply(qual, lhs :: Nil), op), rhs :: Nil), implicits)
if isImplicitMethodType(f.tpe) =>
let(lhs) { left =>
let(rhs) { right =>
ValDef.let(lhs) { left =>
ValDef.let(rhs) { right =>
val app = qual.appliedTo(left).select(sel.symbol).appliedTo(right)
let(Apply(app, implicits)) { result =>
ValDef.let(Apply(app, implicits)) { result =>
val l = left.seal
val r = right.seal
val b = result.seal.cast[Boolean]
Expand Down
4 changes: 2 additions & 2 deletions tests/run-macros/reflect-pos-fun/assert_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ object scalatest {

cond.unseal.underlyingArgument match {
case t @ Apply(TypeApply(Select(lhs, op), targs), rhs) =>
let(lhs) { left =>
lets(rhs) { rs =>
ValDef.let(lhs) { left =>
ValDef.let(rhs) { rs =>
val app = Select.overloaded(left, op, targs.map(_.tpe), rs)
val b = app.seal.cast[Boolean]
'{ scala.Predef.assert($b) }.unseal
Expand Down
12 changes: 6 additions & 6 deletions tests/run-macros/reflect-select-constructor/assert_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ object scalatest {

cond.unseal.underlyingArgument match {
case t @ Apply(Select(lhs, op), rhs :: Nil) =>
let(lhs) { left =>
let(rhs) { right =>
ValDef.let(lhs) { left =>
ValDef.let(rhs) { right =>
val app = Select.overloaded(left, op, Nil, right :: Nil)
let(app) { result =>
ValDef.let(app) { result =>
val l = left.seal
val r = right.seal
val b = result.seal.cast[Boolean]
Expand All @@ -28,10 +28,10 @@ object scalatest {
}.seal.cast[Unit]
case Apply(f @ Apply(Select(Apply(qual, lhs :: Nil), op), rhs :: Nil), implicits)
if isImplicitMethodType(f.tpe) =>
let(lhs) { left =>
let(rhs) { right =>
ValDef.let(lhs) { left =>
ValDef.let(rhs) { right =>
val app = Select.overloaded(Apply(qual, left :: Nil), op, Nil, right :: Nil)
let(Apply(app, implicits)) { result =>
ValDef.let(Apply(app, implicits)) { result =>
val l = left.seal
val r = right.seal
val b = result.seal.cast[Boolean]
Expand Down
12 changes: 6 additions & 6 deletions tests/run-macros/reflect-select-copy-2/assert_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ object scalatest {

cond.unseal.underlyingArgument match {
case Apply(sel @ Select(lhs, op), rhs :: Nil) =>
let(lhs) { left =>
let(rhs) { right =>
let(Apply(Select.copy(sel)(left, op), right :: Nil)) { result =>
ValDef.let(lhs) { left =>
ValDef.let(rhs) { right =>
ValDef.let(Apply(Select.copy(sel)(left, op), right :: Nil)) { result =>
val l = left.seal
val r = right.seal
val b = result.seal.cast[Boolean]
Expand All @@ -27,9 +27,9 @@ object scalatest {
}.seal.cast[Unit]
case Apply(f @ Apply(sel @ Select(Apply(qual, lhs :: Nil), op), rhs :: Nil), implicits)
if isImplicitMethodType(f.tpe) =>
let(lhs) { left =>
let(rhs) { right =>
let(Apply(Apply(Select.copy(sel)(Apply(qual, left :: Nil), op), right :: Nil), implicits)) { result =>
ValDef.let(lhs) { left =>
ValDef.let(rhs) { right =>
ValDef.let(Apply(Apply(Select.copy(sel)(Apply(qual, left :: Nil), op), right :: Nil), implicits)) { result =>
val l = left.seal
val r = right.seal
val b = result.seal.cast[Boolean]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ object scalatest {

cond.unseal.underlyingArgument match {
case t @ Apply(sel @ Select(lhs, op), rhs :: Nil) =>
let(lhs) { left =>
let(rhs) { right =>
ValDef.let(lhs) { left =>
ValDef.let(rhs) { right =>
val app = Apply(Select(left, sel.symbol), right :: Nil)
let(app) { result =>
ValDef.let(app) { result =>
val l = left.seal
val r = right.seal
val b = result.seal.cast[Boolean]
Expand All @@ -28,10 +28,10 @@ object scalatest {
}.seal.cast[Unit]
case Apply(f @ Apply(sel @ Select(Apply(qual, lhs :: Nil), op), rhs :: Nil), implicits)
if isImplicitMethodType(f.tpe) =>
let(lhs) { left =>
let(rhs) { right =>
ValDef.let(lhs) { left =>
ValDef.let(rhs) { right =>
val app = Apply(Select(Apply(qual, left :: Nil), sel.symbol), right :: Nil)
let(Apply(app, implicits)) { result =>
ValDef.let(Apply(app, implicits)) { result =>
val l = left.seal
val r = right.seal
val b = result.seal.cast[Boolean]
Expand Down
12 changes: 6 additions & 6 deletions tests/run-macros/reflect-select-value-class/assert_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ object scalatest {

cond.unseal.underlyingArgument match {
case t @ Apply(Select(lhs, op), rhs :: Nil) =>
let(lhs) { left =>
let(rhs) { right =>
ValDef.let(lhs) { left =>
ValDef.let(rhs) { right =>
val app = Select.overloaded(left, op, Nil, right :: Nil)
let(app) { result =>
ValDef.let(app) { result =>
val l = left.seal
val r = right.seal
val b = result.seal.cast[Boolean]
Expand All @@ -28,10 +28,10 @@ object scalatest {
}.seal.cast[Unit]
case Apply(f @ Apply(Select(Apply(qual, lhs :: Nil), op), rhs :: Nil), implicits)
if isImplicitMethodType(f.tpe) =>
let(lhs) { left =>
let(rhs) { right =>
ValDef.let(lhs) { left =>
ValDef.let(rhs) { right =>
val app = Select.overloaded(Apply(qual, left :: Nil), op, Nil, right :: Nil)
let(Apply(app, implicits)) { result =>
ValDef.let(Apply(app, implicits)) { result =>
val l = left.seal
val r = right.seal
val b = result.seal.cast[Boolean]
Expand Down
4 changes: 2 additions & 2 deletions tests/run-macros/tasty-unsafe-let/quoted_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ object Macros {

val rhsTerm = rhs.unseal

import qctx.reflect.{let => letTerm}
letTerm(rhsTerm) { rhsId =>
import qctx.reflect._
ValDef.let(rhsTerm) { rhsId =>
Expr.betaReduce('{$body(${rhsId.seal.asInstanceOf[Expr[T]]})}).unseal // Dangerous uncheked cast!
}.seal.cast[Unit]
}
Expand Down
1 change: 0 additions & 1 deletion tests/run-staging/staged-streams_1.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import scala.quoted._
import scala.quoted.staging._
import scala.quoted.util._
import language.experimental.namedTypeArguments

/**
Expand Down