Skip to content

Commit a689b34

Browse files
authored
Merge pull request #11061 from jckarter/static-key-path-error
Sema: Don't allow key path literals to refer to static members.
2 parents 808fb60 + 605804c commit a689b34

File tree

5 files changed

+35
-10
lines changed

5 files changed

+35
-10
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ ERROR(noescape_functiontype_mismatch,none,
422422
ERROR(expr_keypath_no_objc_runtime,none,
423423
"'#keyPath' can only be used with the Objective-C runtime", ())
424424
ERROR(expression_unused_keypath_result,none,
425-
"result of '#keyPath' is unused", ())
425+
"result of key path is unused", ())
426426
ERROR(expr_keypath_non_objc_property,none,
427427
"argument of '#keyPath' refers to non-'@objc' property %0",
428428
(DeclName))
@@ -434,14 +434,17 @@ ERROR(expr_keypath_type_of_property,none,
434434
"cannot refer to type member %0 within instance of type %1",
435435
(DeclName, Type))
436436
ERROR(expr_keypath_generic_type,none,
437-
"'#keyPath' cannot refer to generic type %0", (DeclName))
437+
"key path cannot refer to generic type %0", (DeclName))
438438
ERROR(expr_keypath_not_property,none,
439-
"'#keyPath' cannot refer to %0 %1", (DescriptiveDeclKind, DeclName))
439+
"key path cannot refer to %0 %1", (DescriptiveDeclKind, DeclName))
440440
ERROR(expr_keypath_mutating_getter,none,
441-
"'#keyPath' cannot refer to %0, which has a mutating getter",
441+
"key path cannot refer to %0, which has a mutating getter",
442+
(DeclName))
443+
ERROR(expr_keypath_static_member,none,
444+
"key path cannot refer to static member %0",
442445
(DeclName))
443446
ERROR(expr_keypath_empty,none,
444-
"empty '#keyPath' does not refer to a property", ())
447+
"empty key path does not refer to a property", ())
445448
ERROR(expr_unsupported_objc_key_path_component,none,
446449
"an Objective-C key path cannot contain "
447450
"%select{BAD|subscript|BAD|BAD|optional-forcing|optional-chaining|BAD} "
@@ -459,7 +462,7 @@ ERROR(expr_swift_keypath_not_starting_with_type,none,
459462
ERROR(expr_swift_keypath_unimplemented_component,none,
460463
"key path support for %0 components is not implemented", (StringRef))
461464
ERROR(expr_smart_keypath_value_covert_to_contextual_type,none,
462-
"KeyPath value type %0 cannot be converted to contextual type %1",
465+
"key path value type %0 cannot be converted to contextual type %1",
463466
(Type, Type))
464467
ERROR(expr_swift_keypath_empty, none,
465468
"key path must have at least one component", ())

lib/Sema/CSApply.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3992,6 +3992,13 @@ namespace {
39923992
diag::expr_keypath_mutating_getter,
39933993
property->getFullName());
39943994
}
3995+
3996+
// Key paths don't currently support static members.
3997+
if (varDecl->isStatic()) {
3998+
cs.TC.diagnose(origComponent.getLoc(),
3999+
diag::expr_keypath_static_member,
4000+
property->getFullName());
4001+
}
39954002
}
39964003

39974004
// Unwrap if we needed to look through an IUO to find the

test/Constraints/diagnostics.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -971,9 +971,9 @@ class SR_4692_b {
971971

972972
struct R32101765 { let prop32101765 = 0 }
973973
let _: KeyPath<R32101765, Float> = \.prop32101765
974-
// expected-error@-1 {{KeyPath value type 'Int' cannot be converted to contextual type 'Float'}}
974+
// expected-error@-1 {{key path value type 'Int' cannot be converted to contextual type 'Float'}}
975975
let _: KeyPath<R32101765, Float> = \R32101765.prop32101765
976-
// expected-error@-1 {{KeyPath value type 'Int' cannot be converted to contextual type 'Float'}}
976+
// expected-error@-1 {{key path value type 'Int' cannot be converted to contextual type 'Float'}}
977977
let _: KeyPath<R32101765, Float> = \.prop32101765.unknown
978978
// expected-error@-1 {{type 'Int' has no member 'unknown'}}
979979
let _: KeyPath<R32101765, Float> = \R32101765.prop32101765.unknown

test/expr/unary/keypath/keypath-objc.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ func testSemanticErrors() {
113113
let _: String = #keyPath(AnyObject.ambiguous) // expected-error{{ambiguous reference to member 'ambiguous'}}
114114
let _: String = #keyPath(C.nonObjC) // expected-error{{argument of '#keyPath' refers to non-'@objc' property 'nonObjC'}}
115115
let _: String = #keyPath(A.propArray.UTF8View) // expected-error{{type 'String' has no member 'UTF8View'}}
116-
let _: String = #keyPath(A.someMethod) // expected-error{{'#keyPath' cannot refer to instance method 'someMethod()'}}
117-
let _: String = #keyPath(A) // expected-error{{empty '#keyPath' does not refer to a property}}
116+
let _: String = #keyPath(A.someMethod) // expected-error{{key path cannot refer to instance method 'someMethod()'}}
117+
let _: String = #keyPath(A) // expected-error{{empty key path does not refer to a property}}
118118
let _: String = #keyPath(A.propDict.anyKeyName.unknown) // expected-error{{type 'B' has no member 'unknown'}}
119119
let _: String = #keyPath(A.propNSDict.anyKeyName.unknown) // expected-error{{type 'AnyObject' has no member 'unknown'}}
120120
}

test/expr/unary/keypath/keypath.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,21 @@ func testLabeledSubscript() {
364364
let _ = \AA.[keyPath: \AA.[labeled: 0]] // expected-error{{}}
365365
}
366366

367+
func testInvalidKeyPathComponents() {
368+
let _ = \.{return 0} // expected-error* {{}}
369+
}
370+
371+
class X {
372+
class var a: Int { return 1 }
373+
static var b = 2
374+
}
375+
376+
func testStaticKeyPathComponent() {
377+
_ = \X.a // expected-error{{}}
378+
_ = \X.Type.a // expected-error{{cannot refer to static member}}
379+
_ = \X.b // expected-error{{}}
380+
_ = \X.Type.b // expected-error{{cannot refer to static member}}
381+
}
367382

368383
func testSyntaxErrors() { // expected-note{{}}
369384
_ = \. ; // expected-error{{expected member name following '.'}}

0 commit comments

Comments
 (0)