diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java index 1b7486840bbb..08d6811c946a 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java @@ -124,6 +124,7 @@ public enum ErrorMessageID { SymbolChangedSemanticsInVersionID, UnableToEmitSwitchID, MissingCompanionForStaticID, + JavaSymbolIsNotAValueID, ; public int errorNumber() { diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index b8c6a84e771a..54085545e679 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -208,7 +208,7 @@ object messages { case class WildcardOnTypeArgumentNotAllowedOnNew()(implicit ctx: Context) extends Message(WildcardOnTypeArgumentNotAllowedOnNewID) { - val kind = "syntax" + val kind = "Syntax" val msg = "type argument must be fully defined" val code1 = @@ -2064,4 +2064,25 @@ object messages { val explanation = hl"An object that contains ${"@static"} members must have a companion class." } + + case class JavaSymbolIsNotAValue(symbol: Symbol)(implicit ctx: Context) extends Message(JavaSymbolIsNotAValueID) { + val msg = hl"$symbol is not a value" + val kind = "Type Mismatch" + val explanation = { + val javaCodeExample = """class A {public static int a() {return 1;}}""" + + val scalaCodeExample = + """val objectA = A // This does not compile + |val aResult = A.a() // This does compile""".stripMargin + + hl"""Java statics and packages cannot be used as a value. + |For Java statics consider the following Java example: + | + |$javaCodeExample + | + |When used from Scala: + | + |$scalaCodeExample""" + } + } } diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 61dfd30866d7..2a9ee59c9cd8 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -523,7 +523,7 @@ trait Checking { val sym = tree.tpe.termSymbol // The check is avoided inside Java compilation units because it always fails // on the singleton type Module.type. - if ((sym is Package) || ((sym is JavaModule) && !ctx.compilationUnit.isJava)) ctx.error(em"$sym is not a value", tree.pos) + if ((sym is Package) || ((sym is JavaModule) && !ctx.compilationUnit.isJava)) ctx.error(JavaSymbolIsNotAValue(sym), tree.pos) } tree } diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index 69f985e03f61..242ee0a60de6 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -1277,4 +1277,18 @@ class ErrorMessagesTests extends ErrorMessagesTest { val MissingCompanionForStatic(member) = messages.head assertEquals(member.show, "method bar") } + + @Test def javaSymbolIsNotAValue = + checkMessagesAfter("checkStatic") { + """ + |package p + |object O { + | val v = p + |} + """.stripMargin + }.expect { (itcx, messages) => + implicit val ctx: Context = itcx + val JavaSymbolIsNotAValue(symbol) = messages.head + assertEquals(symbol.show, "package p") + } }