Extending Swift dictionary to conform to protocol requiring index use throws Linker error

The title says it all, but I have a protocol like:

protocol MyProtocol {
    typealias KeyType
    typealias ValueType

    subscript(key: KeyType) -> ValueType? { get set }
}

      

And trying to do Dictionary

match MyProtocol

like:

extension Dictionary: MyProtocol {
}

      

results in linker error:

Undefined symbols for architecture x86_64:
"__TFVSs10Dictionarym9subscriptFQ_GSqQ0__", referenced from:
  __TTWUSs8Hashable___GVSs10DictionaryQ_Q0__18ProjectName11MyProtocolS1_FS2_m9subscriptFQQPS2_12KeyTypeGSqQS3_15ValueType_ in Searcher.o

      

Now the interesting part is that if I override the index, the error goes away, but I don't know how to override it without calling infinite recursion.

If instead { get set }

is required for the protocol { get }

, the error also disappears and the extension works as desired.

So my guess is that the problem should be out of the way set

, and trying to demand { get mutating set }

doesn't work either.

Does anyone know (a) what's going on and (b) how to make the Dictionary

match MyProtocol

without resorting to drastic solutions like overriding subscript

?

At first I was convinced that this is a bug with Swift, but after probing a little, I'm not sure.

I am using Swift 1.2

Edit: I managed to get it working by following these steps:

extension Dictionary: MyProtocol {
    subscript(key: Key) -> Value? {
        get {
            let index = self.indexForKey(key)

            if let i = index {
                return self[i].1
            }

            return nil
        }
        set {
            if let value = newValue {
                self.updateValue(value, forKey: key)
            } else {
                self.removeValueForKey(key)
            }
        }
    }
}

      

But re-implementing the dictionary index really doesn't seem like a good idea to me.

Edit 2: Clearer question.

Edit 3: Tried the same code in Swift 2.0 and it still doesn't work. Curiously, this time the linker error is different:

Undefined symbols for architecture x86_64:
  "Swift.Dictionary.subscript.materializeForSet : (A) -> B?", referenced from:
      protocol witness for _Test.MyProtocol.subscript.materializeForSet : (A.KeyType) -> A.ValueType? in conformance <A, B where A: Swift.Hashable> [A : B] : _Test.MyProtocol in _Test in TestFile.o

      

+3


source to share





All Articles