Description
Previous ID | SR-584 |
Radar | None |
Original Reporter | @marcomasser |
Type | Bug |
Additional Detail from JIRA
Votes | 3 |
Component/s | Compiler |
Labels | Bug |
Assignee | None |
Priority | Medium |
md5: 251836798d8c1e10c3054964af248ffc
is duplicated by:
- SR-923 override a property of a NSObject subclass generates inconsistent behavior
Issue Description:
There’s a case where a property (or function) override in a subclass’ extension leads to unexpected behavior:
class Base: NSObject {
var directProperty: String { return "This is Base" }
var indirectProperty: String { return directProperty }
}
class Sub: Base { }
extension Sub {
override var directProperty: String { return "This is Sub" }
}
Accessing directProperty
works as expected:
Base().directProperty // “This is Base”
Sub().directProperty // “This is Sub”
Accessing “indirectProperty”, shows the unexpected behavior:
Base().indirectProperty // “This is Base”
Sub().indirectProperty // “This is Base” <- Unexpected!
Adding the dynamic
keyword to Base.directProperty
resolves the issue, so it seems like the implementation of indirectProperty
always accesses directProperty
of the Base class directly instead of dispatching dynamically.
I think this is a bug, either because this doesn’t work as expected at runtime, or because it compiles at all. Because the Language Guide for Swift 2.1, chapter “Extensions” states in a note near the beginning:
“Extensions can add new functionality to a type, but they cannot override existing functionality.”
That sounds to me like the override
keyword must not appear in an extension. Curiously enough, the above code compiles and some parts of it even run without issues despite violating the Language Guide. If Base
does not inherit from NSObject
but becomes a root class instead, the compiler produces the following error in the extension:
Declarations in extensions cannot override yet
Note the “yet”. Seems like this is just not done yet. Also, I don’t understand how this feature could work except if overriding properties and methods in a subclass’ extension will only be supported if the original property or method was declared as dynamic. Otherwise the compiler could inline their implementation and the extension’s implementation would never be called – assuming the extension isn’t known at compile time, as could be the case for extensions to classes of system frameworks. Everything’s probably fine with Whole Module Optimization if the module contains all the classes and extensions.
Anyways, if this will be supported for non-Objective-C classes in the future, the above bug could point to something that doesn’t work correctly.
Also note that this could be related to (but not the same as) a bug reported already where methods implemented in a protocol extension cannot be overridden by a conforming class’ subclass:
https://bugs.swift.org/browse/SR-103
I posted this to the Swift Users mailing list but got no response:
https://lists.swift.org/pipermail/swift-users/Week-of-Mon-20151228/000670.html