From b3c0d8a48e6861dbdfa3fd2ee973bc176a328b9a Mon Sep 17 00:00:00 2001 From: Kavon Farvardin Date: Tue, 11 Nov 2025 14:04:03 -0800 Subject: [PATCH] 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`. (cherry picked from commit 38af19b95a145c4a7a3b7557a1f7b3d1d4f9122f) --- lib/IRGen/GenProto.cpp | 8 ++++++-- test/IRGen/keypaths_inverses.swift | 29 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 test/IRGen/keypaths_inverses.swift diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index ba8a02bb801ae..805410df1b3bf 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -4622,9 +4622,13 @@ llvm::Constant *IRGenModule::getAddrOfGenericEnvironment( } genericParamCounts.push_back(genericParamCount); + SmallVector reqs; + SmallVector 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); @@ -4651,7 +4655,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(); }); } diff --git a/test/IRGen/keypaths_inverses.swift b/test/IRGen/keypaths_inverses.swift new file mode 100644 index 0000000000000..b9b961c1e43b2 --- /dev/null +++ b/test/IRGen/keypaths_inverses.swift @@ -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: T) -> WritableKeyPath { + return \T.masher +} + +func formKeypath2(_ t: T) -> WritableKeyPath { + return \T.dasher +}