Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-2220] A protocol's mutating keyword is enforced on AnyObject when using generics #44827

Closed
swift-ci opened this issue Jul 30, 2016 · 1 comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-2220
Radar None
Original Reporter bnut (JIRA User)
Type Bug
Status Resolved
Resolution Done
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug
Assignee None
Priority Medium

md5: 68a8c8b12a6c73d972f7bfeeba12af89

relates to:

  • SR-142 mutating function in protocol extension erroneously requires var declaration of class variables

Issue Description:

The `mutating` keyword on protocols is enforced by the compiler on Object types when the type is given by a generic constraint. The `mutating` keyword is not otherwise enforced on objects.

This is inconsistent, I think it should work in this case as well.

Error:

Cannot use mutating member on immutable value: 'base' is a 'let' constant.
Fix-it     Change 'let' to 'var' to make it mutable

Example

protocol SomeProtocol {
    mutating func update()
}
struct ObjectWrapper<T: AnyObject> {
    let base: T
}

This works:

struct Example: SomeProtocol { func update() { } }

let x = ObjectWrapper(base: Example())
x.base.update()

This does not work:

extension ObjectWrapper where T: SomeProtocol {
    func update() {
        self.base.update()
    }
}

This does not work:

func update
    <S: Sequence where S.Iterator.Element: SomeProtocol, S.Iterator.Element: AnyObject>
    (sequence: S)
{
    for element in sequence {
        let wrapper = ObjectWrapper(base: element)
        wrapper.base.update()
    }
}
@slavapestov
Copy link
Member

Swift 4's implementation of subclass existentials fixed a lot of problems here.

Note that the behavior is correct though – a mutating member on a class-constrained type still has to be invoked on an lvalue, because it might be implemented in a protocol extension method that re-assigns self.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself
Projects
None yet
Development

No branches or pull requests

2 participants