# SE-0438: Metatype keypaths

**URL:** <https://forums.swift.org/t/se-0438-metatype-keypaths/72172>\
**Category:** Proposal Reviews\
**Created:** [May 30, 2024, 4:55pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172 "2024-05-30T16:55:59Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [May 30, 2024, 4:55pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/1 "2024-05-30T16:55:59Z")

</div>

Hi everyone. The review of [SE-0438: Metatype keypaths](https://github.com/apple/swift-evolution/blob/main/proposals/0438-metatype-keypath.md) begins now and runs through June 13th, 2024.

Reviews are an important part of the Swift evolution process. All review feedback should be either on this forum thread or, if you would like to keep your feedback private, directly to me as the review manager, either by [DM](https://forums.swift.org/u/Joe_Groff/summary) or [email](mailto:jgroff@apple.com). When contacting the review manager directly, please put "SE-0438" in the subject line.

#### What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

- What is your evaluation of the proposal?
- Is the problem being addressed significant enough to warrant a change to Swift?
- Does this proposal fit well with the feel and direction of Swift?
- If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
- How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

> [swift-evolution/process.md at main · apple/swift-evolution · GitHub](https://github.com/apple/swift-evolution/blob/main/process.md)

Thank you for helping to evolve Swift!

Joe Groff  
Review Manager

---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [May 30, 2024, 5:01pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/2 "2024-05-30T17:01:10Z")

</div>

Pinned globally on May 30, 2024, 5:01pm UTC



---

<div class="post-metadata">

**Author:** ![grynspan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/grynspan/32/15315_2.png) [@grynspan](https://forums.swift.org/u/grynspan)\
**Post date:** [May 30, 2024, 10:17pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/3 "2024-05-30T22:17:12Z")

</div>

We'd love to adopt this in swift-testing to enhance some of our features such as the `@Tag` macro.

If I misspecify `\T.staticProperty` instead of `\T.Type.staticProperty`, it seems to me that a Fix-It is trivially applicable, so I'd like to see one added to the emitted diagnostic. (If one's already there, yay!)

---

<div class="post-metadata">

**Author:** ![davedelong](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/davedelong/32/38708_2.png) [@davedelong](https://forums.swift.org/u/davedelong)\
**Post date:** [May 30, 2024, 10:25pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/4 "2024-05-30T22:25:52Z")

</div>

+1 finally.gif

I'm very excited to see this come, as it fills one of the gaping holes in keypath APIs. I can think of a half-dozen immediate uses I'll have for it.

---

<div class="post-metadata">

**Author:** ![Alc](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/alc/32/33654_2.png) [@Alc](https://forums.swift.org/u/Alc)\
**Post date:** [May 31, 2024, 1:19am UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/5 "2024-05-31T01:19:52Z")

</div>

> Keypath expressions where the component referencing a static property is not the first component do not require .Type

`let kpSecondComponentIsStatic = \Wasp.species.isNative`

The lack of symmetry here seems less intuitive to me, is this behavior intuitive for experienced Swift programmers?

PS: I'm still learning Swift, so this comment comes from a place of curiosity and a desire to understand. Apologies if this question seems simplistic or obvious.

Edit: On second thoughts, this does seem natural considering `Wasp().species.isNative` is how one would normally (without keypaths) access this. I should probably delete this comment, but I will leave this for posterity. 🙃

---

<div class="post-metadata">

**Author:** ![stardustWK](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stardustwk/32/5402_2.png) [@stardustWK](https://forums.swift.org/u/stardustWK)\
**Post date:** [May 31, 2024, 2:01am UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/6 "2024-05-31T02:01:48Z")

</div>

May be this is off topic  
I have noticed that the spelling or phrasing of `KeyPath` varies in swift-evolution. Should these variations be standardized?

It has so many variants: `KeyPath(s)`, `Key Path`, `key path(s)`, `key-path`, `Keypath`, `Key path`.

[SE-0161 Smart KeyPaths: Better Key-Value Coding for Swift](https://github.com/apple/swift-evolution/blob/main/proposals/0161-key-paths.md)  
The title uses the spelling `KeyPaths`, the proposal content includes `Key Path`.

[SE-0062 Referencing Objective-C key-paths](https://github.com/apple/swift-evolution/blob/main/proposals/0062-objc-keypaths.md)  
The title uses `key-paths`, while the proposal content includes `key paths` and `key-paths`.

This proposal also includes the variant `Keypath`.

---

<div class="post-metadata">

**Author:** ![Vinicius\_Vendramini](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vinicius_vendramini/32/12370_2.png) [@Vinicius\_Vendramini](https://forums.swift.org/u/Vinicius_Vendramini)\
**Post date:** [May 31, 2024, 12:42pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/7 "2024-05-31T12:42:14Z")

</div>

> [@Alc](#):
>
> The lack of symmetry here seems less intuitive to me, is this behavior intuitive for experienced Swift programmers?

I agree, what’s the motivation behind this? And wouldn’t it ambiguous if there was also a `isNative` instance variable in the struct? How would we differentiate a keypath to the static variable from a keypath to the instance variable?

---

<div class="post-metadata">

**Author:** ![Slava\_Pestov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slava_pestov/32/30204_2.png) [@Slava\_Pestov](https://forums.swift.org/u/Slava_Pestov)\
**Post date:** [May 31, 2024, 7:47pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/8 "2024-05-31T19:47:22Z")

</div>

I saw this part in the proposal:

> ### ABI compatibility / Implications on adoption
> 
> This feature does not affect ABI compatibility and has no implications on adoption.

However looking at the implementation PR, I see that we now emit more public symbols when we compile a binary, namely property descriptors for static properties.

Does this mean that I can only form a static keypath to a property declared within a module that was built with a sufficiently new compiler? Is the failure mode a linker error? We don't have a way to statically check this kind of availability, but perhaps it should be documented in the proposal.

---

<div class="post-metadata">

**Author:** ![xedin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/xedin/32/309_2.png) [@xedin](https://forums.swift.org/u/xedin)\
**Post date:** [May 31, 2024, 11:14pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/9 "2024-05-31T23:14:54Z")

</div>

> Does this mean that I can only form a static keypath to a property declared within a module that was built with a sufficiently new compiler?

Yeah, it turns out this is how weak linking works, there has to be a symbol during build... We have a test-case in the PR that builds module with a new compiler first and then with an old version that doesn't support these descriptors and then runs clients with the old version of the library.

I agree that it should be mentioned, we had that in the draft but then it got lost...

---

<div class="post-metadata">

**Author:** ![gwendal.roue](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/gwendal.roue/32/13992_2.png) [@gwendal.roue](https://forums.swift.org/u/gwendal.roue)\
**Post date:** [May 31, 2024, 11:28pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/10 "2024-05-31T23:28:58Z")

</div>

I'lm happy that this hole  
Is finally completed. I'm still morally shocked that incomplete features can ship. Of course it's good that partial features ship, and that they are eventually completed. Yet I can't be satisfied with the spirit than accepts such unfisnished job to lay for so long. Thank you, but not 100%.

---

<div class="post-metadata">

**Author:** ![filip-sakel](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/filip-sakel/32/8697_2.png) [@filip-sakel](https://forums.swift.org/u/filip-sakel)\
**Post date:** [June 2, 2024, 5:58am UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/11 "2024-06-02T05:58:21Z")

</div>

Could we perhaps use availability annotations in some way? Because unless a user is tinkering with the linker themselves, I think encountering an error at link time is quite surprising.

---

<div class="post-metadata">

**Author:** ![xedin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/xedin/32/309_2.png) [@xedin](https://forums.swift.org/u/xedin)\
**Post date:** [June 2, 2024, 7:34am UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/12 "2024-06-02T07:34:49Z")

</div>

That is something we considered but couldn’t find an appropriate way to express because, as Slava mentioned, we don’t know whether the symbol is going to be there or not until link time. I think to do something like that we’d need this feature to be attached to some future language mode (cannot use Swift 6) that we could use to determine whether a swiftmodule is new enough to support property descriptors for static properties. This would limit adoption but might be more user-friendly.

---

<div class="post-metadata">

**Author:** ![tshortli](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tshortli/32/15850_2.png) [@tshortli](https://forums.swift.org/u/tshortli)\
**Post date:** [June 2, 2024, 4:45pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/13 "2024-06-02T16:45:34Z")

</div>

The version of the compiler that built the module is embedded in each of the representations of the module. Could we check whether the module was built with a compiler that has version 6.0 or greater, and then diagnose the use of these keypaths if the module come from doesn't support them?

---

<div class="post-metadata">

**Author:** ![xedin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/xedin/32/309_2.png) [@xedin](https://forums.swift.org/u/xedin)\
**Post date:** [June 2, 2024, 5:06pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/14 "2024-06-02T17:06:04Z")

</div>

That is not sufficient because not all of the modules produced by swift 6 compiler would have this available.

---

<div class="post-metadata">

**Author:** ![tshortli](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tshortli/32/15850_2.png) [@tshortli](https://forums.swift.org/u/tshortli)\
**Post date:** [June 2, 2024, 5:12pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/15 "2024-06-02T17:12:19Z")

</div>

> That is not sufficient because not all of the modules produced by swift 6 compiler would have this available.

Can you elaborate on that? What are the conditions under which a Swift 6 compiler won't produce these symbols?

---

<div class="post-metadata">

**Author:** ![xedin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/xedin/32/309_2.png) [@xedin](https://forums.swift.org/u/xedin)\
**Post date:** [June 2, 2024, 5:15pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/16 "2024-06-02T17:15:41Z")

</div>

The changes are not in yet on main and they won’t be merged into 6.0 even if this is accepted.

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [June 2, 2024, 5:20pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/17 "2024-06-02T17:20:48Z")

</div>

Could this change include an increment to `SWIFTMODULE_VERSION_MINOR` and the logic could be based around that? There's no expectation that modules from 6.0 would be compatible with 6.x where x \> 0 anyway.

Edit: On second thought, I might have misunderstood the problem, since we wouldn't be compiling 6.0 modules together with 6.x modules anyway. Does that mean the information would need to be in the object files, not the modules?

---

<div class="post-metadata">

**Author:** ![xedin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/xedin/32/309_2.png) [@xedin](https://forums.swift.org/u/xedin)\
**Post date:** [June 2, 2024, 5:23pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/18 "2024-06-02T17:23:27Z")

</div>

I think we might be better off limiting it to next swift language mode as I suggested in my previous post, I am not sure whether it’s a good idea to conditionalize it on such implementation details, was there a precedent for that?

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [June 2, 2024, 5:30pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/19 "2024-06-02T17:30:18Z")

</div>

So, I'm trying to make sure I fully understand the conditions where this is an issue. At first I thought it was the case above, but I guess if you're building everything from source, it's not going to matter because you're either using a compiler that doesn't have this feature, or you're using a newer one that does, for the _entire build_.

But the case that's problematic is if you have a binary framework + .swiftinterface that was built with an older compiler, and you're consuming it with a newer compiler and trying to use a static keypath into the older framework, right? In that case, since the compiler still has to compile the .swiftinterface file, can we either:

1. Use information written in the .swiftinterface file to determine whether the compiler that produced it was new enough
2. Emit the static keypath symbols directly into the client based on what's present in the .swiftinterface file?

---

<div class="post-metadata">

**Author:** ![tshortli](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tshortli/32/15850_2.png) [@tshortli](https://forums.swift.org/u/tshortli)\
**Post date:** [June 2, 2024, 5:36pm UTC](https://forums.swift.org/t/se-0438-metatype-keypaths/72172/20 "2024-06-02T17:36:46Z")

</div>

> The changes are not in yet on main and they won’t be merged into 6.0 even if this is accepted.

We can gate it on whichever version of the compiler actually implements the feature. To me, the suggestion is just meant to be a minor enhancement to the development experience. Instead of a link time failure, you can get a clear diagnostic at compile time if it's not going to work. Limiting the feature to a future language version also works, but it seems unnecessarily strict to me. Both approaches are roughly the same technically speaking; the only difference is whether it is the language mode or the compiler version that is read from the module to be used in the determination of whether the capability is present. Language version here is just a course-grained proxy for version of the compiler in for the purposes of this diagnostic.

[Next page](https://forums.swift.org/t/se-0438-metatype-keypaths/72172.md?page=2)
