Skip to content

Use wildcard type instead of whitebox cast in IsoFields#1574

Merged
julien-truffaut merged 3 commits into
optics-dev:masterfrom
mbovel:fix-iso-fields-whitebox-type
Jul 13, 2026
Merged

Use wildcard type instead of whitebox cast in IsoFields#1574
julien-truffaut merged 3 commits into
optics-dev:masterfrom
mbovel:fix-iso-fields-whitebox-type

Conversation

@mbovel

@mbovel mbovel commented Apr 11, 2026

Copy link
Copy Markdown
Contributor

Replace the whitebox cast (asInstanceOf[Expr[Iso[S, Tuple]]]) with a wildcard return type using PIso[S, S, ? <: Tuple, ? <: Tuple].

Since IsoFields.apply is a transparent inline method, the compiler still infers the precise tuple type at call sites. This avoids the unsafe cast.

The motivation is to prepare for future stricter checks in the Scala 3 compiler (scala/scala3#25756). The current implementation exploits a missing check to generate an unsound cast.

Note: we use PIso (a trait) directly instead of the Iso type alias (defined as type Iso[S, A] = PIso[S, S, A, A]) because Scala 3 cannot reduce higher-kinded type aliases applied to wildcard arguments. Is that acceptable to use PIso instead of Iso?

@mbovel mbovel force-pushed the fix-iso-fields-whitebox-type branch from 9c3c332 to 6f87f90 Compare May 6, 2026 12:34
@mbovel mbovel marked this pull request as ready for review May 6, 2026 12:36
@julien-truffaut

Copy link
Copy Markdown
Member

Hi @mbovel, sorry for the delay. I missed this PR.

Thanks for your doing it! would you mind adding the following?

  1. Add a fallback match arm in IsoFieldsImpl.apply for better error messages:
  case other => report.errorAndAbort(s"Unexpected mirror type: ${other.show}")
  1. adding a test for the extension syntax in IsoFieldsTest.scala
  test("fields extension method works") {
    case class Foo(s: String, i: Int)
    val foo = Foo("hi", 5)
    val iso: Iso[Foo, (String, Int)] = foo.focus.fields  // or however the syntax works
    assertEquals(iso.get(foo), ("hi", 5))
  }

@mbovel mbovel force-pushed the fix-iso-fields-whitebox-type branch from 6ca022e to 73c588b Compare July 13, 2026 13:01
@mbovel

mbovel commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @julien-truffaut. I addressed your comments in 73c588b.

@julien-truffaut

Copy link
Copy Markdown
Member

Thanks @mbovel !

@mbovel

mbovel commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

CI failed because of formatting; fixed, and rebased on top of main.

mbovel and others added 3 commits July 13, 2026 15:18
Replace the `whitebox` cast (`asInstanceOf[Expr[Iso[S, Tuple]]]`) with a
proper wildcard return type using `PIso[S, S, ? <: Tuple, ? <: Tuple]`.

Since `IsoFields.apply` is a `transparent inline` method, the compiler
still infers the precise tuple type at call sites. This avoids the unsafe
cast and prepares for potential stricter macro type checking in future
Scala versions.

The motivation is to prepare for future stricter checks in the Scala 3
compiler. The current implementation exploits a missing check to generate
an unsound cast.

Note: we use `PIso` (a trait) directly instead of the `Iso` type alias
(defined as `type Iso[S, A] = PIso[S, S, A, A]`) because Scala 3 cannot
reduce higher-kinded type aliases applied to wildcard arguments.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Address review comments:
- Report a proper error message when the mirror expression doesn't match
  the expected shape in IsoFieldsImpl.apply
- Add a test exercising the Iso.fields extension method on a value

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mbovel mbovel force-pushed the fix-iso-fields-whitebox-type branch from 8263797 to 9b87a44 Compare July 13, 2026 13:18
@julien-truffaut julien-truffaut merged commit 065f774 into optics-dev:master Jul 13, 2026
1 of 9 checks passed
julien-truffaut added a commit that referenced this pull request Jul 13, 2026
#1600)

PR #1574 changed IsoFields.apply to return
PIso[S, S, ? <: Tuple, ? <: Tuple] but GenIso._fields still fed the
result into `whitebox`, which expects Expr[Iso[S, A]]. The wildcard type
no longer unifies with Iso[S, A], breaking macrosJVM compilation on every
Scala 3 JVM job (the CI page only showed temurin@25 red because fail-fast
cancelled the others).

Cast the IsoFields result directly to Expr[Iso[S, Any]] in the fallback
branch, matching the erased cast `whitebox` already performs.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mbovel added a commit to mbovel/Monocle that referenced this pull request Jul 13, 2026
Declare the honest supertype PIso[S, S, ?, ?] instead, as optics-dev#1574 did for
IsoFields. All match arms conform without a cast, and transparent inline
still infers the precise type at call sites. This also fixes the master
build, broken since optics-dev#1574.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
julien-truffaut pushed a commit that referenced this pull request Jul 13, 2026
Declare the honest supertype PIso[S, S, ?, ?] instead, as #1574 did for
IsoFields. All match arms conform without a cast, and transparent inline
still infers the precise type at call sites. This also fixes the master
build, broken since #1574.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@mbovel mbovel deleted the fix-iso-fields-whitebox-type branch July 13, 2026 21:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants