Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make SIP-62 - betterFors a standard feature #22652

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

KacperFKorban
Copy link
Member

@KacperFKorban KacperFKorban commented Feb 24, 2025

  • Deprecate experimental language import
  • Make betterFors conditional on -source >= 3.7 instead
  • Drop the experimental.betterFors import from tests

@KacperFKorban KacperFKorban added release-notes Should be mentioned in the release notes needs-minor-release This PR cannot be merged until the next minor release labels Feb 24, 2025
@KacperFKorban
Copy link
Member Author

While working on this, I discovered an unhandled/bug case that apparently isn't used anywhere in the open community build – nested given bindings inside of a pattern of an alias. I added a quickfix for it.
e.g.

for
    x <- Option(23 -> "abc")
    (a @ given Int, b @ given String) = x
    _ <- Option(1)
  yield
    assert(summon[Int] == 23)

betterFors generated:

Option.apply[(Int, String)](ArrowAssoc[Int](23).->[String]("abc")).flatMap
  [Nothing]((x: (Int, String)) =>
  {
    val $2$: ((Int, String), Int, String) =
      x:(Int, String) @unchecked match 
        {
          case 
            $1$ @
              Tuple2.unapply[Int, String](given a @ _:Int,
                given b @ _:String)
            => Tuple3.apply[(Int, String), Int, String]($1$, a, b)
        }
    val $1$: (Int, String) = $2$._1
    val a: Int = $2$._2
    val b: String = $2$._3
    Option.apply[Int](1).map[Nothing]((x$1: Int) =>
      x$1:Int @unchecked match 
        {
          case _ => assert(summon[Int](/* missing */summon[Int]).==())
        }
    )
  }
)

After the fix, it generates:

Option.apply[(Int, String)](ArrowAssoc[Int](23).->[String]("abc")).map[
  ((Int, String), (Int, String))]((x: (Int, String)) =>
  {
    val $2$: ((Int, String), Int, String) =
      x:(Int, String) @unchecked match 
        {
          case 
            $1$ @
              Tuple2.unapply[Int, String](given a @ _:Int,
                given b @ _:String)
            => Tuple3.apply[(Int, String), Int, String]($1$, a, b)
        }
    val $1$: (Int, String) = $2$._1
    val a: Int = $2$._2
    val b: String = $2$._3
    Tuple2.apply[(Int, String), (Int, String)](x, $1$)
  }
).flatMap[Unit]((x$1: ((Int, String), (Int, String))) =>
  x$1:(x$1 : ((Int, String), (Int, String))) @unchecked match 
    {
      case 
        Tuple2.unapply[(Int, String), (Int, String)](x @ _,
          Tuple2.unapply[Int, String](given a @ _:Int, given b @ _:String)
          )
        =>
        Option.apply[Int](1).map[Unit]((x$1: Int) =>
          x$1:Int @unchecked match 
            {
              case _ =>
                if a.==(23).unary_! then
                  scala.runtime.Scala3RunTime.assertFailed() else ()
            }
        )
    }
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-minor-release This PR cannot be merged until the next minor release release-notes Should be mentioned in the release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant