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)
}