Skip to content

Simple enhancement for pattern matching with capturing types #23524

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ import Flags.*, Constants.*
import Decorators.*
import NameKinds.{PatMatStdBinderName, PatMatAltsName, PatMatResultName}
import config.Printers.patmatch
import config.Feature
import reporting.*
import ast.*
import util.Property.*
import cc.{CapturingType, Capabilities}

import scala.annotation.tailrec
import scala.collection.mutable
Expand Down Expand Up @@ -418,8 +420,11 @@ object PatternMatcher {
&& !hasExplicitTypeArgs(extractor)
case _ => false
}
val castTp = if Feature.ccEnabled
then CapturingType(tpt.tpe, scrutinee.termRef.singletonCaptureSet)
else tpt.tpe
TestPlan(TypeTest(tpt, isTrusted), scrutinee, tree.span,
letAbstract(ref(scrutinee).cast(tpt.tpe)) { casted =>
letAbstract(ref(scrutinee).cast(castTp)) { casted =>
nonNull += casted
patternPlan(casted, pat, onSuccess)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ object IndexedSeqView {

@SerialVersionUID(3L)
class Reverse[A](underlying: SomeIndexedSeqOps[A]^) extends SeqView.Reverse[A](underlying) with IndexedSeqView[A] {
override def reverse: IndexedSeqView[A] = underlying match {
override def reverse: IndexedSeqView[A]^{underlying} = underlying match {
case x: IndexedSeqView[A] => x
case _ => super.reverse
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ private[mutable] object CheckedIndexedSeqView {
@SerialVersionUID(3L)
class Reverse[A](underlying: SomeIndexedSeqOps[A]^)(protected val mutationCount: () ->{cap.rd} Int)
extends IndexedSeqView.Reverse[A](underlying) with CheckedIndexedSeqView[A] {
override def reverse: IndexedSeqView[A] = underlying match {
override def reverse: IndexedSeqView[A]^{underlying} = underlying match {
case x: IndexedSeqView[A] => x
case _ => super.reverse
}
Expand Down
21 changes: 21 additions & 0 deletions tests/neg-custom-args/captures/match.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import language.experimental.captureChecking

trait A

case class B(x: AnyRef^) extends A

def test =
val x: AnyRef^ = new AnyRef
val a: A^{x} = B(x)

val y1: A = a match
case b: B => b // error: (b: B) becomes B^{x} implicitly

val y2: A^{x} = a match
case b: B => b // ok

val x3: AnyRef = a match
case B(x2: AnyRef) => x2 // error: we lose some information about field x, but it still cannot be pure

val x4: AnyRef = a match
case b: B => b.x // error
Loading