How to properly cast object to generic enum?

I want to write an enum like Optional, but when I try to cast Codable value "a" to Optionally, it always failed with warning: "Cast from 'any Codable' (aka 'any Decodable & Encodable') to unrelated type 'Optionally' always fails". However, using the system Optional will not have corresponding warnings. What's the difference? How to fix my code?

public enum Optionally<T> {
    case none
    case value(T)

extension Optionally: Codable where T: Codable {
    public init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let value = try? container.decode(T.self) {
            self = .value(value)
        } else {
            self = .none
    public func encode(to encoder: Encoder) throws {
        if case .value(let value) = self {
            var container = encoder.singleValueContainer()
            try container.encode(value)

var a: Codable = Optionally<Int>.none

switch a {
case let o as Optional<Any>: // no warning!
    if case .none = o {
        print("it's none")
case let b as Optionally<Any>: // warning: Cast from 'any Codable' (aka 'any Decodable & Encodable') to unrelated type 'Optionally<Any>' always fails
    print("it's optionally")
    print("not optionally")

Don't know what's the difference is (between built-in Optional and custom Optionally), but here's a workaround:

protocol OptionallyProtocol {
    associatedtype T
    var value: T? { get }

extension Optionally: OptionallyProtocol {
    var value: T? {
        switch self {
        case .none: return nil
        case .value(let v): return v

var a: Codable = Optionally<String>.none

if let v = a as? any OptionallyProtocol {
    if let value = v.value {
        print("Optionally \(value)")
    } else {
        print("Optionally none")
} else {
    print("something else")

By no means sure this is the best approach, just something that compiles and seems to be working.

Your question is the new hotness for some reason. :firecracker:

Thanks for the solution ~