Skip to content

Commit d4fe6e9

Browse files
committed
[Runtime] Fix a bug in handling multi-level generic environment substitutions.
1 parent cc2ee16 commit d4fe6e9

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,6 +1326,9 @@ buildEnvironmentPath(
13261326
unsigned totalKeyParamCount = 0;
13271327
auto genericParams = environment->getGenericParameters();
13281328
for (unsigned numLocalParams : environment->getGenericParameterCounts()) {
1329+
// Adkjust totalParamCount so we have the # of local parameters.
1330+
numLocalParams -= totalParamCount;
1331+
13291332
// Get the local generic parameters.
13301333
auto localGenericParams = genericParams.slice(0, numLocalParams);
13311334
genericParams = genericParams.slice(numLocalParams);

test/stdlib/KeyPath.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,34 @@ keyPath.test("optional chaining component that needs generic instantiation") {
768768
Value6096<Int>().doSomething()
769769
}
770770

771+
// Nested generics.
772+
protocol HasAssoc {
773+
associatedtype A
774+
}
775+
776+
struct Outer<T, U> {
777+
struct Middle<V, W, X> {
778+
}
779+
}
780+
781+
extension Outer.Middle where V: HasAssoc, U == V.A, W == X {
782+
struct Inner<Y: Hashable> {
783+
func foo() -> AnyKeyPath {
784+
return \[Y?: [U]].values
785+
}
786+
}
787+
}
788+
789+
extension Double: HasAssoc {
790+
typealias A = Float
791+
}
792+
793+
keyPath.test("nested generics") {
794+
let nested = Outer<Int, Float>.Middle<Double, String, String>.Inner<UInt>()
795+
let nestedKeyPath = nested.foo()
796+
typealias DictType = [UInt? : [Float]]
797+
expectTrue(nestedKeyPath is KeyPath<DictType, DictType.Values>)
798+
}
771799

772800
runAllTests()
773801

0 commit comments

Comments
 (0)