Skip to content

Commit 38af19b

Browse files
committed
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`.
1 parent b30f635 commit 38af19b

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

lib/IRGen/GenProto.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4665,9 +4665,13 @@ llvm::Constant *IRGenModule::getAddrOfGenericEnvironment(
46654665
}
46664666
genericParamCounts.push_back(genericParamCount);
46674667

4668+
SmallVector<Requirement, 2> reqs;
4669+
SmallVector<InverseRequirement, 2> inverses;
4670+
signature->getRequirementsWithInverses(reqs, inverses);
4671+
46684672
auto flags = GenericEnvironmentFlags()
46694673
.withNumGenericParameterLevels(genericParamCounts.size())
4670-
.withNumGenericRequirements(signature.getRequirements().size());
4674+
.withNumGenericRequirements(reqs.size());
46714675

46724676
ConstantStructBuilder fields = builder.beginStruct();
46734677
fields.setPacked(true);
@@ -4694,7 +4698,7 @@ llvm::Constant *IRGenModule::getAddrOfGenericEnvironment(
46944698
fields.addAlignmentPadding(Alignment(4));
46954699

46964700
// Generic requirements
4697-
irgen::addGenericRequirements(*this, fields, signature);
4701+
irgen::addGenericRequirements(*this, fields, signature, reqs, inverses);
46984702
return fields.finishAndCreateFuture();
46994703
});
47004704
}

test/IRGen/keypaths_inverses.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %target-swift-frontend -module-name keypaths -emit-ir %s | %FileCheck %s
2+
3+
// The purpose of this test is to validate that a keypath formed via a protocol
4+
// that has an inverse requirement on Self produces the same generic environment
5+
// metadata as one without the inverse. So Mashable and Dashable should have the
6+
// same metadata fundamentally.
7+
8+
// CHECK-LABEL: @"generic environment 8keypaths8MashableRzl" = linkonce_odr hidden constant
9+
// CHECK-SAME: i32 4097, i16 1, i8 -128, [1 x i8] zeroinitializer, i32 128
10+
11+
// CHECK-LABEL: @"generic environment 8keypaths8DashableRzl" = linkonce_odr hidden constant
12+
// CHECK-SAME: i32 4097, i16 1, i8 -128, [1 x i8] zeroinitializer, i32 128
13+
14+
15+
protocol Mashable: ~Copyable {
16+
var masher: String { get set }
17+
}
18+
19+
protocol Dashable {
20+
var dasher: String { get set }
21+
}
22+
23+
func formKeypath1<T: Mashable>(_ t: T) -> WritableKeyPath<T, String> {
24+
return \T.masher
25+
}
26+
27+
func formKeypath2<T: Dashable>(_ t: T) -> WritableKeyPath<T, String> {
28+
return \T.dasher
29+
}

0 commit comments

Comments
 (0)