Is #file considered a literal String in Swift?
Yes, #file
and #line
are literal expressions but your program is still ill-formed.
The Swift language reference says:
A literal expression consists of either an ordinary literal (such as a string or a number), an array or dictionary literal, a playground literal, or one of the following special literals:
#file
— String — The name of the file in which it appears.
#line
— Int — The line number on which it appears.[...]
Let's also note the grammar:
literal-expression → literal
literal-expression → array-literal | dictionary-literal | playground-literal
literal-expression → #file | #line | #column | #function | #dsohandle
Now let us consider the grammar of the enum you are defining. I am only including the most relevant parts here you can verify the complete deduction yourself:
enum-declaration → attributes opt access-level-modifier opt raw-value-style-enum
[...]
raw-value-style-enum → enum enum-name generic-parameter-clause opt type-inheritance-clause generic-where-clause opt { raw-value-style-enum-members }
[...]
raw-value-assignment → = raw-value-literal
raw-value-literal → numeric-literal | static-string-literal | boolean-literal
It's noteworthy that only numeric-literal, static-string-literal, boolean-literal are allowed. If we look at their definitions, it's clear that those #
literals thus do not match the raw-value-literal
rule:
numeric-literal → -opt integer-literal | -opt floating-point-literal
boolean-literal → true | false
static-string-literal → string-literal-opening-delimiter quoted-text opt string-literal-closing-delimiter
static-string-literal → multiline-string-literal-opening-delimiter multiline-quoted-text opt multiline-string-literal-closing-delimiter
All relevant rules for completely defining static-string-literal are long, but it's still trivial to see that static-string-literal cannot be deduced to #file
and cannot include interpolation. (That's what makes it static.)
So the Swift compiler is indeed right in refusing your program. Still, a modern compiler shouldn't simply crash on an illegal program, so it might be worth reporting this issue.
This is definitely a bug, so worth submitting feedback to Apple (although they documented that those #file, #function, etc. are special literals)
Anyway, probably the following workaround can be helpful in some use-cases:
enum FileNames {
static let main = FileNames.file(#file)
case file(String)
}