IRGen: Fix crash trying to emit capture descriptor involving element archetype

We could encode local archetypes in reflection info by performing the
local archetype transform, to get an extended generic signature together
with substitutions for the added generic parameters.

However, for now, let's just not crash. This generalizes an earlier hack
for opened existential archetypes. Instead of replacing them with
nonsensical type parameters though, let's just not emit the whole
descriptor.

- Fixes https://github.com/swiftlang/swift/issues/83539.
- Fixes rdar://157554723.
This commit is contained in:
Slava Pestov
2025-08-25 12:41:08 -04:00
parent ec394840b7
commit 831043c132
3 changed files with 18 additions and 18 deletions

View File

@@ -1576,24 +1576,6 @@ public:
boxedInterfaceType = boxedType.mapTypeOutOfContext();
}
{
// FIXME: This seems wrong. We used to just mangle opened archetypes as
// their interface type. Let's make that explicit now.
auto astType = boxedInterfaceType.getASTType();
astType =
astType
.transformRec([](Type t) -> std::optional<Type> {
if (auto *openedExistential = t->getAs<ExistentialArchetypeType>()) {
auto &ctx = openedExistential->getASTContext();
return ctx.TheSelfType;
}
return std::nullopt;
})
->getCanonicalType();
boxedInterfaceType = SILType::getPrimitiveType(
astType, boxedInterfaceType.getCategory());
}
auto boxDescriptor = IGF.IGM.getAddrOfBoxDescriptor(
boxedInterfaceType,
env ? env->getGenericSignature().getCanonicalSignature()

View File

@@ -1693,6 +1693,9 @@ llvm::Constant *IRGenModule::getAddrOfFieldName(StringRef Name) {
llvm::Constant *
IRGenModule::getAddrOfBoxDescriptor(SILType BoxedType,
CanGenericSignature genericSig) {
if (BoxedType.hasLocalArchetype())
return llvm::Constant::getNullValue(CaptureDescriptorPtrTy);
if (IRGen.Opts.ReflectionMetadata != ReflectionMetadataMode::Runtime)
return llvm::Constant::getNullValue(CaptureDescriptorPtrTy);

View File

@@ -0,0 +1,15 @@
// RUN: %target-swift-frontend -emit-ir %s -target %target-swift-5.9-abi-triple
public protocol P {}
public struct G<T>: P {
let s1: String
let s2: String
}
public func f<each T>(t: repeat G<each T>) {
var ts: [any P] = []
for x in repeat each t {
ts.append(x)
}
}