• Stars
    star
    103
  • Rank 333,046 (Top 7 %)
  • Language
    Swift
  • License
    MIT License
  • Created over 7 years ago
  • Updated over 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Unreachable code path optimization hint for Swift

Unreachable

Platform Language: Swift CocoaPods - Unreachable Carthage codebeat badge License

Unreachable is a Swift µframework that allows for letting the compiler know when a code path is unreachable.

Build Status

Branch Status
master Build Status

Installation

Compatibility

  • Platforms:
    • macOS 10.9+
    • iOS 8.0+
    • watchOS 2.0+
    • tvOS 9.0+
    • Linux
  • Xcode 8.0+
  • Swift 3.0+ & 4.0

Install Using Swift Package Manager

The Swift Package Manager is a decentralized dependency manager for Swift.

  1. Add the project to your Package.swift.

    import PackageDescription
    
    let package = Package(
        name: "MyAwesomeProject",
        dependencies: [
            .Package(url: "https://github.com/nvzqz/Unreachable.git",
                     majorVersion: 1)
        ]
    )
  2. Import the Unreachable module.

    import Unreachable

Install Using CocoaPods

CocoaPods is a centralized dependency manager for Objective-C and Swift. Go here to learn more.

  1. Add the project to your Podfile.

    use_frameworks!
    
    pod 'Unreachable', '~> 1.2.0'

    If you want to be on the bleeding edge, replace the last line with:

    pod 'Unreachable', :git => 'https://github.com/nvzqz/Unreachable.git'
  2. Run pod install and open the .xcworkspace file to launch Xcode.

  3. Import the Unreachable framework.

    import Unreachable

Install Using Carthage

Carthage is a decentralized dependency manager for Objective-C and Swift.

  1. Add the project to your Cartfile.

    github "nvzqz/Unreachable"
    
  2. Run carthage update and follow the additional steps in order to add Unreachable to your project.

  3. Import the Unreachable framework.

    import Unreachable

Install Manually

Simply add Unreachable.swift into your project.

Usage

Try it out for yourself! Download the repo and open 'Unreachable.playground'.

Dynamic Loop Exit

In some cases, the only way a function returns a value is from within a loop, but the compiler may not have enough information to know that.

func getValue() -> Int {
    for i in 0... {
        if i == 20 {
            return i
        }
    }
    assertUnreachable()
}

Switch Conditions

A switch statement may have conditions applied to its branches that make it exhaustive, but that may not obvious to the compiler.

func sign(of value: Double?) -> FloatingPointSign? {
    switch value {
    case let x? where x >= 0:
        return .plus
    case let x? where x < 0:
        return .minus
    case .some:
        assertUnreachable()
    case .none:
        return nil
    }
}

Safety

It is undefined behavior for unreachable() to be called. To protect against this, it is recommended to use assertUnreachable() instead.

With assertUnreachable(), debug builds will exit via a fatal error if the function is called. In optimized builds, it's no different than calling unreachable().

Unreachable vs fatalError()

The assertUnreachable() function can be used as somewhat of a drop-in replacement for fatalError(). In debug mode, they emit similar instructions. However, when compiling with optimizations, assertUnreachable() allows its parent to emit very few instructions.

Here we're checking whether a UnicodeScalar has a value in the lower or upper range. Because we know that these are the only valid ranges, we can let the compiler know that the third branch is unreachable. If at some point x has a value that's not within either range, it will emit an assertion failure in unoptimized builds.

With Unreachable

func isLowerRange(_ x: UnicodeScalar) -> Bool {
    switch x.value {
    case 0...0xD7FF:
        return true
    case 0xE000...0x10FFFF:
        return false
    default:
        assertUnreachable()
    }
}

Assembly output:

        .globl  __T011Unreachable12isLowerRangeSbs7UnicodeO6ScalarVF
        .p2align        4, 0x90
__T011Unreachable12isLowerRangeSbs7UnicodeO6ScalarVF:
        pushq   %rbp
        movq    %rsp, %rbp
        cmpl    $55296, %edi
        setb    %al
        popq    %rbp
        retq

With fatalError()

func isLowerRange(_ x: UnicodeScalar) -> Bool {
    switch x.value {
    case 0...0xD7FF:
        return true
    case 0xE000...0x10FFFF:
        return false
    default:
        fatalError("Unreachable")
    }
}

Assembly output:

        .globl  __T011Unreachable12isLowerRangeSbs7UnicodeO6ScalarVF
        .p2align        4, 0x90
__T011Unreachable12isLowerRangeSbs7UnicodeO6ScalarVF:
        .cfi_startproc
        movb    $1, %al
        cmpl    $55296, %edi
        jb      LBB4_3
        addl    $-57344, %edi
        cmpl    $1056768, %edi
        jae     LBB4_4
        xorl    %eax, %eax
