Skip to content

Commit 363a493

Browse files
authored
Merge pull request #13363 from dotty-staging/add-Wildacrd
2 parents 2312258 + d4d5441 commit 363a493

File tree

15 files changed

+124
-23
lines changed

15 files changed

+124
-23
lines changed

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,20 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
448448
end extension
449449
end IdentMethods
450450

451+
type Wildcard = tpd.Ident
452+
453+
object WildcardTypeTest extends TypeTest[Tree, Wildcard]:
454+
def unapply(x: Tree): Option[Wildcard & x.type] = x match
455+
case x: (tpd.Ident & x.type) if x.name == nme.WILDCARD => Some(x)
456+
case _ => None
457+
end WildcardTypeTest
458+
459+
object Wildcard extends WildcardModule:
460+
def apply(): Wildcard =
461+
withDefaultPos(untpd.Ident(nme.WILDCARD).withType(dotc.core.Symbols.defn.AnyType))
462+
def unapply(pattern: Wildcard): true = true
463+
end Wildcard
464+
451465
type Select = tpd.Select
452466

453467
object SelectTypeTest extends TypeTest[Tree, Select]:

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,14 @@ object Extractors {
7272
def result(): String = sb.result()
7373

7474
def visitTree(x: Tree): this.type = x match {
75-
case Ident(name) =>
76-
this += "Ident(\"" += name += "\")"
77-
case Select(qualifier, name) =>
78-
this += "Select(" += qualifier += ", \"" += name += "\")"
75+
case tree: Ref =>
76+
tree match
77+
case Wildcard() =>
78+
this += "Wildcard()"
79+
case Ident(name) =>
80+
this += "Ident(\"" += name += "\")"
81+
case Select(qualifier, name) =>
82+
this += "Select(" += qualifier += ", \"" += name += "\")"
7983
case This(qual) =>
8084
this += "This(" += qual += ")"
8185
case Super(qual, mix) =>

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ object SourceCode {
328328
}
329329
this
330330

331-
case Ident("_") =>
331+
case Wildcard() =>
332332
this += "_"
333333

334334
case tree: Ident =>
@@ -896,13 +896,13 @@ object SourceCode {
896896
}
897897

898898
private def printPattern(pattern: Tree): this.type = pattern match {
899-
case Ident("_") =>
899+
case Wildcard() =>
900900
this += "_"
901901

902-
case Bind(name, Ident("_")) =>
902+
case Bind(name, Wildcard()) =>
903903
this += name
904904

905-
case Bind(name, Typed(Ident("_"), tpt)) =>
905+
case Bind(name, Typed(Wildcard(), tpt)) =>
906906
this += highlightValDef(name) += ": "
907907
printTypeTree(tpt)
908908

@@ -928,7 +928,7 @@ object SourceCode {
928928
case Alternatives(trees) =>
929929
inParens(printPatterns(trees, " | "))
930930

931-
case Typed(Ident("_"), tpt) =>
931+
case Typed(Wildcard(), tpt) =>
932932
this += "_: "
933933
printTypeTree(tpt)
934934

library/src/scala/quoted/Quotes.scala

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
121121
* | | +- DefDef
122122
* | | +- ValDef
123123
* | |
124-
* | +- Term --------+- Ref -+- Ident
124+
* | +- Term --------+- Ref -+- Ident -+- Wildcard
125125
* | | +- Select
126126
* | |
127127
* | +- Literal
@@ -782,6 +782,23 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
782782
end extension
783783
end IdentMethods
784784

785+
/** Pattern representing a `_` wildcard. */
786+
type Wildcard <: Ident
787+
788+
/** `TypeTest` that allows testing at runtime in a pattern match if a `Tree` is a `Wildcard` */
789+
given WildcardTypeTest: TypeTest[Tree, Wildcard]
790+
791+
/** Module object of `type Wildcard` */
792+
val Wildcard: WildcardModule
793+
794+
/** Methods of the module object `val Wildcard` */
795+
trait WildcardModule { this: Wildcard.type =>
796+
/** Create a tree representing a `_` wildcard. */
797+
def apply(): Wildcard
798+
/** Match a tree representing a `_` wildcard. */
799+
def unapply(wildcard: Wildcard): true
800+
}
801+
785802
/** Tree representing a selection of definition with a given name on a given prefix */
786803
type Select <: Ref
787804

project/MiMaFilters.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import com.typesafe.tools.mima.core.ProblemFilters._
55
object MiMaFilters {
66
val Library: Seq[ProblemFilter] = Seq(
77
// New APIs that will be introduced in 3.1.0
8+
exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule.Wildcard"),
9+
exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule.WildcardTypeTest"),
810
exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.getJPath"),
911
exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.name"),
1012
exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SourceFileMethods.path"),
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import scala.quoted.*
2+
3+
object MatchTest {
4+
inline def test[T](inline obj: Any): Unit = ${testImpl('obj)}
5+
6+
def testImpl[T](objExpr: Expr[T])(using Quotes): Expr[Unit] = {
7+
import quotes.reflect.*
8+
// test that the extractors work
9+
val Inlined(None, Nil, Block(Nil, Match(param @ Ident("a"), List(CaseDef(Literal(IntConstant(1)), None, Block(Nil, Literal(UnitConstant()))), CaseDef(Wildcard(), None, Block(Nil, Literal(UnitConstant()))))))) = objExpr.asTerm
10+
// test that the constructors work
11+
Block(Nil, Match(param, List(CaseDef(Literal(IntConstant(1)), None, Block(Nil, Literal(UnitConstant()))), CaseDef(Wildcard(), None, Block(Nil, Literal(UnitConstant())))))).asExprOf[Unit]
12+
}
13+
}

tests/pos-macros/i12188b/Test_2.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
def test(a: Int) = MatchTest.test {
2+
a match
3+
case 1 =>
4+
case _ =>
5+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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(Wildcard(), TypeIdent(defn.IntClass)), None, Block(Nil, Literal(UnitConstant())))))
12+
matchTree.asExprOf[Unit]
13+
}
14+
}

tests/pos-macros/i12188c/Test_2.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
def test(a: Int) = MatchTest.test(a)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
DefDef("foo", Nil, TypeIdent("Int"), Some(Apply(Select(Literal(IntConstant(1)), "+"), List(Literal(IntConstant(2))))))
22
ValDef("bar", TypeIdent("Int"), Some(Apply(Select(Literal(IntConstant(2)), "+"), List(Literal(IntConstant(3))))))
3-
Bind("x", Ident("_"))
3+
Bind("x", Wildcard())

0 commit comments

Comments
 (0)