From 0af1279553a639854d945f01e7d0b69a2a584c80 Mon Sep 17 00:00:00 2001 From: Nate Chandler Date: Tue, 7 Oct 2025 10:50:25 -0700 Subject: [PATCH] [Mangling] Provide signature for param'd types. When a type is appended to the mangling, if that type has a type parameter, provide the relevant generic signature with it. rdar://161968922 --- .../Utils/GenericSpecializationMangler.cpp | 51 ++++++++++++++++++- .../SILOptimizer/rdar161968922.swift | 34 +++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 validation-test/SILOptimizer/rdar161968922.swift diff --git a/lib/SIL/Utils/GenericSpecializationMangler.cpp b/lib/SIL/Utils/GenericSpecializationMangler.cpp index c2ce5017ec17d..306dd9b1b70ec 100644 --- a/lib/SIL/Utils/GenericSpecializationMangler.cpp +++ b/lib/SIL/Utils/GenericSpecializationMangler.cpp @@ -14,6 +14,7 @@ #include "swift/AST/ASTContext.h" #include "swift/AST/GenericEnvironment.h" #include "swift/AST/GenericSignature.h" +#include "swift/AST/ProtocolConformance.h" #include "swift/AST/SubstitutionMap.h" #include "swift/Basic/Assertions.h" #include "swift/Demangling/ManglingMacros.h" @@ -98,7 +99,55 @@ appendSubstitutions(GenericSignature sig, SubstitutionMap subs) { auto ty = Type(ParamType); auto substTy = ty.subst(subs); auto canTy = substTy->getCanonicalType(); - appendType(canTy, nullptr); + + GenericSignature signature; + if (canTy->hasTypeParameter()) { + if (isa(canTy) || + isa(canTy)) { + signature = sig; + } else { + SmallVector requirements; + llvm::SmallSetVector params; + auto mergeComponents = [&](GenericSignature signature) { + for (auto *param : signature.getGenericParams()) { + params.insert(param); + } + for (auto req : signature.getRequirements()) { + requirements.push_back(req); + } + }; + for (auto conformance : subs.getConformances()) { + if (conformance.getType()->getCanonicalType() == canTy) { + if (!conformance.isConcrete()) { + continue; + } + auto concrete = conformance.getConcrete(); + if (auto inherited = + dyn_cast(concrete)) { + mergeComponents( + inherited->getSubstitutionMap().getGenericSignature()); + } else if (auto specialized = + dyn_cast( + concrete)) { + mergeComponents( + specialized->getSubstitutionMap().getGenericSignature()); + } else if (auto builtin = + dyn_cast(concrete)) { + mergeComponents(builtin->getGenericSignature()); + } else { + mergeComponents(concrete->getGenericSignature()); + } + } + } + if (!params.empty()) { + signature = + GenericSignature::get(params.getArrayRef(), requirements); + } + } + } + // TODO: Enable this assertion. + // assert(!canTy->hasTypeParameter() || signature); + appendType(canTy, signature); appendListSeparator(First); } }); diff --git a/validation-test/SILOptimizer/rdar161968922.swift b/validation-test/SILOptimizer/rdar161968922.swift new file mode 100644 index 0000000000000..b3613a8d03e49 --- /dev/null +++ b/validation-test/SILOptimizer/rdar161968922.swift @@ -0,0 +1,34 @@ +// RUN: %target-swift-frontend -emit-sil -debug-diagnostic-names -verify %s + +public protocol Fooable { + func foo() -> Int +} + +extension Int : Fooable { + public func foo() -> Int { + self + } +} + +extension Array: Comparable where Element: Comparable { // expected-warning{{extension_retroactive_conformance}} + // expected-note@-1{{extension_retroactive_conformance_silence}} + public static func < (lhs: Self, rhs: Self) -> Bool { + true + } +} + +extension Array : Fooable where Element : Fooable { + public func foo() -> Int { + 0 + } +} + +struct Wrapper: Hashable { + var partitions: PartitionSet> +} + +struct PartitionSet: Equatable, Hashable { + var partitions: Set> +} + +