LBB4_3:
        retq
LBB4_4:
        pushq   %rbp
Lcfi0:
        .cfi_def_cfa_offset 16
Lcfi1:
        .cfi_offset %rbp, -16
        movq    %rsp, %rbp
Lcfi2:
        .cfi_def_cfa_register %rbp
        subq    $48, %rsp
        leaq    L___unnamed_2(%rip), %rax
        movq    %rax, (%rsp)
        movl    $0, 32(%rsp)
        movq    $56, 24(%rsp)
        movl    $2, 16(%rsp)
        movq    $69, 8(%rsp)
        leaq    L___unnamed_3(%rip), %rdi
        leaq    L___unnamed_4(%rip), %rcx
        movl    $11, %esi
        movl    $2, %edx
        movl    $11, %r8d
        xorl    %r9d, %r9d
        callq   __T0s17_assertionFailures5NeverOs12StaticStringV_SSAE4fileSu4lines6UInt32V5flagstFTfq4nxnnn_n
        subq    $40, %rsp
        .cfi_endproc

License

All source code for Unreachable is released under the MIT License.

Assets for Unreachable are released under the CC BY-SA 4.0 License and can be found in the assets branch.

More Repositories

1

FileKit

Simple and expressive file management in Swift
Swift
2,289
star
2

RandomKit

Random data generation in Swift
Swift
1,473
star
3

divan

Fast and simple benchmarking for Rust projects
Rust
895
star
4

static-assertions

Ensure correct assumptions about constants, types, and more in Rust
Rust
566
star
5

Sage

A cross-platform chess library for Swift
Swift
376
star
6

impls

A Rust macro to determine if a type implements a logical trait expression
Rust
246
star
7

Menubar-Colors

A macOS app for convenient access to the system color panel
Swift
175
star
8

fruity

Rusty bindings for Apple libraries
Rust
169
star
9

swift-bindgen

Bridging the gap between Swift and Rust
Rust
149
star
10

Threadly

Type-safe thread-local storage in Swift
Swift
74
star
11

condtype

Choose Rust types at compile-time via constants
Rust
59
star
12

embed-plist-rs

Embed property list files like Info.plist directly in your Rust executable binary
Rust
39
star
13

Roman

Seamless Roman numeral conversion in Swift
Swift
36
star
14

rosy

Rust and Ruby, sitting in a tree 🌹
Rust
23
star
15

byte-set-rs

Efficient sets of bytes for Rust
Rust
19
star
16

cargo-emit

Talk to Cargo easily at build time
Rust
16
star
17

Clockmoji

Simple and intuitive time formatting using clock emoji.
Swift
13
star
18

XO

A cross-platform tic-tac-toe library for Swift
Swift
13
star
19

Lazy

Save the hard work for later, lazily evaluate values anywhere
Swift
12
star
20

Weak

Weak and Unowned as native Swift types
Swift
10
star
21

typebool

Type-level booleans in Rust for compile-time hackery
Rust
8
star
22

c-utf8-rs

UTF-8 encoded C strings for Rust
Rust
6
star
23

malloced

A malloc-ed box pointer type for Rust
Rust
5
star
24

dotfiles

Personal dotfiles
Shell
5
star
25

aloxide

Compile Rubies on Linux, macOS, and Windows
Rust
5
star
26

mods

Simpler Rust module declaration
Rust
5
star
27

bit-collection-rs

Iterate over bits in Rust
Rust
5
star
28

unsafe-unwrap-rs

Unsafely unwrap Result and Option types without checking in Rust
Rust
5
star
29

uncon-rs

Unchecked and unsafe type conversions in Rust
Rust
4
star
30

head-rs

Common Rust types with inline headers, such as HeaderVec for Vec
Rust
4
star
31

bad-rs

Unlicensed bad ideas
Rust
4
star
32

rust-workshop

A workshop on the Rust programming language
3
star
33

OneOrMore

A Swift collection of one or more elements
Swift
3
star
34

fmty

Rust library of composable `core::fmt` utilities
Rust
3
star
35

mem-cmp-rs

Safe memory comparison between types in Rust
Rust
2
star
36

ShiftOperations

A µframework for a needed ShiftOperations protocol that does not appear in the Swift standard library
Swift
1
star
37

rust-selector-example

My attempt at creating Objective-C selectors in Rust at compile time
Shell
1
star
38

asygnal

Handle signals (e.g. ctrl-c) efficiently and asynchronously in Rust
Rust
1
star
39

chance-rs

Random number generation in Rust
Rust
1
star