From 7f57e4d6a6c3b0c3b7707aeae116fe52cb8999dc Mon Sep 17 00:00:00 2001 From: Yannick Heiber Date: Sun, 27 Sep 2026 17:21:43 +0200 Subject: [PATCH 1/3] Use future lazy val encoding Scala 3.3.8 allows to opt in to the lazy val encoding Scala 3.8+ uses to avoid warnings/errors on JVM 25+. As we already bumped the minimum JDK version to 17, the fact that future lazy vals require 9+ is no problem. On the positive side, we avoid our users getting annoyed (or having to resort to bytecode manipulation via VirtusLab/sloth) when using JVM 25 or higher. --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index e0d2b670..9b3f993f 100644 --- a/build.sbt +++ b/build.sbt @@ -79,7 +79,7 @@ val commonSettings = List( "-Wconf:msg=type parameter .+ defined in .+ shadows .+:s", // esp.Tag "-Wconf:msg=value T is deprecated:s" // jsonpath/xpath literals ) - case Some((3, _)) => List("-source:3.2-migration", "-no-indent") + case Some((3, _)) => List("-source:3.2-migration", "-no-indent", "-Yfuture-lazy-vals") } .toList .flatten, From 3f3686b295642a7bdbbf393dd7e90f403647fb6f Mon Sep 17 00:00:00 2001 From: Yannick Heiber Date: Mon, 28 Sep 2026 13:14:33 +0200 Subject: [PATCH 2/3] Attempt to make MiMa happy on future lazy vals --- build.sbt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 9b3f993f..df60b1cd 100644 --- a/build.sbt +++ b/build.sbt @@ -205,7 +205,9 @@ lazy val csv = crossProject(JVMPlatform, JSPlatform, NativePlatform) description := "Streaming CSV manipulation library", mimaBinaryIssueFilters ++= List( // Static forwarder, only relevant for Java - ProblemFilters.exclude[DirectMissingMethodProblem]("fs2.data.csv.RowEncoderF.fromNonEmptyMapCsvRowEncoder") + ProblemFilters.exclude[DirectMissingMethodProblem]("fs2.data.csv.RowEncoderF.fromNonEmptyMapCsvRowEncoder"), + // Static initializer forwarder, not callable. Scala 3 only, due to future lazy val encoding + ProblemFilters.exclude[DirectMissingMethodProblem]("fs2.data.csv.CellDecoder.") ) ) .jsSettings( @@ -316,7 +318,11 @@ lazy val json = crossProject(JVMPlatform, JSPlatform, NativePlatform) ProblemFilters.exclude[MissingClassProblem]("fs2.data.json.jsonpath.internals.TaggedJson$StartArrayElement$"), ProblemFilters.exclude[MissingClassProblem]("fs2.data.json.jsonpath.internals.TaggedJson$StartObjectValue"), ProblemFilters.exclude[MissingClassProblem]("fs2.data.json.jsonpath.internals.TaggedJson$StartObjectValue$"), - ProblemFilters.exclude[DirectMissingMethodProblem]("fs2.data.json.jsonpath.package.untag") + ProblemFilters.exclude[DirectMissingMethodProblem]("fs2.data.json.jsonpath.package.untag"), + // Static initializer forwarders, not callable. Scala 3 only, due to future lazy val encoding + ProblemFilters.exclude[DirectMissingMethodProblem]("fs2.data.json.Selector."), + ProblemFilters.exclude[DirectMissingMethodProblem]("fs2.data.json.NamePredicate."), + ProblemFilters.exclude[DirectMissingMethodProblem]("fs2.data.json.IndexPredicate.") ) ) .nativeSettings( From e2c4e6e3591326d96386be706849f5876c69f5ca Mon Sep 17 00:00:00 2001 From: Yannick Heiber Date: Fri, 2 Oct 2026 10:29:24 +0200 Subject: [PATCH 3/3] Do not use future lazy vals on Native yet --- build.sbt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index df60b1cd..1d115498 100644 --- a/build.sbt +++ b/build.sbt @@ -79,10 +79,16 @@ val commonSettings = List( "-Wconf:msg=type parameter .+ defined in .+ shadows .+:s", // esp.Tag "-Wconf:msg=value T is deprecated:s" // jsonpath/xpath literals ) - case Some((3, _)) => List("-source:3.2-migration", "-no-indent", "-Yfuture-lazy-vals") + case Some((3, _)) => List("-source:3.2-migration", "-no-indent") } .toList .flatten, + // Scala Native's nscplugin for 3.3.8 cannot handle VarHandle-based lazy vals (scala-native/scala-native#4957) + scalacOptions ++= { + if (scalaBinaryVersion.value == "3" && !crossProjectPlatform.?.value.contains(NativePlatform)) + List("-Yfuture-lazy-vals") + else Nil + }, scalacOptions ++= PartialFunction .condOpt(CrossVersion.partialVersion(scalaVersion.value)) { case Some((2, n)) if n >= 13 =>