Skip to content

Commit 57cc41a

Browse files
committed
Decouple quoted Type interface from encoding
Before, `quoted.Type` was defined as ```scala // old class Type[X <: AnyKind]: type T = X ``` Where `T` is the proper type of the instance of a `Type`. This is the type used for all operations within the compiler. The only purpose of the type `X` was to be able to write context bounds as `[X: Type]` and staged types `Type[X]` instead of `Type { type T = X }`. Unfortunately, the type `X` makes the assumption that `X` is known, which implies that instances of `Type` with unknown types need to be encoded with a whildcard type. A `val t: Type[?] = ...` is unusable as we cannot heal staged wildcard types, even though we do have a `t.T` which can be handled. Now, we change the definition of `Type` to only have the type member. ```scala // new class QuotedType: type T <: AnyKind ``` This solves the aforementioned limitations with unkown staged types. Now we are also able to remove the wildcard from `QuoteContext.tasty.Type.seal` and the result can be used in quotes. To keep the context bound syntax and provide more descriptive name for the concept, we defined the `quoted.Type` type alias. ```scala type Type[X <: AnyKind] = QuotedType { type T = X } ```
1 parent d488d31 commit 57cc41a

File tree

202 files changed

+595
-459
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

202 files changed

+595
-459
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -682,9 +682,9 @@ class Definitions {
682682
@tu lazy val QuotedExprModule_nullExpr: Symbol = QuotedExprModule.requiredMethod(nme.nullExpr)
683683
@tu lazy val QuotedExprModule_unitExpr: Symbol = QuotedExprModule.requiredMethod(nme.unitExpr)
684684

685-
@tu lazy val QuotedStagedClass: Symbol = requiredPackage("scala.quoted").typeRef.select("Staged".toTypeName).typeSymbol
685+
@tu lazy val QuotedTypeAliasClass: Symbol = requiredPackage("scala.quoted").typeRef.select("Type".toTypeName).typeSymbol
686686

687-
@tu lazy val QuotedTypeClass: ClassSymbol = requiredClass("scala.quoted.Type")
687+
@tu lazy val QuotedTypeClass: ClassSymbol = requiredClass("scala.quoted.QuotedType")
688688
@tu lazy val QuotedType_splice: Symbol = QuotedTypeClass.requiredType(tpnme.spliceType)
689689

690690
@tu lazy val QuotedTypeModule: Symbol = QuotedTypeClass.companionModule

compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ object PickledQuotes {
4444
}
4545

4646
/** Transform the expression into its fully spliced TypeTree */
47-
def quotedTypeToTree(tpe: quoted.Type)(using Context): Tree = {
47+
def quotedTypeToTree(tpe: quoted.QuotedType)(using Context): Tree = {
4848
val tpe1 = tpe.asInstanceOf[scala.internal.quoted.Type[Tree]]
4949
QuoteContext.checkScopeId(tpe1.scopeId)
5050
healOwner(tpe1.typeTree)
@@ -91,7 +91,7 @@ object PickledQuotes {
9191
else
9292
// Replaces type holes generated by ReifyQuotes (non-spliced types).
9393
// These are types defined in a quote and used at the same level in a nested quote.
94-
val quotedType = splices(idx).asInstanceOf[Seq[Any] => quoted.Type](reifiedArgs)
94+
val quotedType = splices(idx).asInstanceOf[Seq[Any] => quoted.QuotedType](reifiedArgs)
9595
PickledQuotes.quotedTypeToTree(quotedType)
9696
case tree: Select =>
9797
// Retain selected members
@@ -134,7 +134,7 @@ object PickledQuotes {
134134
assert(tdef.symbol.hasAnnotation(defn.InternalQuoted_QuoteTypeTagAnnot))
135135
val tree = tdef.rhs match
136136
case TypeBoundsTree(_, Hole(_, idx, args), _) =>
137-
val quotedType = splices(idx).asInstanceOf[Seq[Any] => quoted.Type](args)
137+
val quotedType = splices(idx).asInstanceOf[Seq[Any] => quoted.QuotedType](args)
138138
PickledQuotes.quotedTypeToTree(quotedType)
139139
case TypeBoundsTree(_, tpt, _) =>
140140
tpt

compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
222222
* Emits and error if `T` cannot be healed and returns `T`.
223223
*/
224224
protected def tryHeal(sym: Symbol, tp: TypeRef, pos: SourcePosition)(using Context): TypeRef = {
225-
val reqType = defn.QuotedStagedClass.typeRef.appliedTo(tp)
225+
val reqType = defn.QuotedTypeAliasClass.typeRef.appliedTo(tp)
226226
val tag = ctx.typer.inferImplicitArg(reqType, pos.span)
227227
tag.tpe match
228228

compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ class ReifyQuotes extends MacroTransform {
261261
}
262262
assert(tpw.isInstanceOf[ValueType])
263263
val argTpe =
264-
if (tree.isType) defn.QuotedStagedClass.typeRef.appliedTo(tpw)
264+
if (tree.isType) defn.QuotedTypeAliasClass.typeRef.appliedTo(tpw)
265265
else defn.FunctionType(1, isContextual = true).appliedTo(defn.QuoteContextClass.typeRef, defn.QuotedExprClass.typeRef.appliedTo(tpw))
266266
val selectArg = arg.select(nme.apply).appliedTo(Literal(Constant(i))).cast(argTpe)
267267
val capturedArg = SyntheticValDef(UniqueName.fresh(tree.symbol.name.toTermName).toTermName, selectArg)

compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ trait QuotesAndSplices {
167167
case _ => TypeBounds.empty
168168
val typeSym = newSymbol(spliceOwner(ctx), name, EmptyFlags, typeSymInfo, NoSymbol, tree.expr.span)
169169
typeSym.addAnnotation(Annotation(New(ref(defn.InternalQuotedMatcher_patternTypeAnnot.typeRef)).withSpan(tree.expr.span)))
170-
val pat = typedPattern(tree.expr, defn.QuotedStagedClass.typeRef.appliedTo(typeSym.typeRef))(
170+
val pat = typedPattern(tree.expr, defn.QuotedTypeAliasClass.typeRef.appliedTo(typeSym.typeRef))(
171171
using spliceContext.retractMode(Mode.QuotedPattern).withOwner(spliceOwner(ctx)))
172172
pat.select(tpnme.spliceType)
173173
else
@@ -298,7 +298,7 @@ trait QuotesAndSplices {
298298
if (variance == -1)
299299
tdef.symbol.addAnnotation(Annotation(New(ref(defn.InternalQuotedMatcher_fromAboveAnnot.typeRef)).withSpan(tdef.span)))
300300
val bindingType = getBinding(tdef.symbol).symbol.typeRef
301-
val bindingTypeTpe = AppliedType(defn.QuotedStagedClass.typeRef, bindingType :: Nil)
301+
val bindingTypeTpe = AppliedType(defn.QuotedTypeAliasClass.typeRef, bindingType :: Nil)
302302
val bindName = tdef.name.toString.stripPrefix("$").toTermName
303303
val sym = newPatternBoundSymbol(bindName, bindingTypeTpe, tdef.span, flags = ImplicitTerm)(using ctx0)
304304
buff += Bind(sym, untpd.Ident(nme.WILDCARD).withType(bindingTypeTpe)).withSpan(tdef.span)
@@ -436,7 +436,7 @@ trait QuotesAndSplices {
436436
else typed(untpd.Tuple(splices.map(x => untpd.TypedSplice(replaceBindingsInTree.transform(x)))).withSpan(quoted.span), patType)
437437

438438
val unapplySym = if (tree.quoted.isTerm) defn.InternalQuotedExpr_unapply else defn.InternalQuotedType_unapply
439-
val quoteClass = if (tree.quoted.isTerm) defn.QuotedExprClass else defn.QuotedStagedClass
439+
val quoteClass = if (tree.quoted.isTerm) defn.QuotedExprClass else defn.QuotedTypeAliasClass
440440
val quotedPattern =
441441
if (tree.quoted.isTerm) ref(defn.InternalQuoted_exprQuote.termRef).appliedToType(defn.AnyType).appliedTo(shape).select(nme.apply).appliedTo(qctx)
442442
else ref(defn.QuotedTypeModule_apply.termRef).appliedToTypeTree(shape).select(nme.apply).appliedTo(qctx)

library/src-bootstrapped/scala/quoted/Expr.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ abstract class Expr[+T] private[scala] {
4141
!scala.internal.quoted.Expr.unapply[EmptyTuple, EmptyTuple](this)(using that, false, qctx).isEmpty
4242

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

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

133133
/** Lifts this sequence of expressions into an expression of a tuple
@@ -191,7 +191,7 @@ object Expr {
191191
}
192192

193193
/** Given a tuple of the form `(Expr[A1], ..., Expr[An])`, outputs a tuple `Expr[(A1, ..., An)]`. */
194-
def ofTuple[T <: Tuple: Tuple.IsMappedBy[Expr]: Staged](tup: T)(using qctx: QuoteContext): Expr[Tuple.InverseMap[T, Expr]] = {
194+
def ofTuple[T <: Tuple: Tuple.IsMappedBy[Expr]: Type](tup: T)(using qctx: QuoteContext): Expr[Tuple.InverseMap[T, Expr]] = {
195195
val elems: Seq[Expr[Any]] = tup.asInstanceOf[Product].productIterator.toSeq.asInstanceOf[Seq[Expr[Any]]]
196196
ofTupleFromSeq(elems).cast[Tuple.InverseMap[T, Expr]]
197197
}
@@ -204,7 +204,7 @@ object Expr {
204204
* @param tpe quoted type of the implicit parameter
205205
* @param qctx current context
206206
*/
207-
def summon[T](using tpe: Staged[T])(using qctx: QuoteContext): Option[Expr[T]] = {
207+
def summon[T](using tpe: Type[T])(using qctx: QuoteContext): Option[Expr[T]] = {
208208
import qctx.tasty._
209209
searchImplicit(tpe.unseal.tpe) match {
210210
case iss: ImplicitSearchSuccess => Some(iss.tree.seal.asInstanceOf[Expr[T]])

library/src-bootstrapped/scala/quoted/Lambda.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ object Lambda {
1515
* body('{3}) // returns '{ println(3) }
1616
* ```
1717
*/
18-
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] = {
18+
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] = {
1919
import qctx.tasty._
2020
val argTypes = functionType.unseal.tpe match
2121
case AppliedType(_, functionArguments) => functionArguments.init.asInstanceOf[List[Type]]

0 commit comments

Comments
 (0)