Skip to content

Commit 4fd9846

Browse files
authored
Merge pull request #10328 from jckarter/keypath-mutation-warnings-4.0
[4.0] Sema: Track writes through WritableKeyPaths for mutation warnings.
2 parents 0c83953 + 0569a81 commit 4fd9846

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2351,6 +2351,17 @@ void VarDeclUsageChecker::markStoredOrInOutExpr(Expr *E, unsigned Flags) {
23512351
return;
23522352
}
23532353

2354+
// Likewise for key path applications. An application of a WritableKeyPath
2355+
// reads and writes its base.
2356+
if (auto *KPA = dyn_cast<KeyPathApplicationExpr>(E)) {
2357+
auto &C = KPA->getType()->getASTContext();
2358+
KPA->getKeyPath()->walk(*this);
2359+
if (KPA->getKeyPath()->getType()->getAnyNominal()
2360+
== C.getWritableKeyPathDecl())
2361+
markStoredOrInOutExpr(KPA->getBase(), RK_Written|RK_Read);
2362+
return;
2363+
}
2364+
23542365
if (auto *ioe = dyn_cast<InOutExpr>(E))
23552366
return markStoredOrInOutExpr(ioe->getSubExpr(), RK_Written|RK_Read);
23562367

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-swift-frontend -typecheck -verify %s
2+
3+
struct User {
4+
var id: Int
5+
var name: String
6+
}
7+
8+
func setting<Root, Value>(_ kp: WritableKeyPath<Root, Value>, _ root: Root, _ value: Value) -> Root {
9+
var copy = root
10+
// Should not warn about lack of mutation
11+
copy[keyPath: kp] = value
12+
return copy
13+
}
14+
15+
func referenceSetting<Root, Value>(_ kp: ReferenceWritableKeyPath<Root, Value>, _ root: Root, _ value: Value) -> Root {
16+
// Should warn about lack of mutation, since a RefKeyPath doesn't modify its
17+
// base.
18+
// expected-warning@+1 {{was never mutated}}
19+
var copy = root
20+
copy[keyPath: kp] = value
21+
return copy
22+
}

0 commit comments

Comments
 (0)