I defined a struct with a type property. I also defined a child type of that type and accidentally referred to the parent's type property as if it were an instance property of the child type. Unexpectedly this did not produce an error.
Is this correct behaviour?
I see that this post from @Slava_Pestov may explain it, but I have to admit that I don't quite understand it fully.
import Foundation
struct Struct1 {
static let staticLetProperty = "Hello, I am a static let property on the Struct1 Type"
let instanceProperty = "I am an instance property of an instance of Struct1"
class ChildClass {
func doThing() {
print(staticLetProperty)
}
}
}
let test1 = Struct1()
// This works as expected
print(test1.instanceProperty)
// This doesn't work, as expected
// Error: Static member 'staticLetProperty' cannot be used on instance of type 'Struct1'
print(test1.staticLetProperty)
let test2 = Struct1.ChildClass()
// Prints "Hello, I am a static let property on the Struct1 Type" - Is this correct?
test2.doThing()
It's applicable to all enclosing types, not just the direct one:
Here's an example of using self in a type context. You currently have the idea that this is "as if it were an instance property", but that's not the case. self just means something different here, than it does in an instance member. And nobody ever uses it explicitly.
Struct1 static members will trickle down to ChildClass, but only in the definition. If you use extensions, you'll need to qualify where the static member is coming from. I consider the inconsistency a bug but there may be reasons it has to work that way.
I don’t think there’s any real reason it has to work that way, but it’s explainable as follows: unqualified (bare identifier) lookup visits each outer lexical context in turn and performs a qualified (member) lookup into each context. It doesn’t walk the “logical” parent contexts of an extension of a nested type, so it won’t do a qualified lookup into Struct1 at all. But it could (C++ basically implements the rule you’re thinking of, except instead of extensions they have whatever their term is for member declarations outside of a class)