Merge pull request #80213 from slavapestov/protocol-order-fix

AST: Fix a problem with the protocol order
This commit is contained in:
Slava Pestov
2025-03-28 07:37:00 -04:00
committed by GitHub
4 changed files with 66 additions and 3 deletions

View File

@@ -15,6 +15,7 @@
//
//===----------------------------------------------------------------------===//
#include "swift/Strings.h"
#include "swift/AST/Decl.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTMangler.h"
@@ -5434,9 +5435,29 @@ int TypeDecl::compare(const TypeDecl *type1, const TypeDecl *type2) {
// Prefer module names earlier in the alphabet.
if (dc1->isModuleScopeContext() && dc2->isModuleScopeContext()) {
auto module1 = dc1->getParentModule();
auto module2 = dc2->getParentModule();
if (int result = module1->getName().str().compare(module2->getName().str()))
// For protocol declarations specifically, the order here is part
// of the ABI, and so we must take care to get the correct module
// name for the comparison.
auto getModuleNameForOrder = [&](const TypeDecl *decl) -> StringRef {
// Respect @_originallyDefinedIn on the type itself, so that
// moving a protocol across modules does not change its
// position in the order.
auto alternateName = decl->getAlternateModuleName();
if (!alternateName.empty())
return alternateName;
// This used to just call getName(), which caused accidental ABI breaks
// when a module is imported under different aliases.
//
// Ideally, we would use getABIName() here. However, this would
// cause ABI breaks with the _Concurrency and CompilerSwiftSyntax
// builds, which already passed in a -module-abi-name but had
// existing symbols mangled with the wrong order.
auto *module = decl->getDeclContext()->getParentModule();
return module->getRealName().str();
};
if (int result = getModuleNameForOrder(type1).compare(getModuleNameForOrder(type2)))
return result;
}