Skip to content

Commit 9c4ce38

Browse files
authored
Backport "Warn when calling synchronized on AnyVal" to LTS (#19064)
Backports #18021 to the LTS branch. PR submitted by the release tooling. [skip ci]
2 parents 4d4934c + 61c6c62 commit 9c4ce38

File tree

7 files changed

+69
-1
lines changed

7 files changed

+69
-1
lines changed

compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe
196196
case AmbiguousExtensionMethodID // errorNumber 180
197197
case UnqualifiedCallToAnyRefMethodID // errorNumber: 181
198198
case NotConstantID // errorNumber: 182
199+
case SynchronizedCallOnBoxedClassID // errorNumber: 187
199200

200201
def errorNumber = ordinal - 1
201202

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2338,6 +2338,15 @@ class UnqualifiedCallToAnyRefMethod(stat: untpd.Tree, method: Symbol)(using Cont
23382338
|you intended."""
23392339
}
23402340

2341+
class SynchronizedCallOnBoxedClass(stat: tpd.Tree)(using Context)
2342+
extends Message(SynchronizedCallOnBoxedClassID) {
2343+
def kind = MessageKind.PotentialIssue
2344+
def msg(using Context) = i"Suspicious ${hl("synchronized")} call on boxed class"
2345+
def explain(using Context) =
2346+
i"""|You called the ${hl("synchronized")} method on a boxed primitive. This might not be what
2347+
|you intended."""
2348+
}
2349+
23412350
class TraitCompanionWithMutableStatic()(using Context)
23422351
extends SyntaxMsg(TraitCompanionWithMutableStaticID) {
23432352
def msg(using Context) = i"Companion of traits cannot define mutable @static fields"

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,10 @@ class RefChecks extends MiniPhase { thisPhase =>
11791179
checkAnyRefMethodCall(tree)
11801180
tree
11811181

1182+
override def transformSelect(tree: tpd.Select)(using Context): tpd.Tree =
1183+
if defn.ScalaBoxedClasses().contains(tree.qualifier.tpe.typeSymbol) && tree.name == nme.synchronized_ then
1184+
report.warning(SynchronizedCallOnBoxedClass(tree), tree.srcPos)
1185+
tree
11821186
}
11831187

11841188
/* todo: rewrite and re-enable

tests/neg/17284.check

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
-- [E187] Potential Issue Error: tests/neg/17284.scala:4:6 -------------------------------------------------------------
2+
4 | 451.synchronized {} // error
3+
| ^^^^^^^^^^^^^^^^
4+
| Suspicious synchronized call on boxed class
5+
|---------------------------------------------------------------------------------------------------------------------
6+
| Explanation (enabled by `-explain`)
7+
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8+
| You called the synchronized method on a boxed primitive. This might not be what
9+
| you intended.
10+
---------------------------------------------------------------------------------------------------------------------
11+
-- [E187] Potential Issue Error: tests/neg/17284.scala:8:4 -------------------------------------------------------------
12+
8 | x.synchronized {} // error
13+
| ^^^^^^^^^^^^^^
14+
| Suspicious synchronized call on boxed class
15+
|---------------------------------------------------------------------------------------------------------------------
16+
| Explanation (enabled by `-explain`)
17+
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
18+
| You called the synchronized method on a boxed primitive. This might not be what
19+
| you intended.
20+
---------------------------------------------------------------------------------------------------------------------
21+
-- [E187] Potential Issue Error: tests/neg/17284.scala:11:7 ------------------------------------------------------------
22+
11 | true.synchronized {} // error
23+
| ^^^^^^^^^^^^^^^^^
24+
| Suspicious synchronized call on boxed class
25+
|--------------------------------------------------------------------------------------------------------------------
26+
| Explanation (enabled by `-explain`)
27+
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
28+
| You called the synchronized method on a boxed primitive. This might not be what
29+
| you intended.
30+
--------------------------------------------------------------------------------------------------------------------

tests/neg/17284.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// scalac: -Werror -explain
2+
3+
def test =
4+
451.synchronized {} // error
5+
6+
def test2 =
7+
val x: Integer = 451
8+
x.synchronized {} // error
9+
10+
def test3 =
11+
true.synchronized {} // error
12+
13+
def test4 =
14+
true.hashCode() // success

tests/neg/i17266.check

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@
2020
| resolved to calls on Predef or on imported methods. This might not be what
2121
| you intended.
2222
--------------------------------------------------------------------------------------------------------------------
23+
-- [E187] Potential Issue Error: tests/neg/i17266.scala:22:4 -----------------------------------------------------------
24+
22 | 1.synchronized { // error
25+
| ^^^^^^^^^^^^^^
26+
| Suspicious synchronized call on boxed class
27+
|--------------------------------------------------------------------------------------------------------------------
28+
| Explanation (enabled by `-explain`)
29+
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
30+
| You called the synchronized method on a boxed primitive. This might not be what
31+
| you intended.
32+
--------------------------------------------------------------------------------------------------------------------
2333
-- [E181] Potential Issue Error: tests/neg/i17266.scala:108:2 ----------------------------------------------------------
2434
108 | wait() // error
2535
| ^^^^

tests/neg/i17266.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def test3 =
1919
}
2020

2121
def test4 =
22-
1.synchronized { // not an error (should be?)
22+
1.synchronized { // error
2323
println("hello")
2424
}
2525

0 commit comments

Comments
 (0)