You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Entire code snippet may look like this:
( fails with Error:(13, 19) illegal inheritance; self-type crafts.Main7.Foo does not conform to Main7.this.Foo's selftype crafts.Main7.Foo with crafts.Main7.F0 )
The text was updated successfully, but these errors were encountered:
ibaklan
changed the title
problem with anonymous class while using self-type
problem with anonymous class while using self-type + structural type
Aug 13, 2018
Does this count as a duplicate of #9487? That's the root cause, but I think this issue shows how serious it is. I've noticed that the "detect anonymous classes and make their innards private" bit in typedBlock, the thing that's causing this, is royally broken. This specific issue can be fixed by making the hack more hacky, but I don't think that's a good idea, because it appears to be broken in other ways.
For one, the pattern match to find anonymous-class-new-blocks is very weak. It catches actual anonymous classes, like new { def hello = "Hello" }, but it also catches (and breaks)
classSomething(valx: { defhello:String })
locally[Something] {
classAmIAnon { defhello="Hello" }
newSomething(newAmIAnon)
// type mismatch: AmIAnon does not conform to { def hello: String }// are you sure about that, scalac?// block looks like { class <_>; new <_> }, so scalac starts ruining things// locally says it wants Something, so scalac lists its members// then it privatizes stuff that doesn't match in AmIAnon// scalac has confused *two entirely different classes*
}
I'm not very good at reading the spec, but I think the following counts, too. The relevant parts are 6.10 and the following 6.11. Start with
defidentityIsh(t: AnyRef): t.type= t
and try to find the type of
identityIsh(new { defhello="Hello" })
The new-expression can expand, producing
identityIsh { classanonextendsAnyRef { defhello="Hello" }; new anon }
The expected type of the block, and thus the simple-new, is AnyRef. However, new doesn't care about expected types, so its type is anon anyway. Once the type of the block's expression is known, the block's type can also be found without caring about the expected type. That is, the block above should have the same type as a new { def hello = "Hello" } standing by itself, and that type is AnyRef { def hello: String }. However, the privatizing is too strong, and it hides the hello away, making the block have type AnyRef. This is bad, because although identityIsh only wants an AnyRef, which seems to imply that it doesn't matter, the refinement type lets the difference shine through. I believe the spec says the type of the whole should be AnyRef { def hello: String }, but we get just AnyRef.
I agree with #9487 (comment) that making things private by editing the anonymous class itself is too much. It would make more sense and (hopefully) be less broken to calculate the structural types of blocks correctly in the first place, even if it is hard.
Problem occurred when I'm trying to instantiate following class (with self-type construct) by the means of anonymous class (
new Foo {...}
)Entire code snippet may look like this:
( fails with Error:(13, 19) illegal inheritance; self-type crafts.Main7.Foo does not conform to Main7.this.Foo's selftype crafts.Main7.Foo with crafts.Main7.F0 )
While alternative snippets with 'object foo{...}' or explicite subclassing works correctly
The text was updated successfully, but these errors were encountered: