Skip to content

Commit c65573b

Browse files
committed
Always treat underscores as type bounds inside patterns
Always treat underscores as type bounds inside patterns, even when `ctx.settings.XkindProjector.value == "underscores"`. Fixes scala#14952 and scala#21400. [Cherry-picked 374cd4f][modified]
1 parent e57c77b commit c65573b

File tree

4 files changed

+37
-3
lines changed

4 files changed

+37
-3
lines changed

Diff for: compiler/src/dotty/tools/dotc/parsing/Parsers.scala

+11-3
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,14 @@ object Parsers {
429429
finally inEnum = saved
430430
}
431431

432+
private var inMatchPattern = false
433+
private def withinMatchPattern[T](body: => T): T = {
434+
val saved = inMatchPattern
435+
inMatchPattern = true
436+
try body
437+
finally inMatchPattern = saved
438+
}
439+
432440
private var staged = StageKind.None
433441
def withinStaged[T](kind: StageKind)(op: => T): T = {
434442
val saved = staged
@@ -1857,7 +1865,7 @@ object Parsers {
18571865
if isSimpleLiteral then
18581866
SingletonTypeTree(simpleLiteral())
18591867
else if in.token == USCORE then
1860-
if ctx.settings.YkindProjector.value == "underscores" then
1868+
if ctx.settings.YkindProjector.value == "underscores" && !inMatchPattern then
18611869
val start = in.skipToken()
18621870
Ident(tpnme.USCOREkw).withSpan(Span(start, in.lastOffset, start))
18631871
else
@@ -2883,7 +2891,7 @@ object Parsers {
28832891
def caseClause(exprOnly: Boolean = false): CaseDef = atSpan(in.offset) {
28842892
val (pat, grd) = inSepRegion(InCase) {
28852893
accept(CASE)
2886-
(pattern(), guard())
2894+
(withinMatchPattern(pattern()), guard())
28872895
}
28882896
CaseDef(pat, grd, atSpan(accept(ARROW)) {
28892897
if exprOnly then
@@ -2907,7 +2915,7 @@ object Parsers {
29072915
val start = in.skipToken()
29082916
Ident(tpnme.WILDCARD).withSpan(Span(start, in.lastOffset, start))
29092917
case _ =>
2910-
rejectWildcardType(infixType())
2918+
withinMatchPattern(rejectWildcardType(infixType()))
29112919
}
29122920
}
29132921
CaseDef(pat, EmptyTree, atSpan(accept(ARROW)) {

Diff for: tests/pos/14952.scala

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//> using options -Ykind-projector:underscores
2+
3+
import Tuple.*
4+
5+
type LiftP[F[_], T] <: Tuple =
6+
T match {
7+
case _ *: _ => F[Head[T]] *: LiftP[F, Tail[T]]
8+
case _ => EmptyTuple
9+
}

Diff for: tests/pos/21400.scala

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//> using options -Ykind-projector:underscores
2+
3+
import scala.compiletime.ops.int.S
4+
5+
type IndexOf[T <: Tuple, E] <: Int = T match
6+
case E *: _ => 0
7+
case _ *: es => 1 // S[IndexOf[es, E]]

Diff for: tests/pos/21400b.scala

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//> using options -Ykind-projector:underscores
2+
3+
import scala.quoted.Type
4+
import scala.quoted.Quotes
5+
6+
def x[A](t: Type[A])(using Quotes): Boolean = t match
7+
case '[_ *: _] =>
8+
true
9+
case _ =>
10+
false

0 commit comments

Comments
 (0)