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-14761] Poor diagnostic on implicitly overriden init() #57111
Comments
@swift-ci create |
Ah, true. This diagnostic needs a special case for when the compiler synthesizes overrides of designated initializers. Makes for a good starter bug, though. |
Comment by Jevon Mao (JIRA) theindigamer (JIRA User) I'm still learning Swift, and if you don't mind can you explain a bit? Is there some sort of implicit default initializer in class C? Why is overriding not allowed in the extension? |
jevonmao (JIRA User), NSObject has an initializer which takes no arguments. https://developer.apple.com/documentation/objectivec/nsobject/1418641-init IIUC this is a designated initializer, if you look at the docs there you'll see this
which matches how designated initializers work. Designated initializers are supposed to be defined within the class declaration (there is an exception for What is happening here IIUC is that since there are no stored properties (you can try adding stored properties and you'll see an error about no initializers), the parent class's Extensions can be anywhere, including in downstream modules. Allowing overriding in extensions would mean that certain calls would be forced to use dynamic dispatch, since which functions will be called are not known at compile-time. This inhibits performing optimizations at compile-time, and creates runtime overhead due to lookup tables which need to patched (either at load time or lazily during the first run). (There are also more issues with "dirty memory" but let's not go into the weeds...) I'm not exactly sure which of these reasons was used originally, I suspect it's some combination, but if I were to guess, I would guess that having more compile-time optimizations for known calls is the most important reason. What needs to happen to fix this bug, I think, is that when we issue an error related to "has already been overridden", we should do some kind of check whether the declaration that will be pointed to is actually present in the source code. If it was implicitly synthesized, then the note's wording should be changed to make it clear that it talking about an implicitly synthesized declaration. |
Comment by Hanna Yakusevych (JIRA) Is anyone working on this already? If not, I'd like to give it a shot |
I don't think so, no. Please feel free to assign it to yourself and ask questions in case you need help with something. 🙂 |
Comment by Jevon Mao (JIRA) theindigamer (JIRA User) Thanks for the previous explanation, that made sense. I was experimenting with the sample error code above, and for some reason, I could not reproduce the same diagnostic in Xcode 12.5 Playground. Instead, it shows this: import Foundation
class C: NSObject {}
extension C {
public override convenience init() {}
// ^ 'init()' has already been overridden
} I tried again in godbolt, and it gives another different diagnostic: import Foundation
class C: NSObject {}
extension C {
public override convenience init() {}
// ^ error: overriding declarations in extensions is not supported
} I'm trying to learn this compiler stuff, am I misunderstanding anything? Can you explain? |
I think the difference may be coming about because Godbolt is likely running on Linux, not macOS. So the |
Fixed by #38365 Thank you, hanyakus (JIRA User)! |
Environment
Xcode 13 beta
Additional Detail from JIRA
md5: 18501160a0fd0ecc00b62a8c26b1593a
Issue Description:
Pointing to the opening brace is not very helpful IMO to explain what is going on since there is no user-written override there.
The text was updated successfully, but these errors were encountered: