Skip to content

Conversation

@kiendang
Copy link
Contributor

@kiendang kiendang commented Mar 5, 2025

On Scala 3

os.write.outputStream(os.pwd / "text", perms = os.PermSet(420))

java.lang.ClassCastException: class [Ljava.nio.file.attribute.FileAttribute; cannot be cast to class scala.collection.immutable.Seq ([Ljava.nio.file.attribute.FileAttribute; is in module java.base of loader 'bootstrap'; scala.collection.immutable.Seq is in unnamed module of loader java.net.URLClassLoader @4520ebad)
  os.write$.outputStream(ReadWriteOps.scala:35)
  ammonite.$sess.cmd0$.<clinit>(cmd0.sc:1)

@kiendang kiendang force-pushed the outputStream-perms-scala3 branch from e4e1c95 to cacdf03 Compare March 5, 2025 07:55
@lihaoyi
Copy link
Member

lihaoyi commented Mar 5, 2025

Looks reasonable, but do you know why it only fails on Scala 3? I would expect it behave the same on all versions of Scala

Comment on lines -33 to -34
val permArray =
if (perms == null) Array[FileAttribute[PosixFilePermission]]()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@lihaoyi It's because the type here is wrong. It should be Array[FileAttribute[java.util.Set[PosixFilePermission]]] instead. I don't know how this compiles or why it runs on Scala 2 though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know the details, but looks like Scala 3 handles varargs differently https://docs.scala-lang.org/scala3/reference/changed-features/vararg-splices.html

@kiendang
Copy link
Contributor Author

kiendang commented Mar 5, 2025

Also looks like on Scala 2.13 using : _* with Array is a bit inefficient

val arr = Array(0, 1, 2, 3)
val lst = List(arr: _*)

Passing an explicit array value to a Scala varargs method is deprecated (since 2.13.0) and will result in a defensive copy; Use the more efficient non-copying ArraySeq.unsafeWrapArray or an explicit toIndexedSeq call
val lst = List(arr: _*)

Looks Scala 3 doesn't have the problem, but have to use the new syntax unavailable in Scala 2

val arr = Array(0, 1, 2, 3)
val lst = List(arr*) 

For Scala 2, these would not lead to copying

val arr = Seq(0, 1, 2, 3)
val lst = List(arr: _*)
import scala.collection.immutable.ArraySeq.unsafeWrapArray

val arr = Array(0, 1, 2, 3)
val lst = List(unsafeWrapArray(arr): _*)

@lihaoyi lihaoyi merged commit 1e2bbe6 into com-lihaoyi:main Mar 7, 2025
14 of 16 checks passed
@lihaoyi
Copy link
Member

lihaoyi commented Mar 7, 2025

Thanks @kiendang !

@kiendang kiendang deleted the outputStream-perms-scala3 branch March 7, 2025 01:52
@lefou lefou added this to the 0.11.5 milestone Mar 8, 2025
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