Skip to content

Commit

Permalink
Merge pull request #15 from scala/backport-lts-3.3-21718
Browse files Browse the repository at this point in the history
Backport "Always interpret underscores inside patterns as type bounds" to LTS
  • Loading branch information
WojciechMazur authored Dec 6, 2024
2 parents 667a565 + c65573b commit 68fac7e
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 3 deletions.
14 changes: 11 additions & 3 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,14 @@ object Parsers {
finally inEnum = saved
}

private var inMatchPattern = false
private def withinMatchPattern[T](body: => T): T = {
val saved = inMatchPattern
inMatchPattern = true
try body
finally inMatchPattern = saved
}

private var staged = StageKind.None
def withinStaged[T](kind: StageKind)(op: => T): T = {
val saved = staged
Expand Down Expand Up @@ -1857,7 +1865,7 @@ object Parsers {
if isSimpleLiteral then
SingletonTypeTree(simpleLiteral())
else if in.token == USCORE then
if ctx.settings.YkindProjector.value == "underscores" then
if ctx.settings.YkindProjector.value == "underscores" && !inMatchPattern then
val start = in.skipToken()
Ident(tpnme.USCOREkw).withSpan(Span(start, in.lastOffset, start))
else
Expand Down Expand Up @@ -2883,7 +2891,7 @@ object Parsers {
def caseClause(exprOnly: Boolean = false): CaseDef = atSpan(in.offset) {
val (pat, grd) = inSepRegion(InCase) {
accept(CASE)
(pattern(), guard())
(withinMatchPattern(pattern()), guard())
}
CaseDef(pat, grd, atSpan(accept(ARROW)) {
if exprOnly then
Expand All @@ -2907,7 +2915,7 @@ object Parsers {
val start = in.skipToken()
Ident(tpnme.WILDCARD).withSpan(Span(start, in.lastOffset, start))
case _ =>
rejectWildcardType(infixType())
withinMatchPattern(rejectWildcardType(infixType()))
}
}
CaseDef(pat, EmptyTree, atSpan(accept(ARROW)) {
Expand Down
9 changes: 9 additions & 0 deletions tests/pos/14952.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//> using options -Ykind-projector:underscores

import Tuple.*

type LiftP[F[_], T] <: Tuple =
T match {
case _ *: _ => F[Head[T]] *: LiftP[F, Tail[T]]
case _ => EmptyTuple
}
7 changes: 7 additions & 0 deletions tests/pos/21400.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//> using options -Ykind-projector:underscores

import scala.compiletime.ops.int.S

type IndexOf[T <: Tuple, E] <: Int = T match
case E *: _ => 0
case _ *: es => 1 // S[IndexOf[es, E]]
10 changes: 10 additions & 0 deletions tests/pos/21400b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//> using options -Ykind-projector:underscores

import scala.quoted.Type
import scala.quoted.Quotes

def x[A](t: Type[A])(using Quotes): Boolean = t match
case '[_ *: _] =>
true
case _ =>
false

0 comments on commit 68fac7e

Please sign in to comment.