Skip to content

Commit 19a285a

Browse files
committed
Fix Typed abstraction
The typed expression can contain non-Term trees such as Wildcard and Alternatives. The sulution is to type the expression of Typed as a Tree and not a Term. This comes with some complications at the user site where we now need to use `case Typed(expr: Term, _) =>`.
1 parent 8e4dfc1 commit 19a285a

File tree

15 files changed

+45
-28
lines changed

15 files changed

+45
-28
lines changed

compiler/src/scala/quoted/runtime/impl/Matcher.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ object Matcher {
178178

179179
/* Term hole */
180180
// Match a scala.internal.Quoted.patternHole typed as a repeated argument and return the scrutinee tree
181-
case (scrutinee @ Typed(s, tpt1), Typed(TypeApply(patternHole, tpt :: Nil), tpt2))
181+
case (scrutinee @ Typed(s: Term, tpt1), Typed(TypeApply(patternHole, tpt :: Nil), tpt2))
182182
if patternHole.symbol == patternHoleSymbol &&
183183
s.tpe <:< tpt.tpe &&
184184
tpt2.tpe.derivesFrom(defn.RepeatedParamClass) =>

compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ object SourceCode {
428428
inSquare(this += id)
429429
this
430430

431-
case Typed(term, tpt) =>
431+
case Typed(term: Term, tpt) =>
432432
tpt.tpe match {
433433
case Types.Repeated(_) =>
434434
printTree(term)

library/src/scala/quoted/ExprMap.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ trait ExprMap:
5656
tree
5757
case New(tpt) =>
5858
New.copy(tree)(transformTypeTree(tpt)(owner))
59-
case Typed(expr, tpt) =>
59+
case Typed(expr: Term, tpt) =>
6060
val tp = tpt.tpe match
6161
case AppliedType(TypeRef(ThisType(TypeRef(NoPrefix(), "scala")), "<repeated>"), List(tp0: TypeRepr)) =>
6262
TypeRepr.of[Seq].appliedTo(tp0)

library/src/scala/quoted/FromExpr.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ object FromExpr {
8686
def rec(tree: Term): Option[T] = tree match {
8787
case Block(stats, e) => if stats.isEmpty then rec(e) else None
8888
case Inlined(_, bindings, e) => if bindings.isEmpty then rec(e) else None
89-
case Typed(e, _) => rec(e)
89+
case Typed(e: Term, _) => rec(e)
9090
case _ =>
9191
tree.tpe.widenTermRefByName match
9292
case ConstantType(c) => Some(c.value.asInstanceOf[T])

library/src/scala/quoted/Quotes.scala

+7-7
Original file line numberDiff line numberDiff line change
@@ -1101,13 +1101,13 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
11011101
/** Methods of the module object `val Typed` */
11021102
trait TypedModule { this: Typed.type =>
11031103

1104-
/** Create a type ascription `<x: Term>: <tpt: TypeTree>` */
1105-
def apply(expr: Term, tpt: TypeTree): Typed
1104+
/** Create a type ascription `<x: Tree>: <tpt: TypeTree>` */
1105+
def apply(expr: Tree, tpt: TypeTree): Typed
11061106

1107-
def copy(original: Tree)(expr: Term, tpt: TypeTree): Typed
1107+
def copy(original: Tree)(expr: Tree, tpt: TypeTree): Typed
11081108

1109-
/** Matches `<expr: Term>: <tpt: TypeTree>` */
1110-
def unapply(x: Typed): (Term, TypeTree)
1109+
/** Matches `<expr: Tree>: <tpt: TypeTree>` */
1110+
def unapply(x: Typed): (Tree, TypeTree)
11111111
}
11121112

11131113
/** Makes extension methods on `Typed` available without any imports */
@@ -1116,7 +1116,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
11161116
/** Extension methods of `Typed` */
11171117
trait TypedMethods:
11181118
extension (self: Typed)
1119-
def expr: Term
1119+
def expr: Tree
11201120
def tpt: TypeTree
11211121
end extension
11221122
end TypedMethods
@@ -4377,7 +4377,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
43774377
case New(tpt) =>
43784378
New.copy(tree)(transformTypeTree(tpt)(owner))
43794379
case Typed(expr, tpt) =>
4380-
Typed.copy(tree)(transformTerm(expr)(owner), transformTypeTree(tpt)(owner))
4380+
Typed.copy(tree)(transformTree(expr)(owner), transformTypeTree(tpt)(owner))
43814381
case tree: NamedArg =>
43824382
NamedArg.copy(tree)(tree.name, transformTerm(tree.value)(owner))
43834383
case Assign(lhs, rhs) =>

library/src/scala/quoted/Varargs.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ object Varargs {
4242
import quotes.reflect._
4343
def rec(tree: Term): Option[Seq[Expr[T]]] = tree match {
4444
case Repeated(elems, _) => Some(elems.map(x => x.asExpr.asInstanceOf[Expr[T]]))
45-
case Typed(e, _) => rec(e)
45+
case Typed(e: Term, _) => rec(e)
4646
case Block(Nil, e) => rec(e)
4747
case Inlined(_, Nil, e) => rec(e)
4848
case _ => None

scaladoc/src/dotty/tools/scaladoc/tasty/BasicSupport.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ trait BasicSupport:
1616
val dri = annotTerm.tpe.typeSymbol.dri
1717
def inner(t: Term): List[Annotation.AnnotationParameter] = t match {
1818
case i: Ident => List(Annotation.LinkParameter(None, i.tpe.typeSymbol.dri, i.name))
19-
case Typed(term, tpeTree) => inner(term)
19+
case Typed(term: Term, tpeTree) => inner(term)
2020
case SeqLiteral(args, tpeTree) => args.map(_.asInstanceOf[Term]).flatMap(inner)
2121
case Literal(constant) => List(Annotation.PrimitiveParameter(None, constant.show))
2222
case NamedArg(name, Literal(constant)) => List(Annotation.PrimitiveParameter(Some(name), constant.show))

tests/neg-macros/i11483/Macro_1.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ object X {
5151
)
5252
case Apply(f,List()) =>
5353
Apply(TypeApply(Select.unique(m,"pure"),List(Inferred(t.tpe.widen))),List(t))
54-
case Typed(x,tp) => Typed(processTree(x,m), Inferred(TypeRepr.of[F].appliedTo(tp.tpe)) )
54+
case Typed(x: Term,tp) => Typed(processTree(x,m), Inferred(TypeRepr.of[F].appliedTo(tp.tpe)) )
5555
case _ => throw new RuntimeException(s"tree not recoginized: $t")
5656
r
5757

tests/pos-macros/i10910/Macro_1.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ object X:
4848
case Inlined(x,bindings,body) => transform(body) match
4949
case Left(unchanged) => Left(term)
5050
case Right(changed) => Right(Inlined(x,bindings,changed))
51-
case Typed(arg,tp) => transform(arg)
51+
case Typed(arg: Term,tp) => transform(arg)
5252
case Ident(x) => Left(term)
5353
case l@Literal(x) => Left(l)
5454
case other =>

tests/pos-macros/i11401/X_1.scala

+10-10
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class SLSelect[S]:
1616

1717
def fold[S](s0:S)(step: (S,SLSelect[S])=> S): S = {
1818
???
19-
}
19+
}
2020

2121
def fold_async[S](s0:S)(step: (S,SLSelect[S])=> Future[S]): Future[S] = {
2222
???
@@ -27,7 +27,7 @@ class SLSelect[S]:
2727
await(s0.onRead(ch)(f).runAsync())
2828

2929
def runAsync(): Future[S] = ???
30-
30+
3131

3232

3333
object X:
@@ -36,30 +36,30 @@ object X:
3636
processImpl[T]('f)
3737
}
3838

39-
def processImpl[T:Type](t:Expr[T])(using Quotes):Expr[Future[T]] =
39+
def processImpl[T:Type](t:Expr[T])(using Quotes):Expr[Future[T]] =
4040
import quotes.reflect._
4141
val r = processTree[T](t.asTerm)
4242
r.asExprOf[Future[T]]
4343

44-
45-
def processTree[T:Type](using Quotes)(t: quotes.reflect.Term):quotes.reflect.Term =
44+
45+
def processTree[T:Type](using Quotes)(t: quotes.reflect.Term):quotes.reflect.Term =
4646
import quotes.reflect._
4747
val r: Term = t match
4848
case Inlined(_,List(),body) => processTree(body)
49-
case Inlined(d,bindings,body) =>
49+
case Inlined(d,bindings,body) =>
5050
Inlined(d,bindings,processTree[T](body))
5151
case Block(stats,expr) => Block(stats,processTree(expr))
5252
case Apply(Apply(TypeApply(Select(x,"fold"),targs),List(state)),List(fun)) =>
53-
val nFun = processLambda[T](fun)
53+
val nFun = processLambda[T](fun)
5454
Apply(Apply(TypeApply(Select.unique(x,"fold_async"),targs),List(state)),List(nFun))
5555
case Apply(TypeApply(Ident("await"),targs),List(body)) => body
56-
case Typed(x,tp) => Typed(processTree(x), Inferred(TypeRepr.of[Future].appliedTo(tp.tpe)) )
56+
case Typed(x: Term,tp) => Typed(processTree(x), Inferred(TypeRepr.of[Future].appliedTo(tp.tpe)) )
5757
case _ => throw new RuntimeException(s"tree not recoginized: $t")
5858
val checker = new TreeMap() {}
5959
checker.transformTerm(r)(Symbol.spliceOwner)
6060
r
61-
62-
def processLambda[T:Type](using Quotes)(fun: quotes.reflect.Term):quotes.reflect.Term =
61+
62+
def processLambda[T:Type](using Quotes)(fun: quotes.reflect.Term):quotes.reflect.Term =
6363
import quotes.reflect._
6464

6565
def changeArgs(oldArgs:List[Tree], newArgs:List[Tree], body:Term, owner: Symbol):Term =

tests/pos-macros/i12188b/Macro_1.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ object MatchTest {
1010
// test that the constructors work
1111
Block(Nil, Match(param, List(CaseDef(Literal(IntConstant(1)), None, Block(Nil, Literal(UnitConstant()))), CaseDef(Wildcard(), None, Block(Nil, Literal(UnitConstant())))))).asExprOf[Unit]
1212
}
13-
}
13+
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import scala.quoted.*
2+
3+
object MatchTest {
4+
inline def test(a: Int): Unit = ${testImpl('a)}
5+
6+
def testImpl(a: Expr[Any])(using Quotes): Expr[Unit] = {
7+
import quotes.reflect.*
8+
val matchTree = Match(a.asTerm, List(
9+
CaseDef(Literal(IntConstant(1)), None, Block(Nil, Literal(UnitConstant()))),
10+
CaseDef(Alternatives(List(Literal(IntConstant(2)), Literal(IntConstant(3)), Literal(IntConstant(4)))), None, Block(Nil, Literal(UnitConstant()))),
11+
CaseDef(Typed(Alternatives(List(Literal(IntConstant(4)), Literal(IntConstant(5)))), TypeIdent(defn.IntClass)), None, Block(Nil, Literal(UnitConstant()))),
12+
CaseDef(Typed(Wildcard(), TypeIdent(defn.IntClass)), None, Block(Nil, Literal(UnitConstant())))))
13+
matchTree.asExprOf[Unit]
14+
}
15+
}

tests/pos-macros/i12188c/Test_2.scala

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
def test(a: Int) = MatchTest.test(a)

tests/run-custom-args/tasty-interpreter/interpreter/TreeInterpreter.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ abstract class TreeInterpreter[Q <: Quotes & Singleton](using val q: Q) {
152152
case While(cond, body) => log("interpretWhile", tree)(interpretWhile(cond, body))
153153
case Block(stats, expr) => log("interpretBlock", tree)(interpretBlock(stats, expr))
154154
case Literal(const) => log("interpretLiteral", tree)(interpretLiteral(const))
155-
case Typed(expr, _) => log("<interpretTyped>", tree)(eval(expr))
155+
case Typed(expr: Term, _) => log("<interpretTyped>", tree)(eval(expr))
156156
case Repeated(elems, _) => log("<interpretRepeated>", tree)(interpretRepeated(elems.map(elem => eval(elem))))
157157

158158
case _ => throw new MatchError(tree.show(using Printer.TreeStructure))

tests/run-macros/quote-matcher-symantics-3/quoted_1.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ object Const {
132132
case NullConstant() | UnitConstant() | ClassOfConstant(_) => None
133133
case _ => Some(c.value.asInstanceOf[T])
134134
case Block(Nil, e) => rec(e)
135-
case Typed(e, _) => rec(e)
135+
case Typed(e: Term, _) => rec(e)
136136
case Inlined(_, Nil, e) => rec(e)
137137
case _ => None
138138
}

0 commit comments

Comments
 (0)