Issue with `mutating` methods on protocols and `AnyObject` conformers

Not sure if this is a bug or not, but if you have a protocol with a mutating method:

protocol Rearrangeable: Collection {
    mutating func move(from current: Index, to new: Index)
}

And define another AnyObject protocol that conforms to it:

protocol ThisIsNotAValueType: AnyObject, Rearrangeable {}

If you ever have a generic that conforms to the refined protocol, it won't permit calling the mutating method:

func here<T>(object: T) where T: ThisIsNotAValueType {
    // code ...
    object.move(from: current, to: new)
    //        Get error: "Cannot use mutating member on immutable value: 'object' is a 'let' constant"
}

This can be circumvented by redefining the mutating method requirement in the refined protocol:

protocol ThisIsNotAValueType: AnyObject, Rearrangeable {

    /// - Note: Added as `Rearrangeable.move(from:to:)` is marked as `mutating`
    ///   and so doesn't work with immutable references; even though we're an 
    ///   `AnyObject`.
    func move(from current: Index, to new: Index)
}
1 Like
2 Likes