IRGen/ABI: fix count of requirements in getAddrOfGenericEnvironment

`irgen::addGenericRequirements` will later filter out Copyable
and Escapable requirements, so this field's count isn't accurate
if it's using the pre-filtered number.

This should in theory only affect the metadata emission for keypaths,
specifically, the caller `IRGenModule::getAddrOfKeyPathPattern`.
This commit is contained in:
Kavon Farvardin
2025-11-11 14:04:03 -08:00
parent b30f63530a
commit 38af19b95a
2 changed files with 35 additions and 2 deletions

View File

@@ -4665,9 +4665,13 @@ llvm::Constant *IRGenModule::getAddrOfGenericEnvironment(
}
genericParamCounts.push_back(genericParamCount);
SmallVector<Requirement, 2> reqs;
SmallVector<InverseRequirement, 2> inverses;
signature->getRequirementsWithInverses(reqs, inverses);
auto flags = GenericEnvironmentFlags()
.withNumGenericParameterLevels(genericParamCounts.size())
.withNumGenericRequirements(signature.getRequirements().size());
.withNumGenericRequirements(reqs.size());
ConstantStructBuilder fields = builder.beginStruct();
fields.setPacked(true);
@@ -4694,7 +4698,7 @@ llvm::Constant *IRGenModule::getAddrOfGenericEnvironment(
fields.addAlignmentPadding(Alignment(4));
// Generic requirements
irgen::addGenericRequirements(*this, fields, signature);
irgen::addGenericRequirements(*this, fields, signature, reqs, inverses);
return fields.finishAndCreateFuture();
});
}

View File

@@ -0,0 +1,29 @@
// RUN: %target-swift-frontend -module-name keypaths -emit-ir %s | %FileCheck %s
// The purpose of this test is to validate that a keypath formed via a protocol
// that has an inverse requirement on Self produces the same generic environment
// metadata as one without the inverse. So Mashable and Dashable should have the
// same metadata fundamentally.
// CHECK-LABEL: @"generic environment 8keypaths8MashableRzl" = linkonce_odr hidden constant
// CHECK-SAME: i32 4097, i16 1, i8 -128, [1 x i8] zeroinitializer, i32 128
// CHECK-LABEL: @"generic environment 8keypaths8DashableRzl" = linkonce_odr hidden constant
// CHECK-SAME: i32 4097, i16 1, i8 -128, [1 x i8] zeroinitializer, i32 128
protocol Mashable: ~Copyable {
var masher: String { get set }
}
protocol Dashable {
var dasher: String { get set }
}
func formKeypath1<T: Mashable>(_ t: T) -> WritableKeyPath<T, String> {
return \T.masher
}
func formKeypath2<T: Dashable>(_ t: T) -> WritableKeyPath<T, String> {
return \T.dasher
}