diff --git a/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala b/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala index 8d16e5c7ceb2..e5cdc3311e37 100644 --- a/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala +++ b/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala @@ -200,6 +200,7 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe case MatchTypeNoCasesID // errorNumber: 184 case UnimportedAndImportedID // errorNumber: 185 case ImplausiblePatternWarningID // erorNumber: 186 + case SynchronizedCallOnBoxedClassID // errorNumber: 187 def errorNumber = ordinal - 1 diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index 2537911c714f..e194f3740003 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -2345,6 +2345,15 @@ class UnqualifiedCallToAnyRefMethod(stat: untpd.Tree, method: Symbol)(using Cont |you intended.""" } +class SynchronizedCallOnBoxedClass(stat: tpd.Tree)(using Context) + extends Message(SynchronizedCallOnBoxedClassID) { + def kind = MessageKind.PotentialIssue + def msg(using Context) = i"Suspicious ${hl("synchronized")} call on boxed class" + def explain(using Context) = + i"""|You called the ${hl("synchronized")} method on a boxed primitive. This might not be what + |you intended.""" +} + class TraitCompanionWithMutableStatic()(using Context) extends SyntaxMsg(TraitCompanionWithMutableStaticID) { def msg(using Context) = i"Companion of traits cannot define mutable @static fields" diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala index 601dadbb58f9..0b4e60ed5f05 100644 --- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala @@ -1196,6 +1196,10 @@ class RefChecks extends MiniPhase { thisPhase => checkAnyRefMethodCall(tree) tree + override def transformSelect(tree: tpd.Select)(using Context): tpd.Tree = + if defn.ScalaBoxedClasses().contains(tree.qualifier.tpe.typeSymbol) && tree.name == nme.synchronized_ then + report.warning(SynchronizedCallOnBoxedClass(tree), tree.srcPos) + tree } /* todo: rewrite and re-enable diff --git a/tests/neg/17284.check b/tests/neg/17284.check new file mode 100644 index 000000000000..fa248c598311 --- /dev/null +++ b/tests/neg/17284.check @@ -0,0 +1,30 @@ +-- [E187] Potential Issue Error: tests/neg/17284.scala:4:6 ------------------------------------------------------------- +4 | 451.synchronized {} // error + | ^^^^^^^^^^^^^^^^ + | Suspicious synchronized call on boxed class + |--------------------------------------------------------------------------------------------------------------------- + | Explanation (enabled by `-explain`) + |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | You called the synchronized method on a boxed primitive. This might not be what + | you intended. + --------------------------------------------------------------------------------------------------------------------- +-- [E187] Potential Issue Error: tests/neg/17284.scala:8:4 ------------------------------------------------------------- +8 | x.synchronized {} // error + | ^^^^^^^^^^^^^^ + | Suspicious synchronized call on boxed class + |--------------------------------------------------------------------------------------------------------------------- + | Explanation (enabled by `-explain`) + |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | You called the synchronized method on a boxed primitive. This might not be what + | you intended. + --------------------------------------------------------------------------------------------------------------------- +-- [E187] Potential Issue Error: tests/neg/17284.scala:11:7 ------------------------------------------------------------ +11 | true.synchronized {} // error + | ^^^^^^^^^^^^^^^^^ + | Suspicious synchronized call on boxed class + |-------------------------------------------------------------------------------------------------------------------- + | Explanation (enabled by `-explain`) + |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | You called the synchronized method on a boxed primitive. This might not be what + | you intended. + -------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg/17284.scala b/tests/neg/17284.scala new file mode 100644 index 000000000000..177926de7287 --- /dev/null +++ b/tests/neg/17284.scala @@ -0,0 +1,14 @@ +// scalac: -Werror -explain + +def test = + 451.synchronized {} // error + +def test2 = + val x: Integer = 451 + x.synchronized {} // error + +def test3 = + true.synchronized {} // error + +def test4 = + true.hashCode() // success diff --git a/tests/neg/i17266.check b/tests/neg/i17266.check index 7e07e3d43de4..1a84d1bf5e89 100644 --- a/tests/neg/i17266.check +++ b/tests/neg/i17266.check @@ -20,6 +20,16 @@ | resolved to calls on Predef or on imported methods. This might not be what | you intended. -------------------------------------------------------------------------------------------------------------------- +-- [E187] Potential Issue Error: tests/neg/i17266.scala:22:4 ----------------------------------------------------------- +22 | 1.synchronized { // error + | ^^^^^^^^^^^^^^ + | Suspicious synchronized call on boxed class + |-------------------------------------------------------------------------------------------------------------------- + | Explanation (enabled by `-explain`) + |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | You called the synchronized method on a boxed primitive. This might not be what + | you intended. + -------------------------------------------------------------------------------------------------------------------- -- [E181] Potential Issue Error: tests/neg/i17266.scala:108:2 ---------------------------------------------------------- 108 | wait() // error | ^^^^ diff --git a/tests/neg/i17266.scala b/tests/neg/i17266.scala index 5b74ea76810b..166ed2239875 100644 --- a/tests/neg/i17266.scala +++ b/tests/neg/i17266.scala @@ -19,7 +19,7 @@ def test3 = } def test4 = - 1.synchronized { // not an error (should be?) + 1.synchronized { // error println("hello") }