Description
reproduced from https://forums.swift.org/t/value-semantics-of-init-with-defaulted-private-let-fields-does-not-make-sense/86193
one popular way to manually insert padding into a Swift struct is by doing the following
struct S {
let x: Int
private let padding: Int = 0
init(x: Int) {
self.x = x
}
}
now it’s not quite right - the struct isn’t @frozen and so the layout isn’t correctly specified, so this code doesn’t formally do what the library author probably thinks it does. nevertheless, it’s a very popular pattern, it is used, for example, by Google flatc.
if you’re handed an API like this, you run into some really inconsistent compiler policies surrounding definite initialization. you can’t, for example, do this:
extension S {
init() {
self = .init(x: 0)
// Immutable value 'self.padding' may only be initialized once
// Initial value already provided in 'let' declaration
// Change 'let' to 'var' to make it mutable
}
}
this is a rather useless guardrail, because self = new is something that should always be semantically valid for value types, regardless of field mutability, and it’s trivial (but awkward) to circumvent the restriction:
protocol P {
static func create(x: Int) -> Self
}
extension P {
init() {
self = .create(x: 0)
}
}
extension S: P {
static func create(x: Int) -> Self {
.init(x: 0)
}
}
let s: S = .init()
Reproduction
see above
Expected behavior
self = .init(x: 0) should compile
Environment
swift --version
Swift version 6.3.1 (swift-6.3.1-RELEASE)
Target: x86_64-unknown-linux-gnu
Additional information
No response
Description
reproduced from https://forums.swift.org/t/value-semantics-of-init-with-defaulted-private-let-fields-does-not-make-sense/86193
one popular way to manually insert padding into a Swift struct is by doing the following
now it’s not quite right - the struct isn’t
@frozenand so the layout isn’t correctly specified, so this code doesn’t formally do what the library author probably thinks it does. nevertheless, it’s a very popular pattern, it is used, for example, by Google flatc.if you’re handed an API like this, you run into some really inconsistent compiler policies surrounding definite initialization. you can’t, for example, do this:
this is a rather useless guardrail, because
self = newis something that should always be semantically valid for value types, regardless of field mutability, and it’s trivial (but awkward) to circumvent the restriction:Reproduction
see above
Expected behavior
self = .init(x: 0)should compileEnvironment
Additional information
No response