Skip to content

Commit 71c3893

Browse files
committed
Fix an incorrect assertion involving existential formation.
This assertion was tripping when the existential involved a marker protocol, because it was checking for the number of protocols rather than the number of protocols that require witness tables. Correct the assertion and add a test. Fixes rdar://83020734.
1 parent 04edbc3 commit 71c3893

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

lib/IRGen/GenExistential.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1778,6 +1778,16 @@ void irgen::emitClassExistentialContainer(IRGenFunction &IGF,
17781778
});
17791779
}
17801780

1781+
#ifndef NDEBUG
1782+
static size_t numProtocolsWithWitnessTables(
1783+
ArrayRef<ProtocolConformanceRef> conformances) {
1784+
return llvm::count_if(conformances, [](ProtocolConformanceRef conformance) {
1785+
auto proto = conformance.getRequirement();
1786+
return Lowering::TypeConverter::protocolRequiresWitnessTable(proto);
1787+
});
1788+
}
1789+
#endif
1790+
17811791
/// Emit an existential container initialization operation for a concrete type.
17821792
/// Returns the address of the uninitialized fixed-size buffer for the concrete
17831793
/// value.
@@ -1791,7 +1801,8 @@ Address irgen::emitOpaqueExistentialContainerInit(IRGenFunction &IGF,
17911801
"initializing a class existential container as opaque");
17921802
auto &destTI = IGF.getTypeInfo(destType).as<OpaqueExistentialTypeInfo>();
17931803
OpaqueExistentialLayout destLayout = destTI.getLayout();
1794-
assert(destTI.getStoredProtocols().size() == conformances.size());
1804+
assert(destTI.getStoredProtocols().size()
1805+
== numProtocolsWithWitnessTables(conformances));
17951806

17961807
// First, write out the metadata.
17971808
llvm::Value *metadata = IGF.emitTypeMetadataRef(formalSrcType);

test/IRGen/marker_protocol.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,15 @@ public func testGeneric(i: Int, array: [Int]) {
3232
generic(i)
3333
generic(array)
3434
}
35+
36+
// Forming an existential involving a marker protocol would crash the compiler
37+
protocol SelfConstrainedProtocol {
38+
static var shared: Self { get }
39+
}
40+
41+
struct Foo: SelfConstrainedProtocol {
42+
let x: P
43+
static var shared: Self {
44+
Foo(x: 123)
45+
}
46+
}

0 commit comments

Comments
 (0)