Skip to content

Commit f779d5e

Browse files
authored
Merge pull request #18805 from DougGregor/nominal-layout-all-metadata-sources
[Type checker] Request nominal layout for all potential metadata sources
2 parents 4b027c7 + cb97207 commit f779d5e

File tree

3 files changed

+19
-11
lines changed

3 files changed

+19
-11
lines changed

lib/Sema/TypeCheckPattern.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,20 @@ static bool validateParameterType(ParamDecl *decl, DeclContext *DC,
792792
return hadError;
793793
}
794794

795+
/// Given a type of a function parameter, request layout for any
796+
/// nominal types that IRGen could use as metadata sources.
797+
static void requestLayoutForMetadataSources(TypeChecker &tc, Type type) {
798+
type->getCanonicalType().visit([&tc](CanType type) {
799+
// Generic types are sources for typemetadata and conformances. If a
800+
// parameter is of dependent type then the body of a function with said
801+
// parameter could potentially require the generic type's layout to
802+
// recover them.
803+
if (auto *nominalDecl = type->getAnyNominal()) {
804+
tc.requestNominalLayout(nominalDecl);
805+
}
806+
});
807+
}
808+
795809
/// Request nominal layout for any types that could be sources of type metadata
796810
/// or conformances.
797811
void TypeChecker::requestRequiredNominalTypeLayoutForParameters(
@@ -800,13 +814,7 @@ void TypeChecker::requestRequiredNominalTypeLayoutForParameters(
800814
if (!param->hasInterfaceType())
801815
continue;
802816

803-
// Generic types are sources for typemetadata and conformances. If a
804-
// parameter is of dependent type then the body of a function with said
805-
// parameter could potentially require the generic type's layout to
806-
// recover them.
807-
if (auto *nominalDecl = param->getInterfaceType()->getAnyNominal()) {
808-
requestNominalLayout(nominalDecl);
809-
}
817+
requestLayoutForMetadataSources(*this, param->getInterfaceType());
810818
}
811819
}
812820

test/multifile/Inputs/require-layout-generic-class.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ public class Base<T> {
88
public class Sub<T> : Base<T> {
99
}
1010

11-
public func requestTypeThrough<T>(closure: (Sub<T>) -> (), arg: T) {
12-
closure(Sub(arg))
11+
public func requestTypeThrough<T>(closure: ((Sub<T>, Int)) -> (), arg: T) {
12+
closure((Sub(arg), 0))
1313
}

test/multifile/require-layout-generic-arg-closure.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55

66
// The offset of the typemetadata in the class typemetadata must match.
77

8-
// FILE1-LABEL: define internal swiftcc void @"$S4test12requestType21xyx_tlFyAA3SubCyxGXEfU_"(%T4test3SubC*)
8+
// FILE1-LABEL: define internal swiftcc void @"$S4test12requestType21xyx_tlFyAA3SubCyxG_Sit_tXEfU_
99
// FILE1: entry:
1010
// FILE1: [[T1:%.*]] = bitcast %T4test3SubC* %0 to %swift.type**
1111
// FILE1: [[TYPEMETADATA:%.*]] = load %swift.type*, %swift.type** [[T1]]
1212
// FILE1: [[T2:%.*]] = bitcast %swift.type* [[TYPEMETADATA]] to %swift.type**
1313
// FILE1: [[T_PTR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T2]], i64 16
1414
// FILE1: [[T:%.*]] = load %swift.type*, %swift.type** [[T_PTR]]
15-
// FILE1: call swiftcc %swift.metadata_response @"$S4test3SubCMa"(i64 0, %swift.type* [[T]])
15+
// FILE1: call swiftcc %swift.metadata_response @"$S4test3SubCMa"(i64 255, %swift.type* [[T]])
1616

1717
public func requestType2<T>(x: T) {
1818
requestTypeThrough(closure: { x in print(x) }, arg: x)

0 commit comments

Comments
 (0)