-
Notifications
You must be signed in to change notification settings - Fork 21
Illegal inheritance with inner class inheritance #8830
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
Comments
Imported From: https://issues.scala-lang.org/browse/SI-8830?orig=1 |
@retronym said (edited on Sep 1, 2014 3:08:16 AM UTC): class Box[A](var value: A)
class A { class Foo extends Box[A.this.type](A.this) }
class B extends A { class Bar extends Foo }
object Test extends App {
val b: B = new B
val a: A = new A // you wrote `b` here, but I changed to `new A` so as to demonstrate the unsoundness that this restriction prevents.
val mix: b.Bar with a.Foo = new b.Bar().asInstanceOf[b.Bar with a.Foo] // new b.Bar with a.Foo {}
(mix: b.Bar).value = b
val a1: a.type = (mix: a.Foo).value
assert(a1 == a) // fails
} |
@cvogt said: Ok, then back to the original question that got me here: If I have a specific b, how can I access it's A-parent's Foo class, in case it is shadowed by it's B-parent's Foo class like in my original example? |
@retronym said: trait A{ trait Foo; type FooA = Foo }
trait B extends A{ trait Foo extends super.Foo } Generally I would recommend against defining an inner classes with the same name as one in a parent. Use type aliases instead, in the style of scala-reflect. Following that discipline avoids unsoundness traps like #6161. |
@retronym said: In your original code: trait A{ trait Foo }
trait B extends A{ trait Foo extends super.Foo }
val b: B = new B{}
val a: A = b
new b.Foo with a.Foo Why didn't you just write: new b.Foo given that |
@cvogt said (edited on Sep 2, 2014 12:37:44 AM UTC): |
@retronym said: trait A{ trait Foo }
trait B extends A {
trait Foo extends super.Foo { def xxx = 0 }
}
// extension
trait C extends B with A {
type AFoo = super[A].Foo
}
object Test extends App {
val c = new C {}
val afoo = new c.AFoo {}
afoo.xxx // does not compile
} |
@cvogt said: |
This problem can be a blocker when working with inner class inheritance hierarchies.
Reproduce code
Expected result
compiles fine
Actual result
Note that this happens even if the inner child class does not have the same name as the inner parent, but this fact forces having to upcast to B in order to access the inner parent.
In Slick it prevents an external user to us RelationalProfile's SimpleQL class with JdbcProfile's Implicits class.
The text was updated successfully, but these errors were encountered: