Hi Hooman, Since the protocol P is not class-bounded, the requirement can be witnessed by a protocol extension method which re-assigns ‘self’:
protocol Initable { init() } extension P where Self : Initable { mutating func f(_ x: Int) -> Int { self = Self() return x } } class C : P, Initable { required init() {} } Now imagine you could do this, let x: P & AnyObject x.f(12) This would be invalid because ‘x’ is a let binding but the requirement ‘f’ is witnessed by the protocol extension method, which performs a mutating access of ‘self’. Slava > On Dec 21, 2017, at 6:01 PM, Hooman Mehr via swift-evolution > <swift-evolution@swift.org> wrote: > > 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
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution