This is not new news, but nested package syntax interacts with “packages from the class path”.
Concretely, this example compiles, but not if the package clause is scala.p
(or if scala is deleted).
package scala
package p
import jdk.OptionConverters._
import java.util.Optional
class Q {
def f = Optional.ofNullable("hello, world").toScala
}
That is because jdk
is now a top-level package in the JDK.
The expectation is that jdk
means scala.jdk
always, because scala
is a “root import”.
I proposed a fix a few years ago; I remember I justified my expectation, but it went unmerged.
There was a topic on the users
forum about package clauses, and I just saw again Paul’s old commit.
To quote the paulpism:
Confusing, now-it-happens now-it-doesn't mysteries lurk in the darkness.
Now I’m wondering if another hyphen is required, or maybe a comma.
His example:
Then paths relative to scala can easily be broken via the unlucky
presence of an empty (or nonempty) directory. Example:
// a.scala
package scala.foo
class Bar { new util.Random }
% scalac ./a.scala
% mkdir util
% scalac ./a.scala
./a.scala:4: error: type Random is not a member of package util
new util.Random
^
one error found
I remember my unmerged fix corrected lookup in “root” imports.
Because I like -Yimports
at least in theory, it seems to me more likely that user expectations about “lookups in root imports” will be disappointed.
A reference q.Q
to foo.q.Q
with -Yimports:java.lang,scala,scala.Predef,foo
is unresolved if there is a directory q
on the class path (e.g., locally ./q
).
Possibly, the justification was that root imports are logically like package clauses in the current compilation unit, and anything on the class path is not from the current compilation unit.