Skip to content

Commit 2278694

Browse files
authored
Merge pull request #15808 from jckarter/keypath-setter-visibility
Sema: Fix setter visibility computation when checking key path literals.
2 parents bceaab3 + 6d053f5 commit 2278694

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4033,7 +4033,12 @@ ConstraintSystem::simplifyKeyPathConstraint(Type keyPathTy,
40334033
return SolutionKind::Error;
40344034
}
40354035

4036-
if (!storage->isSettable(DC)) {
4036+
// See whether key paths can store to this component. (Key paths don't
4037+
// get any special power from being formed in certain contexts, such
4038+
// as the ability to assign to `let`s in initialization contexts, so
4039+
// we pass null for the DC to `isSettable` here.)
4040+
if (!storage->isSettable(nullptr)
4041+
|| !storage->isSetterAccessibleFrom(DC)) {
40374042
// A non-settable component makes the key path read-only, unless
40384043
// a reference-writable component shows up later.
40394044
capability = ReadOnly;

test/expr/unary/keypath/keypath.swift

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,52 @@ func sr6744() {
499499
_ = get(for: \.value)
500500
}
501501

502+
struct VisibilityTesting {
503+
private(set) var x: Int
504+
fileprivate(set) var y: Int
505+
let z: Int
506+
507+
// Key path exprs should not get special dispensation to write to lets
508+
// in init contexts
509+
init() {
510+
var xRef = \VisibilityTesting.x
511+
var yRef = \VisibilityTesting.y
512+
var zRef = \VisibilityTesting.z
513+
expect(&xRef,
514+
toHaveType: Exactly<WritableKeyPath<VisibilityTesting, Int>>.self)
515+
expect(&yRef,
516+
toHaveType: Exactly<WritableKeyPath<VisibilityTesting, Int>>.self)
517+
expect(&zRef,
518+
toHaveType: Exactly<KeyPath<VisibilityTesting, Int>>.self)
519+
}
520+
521+
func inPrivateContext() {
522+
var xRef = \VisibilityTesting.x
523+
var yRef = \VisibilityTesting.y
524+
var zRef = \VisibilityTesting.z
525+
expect(&xRef,
526+
toHaveType: Exactly<WritableKeyPath<VisibilityTesting, Int>>.self)
527+
expect(&yRef,
528+
toHaveType: Exactly<WritableKeyPath<VisibilityTesting, Int>>.self)
529+
expect(&zRef,
530+
toHaveType: Exactly<KeyPath<VisibilityTesting, Int>>.self)
531+
}
532+
}
533+
534+
struct VisibilityTesting2 {
535+
func inFilePrivateContext() {
536+
var xRef = \VisibilityTesting.x
537+
var yRef = \VisibilityTesting.y
538+
var zRef = \VisibilityTesting.z
539+
expect(&xRef,
540+
toHaveType: Exactly<KeyPath<VisibilityTesting, Int>>.self)
541+
expect(&yRef,
542+
toHaveType: Exactly<WritableKeyPath<VisibilityTesting, Int>>.self)
543+
expect(&zRef,
544+
toHaveType: Exactly<KeyPath<VisibilityTesting, Int>>.self)
545+
}
546+
}
547+
502548
func testSyntaxErrors() { // expected-note{{}}
503549
_ = \. ; // expected-error{{expected member name following '.'}}
504550
_ = \.a ;

0 commit comments

Comments
 (0)