Skip to content

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Sep 1, 2025

Implements SIP 70. Currently, only Seqs and Arrays can be unpacked whereas the SIP also specifies Option unpacking.

@odersky odersky marked this pull request as ready for review September 18, 2025 21:10
@odersky odersky requested a review from a team as a code owner September 18, 2025 21:10
Copy link
Member

@sjrd sjrd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments on the implementation strategy. Overall it looks like the right design, but some details can be improved IMO.

then addArg(typedArg(arg, formal), formal)
else addArg(typedArg(arg, elemFormal), elemFormal)
else
val typedArgs = harmonic(harmonizeArgs, elemFormal):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICT, there is no equivalent code in the code path with multiSpreads. I understand it may be tricky, but it's at least worth calling out at the spec/SIP level. IIUC It means we get:

def foo[A](xs: A*): List[A] = xs.toList

foo(5, 5.6) // List[Double]
val doubles = List(5.6)
foo(5, doubles*) // List[AnyVal]

Basically having any spread in a vararg argument disables harmonization entirely.

@odersky
Copy link
Contributor Author

odersky commented Sep 19, 2025

@sjrd I got harmonization working for spreads and also implemented the other review suggestions

Copy link
Member

@sjrd sjrd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

I'm not sure what happens if we provide an Array[S] where S <: T. For example in Scala 3.7.3 we can do:

scala> def foo(x: CharSequence*): String = x.mkString
def foo(x: CharSequence*): String
                                                                                                              
scala> val strings: Array[String] = Array("foo", "bar")
val strings: Array[String] = Array(foo, bar)
                                                                                                              
scala> foo(strings*)
val res0: String = foobar

What is then the desugaring of

scala> foo(("oof": CharSequence), strings*)

It seems we can't call addArray(strings), because it requires an Array[CharSequence] and strings is an Array[String].

@odersky
Copy link
Contributor Author

odersky commented Sep 19, 2025

I'm not sure what happens if we provide an Array[S] where S <: T.

Good question! In fact it runs fine, but fails -Ycheck. To fix this, I changed the generated code to add a cast if needed. The example

foo(("oof": CharSequence), strings*)

now compiles to

        foo(
          scala.runtime.VarArgsBuilder.ofRef[CharSequence](1 + strings.length)
            .add("oof":CharSequence)
            .addArray(strings.$asInstanceOf[Array[CharSequence]]).result()*
        )

@sjrd
Copy link
Member

sjrd commented Sep 19, 2025

Ah yes, that works.

@odersky
Copy link
Contributor Author

odersky commented Sep 26, 2025

@sjrd Do you have more comments, or can we merge this?

Copy link
Member

@lrytz lrytz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

object Test {
def main(args: Array[String]): Unit = {
val arr: Array[String] = Array("foo")
val lst = List("x", arr*) // error
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stale // error comment

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty file added by accident?

Copy link
Member

@sjrd sjrd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No further comments. I haven't thoroughly reviewed all of the implementation, but the compilation scheme looks good to me.

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.

3 participants