You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Key path expressions access properties dynamically. They are declared with a concrete root type and one or more key path components that define a path to a resulting value via the type’s properties, subscripts, optional-chaining expressions, forced unwrapped expressions, or self. This proposal expands key path expression access to include static properties of a type, i.e., metatype keypaths.
12
+
Key path expressions access properties dynamically. They are declared with a concrete root type and one or more key path components that define a path to a resulting value via the type’s properties, subscripts, optional-chaining expressions, forced unwrapped expressions, or self. This proposal expands key path expression access to include static properties of a type, i.e., metatype key paths.
13
13
14
14
## Motivation
15
15
16
-
Metatype keypaths were briefly explored in the pitch for [SE-0254](https://forums.swift.org/t/pitch-static-and-class-subscripts/21850) and the [proposal](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0254-static-subscripts.md#metatype-key-paths) later recommended them as a future direction. Allowing key path expressions to directly refer to static properties has also been discussed on the Swift Forums for database lookups when used [in conjunction with @dynamicMemberLookup](https://forums.swift.org/t/dynamic-key-path-member-lookup-cannot-refer-to-static-member/30212) and as a way to avoid verbose hacks like [referring to a static property through another computed property](https://forums.swift.org/t/key-path-cannot-refer-to-static-member/28055). Supporting metatype keypaths in the Swift language will address these challenges and improve language semantics.
16
+
Metatype key paths were briefly explored in the pitch for [SE-0254](https://forums.swift.org/t/pitch-static-and-class-subscripts/21850) and the [proposal](https://github.com/apple/swift-evolution/blob/main/proposals/0254-static-subscripts.md#metatype-key-paths) later recommended them as a future direction. Allowing key path expressions to directly refer to static properties has also been discussed on the Swift Forums for database lookups when used [in conjunction with @dynamicMemberLookup](https://forums.swift.org/t/dynamic-key-path-member-lookup-cannot-refer-to-static-member/30212) and as a way to avoid verbose hacks like [referring to a static property through another computed property](https://forums.swift.org/t/key-path-cannot-refer-to-static-member/28055). Supporting metatype key paths in the Swift language will address these challenges and improve language semantics.
17
17
18
18
## Proposed solution
19
19
20
-
We propose to allow keypath expressions to define a reference to static properties. The following usage, which currently generates a compiler error, will be allowed as valid Swift code.
20
+
We propose to allow key path expressions to define a reference to static properties. The following usage, which currently generates a compiler error, will be allowed as valid Swift code.
21
21
22
22
```swift
23
23
structBee {
@@ -31,7 +31,7 @@ let kp = \Bee.Type.name
31
31
32
32
### Metatype syntax
33
33
34
-
Keypath expressions where the first component refers to a static property will include `.Type` on their root types stated in the key path contextual type or in the key path literal. For example:
34
+
Key path expressions where the first component refers to a static property will include `.Type` on their root types stated in the key path contextual type or in the key path literal. For example:
let kpWithLiteral = \Bee.Type.name// key path literal \Bee.Type
43
43
```
44
44
45
-
Attempting to write the above metatype keypath without including `.Type will trigger an error diagnostic:
45
+
Attempting to write the above metatype key path without including `.Type` will trigger an error diagnostic with a fix-it recommending the addition of `Type` after the root type `Bee`:
46
46
47
47
```swift
48
48
let kpWithLiteral = \Bee.name// error: static member 'name' cannot be used on instance of type 'Bee'
49
49
```
50
50
51
-
Keypath expressions where the component referencing a static property is not the first component do not require `.Type`:
51
+
Key path expressions where the component referencing a static property is not the first component do not require `.Type`:
52
52
```swift
53
53
structSpecies {
54
54
staticlet isNative =true
@@ -62,7 +62,7 @@ let kpSecondComponentIsStatic = \Wasp.species.isNative
62
62
```
63
63
### Access semantics
64
64
65
-
Immutable static properties will form the read-only keypaths just like immutable instance properties.
65
+
Immutable static properties will form the read-only key paths just like immutable instance properties.
66
66
```swift
67
67
structTip {
68
68
staticlet isIncluded = True
@@ -72,7 +72,7 @@ struct Tip {
72
72
let kpStaticImmutable: KeyPath<Tip.Type, Bool> = \.isIncluded
73
73
let kpInstanceImmutable: KeyPath<Tip, Bool> = \.isVoluntary
74
74
```
75
-
However, unlike instance members, keypaths to mutable static properties will always conform to `ReferenceWritableKeyPath` because metatypes are reference types.
75
+
However, unlike instance members, key paths to mutable static properties will always conform to `ReferenceWritableKeyPath` because metatypes are reference types.
76
76
```swift
77
77
structTip {
78
78
staticvar total =0
@@ -84,7 +84,7 @@ let kpInstanceMutable: WriteableKeyPath<Tip, Int> = \.flatRate
84
84
```
85
85
## Effect on source compatibility
86
86
87
-
This feature breaks source compatibility for key path expressions that reference static properties after subscript overloads. For example, the compiler cannot differentiate between subscript keypath components by return type in the following:
87
+
This feature breaks source compatibility for key path expressions that reference static properties after subscript overloads. For example, the compiler cannot differentiate between subscript key path components by return type in the following:
88
88
89
89
```swift
90
90
structS {
@@ -99,7 +99,7 @@ struct Test {
99
99
let kpViaSubscript = \Test.[42] // fails to typecheck
100
100
```
101
101
102
-
This keypath does not specify a contextual type, without which the key path value type is unknown. To form a keypath to the metatype subscript and return an `Int`, we can specify a contextual type with a value type of `S.Type` and chain the metatype keypath:
102
+
This key path does not specify a contextual type, without which the key path value type is unknown. To form a key path to the metatype subscript and return an `Int`, we can specify a contextual type with a value type of `S.Type` and chain the metatype key path:
103
103
104
104
```swift
105
105
let kpViaSubscript: KeyPath<Test, S.Type> = \Test.[42]
@@ -125,11 +125,11 @@ note: rebuild <Module> to enable the feature
125
125
126
126
## Future directions
127
127
128
-
### Key Paths to Enum cases
128
+
### Key paths to enum cases
129
129
130
130
Adding language support for read-only key paths to enum cases has been widely discussed on the [Swift Forums](https://forums.swift.org/t/enum-case-key-paths-an-update/68436) but has been left out of this proposal as this merits a separate discussion around [syntax design and implementation concerns](https://forums.swift.org/t/enum-case-keypaths/60899/32).
131
131
132
-
Since references to enum cases must be metatypes, extending keypath expressions to include references to metatypes will hopefully bring the Swift language closer to adopting keypaths to enum cases in a future pitch.
132
+
Since references to enum cases must be metatypes, extending key path expressions to include references to metatypes will hopefully bring the Swift language closer to adopting key paths to enum cases in a future pitch.
0 commit comments