Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions lib/IRGen/GenProto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do the other callers of the three-argument overload need to be audited to see if they need the same fix? Maybe it should be removed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing it is probably a good idea; it's too easy to misuse the 3-argument version.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I can do that.

Copy link
Member Author

@kavon kavon Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's worth doing the auditing in a follow-up PR. I didn't see any other obvious mistakes in other callers of the 3 argument version.

return fields.finishAndCreateFuture();
});
}
29 changes: 29 additions & 0 deletions test/IRGen/keypaths_inverses.swift
Original file line number Diff line number Diff line change
@@ -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
}