Skip to content

Commit 844e501

Browse files
committed
Suggest runtimeChecked in warning/error messages
suggest `.runtimeChecked` instead of `: @unchecked` also, change the patch applied under 3.2-migration.
1 parent d76d5a2 commit 844e501

File tree

7 files changed

+37
-36
lines changed

7 files changed

+37
-36
lines changed

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,8 +1054,9 @@ trait Checking {
10541054
}
10551055

10561056
/** Check that pattern `pat` is irrefutable for scrutinee type `sel.tpe`.
1057-
* This means `sel` is either marked @unchecked or `sel.tpe` conforms to the
1058-
* pattern's type. If pattern is an UnApply, also check that the extractor is
1057+
* This means `sel` is either marked `: @RuntimeChecked`, `: @unchecked` (old style),
1058+
* or `sel.tpe` conforms to the pattern's type. If pattern is an Unapply,
1059+
* also check that the extractor is
10591060
* irrefutable, and do the check recursively.
10601061
*/
10611062
def checkIrrefutable(sel: Tree, pat: Tree, isPatDef: Boolean)(using Context): Boolean = {
@@ -1068,7 +1069,7 @@ trait Checking {
10681069
import Reason.*
10691070
val message = reason match
10701071
case NonConforming =>
1071-
var reportedPt = pt.dropAnnot(defn.UncheckedAnnot)
1072+
var reportedPt = pt.dropAnnot(defn.UncheckedAnnot).dropAnnot(defn.RuntimeCheckedAnnot)
10721073
if !pat.tpe.isSingleton then reportedPt = reportedPt.widen
10731074
val problem = if pat.tpe <:< reportedPt then "is more specialized than" else "does not match"
10741075
em"pattern's type ${pat.tpe} $problem the right hand side expression's type $reportedPt"
@@ -1084,7 +1085,7 @@ trait Checking {
10841085
else em"pattern binding uses refutable extractor `$extractor`"
10851086

10861087
val fix =
1087-
if isPatDef then "adding `: @unchecked` after the expression"
1088+
if isPatDef then "adding `.runtimeChecked` after the expression"
10881089
else "adding the `case` keyword before the full pattern"
10891090
val addendum =
10901091
if isPatDef then "may result in a MatchError at runtime"

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2213,10 +2213,10 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
22132213
typedMatchFinish(tree, sel1, selType, tree.cases, pt)
22142214
}
22152215

2216-
/** Are some form of brackets necessary to annotate the tree `sel` as `@unchecked`?
2216+
/** Are some form of brackets necessary to annotate the tree `sel` as `.runtimeChecked`?
22172217
* If so, return a Some(opening bracket, closing bracket), otherwise None.
22182218
*/
2219-
def uncheckedBrackets(sel: untpd.Tree): Option[(String, String)] = sel match
2219+
def runtimeCheckedBrackets(sel: untpd.Tree): Option[(String, String)] = sel match
22202220
case _: untpd.If
22212221
| _: untpd.Match
22222222
| _: untpd.ForYield
@@ -2235,20 +2235,20 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
22352235
&& sourceVersion.isAtLeast(`3.2`)
22362236
&& sourceVersion.isMigrating
22372237
then
2238-
if isPatDef then uncheckedBrackets(tree.selector) match
2238+
if isPatDef then runtimeCheckedBrackets(tree.selector) match
22392239
case None =>
2240-
patch(Span(tree.selector.span.end), ": @unchecked")
2240+
patch(Span(tree.selector.span.end), ".runtimeChecked")
22412241
case Some(bl, br) =>
22422242
patch(Span(tree.selector.span.start), s"$bl")
2243-
patch(Span(tree.selector.span.end), s"$br: @unchecked")
2243+
patch(Span(tree.selector.span.end), s"$br.runtimeChecked")
22442244
else
22452245
patch(Span(tree.span.start), "case ")
22462246

22472247
// skip exhaustivity check in later phase
22482248
// TODO: move the check above to patternMatcher phase
2249-
val uncheckedTpe = AnnotatedType(sel.tpe.widen, Annotation(defn.UncheckedAnnot, tree.selector.span))
2249+
val runtimeCheckedTpe = AnnotatedType(sel.tpe.widen, Annotation(defn.RuntimeCheckedAnnot, tree.selector.span))
22502250
tpd.cpy.Match(result)(
2251-
selector = tpd.Typed(sel, tpd.TypeTree(uncheckedTpe, inferred = true)),
2251+
selector = tpd.Typed(sel, tpd.TypeTree(runtimeCheckedTpe, inferred = true)),
22522252
cases = result.cases
22532253
)
22542254
case _ =>

tests/neg/i11118.check

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
-- Warning: tests/neg/i11118.scala:2:12 --------------------------------------------------------------------------------
22
2 |val (a,b) = (1,2,3) // error // warning
33
| ^^^^^^^
4-
| pattern's type (Any, Any) does not match the right hand side expression's type (Int, Int, Int)
4+
| pattern's type (Any, Any) does not match the right hand side expression's type (Int, Int, Int)
55
|
6-
| If the narrowing is intentional, this can be communicated by adding `: @unchecked` after the expression,
7-
| which may result in a MatchError at runtime.
8-
| This patch can be rewritten automatically under -rewrite -source 3.2-migration.
6+
| If the narrowing is intentional, this can be communicated by adding `.runtimeChecked` after the expression,
7+
| which may result in a MatchError at runtime.
8+
| This patch can be rewritten automatically under -rewrite -source 3.2-migration.
99
-- Error: tests/neg/i11118.scala:2:4 -----------------------------------------------------------------------------------
1010
2 |val (a,b) = (1,2,3) // error // warning
1111
| ^

tests/neg/refutable-pattern-binding-messages.check

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,22 @@
2727
| ^^^^^^^^^^^^^^^
2828
| pattern binding uses refutable extractor `Test.Positive`
2929
|
30-
| If this usage is intentional, this can be communicated by adding `: @unchecked` after the expression,
30+
| If this usage is intentional, this can be communicated by adding `.runtimeChecked` after the expression,
3131
| which may result in a MatchError at runtime.
3232
| This patch can be rewritten automatically under -rewrite -source 3.2-migration.
3333
-- Warning: tests/neg/refutable-pattern-binding-messages.scala:10:20 ---------------------------------------------------
3434
10 | val i :: is = List(1, 2, 3) // warn: pattern type more specialized
3535
| ^^^^^^^^^^^^^
36-
| pattern's type ::[Int] is more specialized than the right hand side expression's type List[Int]
36+
| pattern's type ::[Int] is more specialized than the right hand side expression's type List[Int]
3737
|
38-
| If the narrowing is intentional, this can be communicated by adding `: @unchecked` after the expression,
39-
| which may result in a MatchError at runtime.
40-
| This patch can be rewritten automatically under -rewrite -source 3.2-migration.
38+
| If the narrowing is intentional, this can be communicated by adding `.runtimeChecked` after the expression,
39+
| which may result in a MatchError at runtime.
40+
| This patch can be rewritten automatically under -rewrite -source 3.2-migration.
4141
-- Warning: tests/neg/refutable-pattern-binding-messages.scala:16:10 ---------------------------------------------------
4242
16 | val 1 = 2 // warn: pattern type does not match
4343
| ^
44-
| pattern's type (1 : Int) does not match the right hand side expression's type (2 : Int)
44+
| pattern's type (1 : Int) does not match the right hand side expression's type (2 : Int)
4545
|
46-
| If the narrowing is intentional, this can be communicated by adding `: @unchecked` after the expression,
47-
| which may result in a MatchError at runtime.
48-
| This patch can be rewritten automatically under -rewrite -source 3.2-migration.
46+
| If the narrowing is intentional, this can be communicated by adding `.runtimeChecked` after the expression,
47+
| which may result in a MatchError at runtime.
48+
| This patch can be rewritten automatically under -rewrite -source 3.2-migration.

tests/neg/t5702-neg-bad-and-wild.check

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@
5757
-- Warning: tests/neg/t5702-neg-bad-and-wild.scala:22:20 ---------------------------------------------------------------
5858
22 | val K(x @ _*) = k
5959
| ^
60-
| pattern's type Int* does not match the right hand side expression's type Int
60+
| pattern's type Int* does not match the right hand side expression's type Int
6161
|
62-
| If the narrowing is intentional, this can be communicated by adding `: @unchecked` after the expression,
63-
| which may result in a MatchError at runtime.
64-
| This patch can be rewritten automatically under -rewrite -source 3.2-migration.
62+
| If the narrowing is intentional, this can be communicated by adding `.runtimeChecked` after the expression,
63+
| which may result in a MatchError at runtime.
64+
| This patch can be rewritten automatically under -rewrite -source 3.2-migration.

tests/rewrites/refutable-pattern-bindings.check

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,26 @@ val xs: List[Any] = ???
22

33
val hd :: tl = (xs match
44
case Nil => null :: xs
5-
case _ => xs): @unchecked
5+
case _ => xs).runtimeChecked
66

7-
val h :: t = xs: @unchecked
7+
val h :: t = xs.runtimeChecked
88

99
val a :: b =
1010
(if xs.isEmpty then null :: xs
11-
else xs): @unchecked
11+
else xs).runtimeChecked
1212

1313
val c :: d =
1414
(try xs.head :: xs
15-
catch case _: NoSuchElementException => null :: xs): @unchecked
15+
catch case _: NoSuchElementException => null :: xs).runtimeChecked
1616

1717
val e :: f =
1818
{val zero = null :: Nil
1919
if xs.isEmpty then zero
20-
else xs}: @unchecked
20+
else xs}.runtimeChecked
2121

2222
val j :: k =
2323
(for
2424
case (x: String) <- xs
25-
yield x): @unchecked
25+
yield x).runtimeChecked
2626

27-
val (_: Int | _: AnyRef) = (??? : AnyRef): @unchecked
27+
val (_: Int | _: AnyRef) = (??? : AnyRef).runtimeChecked

tests/warn/i16649-refutable.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44
| pattern binding uses refutable extractor `'{...}`
55
|
6-
| If this usage is intentional, this can be communicated by adding `: @unchecked` after the expression,
6+
| If this usage is intentional, this can be communicated by adding `.runtimeChecked` after the expression,
77
| which may result in a MatchError at runtime.
88
| This patch can be rewritten automatically under -rewrite -source 3.2-migration.

0 commit comments

Comments
 (0)