Skip to content
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

AST: Fix a problem with the protocol order #80213

Merged
merged 2 commits into from
Mar 28, 2025

Conversation

slavapestov
Copy link
Contributor

@slavapestov slavapestov commented Mar 21, 2025

The last step in building a generic signature is to sort the requirements. Requirements are sorted by comparing their subject types. If two requirements have the same subject type, which can only happen with conformance requirements, we break the tie by comparing protocol declarations.

We compare protocol declarations using TypeDecl::compare(), which is a shortlex order on the components of the fully qualified name of a protocol (eg, Swift.Sequence, etc.)

Ultimately, the protocol order determines mangled symbol names, the order of witness table arguments in the calling convention, the layout of existentials, and so on. While this order is part of the ABI, it has not been updated over the years for several important changes:

  1. It did not handle module aliases; if we import a module via an alias, we should use the real module name to compare protocols, and not the aliased name. This produced inconsistent results if the same module was imported under different names, which can happen with module interface files that use module aliases.

  2. It did not handle the -module-abi-name flag. Changing the ABI name of a module changes how we mangle protocol names, and the order should match the mangling.

  3. It did not use the original module name specified in the @_originallyDefinedIn flag, so moving a protocol between modules would change its position in the order.

This PR fixes 1) and 3), but not 2).

Fixes rdar://147441890.

@slavapestov slavapestov force-pushed the protocol-order-fix branch 2 times, most recently from 5c97d9c to 2dc2cd0 Compare March 24, 2025 20:34
The last step in building a generic signature is to sort the requirements.
Requirements are sorted by comparing their subject types. If two
requirements have the same subject type, which can only happen with
conformance requirements, we break the tie by comparing protocol
declarations.

We compare protocol declarations using TypeDecl::compare(), which is a
shortlex order on the components of the fully qualified name of a
protocol (eg, Swift.Sequence, etc.)

While this order is part of the ABI, it has not been updated over the
years for several important changes:

- It did not handle module aliases; if we import a module via an
  alias, we should use the real module name to compare protocols, and
  not the aliased name. This produced inconsistent results if the
  same module was imported under different names, which can happen
  with module interface files that use module aliases.

- It did not handle the -module-abi-name flag. Changing the ABI name
  of a module changes how we mangle protocol names, and the order
  should match the mangling.

This change fixes the first case only. The second requires more
careful staging, because of _Concurrency and CompilerSwiftSyntax.

Fixes rdar://147441890.
If a protocol was moved from one module to another, we need to
continue using the old module name when comparing it against
other protocols.
@slavapestov
Copy link
Contributor Author

@swift-ci Please test

@slavapestov
Copy link
Contributor Author

@swift-ci Please test source compatibility

@slavapestov slavapestov merged commit dec124e into swiftlang:main Mar 28, 2025
6 of 7 checks passed
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.

2 participants