-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Description
| 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.