From ce855b77ef93e27c69282b15d097de96ea649f4e Mon Sep 17 00:00:00 2001 From: odersky Date: Wed, 9 Apr 2025 19:16:49 +0200 Subject: [PATCH] Mitigate change in status of scala.caps `scala.caps`` was an object until 3.6, it is a package from 3.7. Without special handling this would cause a TypeError to be thrown if a build has several versions of the Scala standard library on the classpath. This was the case for 29 projects in the open CB. These projects should be updated. But until that's the case we issue a warning instead of a hard failure. --- .../src/dotty/tools/dotc/core/SymbolLoaders.scala | 14 +++++++++++++- tests/neg/i22890.check | 7 +++++++ tests/neg/i22890/Test_2.scala | 3 +++ tests/neg/i22890/caps_1.java | 5 +++++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tests/neg/i22890.check create mode 100644 tests/neg/i22890/Test_2.scala create mode 100644 tests/neg/i22890/caps_1.java diff --git a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala index 39297697f29a..6a9d70a19f49 100644 --- a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala +++ b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala @@ -78,7 +78,7 @@ object SymbolLoaders { * and give them `completer` as type. */ def enterPackage(owner: Symbol, pname: TermName, completer: (TermSymbol, ClassSymbol) => PackageLoader)(using Context): Symbol = { - val preExisting = owner.info.decls lookup pname + val preExisting = owner.info.decls.lookup(pname) if (preExisting != NoSymbol) // Some jars (often, obfuscated ones) include a package and // object with the same name. Rather than render them unusable, @@ -95,6 +95,18 @@ object SymbolLoaders { s"Resolving package/object name conflict in favor of object ${preExisting.fullName}. The package will be inaccessible.") return NoSymbol } + else if pname == nme.caps && owner == defn.ScalaPackageClass then + // `scala.caps`` was an object until 3.6, it is a package from 3.7. Without special handling + // this would cause a TypeError to be thrown below if a build has several versions of the + // Scala standard library on the classpath. This was the case for 29 projects in OpenCB. + // These projects should be updated. But until that's the case we issue a warning instead + // of a hard failure. + report.warning( + em"""$owner contains object and package with same name: $pname. + |This indicates that there are several versions of the Scala standard library on the classpath. + |The build should be reconfigured so that only one version of the standard library is on the classpath.""") + owner.info.decls.openForMutations.unlink(preExisting) + owner.info.decls.openForMutations.unlink(preExisting.moduleClass) else throw TypeError( em"""$owner contains object and package with same name: $pname diff --git a/tests/neg/i22890.check b/tests/neg/i22890.check new file mode 100644 index 000000000000..f5e37b10dac2 --- /dev/null +++ b/tests/neg/i22890.check @@ -0,0 +1,7 @@ +-- [E161] Naming Error: tests/neg/i22890/caps_1.java:3:0 --------------------------------------------------------------- +3 |class caps { // error: caps is already defined as package caps + |^ + |caps is already defined as package scala.caps +package scala contains object and package with same name: caps. +This indicates that there are several versions of the Scala standard library on the classpath. +The build should be reconfigured so that only one version of the standard library is on the classpath. diff --git a/tests/neg/i22890/Test_2.scala b/tests/neg/i22890/Test_2.scala new file mode 100644 index 000000000000..4545d5ab94ae --- /dev/null +++ b/tests/neg/i22890/Test_2.scala @@ -0,0 +1,3 @@ +@main def Test = + println("hello") +// nopos-warn diff --git a/tests/neg/i22890/caps_1.java b/tests/neg/i22890/caps_1.java new file mode 100644 index 000000000000..9bc804829932 --- /dev/null +++ b/tests/neg/i22890/caps_1.java @@ -0,0 +1,5 @@ +package scala; + +class caps { // error: caps is already defined as package caps + static public void foo() {} +} \ No newline at end of file