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
[SR-3492] Unexpected inheritance of nested types #46080
Comments
There isn't some notion of "absolute uniqueness" (as though "B.X.Y" were some kind of canonical index into the type) in local scope. When doing a lookup there in the first non-functioning example we gather every possibility. Because `. Reusable` exists as a member in the superclass and in the subclass, and it is not marked private, it is still accessible from `B` so we find it. When Sema sees two valid overloads, it checks both and finds that both references are valid and require no conversions to instantiate the type variable left by the underbar pattern, hence the two solution sets are indistinguishable enough to warrant a diagnostic about ambiguity. In global scope we consider the stricter access you seem to want in the inner scope. |
If something like |
That's…not how I'd expect it to behave, I think @jckarter agree on that (https://twitter.com/jckarter/status/810896048843583488) class A {
struct S1 {
func desc() {
print("S1")
}
}
}
class B: A {
struct S1 {
func desc() {
print("S2")
}
}
}
A.S1().desc() // ok
B.S1().desc() // ambiguous use of 'init()' |
Given there is qualification here we could change lookup to check if it already has a possible qualified overload and reject the overload that requires substituting `B`. @slavapestov Do you foresee any problems with that? |
There is code out there that relies on this working:
As for the case where we have two nested types, I think the best fix is to tighten up the shadowing and override checks in name lookup. If both a base class A and a derived class B define the same member type 'foo', a lookup of 'foo' into 'B' should not find 'A.foo'. For non-type members this is handled by virtue of the fact that they must either be declared 'override', or become invalid. For nested type members, we can extend the override and shadowing filter to handle nested types by dropping the base class's type. |
I agree with Slava's analysis. Nested types are intended to be visible on subclasses, but they should also be shadowable. |
I'll take a look at this soon. I've wanted to investigate the shadowing logic for a while since I suspect it's a big mess |
Hey @slavapestov Does that "taking a look at this soon" finally happen since your last comment ? Would be interested in the follow-up, since we might encounter that exact case on our end too |
Comment by Jason Bobier (JIRA) I just ran into this as well with: class MyClass {
enum Error: Swift.Error {
case someError
}
}
class SubClass: MyClass {
enum Error: Swift.Error {
case anotherError
}
}
let error: Swift.Error = SubClass.Error.anotherError
let otherError = error as? SubClass.Error and yet this works: let error: Swift.Error = MyClass.Error.someError
let otherError = error as? MyClass.Error |
Environment
Swift 3.0.2
Additional Detail from JIRA
md5: 4512528e0c89827aea622ea49002f198
is duplicated by:
Issue Description:
The nested enum type inherits it's options, while it shouldn't inherit anything.
This code should compile without errors:
https://gist.github.com/krzyzanowskim/d02732571b45902154dcf3939a735eb7
this code souldn't compile
The text was updated successfully, but these errors were encountered: