I'm building a path library that has the following protocol:
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:
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:
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:
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.