Skip to content

Commit 798c39a

Browse files
authored
Merge branch 'master' into named-tuples-support
2 parents 79a36f2 + 3aa940b commit 798c39a

11 files changed

Lines changed: 81 additions & 43 deletions

File tree

.github/workflows/ci.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -305,19 +305,19 @@ jobs:
305305
strategy:
306306
matrix:
307307
os: [ubuntu-22.04]
308-
java: [temurin@11]
308+
java: [temurin@17]
309309
runs-on: ${{ matrix.os }}
310310
steps:
311311
- name: Checkout current branch (fast)
312312
uses: actions/checkout@v6
313313

314-
- name: Setup Java (temurin@11)
315-
id: setup-java-temurin-11
316-
if: matrix.java == 'temurin@11'
314+
- name: Setup Java (temurin@17)
315+
id: setup-java-temurin-17
316+
if: matrix.java == 'temurin@17'
317317
uses: actions/setup-java@v5
318318
with:
319319
distribution: temurin
320-
java-version: 11
320+
java-version: 17
321321

322322
- uses: coursier/setup-action@v1
323323
with:

.scalafmt.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version=3.11.0
1+
version=3.11.4
22
docstrings.style = keep
33
align.preset = more
44
maxColumn = 120

build.sbt

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ lazy val kindProjector = "org.typelevel" % "kind-projector" % "0.13.4" cross Cro
4343

