Skip to content

Commit 2c4f360

Browse files
authored
Merge pull request #39454 from DougGregor/existential-marker-protocol-assert
2 parents 7e77bc4 + 71c3893 commit 2c4f360

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)