From 51bfb649bdff34658b8d756541eb78af96682bf5 Mon Sep 17 00:00:00 2001 From: pierscin <30854591+pierscin@users.noreply.github.com> Date: Tue, 6 Oct 2026 10:30:34 +0200 Subject: [PATCH 1/4] Migrate to Scala 3.9.0 LTS - bump Scala 3 from 3.3.8 to 3.9.0 - Scala Steward: pin scala3-library / scala3-library_sjs1 to 3.9. - Scala 3 compile-test harness: ignore the position-less "N warnings/errors found" summary diagnostic, and silence Scala 3.4+ migration warnings (trailing `_` eta-expansion, `with` types) for test cases that are shared with Scala 2; remove an unused import Co-Authored-By: Claude Opus 5.5 --- .scala-steward.conf | 4 ++-- build.sbt | 2 +- .../softwaremill/macwire/CompileTestsSupport.scala | 12 +++++++++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.scala-steward.conf b/.scala-steward.conf index b0b57bf9..72328a0d 100644 --- a/.scala-steward.conf +++ b/.scala-steward.conf @@ -1,6 +1,6 @@ updates.pin = [ {groupId = "com.typesafe.akka", version = "2.6."}, - {groupId = "org.scala-lang", artifactId = "scala3-library", version = "3.3."}, - {groupId = "org.scala-lang", artifactId = "scala3-library_sjs1", version = "3.3."}, + {groupId = "org.scala-lang", artifactId = "scala3-library", version = "3.9."}, + {groupId = "org.scala-lang", artifactId = "scala3-library_sjs1", version = "3.9."}, {groupId = "org.scala-lang", artifactId = "scala-library", version = "2.13."} ] diff --git a/build.sbt b/build.sbt index 846b5e94..91e5e7e8 100644 --- a/build.sbt +++ b/build.sbt @@ -11,7 +11,7 @@ val scala2_12 = "2.12.21" val scala2_13 = "2.13.18" val scala2 = List(scala2_12, scala2_13) -val scala3 = "3.3.8" +val scala3 = "3.9.0" val scala2And3Versions = scala2 :+ scala3 diff --git a/test-util/src/main/scala-3/com/softwaremill/macwire/CompileTestsSupport.scala b/test-util/src/main/scala-3/com/softwaremill/macwire/CompileTestsSupport.scala index 27831099..a3d1e087 100644 --- a/test-util/src/main/scala-3/com/softwaremill/macwire/CompileTestsSupport.scala +++ b/test-util/src/main/scala-3/com/softwaremill/macwire/CompileTestsSupport.scala @@ -10,7 +10,6 @@ import scala.io.Source import java.nio.file.Path import java.nio.file.Paths import java.nio.file.Files -import java.nio.file.OpenOption import java.nio.file.StandardOpenOption import dotty.tools.dotc.reporting.{ThrowingReporter, Diagnostic} @@ -52,10 +51,17 @@ trait CompileTestsSupport extends BaseCompileTestsSupport with OptionValues { val testReporter = new TestReporter val reporter = testReporter val classpath = Array("-classpath", Properties.currentClasspath) + // The test cases are shared with Scala 2, so they use syntax which Scala 3.4+ reports with migration warnings. + val sharedSyntaxWconf = Array( + "-Wconf:msg=for eta-expansion is unnecessary:s", + "-Wconf:msg=with as a type operator has been deprecated:s" + ) - driver.process(classpath :+ path.toString, reporter) + driver.process(classpath ++ sharedSyntaxWconf :+ path.toString, reporter) - val infos = testReporter.storedInfos + // Newer Scala 3 versions (checked with 3.9) also report the "N warnings/errors found" summary is also reported as a (position-less) diagnostic + def isSummary(d: Diagnostic) = !d.pos.exists && d.message.matches("""\S+ (warning|error)s? found""") + val infos = testReporter.storedInfos.filterNot(isSummary) def verifyInfo(level: Int, expected: List[String]) = { val actual = infos.filter(_.level == level).map(_.message) From 95ec1011b4cbafaa0fb6faf33c6ac8a9167c1bc3 Mon Sep 17 00:00:00 2001 From: pierscin <30854591+pierscin@users.noreply.github.com> Date: Tue, 6 Oct 2026 10:30:34 +0200 Subject: [PATCH 2/4] Fix or suppress new Scala 3.9 warnings - Scala-3-only macro sources: `Class[_]`/`Expr[_]` -> `?`, infix `flags is X` -> `flags.is(X)` - shared sources: `Class[_]` -> `Class[?]` (accepted by 2.12/2.13 as well) - shared sources: `xs: _*` and `A with B` cannot be rewritten while Scala 2.12 is supported; suppress those warnings via Scala-3-only -Wconf (TODO) Co-Authored-By: Claude Opus 5.5 --- build.sbt | 16 ++++++++++++++-- .../macwire/internals/CompanionCrimper.scala | 4 ++-- .../macwire/internals/ConstructorCrimper.scala | 2 +- .../macwire/internals/EligibleValuesFinder.scala | 2 +- .../internals/autowire/AutowireProviders.scala | 4 ++-- .../macwire/internals/autowire/creator.scala | 8 ++++---- .../softwaremill/macwire/internals/utils.scala | 2 +- .../macwire/proxy/ProxyCreator.scala | 6 +++--- .../com/softwaremill/macwire/WiredTest.scala | 2 +- .../softwaremill/macwire/InstanceLookup.scala | 4 ++-- .../scala/com/softwaremill/macwire/Wired.scala | 2 +- 11 files changed, 32 insertions(+), 20 deletions(-) diff --git a/build.sbt b/build.sbt index 91e5e7e8..cb1fde6f 100644 --- a/build.sbt +++ b/build.sbt @@ -57,6 +57,17 @@ ideSkipProject := (scalaVersion.value != ideScalaVersion) || thisProjectRef.valu bspEnabled := !ideSkipProject.value scalacOptions ~= (_.filterNot(Set("-Wconf:cat=other-match-analysis:error"))) // doesn't play well with macros +// TODO(scala-3.9): shared (Scala 2.12/2.13/3) sources use `xs: _*` vararg splices and `A with B` types, which Scala 3.4+ +// warns about; the Scala 3 replacements (`xs*`, `A & B`) don't compile on Scala 2.12. Remove once Scala 2.12 is dropped. +val scala3SharedSourcesWconf = scalacOptions ++= { + if (scalaVersion.value == scala3) + Seq( + "-Wconf:msg=is no longer supported for vararg splices:s", + "-Wconf:msg=with as a type operator has been deprecated:s" + ) + else Nil +} + val testSettings = Seq( publishArtifact := false, scalacOptions ++= Seq("-Ywarn-dead-code"), @@ -87,7 +98,7 @@ lazy val root = rootProject lazy val util = projectMatrix .in(file("util")) - .settings(libraryDependencies += tagging) + .settings(libraryDependencies += tagging, scala3SharedSourcesWconf) .jvmPlatform(scalaVersions = scala2And3Versions) .jsPlatform(scalaVersions = scala2And3Versions) .nativePlatform(scalaVersions = scala2And3Versions) @@ -108,6 +119,7 @@ lazy val proxy = projectMatrix .settings( libraryDependencies ++= Seq(javassist, scalatest % Test), compileOrder := CompileOrder.JavaThenScala, + scala3SharedSourcesWconf, javaOptions += "--add-opens java.base/java.lang=ALL-UNNAMED" ) .dependsOn(macros % Test) @@ -135,7 +147,7 @@ lazy val tests = projectMatrix lazy val utilTests = projectMatrix .in(file("util-tests")) - .settings(testSettings) + .settings(testSettings, scala3SharedSourcesWconf) .dependsOn(macros % "provided", util % Test, testUtil % Test) .jvmPlatform(scalaVersions = scala2And3Versions) diff --git a/macros/src/main/scala-3/com/softwaremill/macwire/internals/CompanionCrimper.scala b/macros/src/main/scala-3/com/softwaremill/macwire/internals/CompanionCrimper.scala index a719c30c..a88d850b 100644 --- a/macros/src/main/scala-3/com/softwaremill/macwire/internals/CompanionCrimper.scala +++ b/macros/src/main/scala-3/com/softwaremill/macwire/internals/CompanionCrimper.scala @@ -21,8 +21,8 @@ private[macwire] class CompanionCrimper[Q <: Quotes, T: Type](using val q: Q)( def isCompanionApply(method: Symbol): Boolean = method.isDefDef && - !(method.flags is Flags.Private) && - !(method.flags is Flags.Protected) && + !method.flags.is(Flags.Private) && + !method.flags.is(Flags.Protected) && returnType(method) <:< targetType && method.name == "apply" diff --git a/macros/src/main/scala-3/com/softwaremill/macwire/internals/ConstructorCrimper.scala b/macros/src/main/scala-3/com/softwaremill/macwire/internals/ConstructorCrimper.scala index 76f7f27e..d5c02120 100644 --- a/macros/src/main/scala-3/com/softwaremill/macwire/internals/ConstructorCrimper.scala +++ b/macros/src/main/scala-3/com/softwaremill/macwire/internals/ConstructorCrimper.scala @@ -16,7 +16,7 @@ private[macwire] class ConstructorCrimper[Q <: Quotes, T: Type](using val q: Q)( lazy val targetTypeD = targetType.dealias private def isAccessibleConstructor(s: Symbol) = - s.isClassConstructor && !(s.flags is Flags.Private) && !(s.flags is Flags.Protected) + s.isClassConstructor && !s.flags.is(Flags.Private) && !s.flags.is(Flags.Protected) private def isImplicit(f: Flags): Boolean = f.is(Flags.Implicit) || f.is(Flags.Given) diff --git a/macros/src/main/scala-3/com/softwaremill/macwire/internals/EligibleValuesFinder.scala b/macros/src/main/scala-3/com/softwaremill/macwire/internals/EligibleValuesFinder.scala index 1743c701..a60109d9 100644 --- a/macros/src/main/scala-3/com/softwaremill/macwire/internals/EligibleValuesFinder.scala +++ b/macros/src/main/scala-3/com/softwaremill/macwire/internals/EligibleValuesFinder.scala @@ -62,7 +62,7 @@ private[macwire] class EligibleValuesFinder[Q <: Quotes](log: Logger)(using val } private def isPublic(member: Symbol): Boolean = { - !((member.flags is Flags.Private) || (member.flags is Flags.Protected)) + !(member.flags.is(Flags.Private) || member.flags.is(Flags.Protected)) } case class EligibleValue(tpe: TypeRepr, expr: Tree) { diff --git a/macros/src/main/scala-3/com/softwaremill/macwire/internals/autowire/AutowireProviders.scala b/macros/src/main/scala-3/com/softwaremill/macwire/internals/autowire/AutowireProviders.scala index e1986dad..53b95cce 100644 --- a/macros/src/main/scala-3/com/softwaremill/macwire/internals/autowire/AutowireProviders.scala +++ b/macros/src/main/scala-3/com/softwaremill/macwire/internals/autowire/AutowireProviders.scala @@ -27,7 +27,7 @@ class AutowireProviders[Q <: Quotes](using val q: Q)( raw: Option[Expr[Any]] = None ) - private val classTypeRepr = TypeRepr.of[Class[_]] + private val classTypeRepr = TypeRepr.of[Class[?]] private val providersFromRawDependencies = @tailrec @@ -88,7 +88,7 @@ class AutowireProviders[Q <: Quotes](using val q: Q)( !member.fullName.contains("$default$") && // default params for copy on case classes !member.fullName.matches(".*_\\d+") // tuple methods on case classes - def isPublic(member: Symbol): Boolean = !((member.flags is Flags.Private) || (member.flags is Flags.Protected)) + def isPublic(member: Symbol): Boolean = !(member.flags.is(Flags.Private) || member.flags.is(Flags.Protected)) log.withBlock(s"detected a membersOf provider"): val Apply(_, List(membersOf)) = t: @unchecked diff --git a/macros/src/main/scala-3/com/softwaremill/macwire/internals/autowire/creator.scala b/macros/src/main/scala-3/com/softwaremill/macwire/internals/autowire/creator.scala index 36cd561b..e30ef42a 100644 --- a/macros/src/main/scala-3/com/softwaremill/macwire/internals/autowire/creator.scala +++ b/macros/src/main/scala-3/com/softwaremill/macwire/internals/autowire/creator.scala @@ -52,7 +52,7 @@ object Constructor: import q.reflect.* def isAccessibleConstructor(s: Symbol) = - s.isClassConstructor && !(s.flags is Flags.Private) && !(s.flags is Flags.Protected) + s.isClassConstructor && !s.flags.is(Flags.Private) && !s.flags.is(Flags.Protected) /** In some cases there is one extra (phantom) constructor. This happens when extended trait has implicit param: * @@ -73,7 +73,7 @@ object Constructor: */ def isPhantomConstructor(constructor: Symbol): Boolean = constructor.fullName.endsWith("$init$") - if forType.typeSymbol.flags is Flags.Trait then None + if forType.typeSymbol.flags.is(Flags.Trait) then None else val publicConstructors: Iterable[Symbol] = val ctors = forType.typeSymbol.declarations @@ -124,8 +124,8 @@ object Companion: def isCompanionApply(method: Symbol): Boolean = method.isDefDef && - !(method.flags is Flags.Private) && - !(method.flags is Flags.Protected) && + !method.flags.is(Flags.Private) && + !method.flags.is(Flags.Protected) && returnType(method) <:< forType && method.name == "apply" diff --git a/macros/src/main/scala-3/com/softwaremill/macwire/internals/utils.scala b/macros/src/main/scala-3/com/softwaremill/macwire/internals/utils.scala index fdc3895d..9898e055 100644 --- a/macros/src/main/scala-3/com/softwaremill/macwire/internals/utils.scala +++ b/macros/src/main/scala-3/com/softwaremill/macwire/internals/utils.scala @@ -4,6 +4,6 @@ import scala.quoted.* def showTypeName[T: Type](using q: Quotes): String = showTypeName(using q)(q.reflect.TypeRepr.of[T]) def showTypeName(using q: Quotes)(t: q.reflect.TypeRepr): String = t.typeSymbol.name -def showExprShort(using q: Quotes)(e: Expr[_]): String = +def showExprShort(using q: Quotes)(e: Expr[?]): String = import q.reflect.* e.asTerm.show(using Printer.TreeShortCode) diff --git a/proxy/src/main/scala/com/softwaremill/macwire/proxy/ProxyCreator.scala b/proxy/src/main/scala/com/softwaremill/macwire/proxy/ProxyCreator.scala index 3904d401..22f25801 100644 --- a/proxy/src/main/scala/com/softwaremill/macwire/proxy/ProxyCreator.scala +++ b/proxy/src/main/scala/com/softwaremill/macwire/proxy/ProxyCreator.scala @@ -27,12 +27,12 @@ object ProxyCreator { instance.asInstanceOf[T] } - private def findBestConstructor(cls: Class[_]) = { + private def findBestConstructor(cls: Class[?]) = { val ctors = cls.getConstructors ctors.find(_.getParameterTypes.size == 0).getOrElse(ctors.head) } - private val TypeDefaults = Map[Class[_], AnyRef]( + private val TypeDefaults = Map[Class[?], AnyRef]( java.lang.Byte.TYPE -> java.lang.Byte.valueOf(0.toByte), java.lang.Short.TYPE -> java.lang.Short.valueOf(0.toShort), java.lang.Integer.TYPE -> java.lang.Integer.valueOf(0), @@ -41,7 +41,7 @@ object ProxyCreator { java.lang.Boolean.TYPE -> java.lang.Boolean.FALSE ) - private def getDefaultValueForClass(cls: Class[_]): AnyRef = TypeDefaults.getOrElse(cls, null) + private def getDefaultValueForClass(cls: Class[?]): AnyRef = TypeDefaults.getOrElse(cls, null) private val UnsafeInstance: Option[Unsafe] = { try { diff --git a/util-tests/src/test/scala/com/softwaremill/macwire/WiredTest.scala b/util-tests/src/test/scala/com/softwaremill/macwire/WiredTest.scala index 4ad4b1da..4de52894 100644 --- a/util-tests/src/test/scala/com/softwaremill/macwire/WiredTest.scala +++ b/util-tests/src/test/scala/com/softwaremill/macwire/WiredTest.scala @@ -47,7 +47,7 @@ class WiredTest extends AnyFlatSpec with Matchers { testLookup(implsMap4, classOf[Y], 0) } - def testLookup(map: InstanceFactoryMap, cls: Class[_], expectedCount: Int): Unit = { + def testLookup(map: InstanceFactoryMap, cls: Class[?], expectedCount: Int): Unit = { val result = new Wired(map).lookup(cls) result should have size (expectedCount) result.foreach(r => cls.isAssignableFrom(r.getClass) should be(true)) diff --git a/util/src/main/scala/com/softwaremill/macwire/InstanceLookup.scala b/util/src/main/scala/com/softwaremill/macwire/InstanceLookup.scala index 847c6c02..c0e3f1da 100644 --- a/util/src/main/scala/com/softwaremill/macwire/InstanceLookup.scala +++ b/util/src/main/scala/com/softwaremill/macwire/InstanceLookup.scala @@ -15,10 +15,10 @@ private[macwire] trait InstanceLookup { case l => throw new RuntimeException(s"Found multiple implementations of class $cls: $l!") } - private def prepareLookupMap: Map[Class[_], List[() => AnyRef]] = { + private def prepareLookupMap: Map[Class[?], List[() => AnyRef]] = { instanceFactoryMap.toList .flatMap { case (startingCls, impl) => - def allSuperClasses(cls: Class[_]): List[Class[_]] = { + def allSuperClasses(cls: Class[?]): List[Class[?]] = { if (cls == null) { Nil } else { diff --git a/util/src/main/scala/com/softwaremill/macwire/Wired.scala b/util/src/main/scala/com/softwaremill/macwire/Wired.scala index f71934d6..158f2fc7 100644 --- a/util/src/main/scala/com/softwaremill/macwire/Wired.scala +++ b/util/src/main/scala/com/softwaremill/macwire/Wired.scala @@ -17,6 +17,6 @@ class Wired(protected val instanceFactoryMap: InstanceFactoryMap) extends Instan } object Wired { - private[macwire] type InstanceFactoryMap = Map[Class[_], () => AnyRef] + private[macwire] type InstanceFactoryMap = Map[Class[?], () => AnyRef] def apply(implsByClass: InstanceFactoryMap) = new Wired(implsByClass) } From da5cf611e8500ad1683c85cf9acc3f10609a4282 Mon Sep 17 00:00:00 2001 From: pierscin <30854591+pierscin@users.noreply.github.com> Date: Thu, 8 Oct 2026 12:01:34 +0200 Subject: [PATCH 3/4] Fix the new Scala 3.9 warnings instead of suppressing them - compile shared sources of util, proxy and util-tests with -Xsource:3 on Scala 2, and drop the Scala-3-only -Wconf silencers - `xs: _*` -> `xs*`, `U with V` -> `U & V` - explicit result types where -Xsource:3 reports a changed inferred override type (NoOpScope.get: Nothing, keeping the Scala 2 signature) - compile-test cases: trailing `_` eta-expansion -> explicit lambdas, `with` in self types -> `&`; the Scala 2 compile-tests toolbox now uses -Xsource:3, and the in-test -Wconf silencers in the Scala 3 harness are removed - scalafmt dialect scala213 -> scala213source3 Co-Authored-By: Claude Opus 5.5 --- .scalafmt.conf | 2 +- build.sbt | 17 +++++------------ .../macwire/aop/ProxyingInterceptor.scala | 4 ++-- .../macwire/proxy/ProxyCreator.scala | 2 +- .../softwaremill/macwire/scopes/NoOpScope.scala | 2 +- .../macwire/scopes/ProxyingScope.scala | 2 +- .../macwire/CompileTestsSupport.scala | 2 +- .../macwire/CompileTestsSupport.scala | 8 +------- .../anonFuncAndMethodsArgsWiredOk.success | 2 +- .../methodWithWiredWithinIfThenElse.success | 2 +- .../test-cases/nestedMethodsWired.success | 2 +- .../test/resources/test-cases/selfType.success | 4 ++-- .../test/resources/test-cases/wireWith.success | 2 +- .../test-cases/wireWithImplicits.success | 2 +- .../test-cases/wireWithTwoParamsLists.failure | 2 +- .../test-cases/methodWithTaggedParams.success | 2 +- .../methodWithTaggedParamsAmbiguous.failure | 2 +- .../methodWithTaggedParamsNotFound.failure | 2 +- .../com/softwaremill/macwire/WiredTest.scala | 2 +- .../macwire/DynamicInstantiate.scala | 2 +- .../softwaremill/macwire/tagging/package.scala | 2 +- 21 files changed, 27 insertions(+), 40 deletions(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index 0d989cc2..7cacfc70 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,6 +1,6 @@ version = 3.9.10 maxColumn = 120 -runner.dialect = scala213 +runner.dialect = scala213source3 fileOverride { "glob:**/scala-3/**" { runner.dialect = scala3 diff --git a/build.sbt b/build.sbt index cb1fde6f..3fde0175 100644 --- a/build.sbt +++ b/build.sbt @@ -57,15 +57,8 @@ ideSkipProject := (scalaVersion.value != ideScalaVersion) || thisProjectRef.valu bspEnabled := !ideSkipProject.value scalacOptions ~= (_.filterNot(Set("-Wconf:cat=other-match-analysis:error"))) // doesn't play well with macros -// TODO(scala-3.9): shared (Scala 2.12/2.13/3) sources use `xs: _*` vararg splices and `A with B` types, which Scala 3.4+ -// warns about; the Scala 3 replacements (`xs*`, `A & B`) don't compile on Scala 2.12. Remove once Scala 2.12 is dropped. -val scala3SharedSourcesWconf = scalacOptions ++= { - if (scalaVersion.value == scala3) - Seq( - "-Wconf:msg=is no longer supported for vararg splices:s", - "-Wconf:msg=with as a type operator has been deprecated:s" - ) - else Nil +val scala2Source3 = scalacOptions ++= { + if (scalaVersion.value == scala3) Nil else Seq("-Xsource:3") } val testSettings = Seq( @@ -98,7 +91,7 @@ lazy val root = rootProject lazy val util = projectMatrix .in(file("util")) - .settings(libraryDependencies += tagging, scala3SharedSourcesWconf) + .settings(libraryDependencies += tagging, scala2Source3) .jvmPlatform(scalaVersions = scala2And3Versions) .jsPlatform(scalaVersions = scala2And3Versions) .nativePlatform(scalaVersions = scala2And3Versions) @@ -119,7 +112,7 @@ lazy val proxy = projectMatrix .settings( libraryDependencies ++= Seq(javassist, scalatest % Test), compileOrder := CompileOrder.JavaThenScala, - scala3SharedSourcesWconf, + scala2Source3, javaOptions += "--add-opens java.base/java.lang=ALL-UNNAMED" ) .dependsOn(macros % Test) @@ -147,7 +140,7 @@ lazy val tests = projectMatrix lazy val utilTests = projectMatrix .in(file("util-tests")) - .settings(testSettings, scala3SharedSourcesWconf) + .settings(testSettings, scala2Source3) .dependsOn(macros % "provided", util % Test, testUtil % Test) .jvmPlatform(scalaVersions = scala2And3Versions) diff --git a/proxy/src/main/scala/com/softwaremill/macwire/aop/ProxyingInterceptor.scala b/proxy/src/main/scala/com/softwaremill/macwire/aop/ProxyingInterceptor.scala index f6dfcc77..6388c860 100644 --- a/proxy/src/main/scala/com/softwaremill/macwire/aop/ProxyingInterceptor.scala +++ b/proxy/src/main/scala/com/softwaremill/macwire/aop/ProxyingInterceptor.scala @@ -12,10 +12,10 @@ trait ProxyingInterceptor extends Interceptor { def invoke(self: AnyRef, thisMethod: Method, _proceed: Method, args: Array[AnyRef]) = { val invocationContext = new InvocationContext { def parameters = args - def target = intercepted + def target: AnyRef = intercepted def method = thisMethod - def proceedWithParameters(parameters: Array[AnyRef]) = thisMethod.invoke(intercepted, parameters: _*) + def proceedWithParameters(parameters: Array[AnyRef]) = thisMethod.invoke(intercepted, parameters*) } handle(invocationContext) diff --git a/proxy/src/main/scala/com/softwaremill/macwire/proxy/ProxyCreator.scala b/proxy/src/main/scala/com/softwaremill/macwire/proxy/ProxyCreator.scala index 22f25801..91e363dc 100644 --- a/proxy/src/main/scala/com/softwaremill/macwire/proxy/ProxyCreator.scala +++ b/proxy/src/main/scala/com/softwaremill/macwire/proxy/ProxyCreator.scala @@ -20,7 +20,7 @@ object ProxyCreator { case Some(unsafe) => unsafe.allocateInstance(proxiedClass) case None => val constructor = findBestConstructor(proxiedClass) - constructor.newInstance(constructor.getParameterTypes.map(getDefaultValueForClass): _*) + constructor.newInstance(constructor.getParameterTypes.map(getDefaultValueForClass)*) } instance.asInstanceOf[ProxyObject].setHandler(methodHandler) diff --git a/proxy/src/main/scala/com/softwaremill/macwire/scopes/NoOpScope.scala b/proxy/src/main/scala/com/softwaremill/macwire/scopes/NoOpScope.scala index 7b155871..86228eb3 100644 --- a/proxy/src/main/scala/com/softwaremill/macwire/scopes/NoOpScope.scala +++ b/proxy/src/main/scala/com/softwaremill/macwire/scopes/NoOpScope.scala @@ -4,5 +4,5 @@ import scala.reflect.ClassTag object NoOpScope extends Scope { def apply[T](createT: => T)(implicit tag: ClassTag[T]) = createT - def get[T](key: String, createT: => T) = throw new RuntimeException("Should never be called!") + def get[T](key: String, createT: => T): Nothing = throw new RuntimeException("Should never be called!") } diff --git a/proxy/src/main/scala/com/softwaremill/macwire/scopes/ProxyingScope.scala b/proxy/src/main/scala/com/softwaremill/macwire/scopes/ProxyingScope.scala index 4962d691..5c834286 100644 --- a/proxy/src/main/scala/com/softwaremill/macwire/scopes/ProxyingScope.scala +++ b/proxy/src/main/scala/com/softwaremill/macwire/scopes/ProxyingScope.scala @@ -13,7 +13,7 @@ trait ProxyingScope extends Scope { val methodHandler = new MethodHandler() { def invoke(self: Any, thisMethod: Method, proceed: Method, args: Array[AnyRef]) = { val instance = get(key, createT) - thisMethod.invoke(instance, args: _*) + thisMethod.invoke(instance, args*) } } diff --git a/test-util/src/main/scala-2/com/softwaremill/macwire/CompileTestsSupport.scala b/test-util/src/main/scala-2/com/softwaremill/macwire/CompileTestsSupport.scala index f6c99fde..b1d076f2 100644 --- a/test-util/src/main/scala-2/com/softwaremill/macwire/CompileTestsSupport.scala +++ b/test-util/src/main/scala-2/com/softwaremill/macwire/CompileTestsSupport.scala @@ -22,7 +22,7 @@ trait CompileTestsSupport extends BaseCompileTestsSupport { val cm = universe.runtimeMirror(getClass.getClassLoader) import scala.tools.reflect.ToolBox - val tb = cm.mkToolBox() + val tb = cm.mkToolBox(options = "-Xsource:3") val source = loadTest("/test-cases/" + testName, imports) diff --git a/test-util/src/main/scala-3/com/softwaremill/macwire/CompileTestsSupport.scala b/test-util/src/main/scala-3/com/softwaremill/macwire/CompileTestsSupport.scala index a3d1e087..ac06ee75 100644 --- a/test-util/src/main/scala-3/com/softwaremill/macwire/CompileTestsSupport.scala +++ b/test-util/src/main/scala-3/com/softwaremill/macwire/CompileTestsSupport.scala @@ -51,13 +51,7 @@ trait CompileTestsSupport extends BaseCompileTestsSupport with OptionValues { val testReporter = new TestReporter val reporter = testReporter val classpath = Array("-classpath", Properties.currentClasspath) - // The test cases are shared with Scala 2, so they use syntax which Scala 3.4+ reports with migration warnings. - val sharedSyntaxWconf = Array( - "-Wconf:msg=for eta-expansion is unnecessary:s", - "-Wconf:msg=with as a type operator has been deprecated:s" - ) - - driver.process(classpath ++ sharedSyntaxWconf :+ path.toString, reporter) + driver.process(classpath :+ path.toString, reporter) // Newer Scala 3 versions (checked with 3.9) also report the "N warnings/errors found" summary is also reported as a (position-less) diagnostic def isSummary(d: Diagnostic) = !d.pos.exists && d.message.matches("""\S+ (warning|error)s? found""") diff --git a/tests/src/test/resources/test-cases/anonFuncAndMethodsArgsWiredOk.success b/tests/src/test/resources/test-cases/anonFuncAndMethodsArgsWiredOk.success index 8f47ddba..eccee014 100644 --- a/tests/src/test/resources/test-cases/anonFuncAndMethodsArgsWiredOk.success +++ b/tests/src/test/resources/test-cases/anonFuncAndMethodsArgsWiredOk.success @@ -5,7 +5,7 @@ object Module { def b(b: B) = { wire[C] } - b _ + (bArg: B) => b(bArg) } } diff --git a/tests/src/test/resources/test-cases/methodWithWiredWithinIfThenElse.success b/tests/src/test/resources/test-cases/methodWithWiredWithinIfThenElse.success index 64362474..de1b17b2 100644 --- a/tests/src/test/resources/test-cases/methodWithWiredWithinIfThenElse.success +++ b/tests/src/test/resources/test-cases/methodWithWiredWithinIfThenElse.success @@ -7,7 +7,7 @@ object Module { if (useWire) wire[C] else new C(new A, new B) } - b _ + (bArg: B) => (useWire: Boolean) => b(bArg)(useWire) } } diff --git a/tests/src/test/resources/test-cases/nestedMethodsWired.success b/tests/src/test/resources/test-cases/nestedMethodsWired.success index 5343e978..25d970ef 100644 --- a/tests/src/test/resources/test-cases/nestedMethodsWired.success +++ b/tests/src/test/resources/test-cases/nestedMethodsWired.success @@ -4,7 +4,7 @@ object Module { // method's parameter 'a' will shadow def 'a'. def a(a: A) = { def b(b: B): C = wire[C] - b _ + (bArg: B) => b(bArg) } } diff --git a/tests/src/test/resources/test-cases/selfType.success b/tests/src/test/resources/test-cases/selfType.success index 3a00ff5e..07cf8544 100644 --- a/tests/src/test/resources/test-cases/selfType.success +++ b/tests/src/test/resources/test-cases/selfType.success @@ -13,7 +13,7 @@ trait ModuleSimple { this : AProvider => lazy val c = wire[C] } -trait ModuleMultiple { this : AProvider with BProvider => +trait ModuleMultiple { this : AProvider & BProvider => lazy val c = wire[C] } @@ -38,7 +38,7 @@ require(TestMultiple.c.a == TestMultiple.a) require(TestMultiple.c.b == TestMultiple.b) object ProviderAliasing { - type AAndB = AProvider with BProvider + type AAndB = AProvider & BProvider } trait AliasedMultiModule { this: ProviderAliasing.AAndB => diff --git a/tests/src/test/resources/test-cases/wireWith.success b/tests/src/test/resources/test-cases/wireWith.success index ddc6cc98..f02174b8 100644 --- a/tests/src/test/resources/test-cases/wireWith.success +++ b/tests/src/test/resources/test-cases/wireWith.success @@ -13,7 +13,7 @@ object Test { lazy val a: A = wire[A] lazy val b: B = wire[B] - lazy val c: C = wireWith(C.factory _) + lazy val c: C = wireWith((a: A, b: B) => C.factory(a, b)) } require(Test.c.a eq Test.a) diff --git a/tests/src/test/resources/test-cases/wireWithImplicits.success b/tests/src/test/resources/test-cases/wireWithImplicits.success index 57c7fedd..4aef91b3 100644 --- a/tests/src/test/resources/test-cases/wireWithImplicits.success +++ b/tests/src/test/resources/test-cases/wireWithImplicits.success @@ -7,4 +7,4 @@ object A { lazy val n = 0 implicit lazy val s: String = "s" -wireWith(A.make _) +wireWith((n: Int) => A.make(n)) diff --git a/tests/src/test/resources/test-cases/wireWithTwoParamsLists.failure b/tests/src/test/resources/test-cases/wireWithTwoParamsLists.failure index 1764e015..2402818d 100644 --- a/tests/src/test/resources/test-cases/wireWithTwoParamsLists.failure +++ b/tests/src/test/resources/test-cases/wireWithTwoParamsLists.failure @@ -17,5 +17,5 @@ object Test extends BProvider { } lazy val a: A = wire[A] - lazy val c: C = wireWith(C.factory _) + lazy val c: C = wireWith((a: A) => (b: B) => C.factory(a)(b)) } diff --git a/util-tests/src/test/resources/test-cases/methodWithTaggedParams.success b/util-tests/src/test/resources/test-cases/methodWithTaggedParams.success index a9833e60..85c05ad8 100644 --- a/util-tests/src/test/resources/test-cases/methodWithTaggedParams.success +++ b/util-tests/src/test/resources/test-cases/methodWithTaggedParams.success @@ -3,7 +3,7 @@ object Module { def create(blueberryArg: Berry @@ Blue) = { def inner(blackberryArg: Berry @@ Black): BlueberryBasket = wire[BlueberryBasket] - inner _ + (arg: Berry @@ Black) => inner(arg) } } diff --git a/util-tests/src/test/resources/test-cases/methodWithTaggedParamsAmbiguous.failure b/util-tests/src/test/resources/test-cases/methodWithTaggedParamsAmbiguous.failure index 4236d041..a96fb025 100644 --- a/util-tests/src/test/resources/test-cases/methodWithTaggedParamsAmbiguous.failure +++ b/util-tests/src/test/resources/test-cases/methodWithTaggedParamsAmbiguous.failure @@ -3,7 +3,7 @@ object Module { def create(blueberryArg1: Berry @@ Blue) = { def inner(blueberryArg2: Berry @@ Blue): BlueberryBasket = wire[BlueberryBasket] - inner _ + (arg: Berry @@ Blue) => inner(arg) } } diff --git a/util-tests/src/test/resources/test-cases/methodWithTaggedParamsNotFound.failure b/util-tests/src/test/resources/test-cases/methodWithTaggedParamsNotFound.failure index 88e20dd5..42c1de2a 100644 --- a/util-tests/src/test/resources/test-cases/methodWithTaggedParamsNotFound.failure +++ b/util-tests/src/test/resources/test-cases/methodWithTaggedParamsNotFound.failure @@ -3,7 +3,7 @@ object Module { def create(blackberryArg: Berry @@ Black) = { def inner(raspberryArg: Berry @@ Red): BlueberryBasket = wire[BlueberryBasket] - inner _ + (arg: Berry @@ Red) => inner(arg) } } diff --git a/util-tests/src/test/scala/com/softwaremill/macwire/WiredTest.scala b/util-tests/src/test/scala/com/softwaremill/macwire/WiredTest.scala index 4de52894..a3361d4c 100644 --- a/util-tests/src/test/scala/com/softwaremill/macwire/WiredTest.scala +++ b/util-tests/src/test/scala/com/softwaremill/macwire/WiredTest.scala @@ -8,7 +8,7 @@ class WiredTest extends AnyFlatSpec with Matchers { import WiredTest._ def createInstanceFactoryMap(instances: AnyRef*): InstanceFactoryMap = Map( - instances.map(i => i.getClass -> (() => i)): _* + instances.map(i => i.getClass -> (() => i))* ) val implsMap1 = createInstanceFactoryMap(new X, new Y, new Z) diff --git a/util/src/main/scala/com/softwaremill/macwire/DynamicInstantiate.scala b/util/src/main/scala/com/softwaremill/macwire/DynamicInstantiate.scala index 963414f4..a73c14d0 100644 --- a/util/src/main/scala/com/softwaremill/macwire/DynamicInstantiate.scala +++ b/util/src/main/scala/com/softwaremill/macwire/DynamicInstantiate.scala @@ -26,7 +26,7 @@ private[macwire] trait DynamicInstantiate { } } - ctor.newInstance(params: _*).asInstanceOf[T] + ctor.newInstance(params*).asInstanceOf[T] } protected def lookup[T](cls: Class[T]): List[T] diff --git a/util/src/main/scala/com/softwaremill/macwire/tagging/package.scala b/util/src/main/scala/com/softwaremill/macwire/tagging/package.scala index 0e5f1e97..9dfcbf6f 100644 --- a/util/src/main/scala/com/softwaremill/macwire/tagging/package.scala +++ b/util/src/main/scala/com/softwaremill/macwire/tagging/package.scala @@ -17,6 +17,6 @@ package object tagging { implicit class AndTagger[T, U](t: T @@ U) { @deprecated("Use com.softwaremill.tagging instead") - def andTaggedWith[V]: T @@ (U with V) = new com.softwaremill.tagging.AndTagger[T, U](t).andTaggedWith[V] + def andTaggedWith[V]: T @@ (U & V) = new com.softwaremill.tagging.AndTagger[T, U](t).andTaggedWith[V] } } From 4e5e7643eece576c1f000e307c211175b0401471 Mon Sep 17 00:00:00 2001 From: pierscin <30854591+pierscin@users.noreply.github.com> Date: Thu, 8 Oct 2026 13:12:22 +0200 Subject: [PATCH 4/4] Clarify the comment on filtering compiler summary diagnostics --- .../com/softwaremill/macwire/CompileTestsSupport.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test-util/src/main/scala-3/com/softwaremill/macwire/CompileTestsSupport.scala b/test-util/src/main/scala-3/com/softwaremill/macwire/CompileTestsSupport.scala index ac06ee75..9da2a6d4 100644 --- a/test-util/src/main/scala-3/com/softwaremill/macwire/CompileTestsSupport.scala +++ b/test-util/src/main/scala-3/com/softwaremill/macwire/CompileTestsSupport.scala @@ -13,6 +13,7 @@ import java.nio.file.Files import java.nio.file.StandardOpenOption import dotty.tools.dotc.reporting.{ThrowingReporter, Diagnostic} +import dotty.tools.dotc.interfaces.Diagnostic.WARNING import dotty.tools.dotc.Driver import java.io.IOException @@ -53,12 +54,11 @@ trait CompileTestsSupport extends BaseCompileTestsSupport with OptionValues { val classpath = Array("-classpath", Properties.currentClasspath) driver.process(classpath :+ path.toString, reporter) - // Newer Scala 3 versions (checked with 3.9) also report the "N warnings/errors found" summary is also reported as a (position-less) diagnostic - def isSummary(d: Diagnostic) = !d.pos.exists && d.message.matches("""\S+ (warning|error)s? found""") - val infos = testReporter.storedInfos.filterNot(isSummary) + // since Scala 3.9 update, the "N errors" found summary is reported as a position-less warning + val infosWithoutSummary = testReporter.storedInfos.filterNot(msg => msg.level == WARNING && !msg.pos.exists) def verifyInfo(level: Int, expected: List[String]) = { - val actual = infos.filter(_.level == level).map(_.message) + val actual = infosWithoutSummary.filter(_.level == level).map(_.message) if (expected.size > 0) { val info = actual.mkString("\n")