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だったので仕方ない感はあります。
特に報告する必要もなさそうなのでしていません。