When and how to use @noreturn attribute in Swift?

I read the code block enclosed in curly braces after the keyword else in the context of a guard-else flow, must call a function marked with the noreturn attribute or transfer control using return, break, continue or throw.

The last part is quite clear, while I don’t understand well the first.

  • How to prevent circular reference when Swift bridging header imports a file that imports Hopscotch-Swift.h itself
  • Setting Custom HTTP Headers in Alamofire in iOS 7 not working
  • Unexpected non-void return value in void function
  • Remove subviews from ScrollView Swift
  • Overriding properties in swift
  • No such Module Error
  • First of all, any function returns something (an empty tuple at least) even if you don’t declare any return type. Secondly, when can we use a noreturn function? Are the docs suggesting some core, built-in methods are marked with noreturn?

    The else clause of a guard statement is required, and must either call
    a function marked with the noreturn attribute or transfer program
    control outside the guard statement’s enclosing scope using one of the
    following statements:

    return
    
    break
    
    continue
    
    throw
    

    Here is the source.

    2 Solutions Collect From Internet About “When and how to use @noreturn attribute in Swift?”

    First of all, any function returns something (an empty tuple at least) even if you don’t declare any return type.

    (@noreturn is obsolete; see Swift 3 Update below.)
    No, there are functions which terminate the process immediately
    and do not return to the caller. These are marked in Swift
    with @noreturn, such as

    @noreturn public func fatalError(@autoclosure message: () -> String = default, file: StaticString = #file, line: UInt = #line)
    @noreturn public func preconditionFailure(@autoclosure message: () -> String = default, file: StaticString = #file, line: UInt = #line)
    @noreturn public func abort()
    @noreturn public func exit(_: Int32)
    

    and there may be more.

    (Remark: Similar annotations exist in other programming languages
    or compilers, such as [[noreturn]] in C++11, __attribute__((noreturn)) as a GCC extension, or _Noreturn for the
    Clang compiler.)

    You can mark your own function with @noreturn if it also terminates
    the process unconditionally, e.g. by calling one of the built-in functions, such as

    @noreturn func myFatalError() {
        // Do something else and then ...
        fatalError("Something went wrong!")
    }
    

    Now you can use your function in the else clause of a guard statement:

    guard let n = Int("1234") else { myFatalError() }
    

    @noreturn functions can also be used to mark cases that “should not
    occur” and indicate a programming error. A simple example
    (an extract from Missing return UITableViewCell):

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell: MyTableViewCell
    
        switch (indexPath.row) {
        case 0:
            cell = tableView.dequeueReusableCellWithIdentifier("cell0", forIndexPath: indexPath) as! MyTableViewCell
            cell.backgroundColor = UIColor.greenColor()
        case 1:
            cell = tableView.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as! MyTableViewCell
            cell.backgroundColor = UIColor.redColor()
        default:
            myFatalError()
        }
        // Setup other cell properties ...
        return cell
    }
    

    Without myFatalError() marked as @noreturn, the compiler would
    complain about a missing return in the default case.


    Update: In Swift 3 (Xcode 8 beta 6) the @noreturn attribute
    has been replaced by a Never return type, so the above example
    would now be written as

    func myFatalError() -> Never  {
        // Do something else and then ...
        fatalError("Something went wrong!")
    }
    

    simple playground to see how it works …

    //: Playground - noun: a place where people can play
    
    import Foundation
    @noreturn func foo() {
        print("foo")
        exit(1)
    }
    
    var i: Int?
    
    guard let i = i else {
        foo()
    }
    
    print("after foo") // this line will never executed
    
    //prints foo and finish