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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

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:

  • 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.

  • 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 the above problems. Of course this is an ABI break, however it should have limited impact since module aliases and -module-abi-name are not widely used.

Fixes rdar://147441890.

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 uses the correct module names for comparison to match
what the mangler does.

Of course this is an ABI break, however it should have limited impact
since module aliases and -module-abi-name are not widely used.

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
Copy link
Contributor Author

@swift-ci Please test Windows

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