Skip to content

Decouple quoted Type interface from encoding #9485

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

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

@tu lazy val QuotedStagedClass: Symbol = requiredPackage("scala.quoted").typeRef.select("Staged".toTypeName).typeSymbol

@tu lazy val QuotedTypeClass: ClassSymbol = requiredClass("scala.quoted.Type")
@tu lazy val QuotedType_splice: Symbol = QuotedTypeClass.requiredType(tpnme.spliceType)

@tu lazy val QuotedTypeModule: Symbol = QuotedTypeClass.companionModule
@tu lazy val QuotedTypeModule_apply: Symbol = QuotedTypeModule.requiredMethod("apply")

@tu lazy val QuoteContextClass: ClassSymbol = requiredClass("scala.quoted.QuoteContext")

@tu lazy val LiftableModule: Symbol = requiredModule("scala.quoted.Liftable")
Expand Down Expand Up @@ -714,12 +722,6 @@ class Definitions {
@tu lazy val InternalQuotedTypeModule: Symbol = requiredModule("scala.internal.quoted.Type")
@tu lazy val InternalQuotedType_unapply: Symbol = InternalQuotedTypeModule.requiredMethod(nme.unapply)

@tu lazy val QuotedTypeClass: ClassSymbol = requiredClass("scala.quoted.Type")
@tu lazy val QuotedType_splice: Symbol = QuotedTypeClass.requiredType(tpnme.spliceType)

@tu lazy val QuotedTypeModule: Symbol = QuotedTypeClass.companionModule
@tu lazy val QuotedTypeModule_apply: Symbol = QuotedTypeModule.requiredMethod("apply")

@tu lazy val TastyReflectionClass: ClassSymbol = requiredClass("scala.tasty.Reflection")

@tu lazy val Unpickler_unpickleExpr: Symbol = requiredMethod("scala.internal.quoted.Unpickler.unpickleExpr")
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ object PickledQuotes {
}

/** Transform the expression into its fully spliced TypeTree */
def quotedTypeToTree(tpe: quoted.Type[?])(using Context): Tree = {
def quotedTypeToTree(tpe: quoted.Type)(using Context): Tree = {
val tpe1 = tpe.asInstanceOf[scala.internal.quoted.Type[Tree]]
QuoteContext.checkScopeId(tpe1.scopeId)
healOwner(tpe1.typeTree)
Expand Down Expand Up @@ -91,7 +91,7 @@ object PickledQuotes {
else
// Replaces type holes generated by ReifyQuotes (non-spliced types).
// These are types defined in a quote and used at the same level in a nested quote.
val quotedType = splices(idx).asInstanceOf[Seq[Any] => quoted.Type[?]](reifiedArgs)
val quotedType = splices(idx).asInstanceOf[Seq[Any] => quoted.Type](reifiedArgs)
PickledQuotes.quotedTypeToTree(quotedType)
case tree: Select =>
// Retain selected members
Expand Down Expand Up @@ -134,7 +134,7 @@ object PickledQuotes {
assert(tdef.symbol.hasAnnotation(defn.InternalQuoted_QuoteTypeTagAnnot))
val tree = tdef.rhs match
case TypeBoundsTree(_, Hole(_, idx, args), _) =>
val quotedType = splices(idx).asInstanceOf[Seq[Any] => quoted.Type[?]](args)
val quotedType = splices(idx).asInstanceOf[Seq[Any] => quoted.Type](args)
PickledQuotes.quotedTypeToTree(quotedType)
case TypeBoundsTree(_, tpt, _) =>
tpt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
* Emits and error if `T` cannot be healed and returns `T`.
*/
protected def tryHeal(sym: Symbol, tp: TypeRef, pos: SourcePosition)(using Context): TypeRef = {
val reqType = defn.QuotedTypeClass.typeRef.appliedTo(tp)
val reqType = defn.QuotedStagedClass.typeRef.appliedTo(tp)
val tag = ctx.typer.inferImplicitArg(reqType, pos.span)
tag.tpe match

Expand Down
6 changes: 4 additions & 2 deletions compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ class ReifyQuotes extends MacroTransform {
}
assert(tpw.isInstanceOf[ValueType])
val argTpe =
if (tree.isType) defn.QuotedTypeClass.typeRef.appliedTo(tpw)
if (tree.isType) defn.QuotedStagedClass.typeRef.appliedTo(tpw)
else defn.FunctionType(1, isContextual = true).appliedTo(defn.QuoteContextClass.typeRef, defn.QuotedExprClass.typeRef.appliedTo(tpw))
val selectArg = arg.select(nme.apply).appliedTo(Literal(Constant(i))).cast(argTpe)
val capturedArg = SyntheticValDef(UniqueName.fresh(tree.symbol.name.toTermName).toTermName, selectArg)
Expand Down Expand Up @@ -331,7 +331,9 @@ class ReifyQuotes extends MacroTransform {
def getTypeHoleType(using Context) = new TypeMap() {
override def apply(tp: Type): Type = tp match
case tp: TypeRef if tp.typeSymbol.isTypeSplice =>
apply(tp.dealias)
val dealiased = tp.dealias
if tp == dealiased then apply(tp.symbol.info.hiBound)
else apply(tp.dealias)
case tp @ TypeRef(pre, _) if pre == NoPrefix || pre.termSymbol.isLocal =>
val hiBound = tp.typeSymbol.info match
case info @ ClassInfo(_, _, classParents, _, _) => classParents.reduce(_ & _)
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ trait QuotesAndSplices {
case _ => TypeBounds.empty
val typeSym = newSymbol(spliceOwner(ctx), name, EmptyFlags, typeSymInfo, NoSymbol, tree.expr.span)
typeSym.addAnnotation(Annotation(New(ref(defn.InternalQuotedMatcher_patternTypeAnnot.typeRef)).withSpan(tree.expr.span)))
val pat = typedPattern(tree.expr, defn.QuotedTypeClass.typeRef.appliedTo(typeSym.typeRef))(
val pat = typedPattern(tree.expr, defn.QuotedStagedClass.typeRef.appliedTo(typeSym.typeRef))(
using spliceContext.retractMode(Mode.QuotedPattern).withOwner(spliceOwner(ctx)))
pat.select(tpnme.spliceType)
else
Expand Down Expand Up @@ -298,7 +298,7 @@ trait QuotesAndSplices {
if (variance == -1)
tdef.symbol.addAnnotation(Annotation(New(ref(defn.InternalQuotedMatcher_fromAboveAnnot.typeRef)).withSpan(tdef.span)))
val bindingType = getBinding(tdef.symbol).symbol.typeRef
val bindingTypeTpe = AppliedType(defn.QuotedTypeClass.typeRef, bindingType :: Nil)
val bindingTypeTpe = AppliedType(defn.QuotedStagedClass.typeRef, bindingType :: Nil)
val bindName = tdef.name.toString.stripPrefix("$").toTermName
val sym = newPatternBoundSymbol(bindName, bindingTypeTpe, tdef.span, flags = ImplicitTerm)(using ctx0)
buff += Bind(sym, untpd.Ident(nme.WILDCARD).withType(bindingTypeTpe)).withSpan(tdef.span)
Expand Down Expand Up @@ -436,7 +436,7 @@ trait QuotesAndSplices {
else typed(untpd.Tuple(splices.map(x => untpd.TypedSplice(replaceBindingsInTree.transform(x)))).withSpan(quoted.span), patType)

val unapplySym = if (tree.quoted.isTerm) defn.InternalQuotedExpr_unapply else defn.InternalQuotedType_unapply
val quoteClass = if (tree.quoted.isTerm) defn.QuotedExprClass else defn.QuotedTypeClass
val quoteClass = if (tree.quoted.isTerm) defn.QuotedExprClass else defn.QuotedStagedClass
val quotedPattern =
if (tree.quoted.isTerm) ref(defn.InternalQuoted_exprQuote.termRef).appliedToType(defn.AnyType).appliedTo(shape).select(nme.apply).appliedTo(qctx)
else ref(defn.QuotedTypeModule_apply.termRef).appliedToTypeTree(shape).select(nme.apply).appliedTo(qctx)
Expand Down
10 changes: 5 additions & 5 deletions library/src-bootstrapped/scala/quoted/Expr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ abstract class Expr[+T] private[scala] {
!scala.internal.quoted.Expr.unapply[EmptyTuple, EmptyTuple](this)(using that, false, qctx).isEmpty

/** Checked cast to a `quoted.Expr[U]` */
def cast[U](using tp: scala.quoted.Type[U])(using qctx: QuoteContext): scala.quoted.Expr[U] = {
def cast[U](using tp: scala.quoted.Staged[U])(using qctx: QuoteContext): scala.quoted.Expr[U] = {
val tree = this.unseal
val expectedType = tp.unseal.tpe
if (tree.tpe <:< expectedType)
Expand Down Expand Up @@ -118,7 +118,7 @@ object Expr {
* `'{ Seq($e1, $e2, ...) }` typed as an `Expr[Seq[T]]`
* ```
*/
def ofSeq[T](xs: Seq[Expr[T]])(using tp: Type[T], qctx: QuoteContext): Expr[Seq[T]] = Varargs(xs)
def ofSeq[T](xs: Seq[Expr[T]])(using tp: Staged[T], qctx: QuoteContext): Expr[Seq[T]] = Varargs(xs)

/** Lifts this list of expressions into an expression of a list
*
Expand All @@ -127,7 +127,7 @@ object Expr {
* to an expression equivalent to
* `'{ List($e1, $e2, ...) }` typed as an `Expr[List[T]]`
*/
def ofList[T](xs: Seq[Expr[T]])(using Type[T], QuoteContext): Expr[List[T]] =
def ofList[T](xs: Seq[Expr[T]])(using Staged[T], QuoteContext): Expr[List[T]] =
if (xs.isEmpty) '{ Nil } else '{ List(${Varargs(xs)}: _*) }

/** Lifts this sequence of expressions into an expression of a tuple
Expand Down Expand Up @@ -191,7 +191,7 @@ object Expr {
}

/** Given a tuple of the form `(Expr[A1], ..., Expr[An])`, outputs a tuple `Expr[(A1, ..., An)]`. */
def ofTuple[T <: Tuple: Tuple.IsMappedBy[Expr]: Type](tup: T)(using qctx: QuoteContext): Expr[Tuple.InverseMap[T, Expr]] = {
def ofTuple[T <: Tuple: Tuple.IsMappedBy[Expr]: Staged](tup: T)(using qctx: QuoteContext): Expr[Tuple.InverseMap[T, Expr]] = {
val elems: Seq[Expr[Any]] = tup.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Expr[Any]]]
ofTupleFromSeq(elems).cast[Tuple.InverseMap[T, Expr]]
}
Expand All @@ -204,7 +204,7 @@ object Expr {
* @param tpe quoted type of the implicit parameter
* @param qctx current context
*/
def summon[T](using tpe: Type[T])(using qctx: QuoteContext): Option[Expr[T]] = {
def summon[T](using tpe: Staged[T])(using qctx: QuoteContext): Option[Expr[T]] = {
import qctx.tasty._
searchImplicit(tpe.unseal.tpe) match {
case iss: ImplicitSearchSuccess => Some(iss.tree.seal.asInstanceOf[Expr[T]])
Expand Down
2 changes: 1 addition & 1 deletion library/src-bootstrapped/scala/quoted/Lambda.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ object Lambda {
* body('{3}) // returns '{ println(3) }
* ```
*/
def unapply[F, Args <: Tuple, Res, G](expr: Expr[F])(using qctx: QuoteContext, tf: TupledFunction[F, Args => Res], tg: TupledFunction[G, Tuple.Map[Args, Expr] => Expr[Res]], functionType: Type[F]): Option[/*QuoteContext ?=>*/ G] = {
def unapply[F, Args <: Tuple, Res, G](expr: Expr[F])(using qctx: QuoteContext, tf: TupledFunction[F, Args => Res], tg: TupledFunction[G, Tuple.Map[Args, Expr] => Expr[Res]], functionType: Staged[F]): Option[/*QuoteContext ?=>*/ G] = {
import qctx.tasty._
val argTypes = functionType.unseal.tpe match
case AppliedType(_, functionArguments) => functionArguments.init.asInstanceOf[List[Type]]
Expand Down
Loading