Skip to content

Commit c93a237

Browse files
authored
Merge pull request #14954 from griggt/rewrite-fixes
2 parents 7db4121 + c818e0a commit c93a237

File tree

7 files changed

+92
-4
lines changed

7 files changed

+92
-4
lines changed

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

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,14 +1603,32 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
16031603
typedMatchFinish(tree, sel1, selType, tree.cases, pt)
16041604
}
16051605

1606+
/** Are some form of brackets necessary to annotate the tree `sel` as `@unchecked`?
1607+
* If so, return a Some(opening bracket, closing bracket), otherwise None.
1608+
*/
1609+
def uncheckedBrackets(sel: untpd.Tree): Option[(String, String)] = sel match
1610+
case _: untpd.If
1611+
| _: untpd.Match
1612+
| _: untpd.ForYield
1613+
| _: untpd.ParsedTry
1614+
| _: untpd.Try => Some("(", ")")
1615+
case _: untpd.Block => Some("{", "}")
1616+
case _ => None
1617+
16061618
result match {
16071619
case result @ Match(sel, CaseDef(pat, _, _) :: _) =>
16081620
tree.selector.removeAttachment(desugar.CheckIrrefutable) match {
16091621
case Some(checkMode) if !sel.tpe.hasAnnotation(defn.UncheckedAnnot) =>
16101622
val isPatDef = checkMode == desugar.MatchCheck.IrrefutablePatDef
1611-
if (!checkIrrefutable(sel, pat, isPatDef) && sourceVersion == `future-migration`)
1612-
if (isPatDef) patch(Span(tree.selector.span.end), ": @unchecked")
1613-
else patch(Span(pat.span.start), "case ")
1623+
if !checkIrrefutable(sel, pat, isPatDef) && sourceVersion == `future-migration` then
1624+
if isPatDef then uncheckedBrackets(tree.selector) match
1625+
case None =>
1626+
patch(Span(tree.selector.span.end), ": @unchecked")
1627+
case Some(bl, br) =>
1628+
patch(Span(tree.selector.span.start), s"$bl")
1629+
patch(Span(tree.selector.span.end), s"$br: @unchecked")
1630+
else
1631+
patch(Span(tree.span.start), "case ")
16141632

16151633
// skip exhaustivity check in later phase
16161634
// TODO: move the check above to patternMatcher phase

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ class CompilationTests {
7373
aggregateTests(
7474
compileFile("tests/rewrites/rewrites.scala", scala2CompatMode.and("-rewrite", "-indent")),
7575
compileFile("tests/rewrites/rewrites3x.scala", defaultOptions.and("-rewrite", "-source", "future-migration")),
76+
compileFile("tests/rewrites/filtering-fors.scala", defaultOptions.and("-rewrite", "-source", "future-migration")),
77+
compileFile("tests/rewrites/refutable-pattern-bindings.scala", defaultOptions.and("-rewrite", "-source", "future-migration")),
7678
compileFile("tests/rewrites/i8982.scala", defaultOptions.and("-indent", "-rewrite")),
7779
compileFile("tests/rewrites/i9632.scala", defaultOptions.and("-indent", "-rewrite")),
7880
compileFile("tests/rewrites/i11895.scala", defaultOptions.and("-indent", "-rewrite")),

compiler/test/dotty/tools/vulpix/ParallelTesting.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,13 @@ trait ParallelTesting extends RunnerOrchestration { self =>
10641064
target.copy(dir = copyToDir(outDir, dir))
10651065
}
10661066

1067-
new RewriteTest(copiedTargets, checkFileMap, times, threadLimit, shouldFail || shouldSuppressOutput).executeTestSuite()
1067+
val test = new RewriteTest(copiedTargets, checkFileMap, times, threadLimit, shouldFail || shouldSuppressOutput).executeTestSuite()
1068+
1069+
cleanup()
1070+
1071+
if test.didFail then
1072+
fail("Rewrite test failed")
1073+
10681074
this
10691075
}
10701076

tests/rewrites/filtering-fors.check

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
val xs: List[Any] = ???
2+
val as = for case (x: String) <- xs yield x
3+
val bs =
4+
for
5+
case (x: String) <- xs
6+
yield x

tests/rewrites/filtering-fors.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
val xs: List[Any] = ???
2+
val as = for (x: String) <- xs yield x
3+
val bs =
4+
for
5+
(x: String) <- xs
6+
yield x
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
val xs: List[Any] = ???
2+
3+
val hd :: tl = (xs match
4+
case Nil => null :: xs
5+
case _ => xs): @unchecked
6+
7+
val h :: t = xs: @unchecked
8+
9+
val a :: b =
10+
(if xs.isEmpty then null :: xs
11+
else xs): @unchecked
12+
13+
val c :: d =
14+
(try xs.head :: xs
15+
catch case _: NoSuchElementException => null :: xs): @unchecked
16+
17+
val e :: f =
18+
{val zero = null :: Nil
19+
if xs.isEmpty then zero
20+
else xs}: @unchecked
21+
22+
val j :: k =
23+
(for
24+
case (x: String) <- xs
25+
yield x): @unchecked
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
val xs: List[Any] = ???
2+
3+
val hd :: tl = xs match
4+
case Nil => null :: xs
5+
case _ => xs
6+
7+
val h :: t = xs
8+
9+
val a :: b =
10+
if xs.isEmpty then null :: xs
11+
else xs
12+
13+
val c :: d =
14+
try xs.head :: xs
15+
catch case _: NoSuchElementException => null :: xs
16+
17+
val e :: f =
18+
val zero = null :: Nil
19+
if xs.isEmpty then zero
20+
else xs
21+
22+
val j :: k =
23+
for
24+
(x: String) <- xs
25+
yield x

0 commit comments

Comments
 (0)