Why the Swift compiler allow literal expression that result in runtime crash, related: why are some literal expressions are not allowed?

let range = 10...1
print(range)   // what does this print?
let foo = 1 << 9

print(foo)    // what does this print?
enum Foo: Int {
  case bar  = 1 << 9

print(Foo.bar)    // what does this print?

Nothing, because it doesn't compile, the case needs to be a compile time constant:

1 Like

I know. I'm asking why can't it be a compile time check for all these cases? Like dictionary literal duplicate key compile time check introduced recently to Swift?

And why this:

1 << 9

sometime compile time error, sometime not?

Ah, I misunderstood the question then, I don't know unfortunately, if I had to guess I'd say it's because parsing operators would've been a pain, though I'd really like to see what you mentioned implemented

The case you mentioned to be a compile time error was an enum case with a rawValue,
however, in one of the other examples you showed that doesn't error out:

This doesn't error out because 1 << 9 is evaluated at runtime, not compile time, due to foo not needing to be known at compile time

But Swift does compile 1<<9. It’s just that the result is sometime compile time error like in enum/case definition. But other time, it compile and run. Though I don’t know when the final value is calculated I would guess is runtime.

Yeah, I know. Some complain why this literally constant fully know at compile time expression is not fully evaluated at compile time and people are resorting to manually doing code gen.

Swift is not C: it does no lexical preprocessing. Although the recent Expression Macro proposal looks to change this and modernizes macro.

Indeed it compiles, however it doesn't parse the operators to calculate the final value at compile time, as it stands right now, for anything needing to be known at compile time, Swift requires the value to be a literal, ie with _const let:

And will Expression Macro improve this so this is a compile time evaluation?

Depends on the implementation, if it ends up being like C macros where it's just literal copy and paste done by a preprocessor then the answer is no, because what you'd see is just case someCase = MACRO_STATEMENT, but if MACRO_STATEMENT is 1 << 9, then the only thing that the compiler would see is case someCase = 1 << 9, though I'm not familiar with how expression macros would(are going to?) be implemented