Skip to content

Commit 5ad4fa8

Browse files
committed
SIL: Don't canonicalize struct field and enum element types against the wrong signature
The replacement types of the substitution map are either going to be contextual types, or interface types using some generic signature. There is no requirement that this generic signature is the generic signature of the type declaration itself. By using the generic signature of the type declaration, we could incorrectly canonicalize generic parameters to concrete types if the type itself was defined in a constrained extension, as in the test case here. Fixes <rdar://problem/65272763>.
1 parent 207033e commit 5ad4fa8

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1304,7 +1304,7 @@ class SubstFunctionTypeCollector {
13041304
if (origContextType->hasTypeParameter()) {
13051305
origContextType = origSig->getGenericEnvironment()
13061306
->mapTypeIntoContext(origContextType)
1307-
->getCanonicalType(origSig);
1307+
->getCanonicalType();
13081308
}
13091309

13101310
auto result = origContextType

lib/SIL/IR/TypeLowering.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,7 +1623,7 @@ namespace {
16231623
for (auto field : D->getStoredProperties()) {
16241624
auto substFieldType =
16251625
field->getInterfaceType().subst(subMap)
1626-
->getCanonicalType(D->getGenericSignature());
1626+
->getCanonicalType();
16271627

16281628
// We are determining the recursive properties of the struct here,
16291629
// not the lowered types of the fields, so instead of lowering the
@@ -1676,7 +1676,7 @@ namespace {
16761676

16771677
auto substEltType =
16781678
elt->getArgumentInterfaceType().subst(subMap)
1679-
->getCanonicalType(D->getGenericSignature());
1679+
->getCanonicalType();
16801680

16811681
auto origEltType = origType.unsafeGetSubstFieldType(elt,
16821682
elt->getArgumentInterfaceType()
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %target-swift-frontend -emit-ir %s
2+
3+
public struct S1<T1> {}
4+
public extension S1 where T1 == Int {
5+
public struct S2<T2> {
6+
let value: T2
7+
8+
public init(value: T2) {
9+
self.value = value
10+
}
11+
}
12+
13+
public init<T>(s: [S2<T>]) {
14+
self.init()
15+
16+
s.forEach { _ in
17+
18+
}
19+
}
20+
}
21+

0 commit comments

Comments
 (0)