The title is confusing, let me clarify by example: We have this protocol with a mutating method:
protocol P { mutating func f(_ x: Int) -> Int } And a conforming class (which has to conform with a non-mutating method): class C: P { func f(_ x: Int) -> Int { return x } } An instance of this class can be used with a let constant: let c = C() c.f(1) // OK If we make it an existential object conforming to P, the immutability of the method will be erased: let c: AnyObject & P = C() c.f(1) // Cannot use mutating member on immutable value: 'c' is a 'let' constant A generic context has the same issue: func f<T: AnyObject & P>(_ arg: T)-> Int { return arg.f(1) } // Cannot use mutating member on immutable value: ‘arg' is a 'let' constant My question: Is it too much work to preserve method non-mutability in in these cases? The workaround I am using is this: protocol Q: class, P { func f(_ x: Int) -> Int } // 'Refine' it to be non-mutating. extension C: Q {} // Now these work: let c: Q = C() c.f(1) // OK func f<T: Q>(_ arg: T)-> Int { return arg.f(1) } // OK This workaround creates a lot of duplication and is hard to maintain. It is not something that I do often, but when I do, it is pretty annoying. Supplemental questions: Have you guys ever ran into this? Is there already a bug tracking this?
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution