Skip to content

Wildcard-imported name takes presedence over name in same package #9899

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

Closed
oyvindberg opened this issue Sep 27, 2020 · 3 comments
Closed

Wildcard-imported name takes presedence over name in same package #9899

oyvindberg opened this issue Sep 27, 2020 · 3 comments

Comments

@oyvindberg
Copy link

oyvindberg commented Sep 27, 2020

Minimized code

Given these files

src/main/scala $ find .
./A
./A/internal
./A/internal/NonEmptyPackage.scala
./B
./B/internal.scala
./B/Test.scala
$ cat src/main/scala/A/internal/NonEmptyPackage.scala 
package A.internal
trait NonEmptyPackage
$ cat src/main/scala/B/internal.scala 
package B
class internal 
$ cat src/main/scala/B/Test.scala 
package B
import A._
class Test extends internal 
$ cat build.sbt 
scalaVersion := "0.28.0-bin-20200925-f4528ce-NIGHTLY"
scalacOptions ++= List("-encoding", "utf-8", "-feature", "-language:implicitConversions", "-language:higherKinds", "-language:existentials")

Output

With scala 2.13.3
class Test extends internal resolves to class Test extends B.internal and compiles file.

In dotty it resolves to class Test extends A.internal and fails with:

[error] -- [E093] Syntax Error: src/main/scala/B/Test.scala:5:6 
[error] 5 |class Test extends internal {
[error]   |      ^
[error]   |      class Test cannot extend final package A.internal
[error] -- Error: src/main/scala/B/Test.scala:5:19 
[error] 5 |class Test extends internal {
[error]   |                   ^^^^^^^^
[error]   |                   A.internal does not have a constructor
[error] two errors found

Expectation

Should work like before

@som-snytt
Copy link
Contributor

som-snytt commented Sep 27, 2020

This is working as I would expect, because b.internal is level 4. Move the definition of b.internal into b/Test.scala for the desired behavior.

I don't know offhand why scala 2 is wrong, but I just noticed that package name binding is inherently strange.

package b { object internal } will make scalac agree with dotc that package a.internal is not a value when referenced from b.Test. (That is, the import is correctly higher precedence.)

@odersky
Copy link
Contributor

odersky commented Sep 29, 2020

Indeed, Scala 2 was wrong here.

@odersky odersky closed this as completed Sep 29, 2020
@som-snytt
Copy link
Contributor

som-snytt commented Feb 4, 2021

My previous comment was incorrect.

Package names are term names, even though they have the special property that a type name is not allowed to peacefully coexist.

Selections ppp.mmm from ppp as well as imports from ppp work as for objects. However, unlike other objects, packages may not be used as values. It is illegal to have a package with the same fully qualified name as a module or a class.

The test case is about name space and not precedence, although it appears to be induced by precedence.

Another view:

package p {
  import x._
  package q {
    import y._
    class D extends C
  }
}
package x {
  class C
}
package y {
  //object C    // ok
  package C {   // ambiguous?
    class Dummy
  }
}

Either definition of y.C is ok in Scala 2, but package y.C induces ambiguity in Scala 3.

Verifying what should be obvious but taking nothing for granted, this compiles:

package v {
  class x
  package w {
    package x {
      class C extends x
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants