scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.88k stars 1.06k forks source link

Inline accessor for objects is in the wrong place #13215

Open nicolasstucki opened 3 years ago

nicolasstucki commented 3 years ago

Compiler version

3.0.1

Minimized code

package foo {
  trait Bar:
    inline def baz = Baz

  private[foo] object Baz
}

Output

After typer we generate the following inline accessor for a module

package foo {
  trait Bar:
    inline def baz = this.foo$Bar$$inline$Baz
    def foo$Bar$$inline$Baz = foo.Baz

  private[foo] object Baz
}

There are several issues with this scheme

Expectation

package foo {
  trait Bar:
    inline def baz = foo.inline$Baz

  def inline$Baz = foo.Baz
  private[foo] object Baz
}
nicolasstucki commented 3 years ago

It seems we fall back to the class a location for inline accessors when they should be in a package. https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/AccessProxies.scala#L137

We could create an object Inline$Accessors in that package to place them.

odersky commented 3 years ago

That looks like a pretty tall order. I don't think I have the time to do that. Somebody else will have to pick that up.

smarter commented 3 years ago

Is this fixable without causing existing code to break its ABI on recompilation? If not I don't think this can be done in Scala 3.

smarter commented 3 years ago

Or I guess we could keep the existing accessors to preserve the ABI and just add new ones?

odersky commented 3 years ago

We could do that. It's still a tall order. Inline accessors are a complex piece of code. How urgent is this? Is this a feature request or a real bug? Alternatively, we could also require that the body of quotes can only access public members. I think I would prefer that. It seems weird to expose something that is private as data.

nicolasstucki commented 3 years ago

Test case (should compile)

import scala.quoted.*

package foo {
  trait Bar:
    def bar(using Quotes) = '{ Baz }

  private[foo] object Baz
}