Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is #file considered a literal String in Swift?

Bug > Swift > Enum > String Protocol


I was attempting to create an enumeration in which all its elements were file names, and I stumbled across something interesting. Like so:

enum FileNames: String {
     case main = #file
}

This resulted in an internal error. (Segmentation Fault: 11)


I was able to figure how to get an actual error message:

enum Foo: String {
    case one = "\(1)"
}

Error: Raw value for enum case must be a literal


Related Questions:
• Is #file considered a String literal?
• Why does #file break the enum? Should this be reported on bugs.swift.org?
• I noticed that replacing String to Int and #file to #line causes the same issue. Is this a hint?


Color Literals Don't Work

I thought they did, but I made a mistake. It also causes the same internal error.

import UIKit

enum ColorEnum: UIColor {
    case foo = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0)
}

The Swift Programming Language (Swift 5.2)

According to Apple, #file is considered a literal:

#file is described as a literal according to Apple


What about nil Literals?

These also crash the compiler.

enum Foo: String? {
    case breaks = nil
}

23 Characters of Mass Destruction enum I:Int?{case a=nil}


Bug Fixed

The crash has now been fixed, it has been merged officially into Swift here: Merged on GitHub Here's the bug report: SR-12998. It has officially been implemented in Swift 5.4

Adding Support!
The use of magic literals as raw values for enum cases is being supported here: SR-13022

like image 280
0-1 Avatar asked May 08 '20 16:05

0-1


People also ask

What type of word is is?

Is is what is known as a state of being verb. State of being verbs do not express any specific activity or action but instead describe existence. The most common state of being verb is to be, along with its conjugations (is, am, are, was, were, being, been).

Is in use a word?

Definition of in use : being used All of the computers are currently in use.

Is the word the is a word?

In the English language the word the is classified as an article, which is a word used to define a noun. (More on that a little later.) But an article isn't one of the eight parts of speech. Articles are considered a type of adjective, so "the" is technically an adjective as well.

What is the etymology of the word is?

Etymology 1 From Middle English is, from Old English is, from Proto-West Germanic *ist, from Proto-Germanic *isti (a form of Proto-Germanic *wesaną (“to be”)), from Proto-Indo-European *h₁ésti (“is”).


1 Answers

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.

like image 125
idmean Avatar answered Nov 10 '22 06:11

idmean