Skip to content

Commit d38d6d4

Browse files
mboveljmesyoudiogocanutnicolasstucki
committed
Warn when calling synchronized on AnyVal
Co-Authored-By: James You <[email protected]> Co-Authored-By: diogocanut <[email protected]> Co-Authored-By: Nicolas Stucki <[email protected]>
1 parent ed319e8 commit d38d6d4

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
@@ -200,6 +200,7 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe
200200
case MatchTypeNoCasesID // errorNumber: 184
201201
case UnimportedAndImportedID // errorNumber: 185
202202
case ImplausiblePatternWarningID // erorNumber: 186
203+
case SynchronizedCallOnBoxedClassID // errorNumber: 187
203204

204205
def errorNumber = ordinal - 1
205206

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

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

2348+
class SynchronizedCallOnBoxedClass(stat: tpd.Tree)(using Context)
2349+
extends Message(SynchronizedCallOnBoxedClassID) {
2350+
def kind = MessageKind.PotentialIssue
2351+
def msg(using Context) = i"Suspicious ${hl("synchronized")} call on boxed class"
2352+
def explain(using Context) =
2353+
i"""|You called the ${hl("synchronized")} method on a boxed primitive. This might not be what
2354+
|you intended."""
2355+
}
2356+
23482357
class TraitCompanionWithMutableStatic()(using Context)
23492358
extends SyntaxMsg(TraitCompanionWithMutableStaticID) {
23502359
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
@@ -1196,6 +1196,10 @@ class RefChecks extends MiniPhase { thisPhase =>
11961196
checkAnyRefMethodCall(tree)
11971197
tree
11981198

1199+
override def transformSelect(tree: tpd.Select)(using Context): tpd.Tree =
1200+
if defn.ScalaBoxedClasses().contains(tree.qualifier.tpe.typeSymbol) && tree.name == nme.synchronized_ then
1201+
report.warning(SynchronizedCallOnBoxedClass(tree), tree.srcPos)
1202+
tree
11991203
}
12001204

12011205
/* 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)