Skip to content

Commit 2de84b0

Browse files
oderskynicolasstucki
authored andcommitted
Improve treatment of quoted pattern holes
1 parent c266bc9 commit 2de84b0

File tree

4 files changed

+19
-15
lines changed

4 files changed

+19
-15
lines changed

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -707,12 +707,14 @@ class Definitions {
707707

708708
lazy val InternalQuotedModuleRef: TermRef = ctx.requiredModuleRef("scala.internal.Quoted")
709709
def InternalQuotedModule: Symbol = InternalQuotedModuleRef.symbol
710-
lazy val InternalQuoted_exprQuoteR: TermRef = InternalQuotedModule.requiredMethodRef("exprQuote".toTermName)
710+
lazy val InternalQuoted_exprQuoteR: TermRef = InternalQuotedModule.requiredMethodRef("exprQuote")
711711
def InternalQuoted_exprQuote(implicit ctx: Context): Symbol = InternalQuoted_exprQuoteR.symbol
712-
lazy val InternalQuoted_exprSpliceR: TermRef = InternalQuotedModule.requiredMethodRef("exprSplice".toTermName)
712+
lazy val InternalQuoted_exprSpliceR: TermRef = InternalQuotedModule.requiredMethodRef("exprSplice")
713713
def InternalQuoted_exprSplice(implicit ctx: Context): Symbol = InternalQuoted_exprSpliceR.symbol
714-
lazy val InternalQuoted_typeQuoteR: TermRef = InternalQuotedModule.requiredMethodRef("typeQuote".toTermName)
714+
lazy val InternalQuoted_typeQuoteR: TermRef = InternalQuotedModule.requiredMethodRef("typeQuote")
715715
def InternalQuoted_typeQuote(implicit ctx: Context): Symbol = InternalQuoted_typeQuoteR.symbol
716+
lazy val InternalQuoted_patternHoleR: TermRef = InternalQuotedModule.requiredMethodRef("patternHole")
717+
def InternalQuoted_patternHole(implicit ctx: Context): Symbol = InternalQuoted_patternHoleR.symbol
716718

717719
lazy val QuotedExprsModule: TermSymbol = ctx.requiredModule("scala.quoted.Exprs")
718720
def QuotedExprsClass(implicit ctx: Context): ClassSymbol = QuotedExprsModule.asClass

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

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,7 +1943,7 @@ class Typer extends Namer
19431943
val quoted1 = typedExpr(quoted, quotedPt)(quoteContext.addMode(Mode.QuotedPattern))
19441944
val (shape, splices) = splitQuotePattern(quoted1)
19451945
val splicePat = typed(untpd.Tuple(splices.map(untpd.TypedSplice(_))).withSpan(quoted.span))
1946-
val patType = TypeOps.tupleOf(splices.tpes)
1946+
val patType = TypeOps.tupleOf(splices.tpes.map(_.widen))
19471947
UnApply(
19481948
ref(defn.QuotedMatcher_unapplyR).appliedToType(patType),
19491949
ref(defn.InternalQuoted_exprQuoteR).appliedToType(shape.tpe).appliedTo(shape) :: givenReflection :: Nil,
@@ -1960,10 +1960,10 @@ class Typer extends Namer
19601960
val patBuf = new mutable.ListBuffer[Tree]
19611961
override def transform(tree: Tree)(implicit ctx: Context) = tree match {
19621962
case Typed(Splice(pat), tpt) =>
1963-
val exprTpt = ref(defn.QuotedExprType).appliedToTypeTrees(tpt :: Nil)
1963+
val exprTpt = AppliedTypeTree(TypeTree(defn.QuotedExprType), tpt :: Nil)
19641964
transform(Splice(Typed(pat, exprTpt)))
19651965
case Splice(pat) =>
1966-
try holeForSplice(tree)
1966+
try patternHole(tree)
19671967
finally patBuf += pat
19681968
case _ =>
19691969
super.transform(tree)
@@ -1973,12 +1973,9 @@ class Typer extends Namer
19731973
(result, splitter.patBuf.toList)
19741974
}
19751975

1976-
// TODO: Currently, a hole is expressed as interal.quoted.ExprSplice[T](???)
1977-
// Settle on a different representation and apply Stagin
1978-
def holeForSplice(splice: Tree)(implicit ctx: Context): Tree = {
1979-
val Apply(fn, arg) = splice
1980-
tpd.cpy.Apply(splice)(fn, ref(defn.Predef_undefined) :: Nil)
1981-
}
1976+
/** A hole the shape pattern of a quoted.Matcher.unapply, representing a splice */
1977+
def patternHole(splice: Tree)(implicit ctx: Context): Tree =
1978+
ref(defn.InternalQuoted_patternHoleR).appliedToType(splice.tpe).withSpan(splice.span)
19821979

19831980
def givenReflection(implicit ctx: Context): Tree = Literal(Constant(null)) // FIXME: fill in
19841981

library/src-bootstrapped/scala/internal/Quoted.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,7 @@ object Quoted {
1616
def typeQuote[T <: AnyKind]: Type[T] =
1717
throw new Error("Internal error: this method call should have been replaced by the compiler")
1818

19+
/** A splice in a quoted pattern is desugared by the compiler into a call to this method */
20+
def patternHole[T]: T =
21+
throw new Error("Internal error: this method call should have been replaced by the compiler")
1922
}

tests/pos/quotedPatterns.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ object Test {
44

55
def f(x: Int) = x
66

7-
x match {
8-
case '{1 + 2} => 0
9-
case '{f($x)} => x
7+
val res: quoted.Expr[Int] = x match {
8+
case '{1 + 2} => '{0}
9+
case '{f($y)} => y
10+
//case '{ 1 + ($y: Int)} => y // currently gives an unreachable case error
11+
case _ => '{1}
1012
}
1113
}

0 commit comments

Comments
 (0)