# Class-constrained protocol extension has incorrect mutatingness

**URL:** <https://forums.swift.org/t/class-constrained-protocol-extension-has-incorrect-mutatingness/27962>\
**Category:** Discussion\
**Created:** [August 16, 2019, 6:48pm UTC](https://forums.swift.org/t/class-constrained-protocol-extension-has-incorrect-mutatingness/27962 "2019-08-16T18:48:32Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![suyashsrijan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/suyashsrijan/32/5292_2.png) [@suyashsrijan](https://forums.swift.org/u/suyashsrijan)\
**Post date:** [August 16, 2019, 6:48pm UTC](https://forums.swift.org/t/class-constrained-protocol-extension-has-incorrect-mutatingness/27962/1 "2019-08-16T18:48:32Z")

</div>

At the moment, a property in a class-constrained protocol extension, where the protocol does not impose a class-requirement, would have a mutating setter by default. For example:

```swift
protocol P {}
	
class A: P {
  var property: String = ""
}

extension P where Self: A {
  var wrappingProperty: String {
    get { return property }
    set { property = newValue }
  }
}
	
let instance = A()
instance.wrappingProperty = "" // Cannot assign to property: 'instance' is a 'let' constant

```

@Joe_Groff [mentioned](https://twitter.com/jckarter/status/1161268740757086208) that this is a bug, because even though the protocol does not impose a class constraint, it's implied by the `Self: A` requirement in the extension, so `wrappingProperty`'s setter should be non-mutating instead. This was [fixed](https://github.com/apple/swift/pull/26669) today (but it's being reverted now).

However, it's been bought to attention that the new behaviour can be source breaking in some cases. For example:

```swift
protocol P {
  var property: String { get set }
}

extension P where Self : AnyObject {
  var wrappingProperty: String {
    get { property }
    // This will now error and ask the user to explicitly 
    // mark the setter as mutating.
    set { property = newValue }
  }
}

```

What is the best way to handle this? Is the behaviour acceptable or does this change need to go through Swift Evolution? or should we leave this unfixed? cc @John_McCall @Douglas_Gregor

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [August 17, 2019, 4:18am UTC](https://forums.swift.org/t/class-constrained-protocol-extension-has-incorrect-mutatingness/27962/2 "2019-08-17T04:18:29Z")

</div>

> [@suyashsrijan](#):
>
> What is the best way to handle this? Is the behaviour acceptable or does this change need to go through Swift Evolution?

It's worth noting that what is potentially source breaking is the declaration site only and not any use sites.

Currently, `wrappingProperty` can't be set for _any_ `let` constant; if the issue is fixed, then that's the case only when it wraps a property that can potentially reassign `self`.

I think the best way to handle this is to improve the diagnostic that's emitted where there is source breakage: explain to the user that the setter must be marked as mutating because `property` is a protocol requirement that can reassign `self`; if the protocol is under the user's control as well, offer both fix-its (mark the setter of `wrappingProperty` as `mutating`, or mark the protocol requirement `property` as `nonmutating set`).

---

<div class="post-metadata">

**Author:** ![igor-makarov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/igor-makarov/32/7490_2.png) [@igor-makarov](https://forums.swift.org/u/igor-makarov)\
**Post date:** [August 17, 2019, 12:44pm UTC](https://forums.swift.org/t/class-constrained-protocol-extension-has-incorrect-mutatingness/27962/3 "2019-08-17T12:44:43Z")

</div>

Do we have examples of source breakages in the compat suite?  
Also, this breakage example mentioned here - should it error, in fact? Isn't the extension being constrained to AnyObject imply mutating?

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [August 17, 2019, 3:11pm UTC](https://forums.swift.org/t/class-constrained-protocol-extension-has-incorrect-mutatingness/27962/4 "2019-08-17T15:11:56Z")

</div>

What exactly does `P where Self` mean?  
Is `P` the protocol or the existential here?  
If the latter, what does `Self` mean in context of the existential?

* * *

Just trying to understand these tiny things and complete my knowledge about the existential type:

> [@Is the 'existential' a value or ref type?](https://forums.swift.org/t/is-the-existential-a-value-or-ref-type/27817/13):
>
> There is hidden achievement to unlock in this setup. First, we know that the "existential" type itself is a value type which has no value semantics unless it wraps another type with value semantics. struct Existential\<Value\> { // invisible to the user var \_value: Value // forwards all members of Value } Now let's see our protocols: protocol P0 { // this is a `mutating set` var x: Int { get set } } // protocol is class bound but it still has a `mutating set` protocol P1: AnyObject,…

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [August 17, 2019, 4:28pm UTC](https://forums.swift.org/t/class-constrained-protocol-extension-has-incorrect-mutatingness/27962/5 "2019-08-17T16:28:52Z")

</div>

> [@DevAndArtist](#):
>
> What exactly does `P where Self` mean?  
> Is `P` the protocol or the existential here?  
> If the latter, what does `Self` mean in context of the existential?

The protocol.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [August 17, 2019, 5:00pm UTC](https://forums.swift.org/t/class-constrained-protocol-extension-has-incorrect-mutatingness/27962/6 "2019-08-17T17:00:42Z")

</div>

I think this is unquestionably just a bug that should be fixed and doesn’t require evolution approval. Xiaodi’s point that such an implementation can’t actually be used is important.

---

<div class="post-metadata">

**Author:** ![suyashsrijan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/suyashsrijan/32/5292_2.png) [@suyashsrijan](https://forums.swift.org/u/suyashsrijan)\
**Post date:** [August 21, 2019, 12:12pm UTC](https://forums.swift.org/t/class-constrained-protocol-extension-has-incorrect-mutatingness/27962/7 "2019-08-21T12:12:13Z")

</div>

Thanks! Could you raise this with the Core Team? Or is it not necessary? Once I get confirmation, I can go ahead and un-revert the patch and tweak the diagnostics.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [August 21, 2019, 4:52pm UTC](https://forums.swift.org/t/class-constrained-protocol-extension-has-incorrect-mutatingness/27962/8 "2019-08-21T16:52:47Z")

</div>

Sure, I’ll raise it to the rest of the Core Team.

---

<div class="post-metadata">

**Author:** ![suyashsrijan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/suyashsrijan/32/5292_2.png) [@suyashsrijan](https://forums.swift.org/u/suyashsrijan)\
**Post date:** [August 21, 2019, 4:53pm UTC](https://forums.swift.org/t/class-constrained-protocol-extension-has-incorrect-mutatingness/27962/9 "2019-08-21T16:53:32Z")

</div>

Thanks!

---

<div class="post-metadata">

**Author:** ![suyashsrijan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/suyashsrijan/32/5292_2.png) [@suyashsrijan](https://forums.swift.org/u/suyashsrijan)\
**Post date:** [September 6, 2019, 5:17pm UTC](https://forums.swift.org/t/class-constrained-protocol-extension-has-incorrect-mutatingness/27962/10 "2019-09-06T17:17:38Z")

</div>

Any update on this?

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [September 6, 2019, 5:21pm UTC](https://forums.swift.org/t/class-constrained-protocol-extension-has-incorrect-mutatingness/27962/11 "2019-09-06T17:21:35Z")

</div>

Thanks for the reminder. General agreement is that it's okay to treat this as a bug fix, so it doesn't need an evolution proposal.

---

<div class="post-metadata">

**Author:** ![suyashsrijan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/suyashsrijan/32/5292_2.png) [@suyashsrijan](https://forums.swift.org/u/suyashsrijan)\
**Post date:** [September 6, 2019, 5:23pm UTC](https://forums.swift.org/t/class-constrained-protocol-extension-has-incorrect-mutatingness/27962/12 "2019-09-06T17:23:44Z")

</div>

Thanks! I’ll unrevert the fix.
