Skip to content

Template param with access modifier is over-specified or under-implemented #14735

Open
@som-snytt

Description

@som-snytt

Compiler version

3.1.1

Minimized code

package p

class C(private[p] c: Int)

object X:
  trait T(private[X] i: Int)
  class C(n: Int) extends T(n)
  def x = C(42).i

@main def test() = println {
  C(42).c
}

Output

-- [E008] Not Found Error: param-access.scala:9:16 ---------------------------------------------------------------------
9 |  def x = C(42).i
  |          ^^^^^^^
  |          value i is not a member of p.X.C
-- Error: param-access.scala:12:8 --------------------------------------------------------------------------------------
12 |  C(42).c
   |  ^^^^^^^
   |  value c cannot be accessed as a member of p.C from module class param-access$package$.
Compilation output
[[syntax trees at end of                     typer]] // param-access.scala
package p {
  class C(private[p] c: Int) extends Object() {
    private[this] private[this] val c: Int
  }
  final lazy module val X: p.X = new p.X()
  final module class X() extends Object() { this: p.X.type =>
    trait T(private[X] i: Int) extends Object {
      private[this] private[this] val i: Int
    }
    class C(n: Int) extends Object(), p.X.T(C.this.n) {
      private[this] val n: Int
    }
    def x: <error value i is not a member of p.X.C> = new p.X.C(42).i
  }
  final lazy module val param-access$package: p.param-access$package = new p.param-access$package()
  final module class param-access$package() extends Object() { this: p.param-access$package.type =>
    @main def test(): Unit =
      println(
        {
          new p.C(42).c
        }
      )
  }
}

Expectation

Probably no one is confused by scala/bug#12562 unless they read the spec, which says that when there is an access modifier on a class (or trait) param, val is assumed.

That specified behavior makes sense because "whether there is a member field" for "private" is inferred.

Actually I also expected "assumed val" for param access equivalent to private or private[C].

scala> class C(c: Int) { def ok(other: C) = other.c == c }
-- Error: --------------------------------------------------------------------------------------------------------------
1 |class C(c: Int) { def ok(other: C) = other.c == c }
  |                                     ^^^^^^^
  |                                     value c cannot be accessed as a member of (other : C) from class C.
1 error found

Probably during the long pandemic, in my imagination, private[this] inference took on additional powers.

For clarification, I would expect either the spec behavior or just reject the meaningless modifier, if it is meaningless.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:typerbacklogNo work planned on this by the core team for the time being.itype:bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions