Skip to content

Use wildcard type instead of whitebox cast in IsoFields#1574

Open
mbovel wants to merge 1 commit into
optics-dev:masterfrom
mbovel:fix-iso-fields-whitebox-type
Open

Use wildcard type instead of whitebox cast in IsoFields#1574
mbovel wants to merge 1 commit into
optics-dev:masterfrom
mbovel:fix-iso-fields-whitebox-type

Conversation

@mbovel
Copy link
Copy Markdown

@mbovel mbovel commented Apr 11, 2026

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?

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) <[email protected]>
@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))
  }

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