Skip to content

Commit d6a6df2

Browse files
authored
[CS] Fix invalid key path crasher (#30832)
[CS] Fix invalid key path crasher
2 parents cbf3cab + 3339ea4 commit d6a6df2

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7543,6 +7543,7 @@ ConstraintSystem::simplifyKeyPathConstraint(
75437543
} capability = Writable;
75447544

75457545
bool anyComponentsUnresolved = false;
7546+
bool didOptionalChain = false;
75467547

75477548
for (unsigned i : indices(keyPath->getComponents())) {
75487549
auto &component = keyPath->getComponents()[i];
@@ -7642,26 +7643,27 @@ ConstraintSystem::simplifyKeyPathConstraint(
76427643
}
76437644

76447645
case KeyPathExpr::Component::Kind::OptionalChain:
7645-
// Optional chains force the entire key path to be read-only.
7646-
capability = ReadOnly;
7647-
goto done;
7646+
didOptionalChain = true;
7647+
break;
76487648

76497649
case KeyPathExpr::Component::Kind::OptionalForce:
76507650
// Forcing an optional preserves its lvalue-ness.
76517651
break;
76527652

76537653
case KeyPathExpr::Component::Kind::OptionalWrap:
7654-
// An optional chain should already have forced the entire key path to
7655-
// be read-only.
7656-
assert(capability == ReadOnly);
7654+
// An optional chain should already have been recorded.
7655+
assert(didOptionalChain);
76577656
break;
76587657

76597658
case KeyPathExpr::Component::Kind::TupleElement:
76607659
llvm_unreachable("not implemented");
76617660
break;
76627661
}
76637662
}
7664-
done:
7663+
7664+
// Optional chains force the entire key path to be read-only.
7665+
if (didOptionalChain)
7666+
capability = ReadOnly;
76657667

76667668
// Resolve the type.
76677669
NominalTypeDecl *kpDecl;

test/expr/unary/keypath/keypath.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,16 @@ func test_keypath_with_method_refs() {
811811
let _ = \A.Type.faz.bar // expected-error {{key path cannot refer to static method 'faz()'}}
812812
}
813813

814+
// SR-12519: Compiler crash on invalid method reference in key path.
815+
protocol Zonk {
816+
func wargle()
817+
}
818+
typealias Blatz = (gloop: String, zoop: Zonk?)
819+
820+
func sr12519(fleep: [Blatz]) {
821+
fleep.compactMap(\.zoop?.wargle) // expected-error {{key path cannot refer to instance method 'wargle()'}}
822+
}
823+
814824
// SR-10467 - Argument type 'KeyPath<String, Int>' does not conform to expected type 'Any'
815825
func test_keypath_in_any_context() {
816826
func foo(_: Any) {}

0 commit comments

Comments
 (0)