Unneeded Synthesized Initializer removes needed initializers with property wrappers
New Issue Checklist
- [x] Updated SwiftLint to the latest version
- [x] I searched for existing GitHub issues
Describe the bug
This new rule correct actually needed initializers. Example:
private struct Data {
@PropertyWrapper<E> var e: E
init(e: E) {
self.e = e
}
}
SwiftLint removes that constructor, but it is required to be able to initialize it with a value of type E instead of @PropertyWrapper<E>
Environment
- SwiftLint version: 0.52.4
To add to this, it also removes initializers that just apply property wrappers to the arguments (it does not seem to trigger the rule in the linting digest?)
struct Title {
let text: String
let color: Color
let font: Font
init(
@Localised text: String, // 👈 some property wrapper that alters the input
color: Color,
font: Font
) {
self.text = text
self.color = color
self.font = font
}
}
weirder still, it will produce a "Superfluous Disable Command Violation" warning if disabled
// swiftlint:disable:next unneeded_synthesized_initializer // 👈 stops the removal but produces a superfluous warning
init(
@Localised text: String,
swiftlint version: 0.55.1
To add to this, it also removes initializers that just apply property wrappers to the arguments (it does not seem to trigger the rule in the linting digest?)
struct Title { let text: String let color: Color let font: Font init( @Localised text: String, // 👈 some property wrapper that alters the input color: Color, font: Font ) { self.text = text self.color = color self.font = font } }
This is addressed by #5594.
weirder still, it will produce a "Superfluous Disable Command Violation" warning if disabled
// swiftlint:disable:next unneeded_synthesized_initializer // 👈 stops the removal but produces a superfluous warning init( @Localised text: String,
I'm unable to reproduce this. The disable command works as expected in my little test setup.
@NachoSoto: Taking a look at your initially reported example, I wonder why e would be initialized as @PropertyWrapper<E> without the explicit initializer. In a little example, the compiler seems to be happy without the initializer. Could you provide a complete example that shows the issue?
@NachoSoto, @aclima93: Are these still issues for you?
... it also removes initializers that just apply property wrappers to the arguments
This is still happening,
struct Title {
let text: String
init(@Localised text: String) {
self.text = text
}
}
gets re-written as
struct Title {
let text: String
}
unless I disable it with unneeded_synthesized_initializer
// swiftlint:disable:next unneeded_synthesized_initializer
init(@Localised text: String) {
weirder still, it will produce a "Superfluous Disable Command Violation" warning if disabled
I can no longer reproduce this part.
installed via homebrew and executed as /opt/homebrew/bin/swiftlint --fix && /opt/homebrew/bin/swiftlint
... it also removes initializers that just apply property wrappers to the arguments
This is still happening,
struct Title { let text: String init(@Localised text: String) { self.text = text } }gets re-written as
struct Title { let text: String }unless I disable it with
unneeded_synthesized_initializer// swiftlint:disable:next unneeded_synthesized_initializer init(@Localised text: String) {
Yeah, this got fixed after the 0.55.1 release only.
@SimplyDanny will your fix also address the scenario when the initializer is marked @usableFromInline and is required in an @inlinable call chain?
@SimplyDanny will your fix also address the scenario when the initializer is marked
@usableFromInlineand is required in an@inlinablecall chain?
Ah - I thought I saw an issue relating to this recently in the periphery codebase
@SimplyDanny will your fix also address the scenario when the initializer is marked
@usableFromInlineand is required in an@inlinablecall chain?
It doesn't. I wonder if initializers with any type of attribute should be excluded.