'Scala 3 Explicit Nulls flag makes String operations quite unusable

When using the new Scala 3's flag -Yexplicit-nulls, every Java code which doesn't have explicit non-null annotations is treated as nullable, thus every Java method not returning a primitive type T effectively returns T | Null.

Problem: In Scala, String is just an alias for java.lang.String. And because core Java doesn't contain any annotations about the nullability, Scala 3 treats the return types of String methods as nullable.

Example: (tried via both Scala REPL / sbt console, and with Gradle)

scala> val bla: String = null // check whether the compiler option is turned on
-- Error:
1 |val bla: String = null
  |                  ^^^^
  |                  Found:    Null
  |                  Required: String
scala> val bla: String = "hey"
val bla: String = hey
scala> bla.split("e")
val res0: Array[String | Null] | Null = Array(h, y)

The return type Array[String | Null] | Null is completely insane. The contract of the split method is obviously given as it always returns an array and that array always contains at least one string (and none of the strings is null).

Is this really the sad reality, or am I doing something wrong?

To make the above work, I would always have to write:

"hey".split("e").nn.map(_.nn) // this would finally give me just Array[String]


Solution 1:[1]

I have found a bug report talking about practically the same thing I was originally asking here. It seems the Dotty/Scala3 team considers this as "not a bug".

There was a suggestion to use unsafeNulls flag. Which is more of a "let's disable the feature we've just enabled".

Solution 2:[2]

Here is an experiment language feature, unsafeJavaReturn, which assumes Java methods don't return nullable values in explicit nulls

https://github.com/lampepfl/dotty/pull/15096

This is less aggressive than unsafeNulls, since it only affects Java interop in a certain scope.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ota Hauptmann
Solution 2 yzhao