# Mutating Function on Class Type (Possible bug?)

**URL:** <https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066>\
**Category:** Using Swift\
**Created:** [August 7, 2018, 3:29pm UTC](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066 "2018-08-07T15:29:53Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ponyboy47](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ponyboy47/32/2605_2.png) [@Ponyboy47](https://forums.swift.org/u/Ponyboy47)\
**Post date:** [August 7, 2018, 3:29pm UTC](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/1 "2018-08-07T15:29:53Z")

</div>

I'm building a path library that has the following protocol:

```swift
public protocol Ownable {
    var owner: uid_t { get set }
    var group: gid_t { get set }
    var ownerName: String? { get set }
    var groupName: String? { get set }
    mutating func change(owner uid: uid_t, group gid: gid_t) throws
}

```

(The default protocol implementation of all the setters basically just calls the `change` function)

Then I have another protocol which inherits from Ownable:

```swift
public protocol Path: Creatable, Deletable, Movable, Ownable /*, etc...*/ {
    public mutating func change(owner uid: uid_t, group gid: gid_t) throws {
        guard chown(string, uid, gid) == 0 else {
            // Just reads the `errno` and generates the corresponding error
            throw ChangeOwnershipError.getError()
        }
    }
}

```

Then I have this:

```swift
open class DirectoryPath: Path {
    /*
    lots of implementation
    */

    public func changeRecursive(owner uid: uid_t, group gid: gid_t) throws {
        try change(owner: uid, group: gid)

        // Get directory contents and change all of their ownerships recursively...
    }
}

```

The line `try change(owner: uid, group: gid)` fails to compile with the error:  
`cannot use mutating member on immutable value: 'self' is immutable`  
Since this is a class I obviously can't mark the `changeRecursive` function `mutating`.

I found a number of posts that seem to describe the exact error I'm running into:

> [@Protocols, \`mutating\` and Value vs Reference Types.](https://forums.swift.org/t/protocols-mutating-and-value-vs-reference-types/2395):
>
> Hi, I am designing APIs that need to support both reference (class/object) and value types. I am running into restrictions of `mutating` keyword in my protocols and this is causing a lot of duplication of code. In order to understand what I mean please take a look at this gist \<[http://gist.github.com/hooman/2b74d9756976a43330c1acfcfba699f3&gt;\](http://gist.github.com/hooman/2b74d9756976a43330c1acfcfba699f3&gt;%5C). As you see, I have pairs of almost identical declarations: KeyValueStore vs KeyValueStoreObject, and AnyDictionaryStore vs AnyDictionaryStoreObject. T…

> [@Proposal: Intermediate mutation qualifier for protocol functions on reference-types](https://forums.swift.org/t/proposal-intermediate-mutation-qualifier-for-protocol-functions-on-reference-types/401/12):
>
> BTW, we have three workarounds to the initial problem so far, using the current state of Swift: 1. the one by Kevin Ballard below in the thread (the best one) 2. my first work around at [[SR-142] mutating function in protocol extension erroneously requires `var` declaration of class variables · Issue #42764 · apple/swift · GitHub](https://bugs.swift.org/browse/SR-142) 3. declare a non-mutating protocol that inherits from the mutating one, and let classes adopt the non-mutating one, as in: &nbsp;&nbsp;protocol MutableP { &nbsp;&nbsp;&nbsp;&nbsp;mutating func f…

It seems this is caused by having a default implementation marked `mutating` and so I can't directly call it in a reference type that conforms to the protocol.

Unfortunately, those threads haven't been touched in 2-3 years and A LOT has changed in swift in the past few years. The second link has a few workarounds, unfortunately they all feel sorta hack-ish and I'd rather not do them if I can avoid it. I want it to just work the way I have it, duh ;)

That being said, does anyone know if this is a bug that should be filed (again?) or something that can be re-looked at to see if it can be fixed in the compiler? Or even if there's just a better workaround.

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [August 7, 2018, 3:50pm UTC](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/2 "2018-08-07T15:50:48Z")

</div>

It's "correct" behavior because the default implementation is allowed to go `self = someCompletelyDifferentObjectOfTheSameType`, and that would reassign the reference at the call site. See [SR-142](https://bugs.swift.org/browse/SR-142) for some more discussion.

Even beyond this, `mutating` and classes don't play so well together. It may not be the best model for what you're trying to do.

---

<div class="post-metadata">

**Author:** ![hooman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hooman/32/43536_2.png) [@hooman](https://forums.swift.org/u/hooman)\
**Post date:** [August 7, 2018, 5:23pm UTC](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/3 "2018-08-07T17:23:22Z")

</div>

This is my other more recent thread that contains some useful information from @Slava_Pestov:

> [@Preserving non-mutability of methods of an existential or generic object](https://forums.swift.org/t/preserving-non-mutability-of-methods-of-an-existential-or-generic-object/7318):
>
> 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) /…

---

<div class="post-metadata">

**Author:** ![Ponyboy47](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ponyboy47/32/2605_2.png) [@Ponyboy47](https://forums.swift.org/u/Ponyboy47)\
**Post date:** [August 7, 2018, 5:52pm UTC](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/4 "2018-08-07T17:52:16Z")

</div>

Thanks y'all for the information! I think I will do some slight redesigning to get it working the way I want. Probably just by removing the `mutating` keyword on the protocol requirements since I'm working with all classes. I started with structs originally, but because I'm working with file handles and some of the ways I'm doing things I don't think I could switch back to structs (at least not easily).

---

<div class="post-metadata">

**Author:** ![Ling\_Wang](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ling_wang/32/2691_2.png) [@Ling\_Wang](https://forums.swift.org/u/Ling_Wang)\
**Post date:** [December 20, 2018, 3:59am UTC](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/5 "2018-12-20T03:59:07Z")

</div>

Why not simply treat `mutating` differently and specially—as if it is not there—in reference types? We know it is only specified for value type adopters since reference types are always mutable. As to `self` being reassigned in the default implementation, I feel we should have to a way to specify that the protocol is only for value types and disallow such reassignments in not-value-type-only implementations.

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [December 20, 2018, 4:11am UTC](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/6 "2018-12-20T04:11:18Z")

</div>

Until we have the "this protocol is only for value types" part, we can't do the "treat `mutating` as if it is not there in reference types" part. It's also not obviously a good idea since an immutable class type is pretty much indistinguishable from a value type except for `ObjectIdentifier` (and `===`).

(A long time ago @dabrahams and I talked about disallowing classes from conforming to protocols with `mutating` requirements, which is similar. But at this point it'd be massively source-breaking to do so.)

---

<div class="post-metadata">

**Author:** ![Dante-Broggi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dante-broggi/32/7955_2.png) [@Dante-Broggi](https://forums.swift.org/u/Dante-Broggi)\
**Post date:** [December 20, 2018, 11:31am UTC](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/7 "2018-12-20T11:31:19Z")

</div>

One thing I have wondered about related to this issue is why Swift does not allow writing:

```swift
class Foo {
  mutating func bar() {
    self = Foo()
  }
}

```

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [December 20, 2018, 4:48pm UTC](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/8 "2018-12-20T16:48:31Z")

</div>

We could allow it, sure. But it would only change _this_ reference, not any other references pointing to the same object, and _not_ having `mutating` doesn't prevent you from changing stored properties (see [Avoiding unbreakable reference cycle with value types and closures? - #17 by jrose](https://forums.swift.org/t/avoiding-unbreakable-reference-cycle-with-value-types-and-closures/18757/17)). So it's left out of the language to avoid introducing a point of confusion.

Have you come across a situation where you would have wanted this?

---

<div class="post-metadata">

**Author:** ![Dante-Broggi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dante-broggi/32/7955_2.png) [@Dante-Broggi](https://forums.swift.org/u/Dante-Broggi)\
**Post date:** [December 20, 2018, 7:46pm UTC](https://forums.swift.org/t/mutating-function-on-class-type-possible-bug/15066/9 "2018-12-20T19:46:13Z")

</div>

No, I just noted it would be a generally consistent and unambiguous extension of the current meaning.
