Apologies for not addressing these concerns earlier.
Let me try to do that now, and if the explanation makes sense I'll update the proposal accordingly.
What metadata does Swift 5 currently include for all types that Swift 6 will make opt-in? The existing flags are not documented and not very well known, so this is knowledge you can't expect reviewers to have.
I perhaps need to add more details to the proposal explaining different kinds of metadata and what information reflection metadata contains.
But in general, there are two levels of metadata:
- Core metadata, such as the type metadata record, nominal type descriptor, etc.
- Reflection metadata which contains information about fields' types and their names. (Data from swift5_fieldmd section of a binary)
Core metadata will be emitted in full and not affected by this proposal, while Reflection metadata will be emitted only for types that conform to Reflectable protocol or for debug builds.
(In particular, I would hope that the names of non-Reflectable types would not appear in the final binary, and this proposal does not tell me if that is the case.)
Type names are kept in "nominal type descriptor" which isn't a part of this proposal.
What stdlib APIs (and perhaps Foundation APIs, as part of corelibs) will behave differently on non-Reflectable types? In particular, if a type is used with NSCoding, even as a generic parameter, it must be findable by name later, which would be a migration hazard going from Swift 5 to Swift 6 that could result in the loss of user data.
We decided not to include changes in stdlib in the proposal, because all current API that consumes reflection are kinda for debug purposes and developers shouldn't rely on the output of those APIs. (But might be proposed separately)
Foundation APIs, as far as I am aware, it doesn't know about Swift's reflection and won't be affected.
What happens when I compile in release mode with full debug info? Does my debugging experience suffer? (more than it does today)
By full debug info did you mean an arg from -g
family?
I didn't consider that case, and probably it makes sense to keep reflection emission enabled for at least ASTTypes
and DwarfTypes
debug options.
I also think not supporting the Reflectable casts on older OSs makes this tricky to adopt on the consumer side, but maybe it's okay because you're not proposing to add bounds to existing stdlib APIs, which will have some sensible fallback (like "no children") for non-Reflectable types on new and old OSs. Still, I know our dynamic cast system is hookable, and it may be that on older OSs you can use something like "has no name" as a proxy for non-Reflectable.
We considered backporting the Reflectable casts, but wouldn't want to introduce a compatibility library only for that case. I also don't think this feature will be critical since not many libraries consume reflection nowadays.
A thought I've just had now: what reflection metadata is generated for imported types? Do we have any hope of controlling that?
No, that topic was raised already in the thread and it doesn't seem reasonable to generate reflection for imported types.
I'll mention explicitly in the proposal that conformance to Reflectable is allowed only at the type declaration level, not at the extension level.