Skip to content

Commit

Permalink
Merge pull request #11061 from jckarter/static-key-path-error
Browse files Browse the repository at this point in the history
Sema: Don't allow key path literals to refer to static members.
  • Loading branch information
jckarter committed Jul 19, 2017
2 parents 808fb60 + 605804c commit a689b34
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 10 deletions.
15 changes: 9 additions & 6 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ ERROR(noescape_functiontype_mismatch,none,
ERROR(expr_keypath_no_objc_runtime,none,
"'#keyPath' can only be used with the Objective-C runtime", ())
ERROR(expression_unused_keypath_result,none,
"result of '#keyPath' is unused", ())
"result of key path is unused", ())
ERROR(expr_keypath_non_objc_property,none,
"argument of '#keyPath' refers to non-'@objc' property %0",
(DeclName))
Expand All @@ -434,14 +434,17 @@ ERROR(expr_keypath_type_of_property,none,
"cannot refer to type member %0 within instance of type %1",
(DeclName, Type))
ERROR(expr_keypath_generic_type,none,
"'#keyPath' cannot refer to generic type %0", (DeclName))
"key path cannot refer to generic type %0", (DeclName))
ERROR(expr_keypath_not_property,none,
"'#keyPath' cannot refer to %0 %1", (DescriptiveDeclKind, DeclName))
"key path cannot refer to %0 %1", (DescriptiveDeclKind, DeclName))
ERROR(expr_keypath_mutating_getter,none,
"'#keyPath' cannot refer to %0, which has a mutating getter",
"key path cannot refer to %0, which has a mutating getter",
(DeclName))
ERROR(expr_keypath_static_member,none,
"key path cannot refer to static member %0",
(DeclName))
ERROR(expr_keypath_empty,none,
"empty '#keyPath' does not refer to a property", ())
"empty key path does not refer to a property", ())
ERROR(expr_unsupported_objc_key_path_component,none,
"an Objective-C key path cannot contain "
"%select{BAD|subscript|BAD|BAD|optional-forcing|optional-chaining|BAD} "
Expand All @@ -459,7 +462,7 @@ ERROR(expr_swift_keypath_not_starting_with_type,none,
ERROR(expr_swift_keypath_unimplemented_component,none,
"key path support for %0 components is not implemented", (StringRef))
ERROR(expr_smart_keypath_value_covert_to_contextual_type,none,
"KeyPath value type %0 cannot be converted to contextual type %1",
"key path value type %0 cannot be converted to contextual type %1",
(Type, Type))
ERROR(expr_swift_keypath_empty, none,
"key path must have at least one component", ())
Expand Down
7 changes: 7 additions & 0 deletions lib/Sema/CSApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3992,6 +3992,13 @@ namespace {
diag::expr_keypath_mutating_getter,
property->getFullName());
}

// Key paths don't currently support static members.
if (varDecl->isStatic()) {
cs.TC.diagnose(origComponent.getLoc(),
diag::expr_keypath_static_member,
property->getFullName());
}
}

// Unwrap if we needed to look through an IUO to find the
Expand Down
4 changes: 2 additions & 2 deletions test/Constraints/diagnostics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -971,9 +971,9 @@ class SR_4692_b {

struct R32101765 { let prop32101765 = 0 }
let _: KeyPath<R32101765, Float> = \.prop32101765
// expected-error@-1 {{KeyPath value type 'Int' cannot be converted to contextual type 'Float'}}
// expected-error@-1 {{key path value type 'Int' cannot be converted to contextual type 'Float'}}
let _: KeyPath<R32101765, Float> = \R32101765.prop32101765
// expected-error@-1 {{KeyPath value type 'Int' cannot be converted to contextual type 'Float'}}
// expected-error@-1 {{key path value type 'Int' cannot be converted to contextual type 'Float'}}
let _: KeyPath<R32101765, Float> = \.prop32101765.unknown
// expected-error@-1 {{type 'Int' has no member 'unknown'}}
let _: KeyPath<R32101765, Float> = \R32101765.prop32101765.unknown
Expand Down
4 changes: 2 additions & 2 deletions test/expr/unary/keypath/keypath-objc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ func testSemanticErrors() {
let _: String = #keyPath(AnyObject.ambiguous) // expected-error{{ambiguous reference to member 'ambiguous'}}
let _: String = #keyPath(C.nonObjC) // expected-error{{argument of '#keyPath' refers to non-'@objc' property 'nonObjC'}}
let _: String = #keyPath(A.propArray.UTF8View) // expected-error{{type 'String' has no member 'UTF8View'}}
let _: String = #keyPath(A.someMethod) // expected-error{{'#keyPath' cannot refer to instance method 'someMethod()'}}
let _: String = #keyPath(A) // expected-error{{empty '#keyPath' does not refer to a property}}
let _: String = #keyPath(A.someMethod) // expected-error{{key path cannot refer to instance method 'someMethod()'}}
let _: String = #keyPath(A) // expected-error{{empty key path does not refer to a property}}
let _: String = #keyPath(A.propDict.anyKeyName.unknown) // expected-error{{type 'B' has no member 'unknown'}}
let _: String = #keyPath(A.propNSDict.anyKeyName.unknown) // expected-error{{type 'AnyObject' has no member 'unknown'}}
}
Expand Down
15 changes: 15 additions & 0 deletions test/expr/unary/keypath/keypath.swift
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,21 @@ func testLabeledSubscript() {
let _ = \AA.[keyPath: \AA.[labeled: 0]] // expected-error{{}}
}

func testInvalidKeyPathComponents() {
let _ = \.{return 0} // expected-error* {{}}
}

class X {
class var a: Int { return 1 }
static var b = 2
}

func testStaticKeyPathComponent() {
_ = \X.a // expected-error{{}}
_ = \X.Type.a // expected-error{{cannot refer to static member}}
_ = \X.b // expected-error{{}}
_ = \X.Type.b // expected-error{{cannot refer to static member}}
}

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

0 comments on commit a689b34

Please sign in to comment.