I'm having a bit of a strange issue with one of my struct initializers.
I have an initializer which assigns every property of the struct, init<EncodeSet>(byte: UInt8, encodeSet: EncodeSet)
. Then I split one branch of it in to a second initializer, init(percentEncoded byte: UInt8)
. However, when I replace that branch in the original initializer with a call to that second initializer, the compiler starts complaining about the other branch, telling me that I'm not allowed to set these properties directly.
public protocol PercentEncodeSet {
func shouldPercentEncode(ascii codePoint: UInt8) -> Bool
}
internal struct _EncodedByte {
internal let byte: UInt8
internal let count: UInt8
internal let isEncodedOrSubstituted: Bool
internal init<EncodeSet>(byte: UInt8, encodeSet: EncodeSet) where EncodeSet: PercentEncodeSet {
if !encodeSet.shouldPercentEncode(ascii: byte) {
self.byte = byte // โ 'let' property 'byte' may not be initialized directly; use "self.init(...)" or "self = ..."
self.count = 1 // โ 'let' property 'count' may not be initialized directly; use "self.init(...)" or "self = ..." instead
self.isEncodedOrSubstituted = false // โ 'let' property 'isEncodedOrSubstituted' may not be initialized directly; use "self.init(...)" or "self = ..."
} else {
// This is the call which creates the problems
self.init(percentEncoded: byte)
// Assigning the values directly works, but why do I need to duplicate this code?
// self.byte = byte
// self.count = 3
// self.isEncodedOrSubstituted = true
}
}
internal init(percentEncoded byte: UInt8) {
self.byte = byte
self.count = 3
self.isEncodedOrSubstituted = true
}
}
This issue has come up before, but in a cross-module context when extending a public struct from a dependency. That doesn't apply in this case - this is an internal struct, which I'm refactoring in a very minor way.
I don't understand why this is happening. Is there a reason for it, or could it be a bug?