Skip to content

[SR-8384] WritableKeyPath + inout argument of placeholder type doesn't compile #50911

@mayoff

Description

@mayoff
Previous ID SR-8384
Radar None
Original Reporter @mayoff
Type Bug
Status Closed
Resolution Invalid
Environment

swift-DEVELOPMENT-SNAPSHOT-2018-07-24-a.xctoolchain / Apple Swift version 4.2-dev (LLVM a4d539e482, Clang 773ac0251a, Swift c2452cf)

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, KeyPaths
Assignee None
Priority Medium

md5: 45bd97941ce71697b87a2a39a56f68cc

Issue Description:

Given this protocol:

protocol MyStateSlice {
    var flag: Bool { get set }
}

I want to write a class that operates on objects conforming to this protocol generically using a WritableKeyPath on an inout argument, like this:

struct MyGenericController<State: MyStateSlice> {
    let flagKeyPath = \MyStateSlice.flag
    // inferred type: WritableKeyPath<MyStateSlice, Bool>

    func withState(do body: (inout State) -> ()) { /* blah blah */ }

    func buttonWasClicked() {
        withState {
            print($0[keyPath: flagKeyPath]) // compiles just fine

            $0[keyPath: flagKeyPath] = true // <-- error on this line
            // error: cannot assign to immutable expression of type 'Bool'
        }
    }
}

The problem with the assignment is that flagKeyPath has type WritableKeyPath<MyStateSlice, Bool>, but Swift wants it to be WritableKeyPath<State, Bool>. If I initialize flagKeyPath to \State.flag instead, then the code compiles.

Note that the print works with either definition of flagKeyPath. I don't know why the assignment can't work with \MyStateSlice.flag, since the argument ($0) conforms to MyStateSlice.

Either Swift should allow the assignment, or Swift should provide a more helpful error message about why the assignment isn't allowed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselfkey pathsFeature: key paths (both native and Objective-C)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions