Skip to content

[c-interop] Make Extern a suppressible language feature #70852

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 12, 2024

Conversation

tshortli
Copy link
Contributor

Fixes building the standard library's .swiftinterface with older Swift compilers.

@tshortli
Copy link
Contributor Author

Addresses regression from #69352.

@tshortli tshortli changed the title [c-interop] Make Extern a suppressible language feature. [c-interop] Make Extern a suppressible language feature Jan 11, 2024
@tshortli
Copy link
Contributor Author

@swift-ci please smoke test

@kateinoigakukun
Copy link
Member

kateinoigakukun commented Jan 11, 2024

@tshortli Thank you for fixing this 🙏 I don't know when older compiler parses newer stdlib's module interface, but is it safe to change the symbol name by suppressing the attribute depending on whether the compiler supports the feature?

Looks like other suppressible language features are not ABI-affecting features but @_extern is.

@tshortli
Copy link
Contributor Author

As a rule of thumb, the most recently released Swift compiler toolchain should be able to successfully compile the Standard library module from its .swiftinterface. This is needed to support workflows where users have an older, stable toolchain installed but update to more recent SDKs with a newer standard library. The most important aspect of supporting this workflow is simply that the interface is buildable (that is, it typechecks and serializes successfully). Generally speaking, newly added language or stdlib features don't need to work in this configuration, they just need to not prevent the module from building.

@tshortli
Copy link
Contributor Author

tshortli commented Jan 11, 2024

If @_extern here affects the ABI of something that was existing and therefore users in this configuration might actually depend on then I suppose your concern is valid. If that's the case I'm afraid we need to revert #69352 and go back to the drawing board with how to implement it in a way that does not break the stdlib interface for older compilers.

@tshortli tshortli requested a review from mikeash January 11, 2024 19:44
@kateinoigakukun
Copy link
Member

kateinoigakukun commented Jan 11, 2024

Thanks for your detailed explanation. Those functions attributed with @_extern are only referenced from debugger, so hopefully it just breaks LLDB's language swift refcount command. To avoid the breakage, I think the safest way would be to keep the old wrong (but works on most platforms) way like below:

#if compiler(>=5.3) && $Extern
@_extern(c, "swift_retainCount")
#else
@_silgen_name("swift_retainCount")
#endif
@usableFromInline
internal func _swift_retainCount(_: UnsafeMutableRawPointer) -> Int

@tshortli
Copy link
Contributor Author

It looks to me like the functions that gained @_extern(c) in #69352 are only the retainCount family of functions, which are only ever used from the debugger right? If that's the case, I'm inclined to say that it's unfortunate but not a showstopper that they be broken in the configuration where an older compiler is being used. However, we should fix this properly in a follow up. It looks to me like maybe a proper fix for this would be to print the @_silgen_name(<name>) attribute instead of @_extern(c, <name>) for the branch where the @_extern attribute is not supported. Does that make sense? It seems like it would return things to the status quo from before #69352.

Copy link
Member

@lorentey lorentey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thank you for following up on this. 👍

@kateinoigakukun
Copy link
Member

kateinoigakukun commented Jan 11, 2024

It looks to me like the functions that gained @_extern(c) in #69352 are only the retainCount family of functions, which are only ever used from the debugger right?

Yes, that's correct.

If that's the case, I'm inclined to say that it's unfortunate but not a showstopper that they be broken in the configuration where an older compiler is being used.

Yeah, that's reasonable. If it's not critical path, I think we can accept the breakage.

It looks to me like maybe a proper fix for this would be to print the @_silgen_name() attribute instead of @_extern(c, ) for the branch where the @_extern attribute is not supported. Does that make sense?

Hmm, they have slightly different ABI semantics and we can expect there is no other usage of @_extern except for stdlib at the moment, so falling back as a part of compiler output might be too much.

Anyway, this approach seems reasonable to me. Thanks again!

@tshortli
Copy link
Contributor Author

@swift-ci please smoke test macOS

@tshortli
Copy link
Contributor Author

@swift-ci please smoke test Linux

Fixes building the standard library's .swiftinterface with older Swift
compilers.
@tshortli tshortli force-pushed the suppressible-extern-feature branch from 3dad7b5 to ba1f50f Compare January 11, 2024 21:54
@tshortli
Copy link
Contributor Author

@swift-ci please smoke test

@tshortli tshortli enabled auto-merge January 11, 2024 23:35
@tshortli tshortli merged commit 04ca86b into swiftlang:main Jan 12, 2024
@tshortli tshortli deleted the suppressible-extern-feature branch January 12, 2024 00:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants