Skip to content
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

Can't access protected member of another instance of super class #9890

Closed
scabug opened this issue Aug 15, 2016 · 5 comments
Closed

Can't access protected member of another instance of super class #9890

scabug opened this issue Aug 15, 2016 · 5 comments

Comments

@scabug
Copy link

scabug commented Aug 15, 2016

I have the following layout of code which does not compile but according to the spec for protected should:

trait A {
  protected def callMe(): Unit
}

trait B extends A {
  protected def a: A
  final override protected def callMe(): Unit = a.callMe()
}

The compiler gives me an error

 error: method callMe in trait A cannot be accessed in A
 Access to protected method callMe not permitted because
 prefix type A does not conform to
 trait B where the access take place
         final override protected def callMe(): Unit = a.callMe()
                                                         ^

According to the spec:
The protected modifier applies to class member definitions. Protected members
of a class can be accessed from within
– the template of the defining class,
– all templates that have the defining class as a base class,
– the companion module of any of those classes.

Especially the second point should apply here but the compiler seems to treat callMe as protected[this]

@scabug
Copy link
Author

scabug commented Aug 15, 2016

Imported From: https://issues.scala-lang.org/browse/SI-9890?orig=1
Reporter: Jonathan Schuchart (j.schuchart)
Affected Versions: 2.11.8

@scabug
Copy link
Author

scabug commented Aug 15, 2016

@som-snytt said:
The second section of bullets says you can select r.x only if "r's type conforms to a type-instance of the class which contains the access." So the member should be of type B. Otherwise, you could access members of other implementations of A with arbitrary behaviors for the template method.

By contrast,

object X {
  trait A { protected[X] def callMe(): Unit }
  trait B extends A { protected def a: A ; final override protected[X] def callMe(): Unit = a.callMe() }
}

@scabug
Copy link
Author

scabug commented Aug 15, 2016

Jonathan Schuchart (j.schuchart) said:
I am not sure what the exact meaning of "r's type conforms to a type-instance of the class which contains the access" is then. Maybe you can point me to a site that has it explained in more detail?
As I understand it, in my example B is a subtype of A and should therefore conform to being of type A which should give B access to protected members of other instances of A.
Since both of the following access patterns work

trait A {
  protected def callMe(): Unit
  def runOther(a: A): Unit = a.callMe()
}
trait SubA extends A {
  callMe()
}

Why would the combination of the two as outlined above not work as well? Where is the difference to protected[this] then?

@scabug
Copy link
Author

scabug commented Aug 15, 2016

@som-snytt said:
You have def a: A, and you attempt a.callMe. A does not conform to B, where you attempt the access. You can try StackOverflow or the gitter channel for better clarifications. Protected access is kind of a stickler, especially because of mix-in traits. You might want to ask about your use case on gitter.

@scabug
Copy link
Author

scabug commented Aug 16, 2016

Jonathan Schuchart (j.schuchart) said:
Ok. It makes sense now. Sorry for the false report. Thanks

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

2 participants