4444
lazy val buildSettings = Seq(
4545
scalacOptions ++= Seq(
46-
"-release:8",
4746
"-encoding",
4847
"UTF-8",
4948
"-feature",
@@ -108,16 +107,16 @@ lazy val buildSettings = Seq(
108107

109108
lazy val catsVersion = "2.13.0"
110109
lazy val scala2Version = "2.13.18"
111-
lazy val scala3Version = "3.3.7"
110+
lazy val scala3Version = "3.3.8"
112111
lazy val scalaNextVersion = "3.8.4"
113112

114113
lazy val cats = Def.setting("org.typelevel" %%% "cats-core" % catsVersion)
115114
lazy val catsFree = Def.setting("org.typelevel" %%% "cats-free" % catsVersion)
116115
lazy val catsLaws = Def.setting("org.typelevel" %%% "cats-laws" % catsVersion)
117116
lazy val alleycats = Def.setting("org.typelevel" %%% "alleycats-core" % catsVersion)
118117
lazy val shapeless = Def.setting("com.chuusai" %%% "shapeless" % "2.3.13")
119-
lazy val refinedDep = Def.setting("eu.timepit" %%% "refined" % "0.11.3")
120-
lazy val refinedScalacheck = Def.setting("eu.timepit" %%% "refined-scalacheck" % "0.11.3" % "test")
118+
lazy val refinedDep = Def.setting("eu.timepit" %%% "refined" % "0.11.4")
119+
lazy val refinedScalacheck = Def.setting("eu.timepit" %%% "refined-scalacheck" % "0.11.4" % "test")
121120

122121
lazy val discipline = Def.setting("org.typelevel" %%% "discipline-core" % "1.7.0")
123122
lazy val munit = Def.setting("org.scalameta" %%% "munit" % "1.0.0-M6" % Test)
@@ -134,10 +133,31 @@ lazy val scalaNativeSettings = Seq(
134133
tlMimaPreviousVersions := Set.empty
135134
)
136135

137-
lazy val monocleSettings = buildSettings
138-
lazy val monocleJvmSettings = monocleSettings
139-
lazy val monocleJsSettings = monocleSettings ++ scalajsSettings
140-
lazy val monocleNativeSettings = monocleSettings ++ scalaNativeSettings
136+
lazy val defaultReleaseOption = "-release:8"
137+
138+
lazy val monocleSettings = buildSettings
139+
lazy val monocleJvmSettings = monocleSettings ++ Seq(
140+
scalacOptions ++= {
141+
if (scalaVersion.value.startsWith("3.3.")) {
142+
Seq(
143+
"-Yfuture-lazy-vals",
144+
"-release:11"
145+
)
146+
} else if (scalaBinaryVersion.value == "3") {
147+
Nil
148+
} else {
149+
Seq(
150+
defaultReleaseOption
151+
)
152+
}
153+
}
154+
)
155+
lazy val monocleJsSettings = monocleSettings ++ scalajsSettings ++ Seq(
156+
scalacOptions += defaultReleaseOption
157+
)
158+
lazy val monocleNativeSettings = monocleSettings ++ scalaNativeSettings ++ Seq(
159+
scalacOptions += defaultReleaseOption
160+
)
141161

142162
lazy val root = tlCrossRootProject.aggregate(
143163
core,
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
package monocle.internal
22

3-
import monocle.Iso
3+
import monocle.{Iso, PIso}
44
import scala.quoted.{quotes, Expr, Quotes, Type}
55
import scala.deriving.Mirror
66

77
object IsoFields {
8-
transparent inline def apply[S <: Product](using mirror: Mirror.ProductOf[S]): Iso[S, Tuple] =
8+
transparent inline def apply[S <: Product](using mirror: Mirror.ProductOf[S]): PIso[S, S, ? <: Tuple, ? <: Tuple] =
99
${ IsoFieldsImpl.apply[S]('mirror) }
1010
}
1111

1212
private[monocle] object IsoFieldsImpl {
1313

14-
def apply[S <: Product](mirror: Expr[Mirror.ProductOf[S]])(using Quotes, Type[S]): Expr[Iso[S, Tuple]] = {
15-
16-
def whitebox[A <: Tuple](e: Expr[Iso[S, A]]): Expr[Iso[S, Tuple]] =
17-
e.asInstanceOf[Expr[Iso[S, Tuple]]]
18-
14+
def apply[S <: Product](
15+
mirror: Expr[Mirror.ProductOf[S]]
16+
)(using Quotes, Type[S]): Expr[PIso[S, S, ? <: Tuple, ? <: Tuple]] =
1917
mirror match {
2018
case '{ type a <: Tuple; $m: Mirror.ProductOf[S] { type MirroredElemTypes = `a` } } =>
21-
whitebox('{
19+
'{
2220
val f: S => a = Tuple.fromProductTyped(_)(using $m)
2321
val g: a => S = $m.fromProduct(_)
2422
Iso[S, a](f)(g)
25-
})
23+
}
24+
case other =>
25+
quotes.reflect.report.errorAndAbort(s"Unexpected mirror type: ${other.show}")
2626
}
27-
}
2827
}

core/shared/src/main/scala-3/monocle/syntax/MacroSyntax.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ trait MacroSyntax {
1313
* Case classes with 0 fields will correspond with `EmptyTuple`, 1 with `Tuple1[field type]`, 2 or more with a
1414
* tuple of all field types in the same order as the fields themselves.
1515
*/
16-
transparent inline def fields[S <: Product: Mirror.ProductOf]: Iso[S, Tuple] =
16+
transparent inline def fields[S <: Product: Mirror.ProductOf]: PIso[S, S, ? <: Tuple, ? <: Tuple] =
1717
IsoFields[S]
1818
}
1919

core/shared/src/main/scala/monocle/std/String.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ trait StringOptics extends PlatformSpecificStringOptics {
3636
// we reject cases where String will be an invalid Prism according 2nd Prism law
3737
// * String starts with +
3838
// * String starts with 0 and has multiple digits
39+
// * String starts with -0 (negative zero forms never round-trip)
3940
def inputBreaksPrismLaws(input: String): Boolean =
40-
s.isEmpty || s.startsWith("+") || (s.startsWith("0") && s.length > 1)
41+
s.isEmpty || s.startsWith("+") || (s.startsWith("0") && s.length > 1) ||
42+
(s.length > 1 && s.charAt(0) == '-' && s.charAt(1) == '0')
4143

4244
if (inputBreaksPrismLaws(s)) None
4345
else

core/shared/src/test/scala-3/monocle/internal/IsoFieldsTest.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,13 @@ final class IsoFieldsTest extends munit.FunSuite {
3131
assertEquals(iso.reverseGet(("hi", 5)), Foo("hi", 5))
3232
assertEquals(iso.reverseGet(iso.get(Foo("hi", 5))), Foo("hi", 5))
3333
}
34+
35+
test("fields extension method works") {
36+
case class Foo(s: String, i: Int)
37+
val foo = Foo("hi", 5)
38+
val iso: Iso[Foo, (String, Int)] = Iso.fields[Foo]
39+
40+
assertEquals(iso.get(foo), ("hi", 5))
41+
assertEquals(iso.reverseGet(("hi", 5)), foo)
42+
}
3443
}

macro/src/main/scala-3/monocle/macros/GenIso.scala

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package monocle.macros
22

3-
import monocle.Iso
3+
import monocle.{Iso, PIso}
44
import scala.language.`3.0`
55
import scala.deriving.*
66
import scala.quoted.*
@@ -58,23 +58,18 @@ object GenIso {
5858
* types in the same order as the fields themselves.
5959
*/
6060
@deprecated("use monocle.Iso.fields", since = "3.1.0")
61-
transparent inline def fields[S <: Product](using m: Mirror.ProductOf[S]): Iso[S, Any] =
61+
transparent inline def fields[S <: Product](using m: Mirror.ProductOf[S]): PIso[S, S, ?, ?] =
6262
${ _fields[S]('m) }
6363

64-
private def _fields[S <: Product](e: Expr[Mirror.ProductOf[S]])(using Quotes, Type[S]): Expr[Iso[S, Any]] = {
65-
66-
def whitebox[A](e: Expr[Iso[S, A]]): Expr[Iso[S, Any]] =
67-
e.asInstanceOf[Expr[Iso[S, Any]]]
68-
64+
private def _fields[S <: Product](e: Expr[Mirror.ProductOf[S]])(using Quotes, Type[S]): Expr[PIso[S, S, ?, ?]] =
6965
e match {
7066
case '{ $m: Mirror.ProductOf[S] { type MirroredElemTypes = EmptyTuple } } =>
71-
whitebox(_unit[S](e))
67+
_unit[S](e)
7268

7369
case '{ $m: Mirror.ProductOf[S] { type MirroredElemTypes = a *: EmptyTuple } } =>
74-
whitebox(_apply[S, a](e))
70+
_apply[S, a](e)
7571

7672
case _ =>
77-
whitebox('{ monocle.internal.IsoFields[S](using $e) })
73+
'{ monocle.internal.IsoFields[S](using $e) }
7874
}
79-
}
8075
}

project/build.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
sbt.version=1.12.11
1+
sbt.version=1.12.14

project/plugins.sbt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
addSbtPlugin("org.typelevel" % "sbt-typelevel-ci-release" % "0.8.5")
1+
addSbtPlugin("org.typelevel" % "sbt-typelevel-ci-release" % "0.8.7")
22
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.13.1")
33
addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.8")
44

5-
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.21.0")
5+
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.22.0")
66
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.3.2")
7-
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.11")
7+
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.12")
88
addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.3.2")
9-
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.6.0")
10-
addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.9.0")
9+
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.6.2")
10+
addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.9.1")
1111

1212
scalacOptions += "-deprecation"

0 commit comments

Comments
 (0)