Skip to content

Cleanup reification of primitive liftables #7268

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
11 changes: 11 additions & 0 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -630,12 +630,23 @@ class Definitions {

@tu lazy val QuotedExprClass: ClassSymbol = ctx.requiredClass("scala.quoted.Expr")
@tu lazy val QuotedExprModule: Symbol = QuotedExprClass.companionModule
@tu lazy val QuotedExprModule_nullExpr: Symbol = QuotedExprModule.requiredMethod(nme.nullExpr)
@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")
@tu lazy val LiftableModule_ByteIsLiftable: Symbol = LiftableModule.requiredMethod("ByteIsLiftable")
@tu lazy val LiftableModule_ShortIsLiftable: Symbol = LiftableModule.requiredMethod("ShortIsLiftable")
@tu lazy val LiftableModule_IntIsLiftable: Symbol = LiftableModule.requiredMethod("IntIsLiftable")
@tu lazy val LiftableModule_LongIsLiftable: Symbol = LiftableModule.requiredMethod("LongIsLiftable")
@tu lazy val LiftableModule_FloatIsLiftable: Symbol = LiftableModule.requiredMethod("FloatIsLiftable")
@tu lazy val LiftableModule_DoubleIsLiftable: Symbol = LiftableModule.requiredMethod("DoubleIsLiftable")
@tu lazy val LiftableModule_CharIsLiftable: Symbol = LiftableModule.requiredMethod("CharIsLiftable")
@tu lazy val LiftableModule_StringIsLiftable: Symbol = LiftableModule.requiredMethod("StringIsLiftable")

@tu lazy val InternalQuotedModule: Symbol = ctx.requiredModule("scala.internal.Quoted")
@tu lazy val InternalQuoted_exprQuote : Symbol = InternalQuotedModule.requiredMethod("exprQuote")
Expand Down
3 changes: 3 additions & 0 deletions compiler/src/dotty/tools/dotc/core/StdNames.scala
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ object StdNames {
val notifyAll_ : N = "notifyAll"
val notify_ : N = "notify"
val null_ : N = "null"
val nullExpr: N = "nullExpr"
val ofDim: N = "ofDim"
val opaque: N = "opaque"
val ordinal: N = "ordinal"
Expand Down Expand Up @@ -556,6 +557,7 @@ object StdNames {
val thisPrefix : N = "thisPrefix"
val throw_ : N = "throw"
val toArray: N = "toArray"
val toExpr: N = "toExpr"
val toList: N = "toList"
val toObjectArray : N = "toObjectArray"
val toSeq: N = "toSeq"
Expand All @@ -569,6 +571,7 @@ object StdNames {
val unapply: N = "unapply"
val unapplySeq: N = "unapplySeq"
val unbox: N = "unbox"
val unitExpr: N = "unitExpr"
val universe: N = "universe"
val update: N = "update"
val updateDynamic: N = "updateDynamic"
Expand Down
46 changes: 22 additions & 24 deletions compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -206,25 +206,23 @@ class ReifyQuotes extends MacroTransform {
qctx
}

def liftedValue[T](value: T, name: TermName) =
ref(defn.LiftableModule)
.select(name).appliedToType(originalTp)
.select("toExpr".toTermName).appliedTo(Literal(Constant(value)))

def pickleAsValue[T](value: T) =
value match {
case null => ref(defn.QuotedExprModule).select("nullExpr".toTermName)
case _: Unit => ref(defn.QuotedExprModule).select("unitExpr".toTermName)
case _: Boolean => liftedValue(value, "Liftable_Boolean_delegate".toTermName)
case _: Byte => liftedValue(value, "Liftable_Byte_delegate".toTermName)
case _: Short => liftedValue(value, "Liftable_Short_delegate".toTermName)
case _: Int => liftedValue(value, "Liftable_Int_delegate".toTermName)
case _: Long => liftedValue(value, "Liftable_Long_delegate".toTermName)
case _: Float => liftedValue(value, "Liftable_Float_delegate".toTermName)
case _: Double => liftedValue(value, "Liftable_Double_delegate".toTermName)
case _: Char => liftedValue(value, "Liftable_Char_delegate".toTermName)
case _: String => liftedValue(value, "Liftable_String_delegate".toTermName)
def pickleAsLiteral(lit: Literal) = {
def liftedValue(lifter: Symbol) =
ref(lifter).appliedToType(originalTp).select(nme.toExpr).appliedTo(lit)
lit.const.tag match {
case Constants.NullTag => ref(defn.QuotedExprModule_nullExpr)
case Constants.UnitTag => ref(defn.QuotedExprModule_unitExpr)
case Constants.BooleanTag => liftedValue(defn.LiftableModule_BooleanIsLiftable)
case Constants.ByteTag => liftedValue(defn.LiftableModule_ByteIsLiftable)
case Constants.ShortTag => liftedValue(defn.LiftableModule_ShortIsLiftable)
case Constants.IntTag => liftedValue(defn.LiftableModule_IntIsLiftable)
case Constants.LongTag => liftedValue(defn.LiftableModule_LongIsLiftable)
case Constants.FloatTag => liftedValue(defn.LiftableModule_FloatIsLiftable)
case Constants.DoubleTag => liftedValue(defn.LiftableModule_DoubleIsLiftable)
case Constants.CharTag => liftedValue(defn.LiftableModule_CharIsLiftable)
case Constants.StringTag => liftedValue(defn.LiftableModule_StringIsLiftable)
}
}

def pickleAsTasty() = {
val meth =
Expand All @@ -243,8 +241,8 @@ class ReifyQuotes extends MacroTransform {
if (splices.isEmpty && body.symbol.isPrimitiveValueClass) tag(s"${body.symbol.name}Tag")
else pickleAsTasty().select(nme.apply).appliedTo(qctx)
}
else toValue(body) match {
case Some(value) => pickleAsValue(value)
else getLiteral(body) match {
case Some(lit) => pickleAsLiteral(lit)
case _ => pickleAsTasty()
}
}
Expand Down Expand Up @@ -429,10 +427,10 @@ object ReifyQuotes {

val name: String = "reifyQuotes"

def toValue(tree: tpd.Tree): Option[Any] = tree match {
case Literal(Constant(c)) => Some(c)
case Block(Nil, e) => toValue(e)
case Inlined(_, Nil, e) => toValue(e)
def getLiteral(tree: tpd.Tree): Option[Literal] = tree match {
case tree: Literal => Some(tree)
case Block(Nil, e) => getLiteral(e)
case Inlined(_, Nil, e) => getLiteral(e)
case _ => None
}

Expand Down
18 changes: 9 additions & 9 deletions library/src-bootstrapped/scala/quoted/Liftable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ trait Liftable[T] {
*/
object Liftable {

given Liftable_Boolean_delegate[T <: Boolean] : Liftable[T] = new PrimitiveLiftable
given Liftable_Byte_delegate[T <: Byte] : Liftable[T] = new PrimitiveLiftable
given Liftable_Short_delegate[T <: Short] : Liftable[T] = new PrimitiveLiftable
given Liftable_Int_delegate[T <: Int] : Liftable[T] = new PrimitiveLiftable
given Liftable_Long_delegate[T <: Long] : Liftable[T] = new PrimitiveLiftable
given Liftable_Float_delegate[T <: Float] : Liftable[T] = new PrimitiveLiftable
given Liftable_Double_delegate[T <: Double] : Liftable[T] = new PrimitiveLiftable
given Liftable_Char_delegate[T <: Char] : Liftable[T] = new PrimitiveLiftable
given Liftable_String_delegate[T <: String] : Liftable[T] = new PrimitiveLiftable
given BooleanIsLiftable[T <: Boolean] : Liftable[T] = new PrimitiveLiftable
given ByteIsLiftable[T <: Byte] : Liftable[T] = new PrimitiveLiftable
given ShortIsLiftable[T <: Short] : Liftable[T] = new PrimitiveLiftable
given IntIsLiftable[T <: Int] : Liftable[T] = new PrimitiveLiftable
given LongIsLiftable[T <: Long] : Liftable[T] = new PrimitiveLiftable
given FloatIsLiftable[T <: Float] : Liftable[T] = new PrimitiveLiftable
given DoubleIsLiftable[T <: Double] : Liftable[T] = new PrimitiveLiftable
given CharIsLiftable[T <: Char] : Liftable[T] = new PrimitiveLiftable
given StringIsLiftable[T <: String] : Liftable[T] = new PrimitiveLiftable

private class PrimitiveLiftable[T <: Unit | Null | Int | Boolean | Byte | Short | Int | Long | Float | Double | Char | String] extends Liftable[T] {
/** Lift a primitive value `n` into `'{ n }` */
Expand Down