LoginSignup
76
43

More than 5 years have passed since last update.

Swift 3.1で死んだコードまとめ

Last updated at Posted at 2017-03-31

Swiftのリリースの度に型が破壊されるたるのんです、こんにちは。
Swift3.1への移行の調子はいかがでしょうか?すこぶる順調でしょうか?僕は大変でした。
ということでSwift3.1でコンパイルできなくなったコードまとめ。

switchを使ってenumからprotocolを複数のパターンで取り出す

protocol X {}
extension String: X {}

enum A {
    case hoge(X)
    case fuga(X)
}

let a = A.hoge("hello")

switch a {
case .hoge(let x), .fuga(let x):
    print(x)
default:
    break
}

Swiftのswitchは有能で、一つのcaseに複数のパターンを列挙し同じ型なら同じ変数として取り出すことが出来ます。
が、3.1ではProtocol型であった場合、コンパイラがクラッシュします。
地道にcaseを分けてください。

報告済み
https://bugs.swift.org/browse/SR-4417

NSErrorを拡張してError型をキャストするとNSErrorに強制的にキャストされる

import Foundation

protocol MyCustomErrorProtocol {
    var hoge: Int { get }
}

struct MyCustomError: Error, MyCustomErrorProtocol {
    var hoge: Int {
        return 1
    }
}

extension NSError: MyCustomErrorProtocol {
    var hoge: Int {
        return 0
    }
}

let error: Error = MyCustomError()

if let cError = error as? MyCustomErrorProtocol {
    cError.hoge // 0 (If Swift 3.0 then 1)
}

かなりヤバいバグです。
同じ型でNSErrorと任意のErrorを拡張しているとハマります。
もし貴方がSwift3.1を使っているなら、絶対にNSErrorを拡張してはいけません。

報告済み
https://bugs.swift.org/browse/SR-4414

Generics型で重複した型の制約を書くとクラッシュする"場合がある"

https://github.com/tarunon/SR-4434
限定的な条件下でのみクラッシュしますが、重複した型の制約を外せば良いだけなので実務上影響は無いです。
しかし、クラッシュする箇所が重複した型の制約の箇所ではなく、他の場所でクラッシュするため見つけにくい。
不幸にもクラッシュしてしまった場合は重複した型の制約を探すと良いかもしれません。

報告済み
https://bugs.swift.org/browse/SR-4434

classでassociatedtypeをSelfに束縛できなくなった

http://qiita.com/tarunon/items/343ec5fcc059a144f2d1
↑死にました
元々Linux版ではクラッシュしていたようで、完全にコンパイラの虚を突いたworkaroundだったので仕方ない感はあります。
特に報告する必要もなさそうなのでしていません。

76
43
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
76
43