Skip to content

Commit b01b407

Browse files
committed
Extend SplicePattern with typeargs
1 parent 10b1a74 commit b01b407

File tree

9 files changed

+35
-20
lines changed

9 files changed

+35
-20
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2006,7 +2006,7 @@ object desugar {
20062006
case Quote(body, _) =>
20072007
new UntypedTreeTraverser {
20082008
def traverse(tree: untpd.Tree)(using Context): Unit = tree match {
2009-
case SplicePattern(body, _) => collect(body)
2009+
case SplicePattern(body, _, _) => collect(body)
20102010
case _ => traverseChildren(tree)
20112011
}
20122012
}.traverse(body)

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
816816
}
817817
private object quotePatVars extends TreeAccumulator[List[Symbol]] {
818818
def apply(syms: List[Symbol], tree: Tree)(using Context) = tree match {
819-
case SplicePattern(pat, _) => outer.apply(syms, pat)
819+
case SplicePattern(pat, _, _) => outer.apply(syms, pat)
820820
case _ => foldOver(syms, tree)
821821
}
822822
}

compiler/src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,7 @@ object Trees {
762762
* @param body The tree that was spliced
763763
* @param args The arguments of the splice (the HOAS arguments)
764764
*/
765-
case class SplicePattern[+T <: Untyped] private[ast] (body: Tree[T], args: List[Tree[T]])(implicit @constructorOnly src: SourceFile)
765+
case class SplicePattern[+T <: Untyped] private[ast] (body: Tree[T], typeargs: List[Tree[T]], args: List[Tree[T]])(implicit @constructorOnly src: SourceFile)
766766
extends TermTree[T] {
767767
type ThisTree[+T <: Untyped] = SplicePattern[T]
768768
}
@@ -1360,9 +1360,9 @@ object Trees {
13601360
case tree: QuotePattern if (bindings eq tree.bindings) && (body eq tree.body) && (quotes eq tree.quotes) => tree
13611361
case _ => finalize(tree, untpd.QuotePattern(bindings, body, quotes)(sourceFile(tree)))
13621362
}
1363-
def SplicePattern(tree: Tree)(body: Tree, args: List[Tree])(using Context): SplicePattern = tree match {
1364-
case tree: SplicePattern if (body eq tree.body) && (args eq tree.args) => tree
1365-
case _ => finalize(tree, untpd.SplicePattern(body, args)(sourceFile(tree)))
1363+
def SplicePattern(tree: Tree)(body: Tree, typeargs: List[Tree], args: List[Tree])(using Context): SplicePattern = tree match {
1364+
case tree: SplicePattern if (body eq tree.body) && (typeargs eq tree.typeargs) & (args eq tree.args) => tree
1365+
case _ => finalize(tree, untpd.SplicePattern(body, typeargs, args)(sourceFile(tree)))
13661366
}
13671367
def SingletonTypeTree(tree: Tree)(ref: Tree)(using Context): SingletonTypeTree = tree match {
13681368
case tree: SingletonTypeTree if (ref eq tree.ref) => tree
@@ -1607,8 +1607,8 @@ object Trees {
16071607
cpy.Splice(tree)(transform(expr)(using spliceContext))
16081608
case tree @ QuotePattern(bindings, body, quotes) =>
16091609
cpy.QuotePattern(tree)(transform(bindings), transform(body)(using quoteContext), transform(quotes))
1610-
case tree @ SplicePattern(body, args) =>
1611-
cpy.SplicePattern(tree)(transform(body)(using spliceContext), transform(args))
1610+
case tree @ SplicePattern(body, targs, args) =>
1611+
cpy.SplicePattern(tree)(transform(body)(using spliceContext), transform(targs), transform(args))
16121612
case tree @ Hole(isTerm, idx, args, content) =>
16131613
cpy.Hole(tree)(isTerm, idx, transform(args), transform(content))
16141614
case _ =>
@@ -1756,8 +1756,8 @@ object Trees {
17561756
this(x, expr)(using spliceContext)
17571757
case QuotePattern(bindings, body, quotes) =>
17581758
this(this(this(x, bindings), body)(using quoteContext), quotes)
1759-
case SplicePattern(body, args) =>
1760-
this(this(x, body)(using spliceContext), args)
1759+
case SplicePattern(body, typeargs, args) =>
1760+
this(this(this(x, body)(using spliceContext), typeargs), args)
17611761
case Hole(_, _, args, content) =>
17621762
this(this(x, args), content)
17631763
case _ =>

compiler/src/dotty/tools/dotc/ast/untpd.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
409409
def Quote(body: Tree, tags: List[Tree])(implicit src: SourceFile): Quote = new Quote(body, tags)
410410
def Splice(expr: Tree)(implicit src: SourceFile): Splice = new Splice(expr)
411411
def QuotePattern(bindings: List[Tree], body: Tree, quotes: Tree)(implicit src: SourceFile): QuotePattern = new QuotePattern(bindings, body, quotes)
412-
def SplicePattern(body: Tree, args: List[Tree])(implicit src: SourceFile): SplicePattern = new SplicePattern(body, args)
412+
def SplicePattern(body: Tree, typeargs: List[Tree], args: List[Tree])(implicit src: SourceFile): SplicePattern = new SplicePattern(body, typeargs, args)
413413
def TypeTree()(implicit src: SourceFile): TypeTree = new TypeTree()
414414
def InferredTypeTree()(implicit src: SourceFile): TypeTree = new InferredTypeTree()
415415
def SingletonTypeTree(ref: Tree)(implicit src: SourceFile): SingletonTypeTree = new SingletonTypeTree(ref)

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1808,7 +1808,7 @@ object Parsers {
18081808
syntaxError(em"$msg\n\nHint: $hint", Span(start, in.lastOffset))
18091809
Ident(nme.ERROR.toTypeName)
18101810
else if inPattern then
1811-
SplicePattern(expr, Nil)
1811+
SplicePattern(expr, Nil, Nil)
18121812
else
18131813
Splice(expr)
18141814
}

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
749749
val open = if (body.isTerm) keywordStr("{") else keywordStr("[")
750750
val close = if (body.isTerm) keywordStr("}") else keywordStr("]")
751751
keywordStr("'") ~ quotesText ~ open ~ bindingsText ~ toTextGlobal(body) ~ close
752-
case SplicePattern(pattern, args) =>
752+
case SplicePattern(pattern, typeargs, args) =>
753+
// TODO-18271: print `typeargs`
753754
val spliceTypeText = (keywordStr("[") ~ toTextGlobal(tree.typeOpt) ~ keywordStr("]")).provided(printDebug && tree.typeOpt.exists)
754755
keywordStr("$") ~ spliceTypeText ~ {
755756
if args.isEmpty then keywordStr("{") ~ inPattern(toText(pattern)) ~ keywordStr("}")

compiler/src/dotty/tools/dotc/quoted/QuotePatterns.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,10 @@ object QuotePatterns:
197197
val patBuf = new mutable.ListBuffer[Tree]
198198
val shape = new tpd.TreeMap {
199199
override def transform(tree: Tree)(using Context) = tree match {
200-
case Typed(splice @ SplicePattern(pat, Nil), tpt) if !tpt.tpe.derivesFrom(defn.RepeatedParamClass) =>
200+
case Typed(splice @ SplicePattern(pat, Nil, Nil), tpt) if !tpt.tpe.derivesFrom(defn.RepeatedParamClass) =>
201201
transform(tpt) // Collect type bindings
202202
transform(splice)
203-
case SplicePattern(pat, args) =>
203+
case SplicePattern(pat, typeargs, args) =>
204204
val patType = pat.tpe.widen
205205
val patType1 = patType.translateFromRepeated(toArray = false)
206206
val pat1 = if (patType eq patType1) pat else pat.withType(patType1)
@@ -238,11 +238,12 @@ object QuotePatterns:
238238
case pat: Bind => !pat.symbol.name.is(PatMatGivenVarName)
239239
case _ => true
240240
}
241+
// TODO-18271: Support for typeargs?
241242
override def transform(tree: tpd.Tree)(using Context): tpd.Tree = tree match
242243
case TypeApply(patternHole, _) if patternHole.symbol == defn.QuotedRuntimePatterns_patternHole =>
243-
cpy.SplicePattern(tree)(patternIterator.next(), Nil)
244+
cpy.SplicePattern(tree)(patternIterator.next(), Nil, Nil)
244245
case Apply(patternHole, SeqLiteral(args, _) :: Nil) if patternHole.symbol == defn.QuotedRuntimePatterns_higherOrderHole =>
245-
cpy.SplicePattern(tree)(patternIterator.next(), args)
246+
cpy.SplicePattern(tree)(patternIterator.next(), Nil, args)
246247
case _ => super.transform(tree)
247248
}
248249
val body = addPattenSplice.transform(shape) match

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,23 @@ trait QuotesAndSplices {
119119
EmptyTree
120120
}
121121
}
122+
val typedTypeargs = tree.typeargs.map {
123+
// TODO-18271: What is representation of type variables?
124+
case arg: untpd.Ident =>
125+
typedType(arg) // TODO-18271: Is this appropriate?
126+
case arg =>
127+
report.error("Open pattern expected an identifier", arg.srcPos)
128+
EmptyTree
129+
}
122130
for arg <- typedArgs if arg.symbol.is(Mutable) do // TODO support these patterns. Possibly using scala.quoted.util.Var
123131
report.error("References to `var`s cannot be used in higher-order pattern", arg.srcPos)
124132
val argTypes = typedArgs.map(_.tpe.widenTermRefExpr)
133+
// TODO-18271: Generate polyType if typedTypeargs is not empty
125134
val patType = if tree.args.isEmpty then pt else defn.FunctionOf(argTypes, pt)
126135
val pat = typedPattern(tree.body, defn.QuotedExprClass.typeRef.appliedTo(patType))(using quotePatternSpliceContext)
127136
val baseType = pat.tpe.baseType(defn.QuotedExprClass)
128137
val argType = if baseType.exists then baseType.argTypesHi.head else defn.NothingType
129-
untpd.cpy.SplicePattern(tree)(pat, typedArgs).withType(pt)
138+
untpd.cpy.SplicePattern(tree)(pat, typedTypeargs, typedArgs).withType(pt)
130139
else
131140
errorTree(tree, em"Type must be fully defined.\nConsider annotating the splice using a type ascription:\n ($tree: XYZ).", tree.body.srcPos)
132141
}
@@ -151,9 +160,10 @@ trait QuotesAndSplices {
151160
val splice1 = typedSplicePattern(splice, defn.FunctionOf(argTypes, pt))
152161
untpd.cpy.Apply(tree)(splice1.select(nme.apply), typedArgs).withType(pt)
153162
else // $x(...) higher-order quasipattern
163+
// TODO-18271: Case for highr-order quasi-quote pattern with type params
154164
if args.isEmpty then
155165
report.error("Missing arguments for open pattern", tree.srcPos)
156-
typedSplicePattern(untpd.cpy.SplicePattern(tree)(splice.body, args), pt)
166+
typedSplicePattern(untpd.cpy.SplicePattern(tree)(splice.body, Nil, args), pt)
157167
}
158168

159169
/** Type check a type binding reference in a quoted pattern.

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,16 @@ class ReTyper(nestingLevel: Int = 0) extends Typer(nestingLevel) with ReChecking
131131
override def typedSplicePattern(tree: untpd.SplicePattern, pt: Type)(using Context): Tree =
132132
assertTyped(tree)
133133
val args1 = tree.args.mapconserve(typedExpr(_))
134+
val typeargs1 = tree.typeargs.mapconserve(typedType(_))
135+
// TODO-18217: Generate polytype when typeagrs1 is not empty
134136
val patternTpe =
135137
if args1.isEmpty then tree.typeOpt
136138
else defn.FunctionType(args1.size).appliedTo(args1.map(_.tpe) :+ tree.typeOpt)
137139
val bodyCtx = spliceContext.addMode(Mode.Pattern).retractMode(Mode.QuotedPatternBits)
138140
val body1 = typed(tree.body, defn.QuotedExprClass.typeRef.appliedTo(patternTpe))(using bodyCtx)
141+
// TODO-18217: Not necessarry?
139142
val args = tree.args.mapconserve(typedExpr(_))
140-
untpd.cpy.SplicePattern(tree)(body1, args1).withType(tree.typeOpt)
143+
untpd.cpy.SplicePattern(tree)(body1, typeargs1, args1).withType(tree.typeOpt)
141144

142145
override def typedHole(tree: untpd.Hole, pt: Type)(using Context): Tree =
143146
promote(tree)

0 commit comments

Comments
 (0)