Dotty: Cannot have type alias and package with same name

Created on 27 Sep 2020  路  3Comments  路  Source: lampepfl/dotty

Minimized code

// this is an encoding in Scala 2 of a trait/class with a "companion package". 
// A name clash between traits/classes and packages didnt work, but type aliases did.
package A {
  package Foo {}
  trait Foo_ {
    def test = "asd"
  }
}
package object A {
  type Foo = Foo_
}

object Tester extends App {
  println(new A.Foo {}.test)
}

(this doesn't work when pasted directly into say scastie, but it does in a normal .scala file)

Output

We get multiple errors:

  type Foo = Foo_ // Foo is already defined as package A.Foo in package A
  new A.Foo {} // anonymous class {...} cannot extend final package A.Foo
  // A.Foo does not have a constructor

Expectation

I would expect it to keep working.

A few comments about this:

  • I can see why this is a tempting simplification of the language, but it is one of many small things which differentiates dotty from scala 3 so I thought it best to highlight it

    • I know we typically use companion objects for this, but there are a few reasons why a package may be necessary. In my particular case the companion object would extend js.Object and thus cannot have normal scala code inside it, which I also wanted.

      Breaking the object up into a package, renaming the class and using the type alias as a rename mechanism was an easy enough solution to the problem.

bug

Most helpful comment

@sjrd I filed the issue primarily because it's a capability of Scala 2 that I and perhaps others have found a use for.
If it is going away it should be a conscious decision, not lack of awareness.


So for your specific question. Thinking about it again I see conflated two issues.

  • Companion objects extending js.Object is not actually the main driver. When rewriting such an object to a package any inherent reason for it to extend js.Object (such as it describing a function or inheriting from a native type) is moved into a member with a special name, so the case is sort of handled.

  • Disregarding some accidental complexity, the real reason why my code breaks up companion objects into packages is that they sometimes become huge, thousands of lines. Most tooling works better when that is broken up into files, hence "companion packages". See for instance jquery which has a "companion package" with 14kloc.

All 3 comments

In my particular case the companion object would extend js.Object and thus cannot have normal scala code inside it, which I also wanted.

I don't really understand why the companion object would have to extend js.Object. Packages can never extend js.Object, so the natural adaptation would be an object that does not extend js.Object.

@sjrd I filed the issue primarily because it's a capability of Scala 2 that I and perhaps others have found a use for.
If it is going away it should be a conscious decision, not lack of awareness.


So for your specific question. Thinking about it again I see conflated two issues.

  • Companion objects extending js.Object is not actually the main driver. When rewriting such an object to a package any inherent reason for it to extend js.Object (such as it describing a function or inheriting from a native type) is moved into a member with a special name, so the case is sort of handled.

  • Disregarding some accidental complexity, the real reason why my code breaks up companion objects into packages is that they sometimes become huge, thousands of lines. Most tooling works better when that is broken up into files, hence "companion packages". See for instance jquery which has a "companion package" with 14kloc.

I don't think there's anything we can reasonably do about this without upsetting lots of other things.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Blaisorblade picture Blaisorblade  路  3Comments

andreaTP picture andreaTP  路  3Comments

dwijnand picture dwijnand  路  3Comments

liufengyun picture liufengyun  路  3Comments

DarkDimius picture DarkDimius  路  3Comments