Skip to content

Commit fc632b2

Browse files
committed
Check 'unsafe' within keypaths
1 parent d6c020d commit fc632b2

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

lib/Sema/TypeCheckEffects.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,31 @@ class EffectsHandlingWalker : public ASTWalker {
613613
if (!TE->isImplicit()) {
614614
recurse = asImpl().checkType(TE, TE->getTypeRepr(), TE->getInstanceType());
615615
}
616+
} else if (auto KPE = dyn_cast<KeyPathExpr>(E)) {
617+
for (auto &component : KPE->getComponents()) {
618+
switch (component.getKind()) {
619+
case KeyPathExpr::Component::Kind::Property:
620+
case KeyPathExpr::Component::Kind::Subscript: {
621+
(void)asImpl().checkDeclRef(KPE, component.getDeclRef(),
622+
component.getLoc(),
623+
/*isImplicitlyAsync=*/false,
624+
/*isImplicitlyThrows=*/false);
625+
break;
626+
}
627+
628+
case KeyPathExpr::Component::Kind::TupleElement:
629+
case KeyPathExpr::Component::Kind::Invalid:
630+
case KeyPathExpr::Component::Kind::UnresolvedProperty:
631+
case KeyPathExpr::Component::Kind::UnresolvedSubscript:
632+
case KeyPathExpr::Component::Kind::OptionalChain:
633+
case KeyPathExpr::Component::Kind::OptionalWrap:
634+
case KeyPathExpr::Component::Kind::OptionalForce:
635+
case KeyPathExpr::Component::Kind::Identity:
636+
case KeyPathExpr::Component::Kind::DictionaryKey:
637+
case KeyPathExpr::Component::Kind::CodeCompletion:
638+
break;
639+
}
640+
}
616641
}
617642
// Error handling validation (via checkTopLevelEffects) happens after
618643
// type checking. If an unchecked expression is still around, the code was

test/Unsafe/safe.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,13 @@ func metatypes() {
124124
let _: Any.Type = unsafe UnsafeType.self
125125
}
126126

127+
func testKeyPath() {
128+
// expected-warning@+1{{expression uses unsafe constructs but is not marked with 'unsafe'}}
129+
_ = \HasProperties.computedUnsafe // expected-note{{reference to unsafe property 'computedUnsafe'}}
130+
131+
_ = unsafe \HasProperties.computedUnsafe
132+
}
133+
127134
// Parsing of `unsafe` expressions.
128135
func testUnsafePositionError() -> Int {
129136
return 3 + unsafe unsafeInt() // expected-error{{'unsafe' cannot appear to the right of a non-assignment operator}}

0 commit comments

Comments
 (0)