-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
In 3.4 make refutable patterns in a for comprehension an error (#18842)
supersedes #16665 Only make refutable patterns in a for comprehension an error, here we have a clear set in stone solution: put `case` before the pattern. It is still in the air the ideal solution for pattern val definitions, see https://contributors.scala-lang.org/t/pre-sip-replace-non-sensical-unchecked-annotations/6342/85, so keep those as a warning for now
- Loading branch information
Showing
19 changed files
with
137 additions
and
57 deletions.
There are no files selected for viewing
Submodule scala-xml
updated
2 files
+1 −1 | shared/src/main/scala/scala/xml/parsing/MarkupHandler.scala | |
+1 −1 | shared/src/test/scala/scala/xml/XMLTest.scala |
Submodule scalatest
updated
2 files
+1 −2 | jvm/core/src/main/scala/org/scalatest/Doc.scala | |
+27 −27 | jvm/core/src/main/scala/org/scalatest/tools/SuiteDiscoveryHelper.scala |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
-- [E008] Not Found Error: tests/neg/irrefutable.scala:27:29 ----------------------------------------------------------- | ||
27 | for (case Foo(x: Int) <- xs) yield x // error | ||
| ^^ | ||
| value withFilter is not a member of Lst[Foo[Any]] | ||
-- Error: tests/neg/irrefutable.scala:30:16 ---------------------------------------------------------------------------- | ||
30 | for (Foo(x: Int) <- xs) yield x // error | ||
| ^^^ | ||
| pattern's type Int is more specialized than the right hand side expression's type Any | ||
| | ||
| If the narrowing is intentional, this can be communicated by adding the `case` keyword before the full pattern, | ||
| which will result in a filtering for expression (using `withFilter`). | ||
| This patch can be rewritten automatically under -rewrite -source 3.2-migration. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// This tests that A.f1 is recognized as an irrefutable pattern and A.f2_nocase is not, and therefore A.f2 solves this | ||
// by adding a case to the pattern, which results in withFilter being inserted. | ||
// see also: tests/run/irrefutable.scala for an example that exercises the insertion of withFilter. | ||
|
||
class Lst[+T](val id: String, val underlying: List[T]) { | ||
def map[U](f: T => U): Lst[U] = new Lst(id, underlying.map(f)) | ||
|
||
// hide the withFilter so that there is a compile error | ||
// def withFilter(f: T => Boolean): Lst.WithFilter[T] = new Lst.WithFilter(this, f) | ||
} | ||
|
||
// object Lst: | ||
// class WithFilter[+T](lst: Lst[T], filter: T => Boolean): | ||
// def forwardingFilter[T1](filter: T1 => Boolean): T1 => Boolean = t => | ||
// println(s"filtering $t in ${lst.id}") | ||
// filter(t) | ||
|
||
// def map[U](f: T => U): Lst[U] = Lst(lst.id, lst.underlying.withFilter(forwardingFilter(filter)).map(f)) | ||
|
||
case class Foo[T](x: T) | ||
|
||
object A { | ||
def f1(xs: Lst[Foo[Int]]): Lst[Int] = { | ||
for (Foo(x: Int) <- xs) yield x | ||
} | ||
def f2(xs: Lst[Foo[Any]]): Lst[Int] = { | ||
for (case Foo(x: Int) <- xs) yield x // error | ||
} | ||
def f2_nocase(xs: Lst[Foo[Any]]): Lst[Int] = { | ||
for (Foo(x: Int) <- xs) yield x // error | ||
} | ||
} | ||
|
||
@main def Test = | ||
val xs = new Lst("xs", List(Foo(1), Foo(2), Foo(3))) | ||
println("=== mapping xs with A.f1 ===") | ||
val xs1 = A.f1(xs) | ||
assert(xs1.underlying == List(1, 2, 3)) | ||
val ys = new Lst("ys", List(Foo(1: Any), Foo(2: Any), Foo(3: Any))) | ||
println("=== mapping ys with A.f2 ===") | ||
val ys1 = A.f2(ys) | ||
assert(ys1.underlying == List(1, 2, 3)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
=== mapping xs with A.f1 === | ||
=== mapping ys with A.f2 === | ||
filtering Foo(1) in ys | ||
filtering Foo(2) in ys | ||
filtering Foo(3) in ys |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// This tests that A.f1 does not filter its inputs, whereas A.f2 does. | ||
// see also: tests/neg/irrefutable.scala for an example that exercises the requirement to insert case. | ||
|
||
class Lst[+T](val id: String, val underlying: List[T]) { | ||
def map[U](f: T => U): Lst[U] = new Lst(id, underlying.map(f)) | ||
def withFilter(f: T => Boolean): Lst.WithFilter[T] = new Lst.WithFilter(this, f) | ||
} | ||
|
||
object Lst: | ||
class WithFilter[+T](lst: Lst[T], filter: T => Boolean): | ||
def forwardingFilter[T1](filter: T1 => Boolean): T1 => Boolean = t => | ||
println(s"filtering $t in ${lst.id}") | ||
filter(t) | ||
|
||
def map[U](f: T => U): Lst[U] = Lst(lst.id, lst.underlying.withFilter(forwardingFilter(filter)).map(f)) | ||
|
||
case class Foo[T](x: T) | ||
|
||
object A { | ||
def f1(xs: Lst[Foo[Int]]): Lst[Int] = { | ||
for (Foo(x: Int) <- xs) yield x | ||
} | ||
def f2(xs: Lst[Foo[Any]]): Lst[Int] = { | ||
for (case Foo(x: Int) <- xs) yield x | ||
} | ||
} | ||
|
||
@main def Test = | ||
val xs = new Lst("xs", List(Foo(1), Foo(2), Foo(3))) | ||
println("=== mapping xs with A.f1 ===") | ||
val xs1 = A.f1(xs) | ||
assert(xs1.underlying == List(1, 2, 3)) | ||
val ys = new Lst("ys", List(Foo(1: Any), Foo(2: Any), Foo(3: Any))) | ||
println("=== mapping ys with A.f2 ===") | ||
val ys1 = A.f2(ys) | ||
assert(ys1.underlying == List(1, 2, 3)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
object Test { | ||
def main(args: Array[String]): Unit = { | ||
val mixedList = List(1,(1,2),4,(3,1),(5,4),6) | ||
val as = for((a,b) <- mixedList) yield a | ||
val as = for(case (a,b) <- mixedList) yield a | ||
println(as.mkString(", ")) | ||
} | ||
} |