JetForMe
(Rick M)
1
I just ran into the limitation “Raw value for enum case must be a literal” when my expression was made up of literals. I'm wondering why Swift can't support simple expression evaluation at compile time. I was trying to write this:
enum
IOC : UInt32
{
case void = 0x20000000
case out = 0x40000000
case `in` = 0x80000000
case `inout` = 0x40000000 | 0x80000000
case dirMask = 0xe0000000
}
or even have inout be like this:
case `inout` = IOC.out.rawValue | IOC.in.rawValue
To my untrained eye, there’s no reason the compiler shouldn’t support this, is there? Ideally, any expression it can evaluate at compile time to a suitable value should be allowed.
2 Likes
The or operator is implemented as a normal function, and as there isn't a Swift equivalent of constexpr it can't call that function at compile time.
7 Likes
tera
3
Shouldn't that be represented as an option set?
struct IOC: OptionSet {
let rawValue: UInt32
static let void = Self(rawValue: 1 << 29)
static let output = Self(rawValue: 1 << 30)
static let input = Self(rawValue: 1 << 31)
static let inout1 = Self(rawValue: (1 << 30) | (1 << 31))
static let inout2 = Self(rawValue: input.rawValue | output.rawValue)
}
You won't have enum behaviour (like switching exhaustively, etc) but it doesn't look you are going to have it anyway using IOC in the enum form in your particular example.
4 Likes
JetForMe
(Rick M)
4
Sure, it could be I suppose. But it feels like quite the limitation that this stuff can't be figure out at compile time.
tera
5
I guess it boils down to << being in standard library and Swift, oblivious to what << is doing` must assume "the worst" and doesn't want to open itself for any of the following at the compile time:
public func << (lhs: Self, rhs: Self) -> Self {
// do whatever here including but not limited to:
// - crash or trap
// - infinite loop
// - do unbound time or space operation
// - use disk or network
// - and so on and so forth
}
1 Like