Skip to content

Commit fb0bfa4

Browse files
committed
Enforce stricter pattern binding rules by default
1 parent e49f2b8 commit fb0bfa4

File tree

11 files changed

+59
-175
lines changed

11 files changed

+59
-175
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,10 +1578,10 @@ object desugar {
15781578
case _ => false
15791579

15801580
def needsNoFilter(gen: GenFrom): Boolean =
1581-
if (gen.checkMode == GenCheckMode.FilterAlways) // pattern was prefixed by `case`
1581+
if gen.checkMode == GenCheckMode.FilterAlways then // pattern was prefixed by `case`
15821582
false
15831583
else
1584-
gen.checkMode != GenCheckMode.FilterNow
1584+
gen.checkMode == GenCheckMode.Ignore
15851585
|| isVarBinding(gen.pat)
15861586
|| isIrrefutable(gen.pat, gen.expr)
15871587

compiler/src/dotty/tools/dotc/ast/untpd.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
169169
enum GenCheckMode {
170170
case Ignore // neither filter nor check since filtering was done before
171171
case Check // check that pattern is irrefutable
172-
case FilterNow // filter out non-matching elements since we are not yet in 3.x
173172
case FilterAlways // filter out non-matching elements since pattern is prefixed by `case`
174173
}
175174

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2508,9 +2508,8 @@ object Parsers {
25082508
def generatorRest(pat: Tree, casePat: Boolean): GenFrom =
25092509
atSpan(startOffset(pat), accept(LARROW)) {
25102510
val checkMode =
2511-
if (casePat) GenCheckMode.FilterAlways
2512-
else if sourceVersion.isAtLeast(future) then GenCheckMode.Check
2513-
else GenCheckMode.FilterNow // filter for now, to keep backwards compat
2511+
if casePat then GenCheckMode.FilterAlways
2512+
else GenCheckMode.Check
25142513
GenFrom(pat, subExpr(), checkMode)
25152514
}
25162515

compiler/src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,6 @@ trait Checking {
817817
def check(pat: Tree, pt: Type): Boolean = (pt <:< pat.tpe) || fail(pat, pt)
818818

819819
def recur(pat: Tree, pt: Type): Boolean =
820-
!sourceVersion.isAtLeast(future) || // only for 3.x for now since mitigations work only after this PR
821820
pt.hasAnnotation(defn.UncheckedAnnot) || {
822821
patmatch.println(i"check irrefutable $pat: ${pat.tpe} against $pt")
823822
pat match {

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,6 @@ class CompilationTests {
202202
aggregateTests(
203203
compileFile("tests/run-custom-args/tuple-cons.scala", allowDeepSubtypes),
204204
compileFile("tests/run-custom-args/i5256.scala", allowDeepSubtypes),
205-
compileFile("tests/run-custom-args/fors.scala", defaultOptions.and("-source", "future")),
206205
compileFile("tests/run-custom-args/no-useless-forwarders.scala", defaultOptions and "-Xmixin-force-forwarders:false"),
207206
compileFile("tests/run-custom-args/defaults-serizaliable-no-forwarders.scala", defaultOptions and "-Xmixin-force-forwarders:false"),
208207
compileFilesInDir("tests/run-custom-args/erased", defaultOptions.and("-language:experimental.erasedDefinitions")),

tests/run-custom-args/fors.check

Lines changed: 0 additions & 46 deletions
This file was deleted.

tests/run-custom-args/fors.scala

Lines changed: 0 additions & 117 deletions
This file was deleted.

tests/run/fors.check

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,21 @@ testNew
2626
0 2 4 6 8
2727
0 2 4 6 8
2828
a b c
29+
30+
testFiltering
31+
hello world
32+
hello world
33+
hello world
34+
1~2 3~4
35+
(empty)
36+
hello world
37+
hello/1~2 hello/3~4 /1~2 /3~4 world/1~2 world/3~4
38+
(2,1) (4,3)
39+
hello world
40+
hello world
41+
hello world
42+
1~2 3~4
43+
(empty)
44+
hello world
45+
hello/1~2 hello/3~4 /1~2 /3~4 world/1~2 world/3~4
46+
(2,1) (4,3)

tests/run/fors.scala

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ object Test extends App {
1414

1515
/////////////////// old syntax ///////////////////
1616

17-
def testOld: Unit = {
17+
def testOld(): Unit = {
1818
println("\ntestOld")
1919

2020
// lists
@@ -46,7 +46,7 @@ object Test extends App {
4646

4747
/////////////////// new syntax ///////////////////
4848

49-
def testNew: Unit = {
49+
def testNew(): Unit = {
5050
println("\ntestNew")
5151

5252
// lists
@@ -77,8 +77,41 @@ object Test extends App {
7777

7878
}
7979

80+
/////////////////// filtering with case ///////////////////
81+
82+
def testFiltering(): Unit = {
83+
println("\ntestFiltering")
84+
85+
val xs: List[Any] = List((1, 2), "hello", (3, 4), "", "world")
86+
87+
for (case x: String <- xs) do print(s"$x "); println()
88+
for (case (x: String) <- xs) do print(s"$x "); println()
89+
for (case y@ (x: String) <- xs) do print(s"$y "); println()
90+
91+
for (case (x, y) <- xs) do print(s"$x~$y "); println()
92+
93+
for (case (x: String) <- xs if x.isEmpty) do print("(empty)"); println()
94+
for (case (x: String) <- xs; y = x) do print(s"$y "); println()
95+
for (case (x: String) <- xs; case (y, z) <- xs) do print(s"$x/$y~$z "); println()
96+
97+
for (case (x, y) <- xs) do print(s"${(y, x)} "); println()
98+
99+
for case x: String <- xs do print(s"$x "); println()
100+
for case (x: String) <- xs do print(s"$x "); println()
101+
for case y@ (x: String) <- xs do print(s"$y "); println()
102+
103+
for case (x, y) <- xs do print(s"$x~$y "); println()
104+
105+
for case (x: String) <- xs if x.isEmpty do print("(empty)"); println()
106+
for case (x: String) <- xs; y = x do print(s"$y "); println()
107+
for case (x: String) <- xs; case (y, z) <- xs do print(s"$x/$y~$z "); println()
108+
109+
for case (x, y) <- xs do print(s"${(y, x)} "); println()
110+
}
111+
80112
////////////////////////////////////////////////////
81113

82-
testOld
83-
testNew
114+
testOld()
115+
testNew()
116+
testFiltering()
84117
}

0 commit comments

Comments
 (0)