diff --git a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala index 54af9f8dd088..d1f5f1b63d26 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala @@ -793,6 +793,9 @@ class JSCodeGen()(using genCtx: Context) { name.name }.toSet + val staticNames = moduleClass.companionClass.info.allMembers + .collect { case d if d.name.isTermName && d.symbol.isScalaStatic => d.name }.toSet + val members = { moduleClass.info.membersBasedOnFlags(required = Flags.Method, excluded = Flags.ExcludedForwarder).map(_.symbol) @@ -815,6 +818,7 @@ class JSCodeGen()(using genCtx: Context) { || hasAccessBoundary || isOfJLObject || m.hasAnnotation(jsdefn.JSNativeAnnot) || isDefaultParamOfJSNativeDef // #4557 + || staticNames(m.name) } val forwarders = for { @@ -4769,7 +4773,7 @@ class JSCodeGen()(using genCtx: Context) { } private def isMethodStaticInIR(sym: Symbol): Boolean = - sym.is(JavaStatic) + sym.is(JavaStatic) || sym.isScalaStatic /** Generate a Class[_] value (e.g. coming from classOf[T]) */ private def genClassConstant(tpe: Type)(implicit pos: Position): js.Tree = diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index 3e5d65070a80..9594fe3f5373 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -1167,7 +1167,8 @@ trait Checking { def javaFieldMethodPair = decl.is(JavaDefined) && other.is(JavaDefined) && decl.is(Method) != other.is(Method) - if (decl.matches(other) && !javaFieldMethodPair) { + def staticNonStaticPair = decl.isScalaStatic != other.isScalaStatic + if (decl.matches(other) && !javaFieldMethodPair && !staticNonStaticPair) { def doubleDefError(decl: Symbol, other: Symbol): Unit = if (!decl.info.isErroneous && !other.info.isErroneous) report.error(DoubleDefinition(decl, other, cls), decl.srcPos) diff --git a/tests/run/i17332.scala b/tests/run/i17332.scala new file mode 100644 index 000000000000..b609bf215d80 --- /dev/null +++ b/tests/run/i17332.scala @@ -0,0 +1,18 @@ +package foo { + +import annotation.static + +class MirrorHelpers + +object MirrorHelpers: + + @static + def throwStuff(i: Int): Any = throw new NoSuchElementException(String.valueOf(i)) + +} + +@main def Test = + try + foo.MirrorHelpers.throwStuff(23) + ??? // ko + catch case ex: NoSuchElementException if ex.getMessage == "23" => () // ok diff --git a/tests/run/i19394.scala b/tests/run/i19394.scala new file mode 100644 index 000000000000..7c6938c97503 --- /dev/null +++ b/tests/run/i19394.scala @@ -0,0 +1,20 @@ +import scala.annotation.{ static, targetName } + +class Foo +object Foo: + @static def foo: String = "foo" + @targetName("foo") def fooBincompat: String = foo + +class Bar +object Bar: + @static def bar: String = "bar" + def bar: String = bar + +object Test: + def main(args: Array[String]): Unit = + assert(Foo.foo == "foo") + assert(Bar.bar == "bar") + + import scala.reflect.Selectable.reflectiveSelectable + assert(Foo.asInstanceOf[{ def foo: String }].foo == "foo") + assert(Bar.asInstanceOf[{ def bar: String }].bar == "bar") diff --git a/tests/run/i19396.scala b/tests/run/i19396.scala new file mode 100644 index 000000000000..2fcf23022b0f --- /dev/null +++ b/tests/run/i19396.scala @@ -0,0 +1,16 @@ +import scala.annotation.static + +class Foo + +object Foo { + @static def foo = "foo" +} + +class Bar { + def bar = Foo.foo +} + +object Test: + def main(args: Array[String]): Unit = + Foo.foo + Bar().bar diff --git a/tests/run/static/i2054.scala b/tests/run/static/i2054.scala index dbf88b0efa14..84ebf5d9efeb 100644 --- a/tests/run/static/i2054.scala +++ b/tests/run/static/i2054.scala @@ -1,5 +1,3 @@ -// scalajs: --skip --pending - import scala.annotation.static class Test