Skip to content

Commit 2546c2d

Browse files
committed
Fetch associated types abstractly when fetching an associated conformance.
By default, emitTypeMetadataRef does a blocking request for complete metadata, which is the right thing to do for most purposes in IRGen. Unfortunately, it's actively dangerous in code that can be called during metadata completion, like an associated conformance accessor, because it can cause artificial dependency cycles that the runtime isn't equipped to detect, much less solve. This is a partial fix for rdar://69901318, which also exposes a bad metadata access path that seems to be causing an artificial problem.
1 parent d21ff5c commit 2546c2d

File tree

5 files changed

+7
-10
lines changed

5 files changed

+7
-10
lines changed

lib/IRGen/GenProto.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2567,8 +2567,10 @@ MetadataResponse MetadataPath::followComponent(IRGenFunction &IGF,
25672567

25682568
if (!source) return MetadataResponse();
25692569

2570-
auto sourceMetadata = IGF.emitTypeMetadataRef(sourceType);
2571-
auto associatedMetadata = IGF.emitTypeMetadataRef(sourceKey.Type);
2570+
auto sourceMetadata =
2571+
IGF.emitAbstractTypeMetadataRef(sourceType);
2572+
auto associatedMetadata =
2573+
IGF.emitAbstractTypeMetadataRef(sourceKey.Type);
25722574
auto sourceWTable = source.getMetadata();
25732575

25742576
AssociatedConformance associatedConformanceRef(sourceProtocol,

test/IRGen/associated_types.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ func testFastRuncible<T: Runcible, U: FastRuncible>(_ t: T, u: U)
7575
// 1. Get the type metadata for U.RuncerType.Runcee.
7676
// 1a. Get the type metadata for U.RuncerType.
7777
// Note that we actually look things up in T, which is going to prove unfortunate.
78-
// CHECK: [[T2:%.*]] = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness([[INT]] 0, i8** %T.Runcible, %swift.type* %T, %swift.protocol_requirement* getelementptr{{.*}}i32 12), i32 -1), %swift.protocol_requirement* getelementptr inbounds (<{{.*}}>, <{{.*}}>* @"$s16associated_types8RuncibleMp", i32 0, i32 14)) [[NOUNWIND_READNONE:#.*]]
78+
// CHECK: [[T2:%.*]] = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness([[INT]] 255, i8** %T.Runcible, %swift.type* %T, %swift.protocol_requirement* getelementptr{{.*}}i32 12), i32 -1), %swift.protocol_requirement* getelementptr inbounds (<{{.*}}>, <{{.*}}>* @"$s16associated_types8RuncibleMp", i32 0, i32 14)) [[NOUNWIND_READNONE:#.*]]
7979
// CHECK-NEXT: %T.RuncerType = extractvalue %swift.metadata_response [[T2]], 0
80+
// CHECK-NEXT: extractvalue %swift.metadata_response [[T2]], 1
8081
// 2. Get the witness table for U.RuncerType.Runcee : Speedy
8182
// 2a. Get the protocol witness table for U.RuncerType : FastRuncer.
8283
// CHECK-NEXT: %T.RuncerType.FastRuncer = call swiftcc i8** @swift_getAssociatedConformanceWitness(i8** %U.FastRuncible, %swift.type* %U, %swift.type* %T.RuncerType

test/IRGen/generic_structs.sil

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,6 @@ struct GenericLayoutWithAssocType<T: ParentHasAssociatedType> {
246246

247247
// CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$s15generic_structs26GenericLayoutWithAssocTypeVMr"(
248248

249-
// CHECK: [[T0:%.*]] = call{{( tail)?}} swiftcc %swift.metadata_response @swift_checkMetadataState(i64 0, %swift.type* %T)
250-
// CHECK: [[T_CHECKED:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
251-
252249
// CHECK: [[T0_GEP:%.*]] = getelementptr inbounds i8*, i8** %T.ParentHasAssociatedType, i32 1
253250
// CHECK: [[T0:%.*]] = load i8*, i8** [[T0_GEP]]
254251
// CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to i8**

test/IRGen/generic_structs_future.sil

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,6 @@ struct GenericLayoutWithAssocType<T: ParentHasAssociatedType> {
247247

248248
// CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$s22generic_structs_future26GenericLayoutWithAssocTypeVMr"(
249249

250-
// CHECK: [[T0:%.*]] = call{{( tail)?}} swiftcc %swift.metadata_response @swift_checkMetadataState(i64 0, %swift.type* %T)
251-
// CHECK: [[T_CHECKED:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
252-
253250
// CHECK: [[T0_GEP:%.*]] = getelementptr inbounds i8*, i8** %T.ParentHasAssociatedType, i32 1
254251
// CHECK: [[T0:%.*]] = load i8*, i8** [[T0_GEP]]
255252
// CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to i8**

test/IRGen/same_type_constraints.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ where Self : CodingType,
6767
print(Self.ValueType.self)
6868
}
6969

70-
// OSIZE: define internal swiftcc i8** @"$s21same_type_constraints12GenericKlazzCyxq_GAA1EAA4Data_AA0F4TypePWT"(%swift.type* %"GenericKlazz<T, R>.Data", %swift.type* nocapture readonly %"GenericKlazz<T, R>", i8** nocapture readnone %"GenericKlazz<T, R>.E") [[ATTRS:#[0-9]+]] {
70+
// OSIZE: define internal swiftcc i8** @"$s21same_type_constraints12GenericKlazzCyxq_GAA1EAA4Data_AA0F4TypePWT"(%swift.type* readnone %"GenericKlazz<T, R>.Data", %swift.type* nocapture readonly %"GenericKlazz<T, R>", i8** nocapture readnone %"GenericKlazz<T, R>.E") [[ATTRS:#[0-9]+]] {
7171
// OSIZE: [[ATTRS]] = {{{.*}}noinline
7272

7373
// Check that same-typing two generic parameters together lowers correctly.

0 commit comments

Comments
 (0)