From b9375f5e6b1b5c55b67b7d5987efe25bca3df699 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Mon, 22 Jan 2024 13:41:51 +0100 Subject: [PATCH] Update scala-library in scala-tool configuration for Scala 3 When a macro was compiled against a new scala-library (say 2.13.15), the runtime classpath of the Scala compiler should not contain an older scala-library. Otherwise the macro can cause a NoSuchMethodException during expansion. This commit updates scala-library in the scalaInstance to the version on the projects dependency classpath. --- main/src/main/scala/sbt/Defaults.scala | 27 +++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index ed83474dc..133e46434 100644 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -1149,9 +1149,29 @@ object Defaults extends BuildCommon { val sv = scalaVersion.value val fullReport = update.value - val toolReport = fullReport - .configuration(Configurations.ScalaTool) - .getOrElse(sys.error(noToolConfiguration(managedScalaInstance.value))) + // For Scala 3, update scala-library.jar in `scala-tool` and `scala-doc-tool` in case a newer version + // is present in the `compile` configuration. This is needed once forwards binary compatibility is dropped + // to avoid NoSuchMethod exceptions when expanding macros. + def updateLibraryToCompileConfiguration(report: ConfigurationReport) = + if (!ScalaArtifacts.isScala3(sv)) report + else + (for { + compileConf <- fullReport.configuration(Configurations.Compile) + compileLibMod <- compileConf.modules.find(_.module.name == ScalaArtifacts.LibraryID) + reportLibMod <- report.modules.find(_.module.name == ScalaArtifacts.LibraryID) + if VersionNumber(reportLibMod.module.revision) + .matchesSemVer(SemanticSelector(s"<${compileLibMod.module.revision}")) + } yield { + val newMods = report.modules + .filterNot(_.module.name == ScalaArtifacts.LibraryID) :+ compileLibMod + report.withModules(newMods) + }).getOrElse(report) + + val toolReport = updateLibraryToCompileConfiguration( + fullReport + .configuration(Configurations.ScalaTool) + .getOrElse(sys.error(noToolConfiguration(managedScalaInstance.value))) + ) if (Classpaths.isScala213(sv)) { for { @@ -1182,6 +1202,7 @@ object Defaults extends BuildCommon { val allDocJars = fullReport .configuration(Configurations.ScalaDocTool) + .map(updateLibraryToCompileConfiguration) .toSeq .flatMap(_.modules) .flatMap(_.artifacts.map(_._2))