2つの型T
, U
を考えそれぞれの値をt
, u
とします。 ここで関数 func ~= (_ lhs: U, _ rhs: T) -> Bool
が存在するとすると、if-case文 if case u = t { ... }
がコンパイルでき正しく動作します。 ここで、Optional<T>
型の値をot
とすると、if-case文 if case u? = ot { ... } // あるいは上と同等の if case .some(u) = ot { ... }
がコンパイルでき、もっともらしい動作を行います。 この動作は if ot.map({ u ~= $0 }) ?? false { ... }
と同じで、ot
がnil
ならfalse
、そうでないならu ~= ot!
の結果を用いる、となります。 この.some(u)
を用いたif-case文は、僕が調べた限り仕様に存在せず、これがコンパイル可能であることが問題である可能性があります。 さらに、.some(u)
の型が何であるのかを考えます。 これはもちろんOptional<U>
であるはずです。 ところが if case Optional<U>.some(u) = ot { ... }
はコンパイルエラーとなります。 エラーの内容は「Optional<U>
型はOptional<T>
型と合致しない」です。 では先の.some(u)
の型は何なのか。ここでとんでもない値を導入します。 Optional<T>.some(u)
もちろんこの値は間違いです。この値はSwiftの世界には存在してはならない値です。 にもかかわらず if case Optional<T>.some(u) = ot { ... }
はコンパイル可能で.some(u)
を用いた場合と同様の動作を行います。 つまり本来存在してはならない値を含むプログラムがコンパイルできてしまう。 というのが今回の問題です。 (edited)