Skip to content

Commit f38ad4b

Browse files
committed
Start support for protocol witness tables
1 parent 4285a21 commit f38ad4b

File tree

4 files changed

+78
-7
lines changed

4 files changed

+78
-7
lines changed

include/swift/IRGen/Linking.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ inline bool isEmbedded(const ProtocolConformance *c) {
126126
return c->getType()->getASTContext().LangOpts.hasFeature(Feature::Embedded);
127127
}
128128

129+
inline bool isEmbeddedWithoutEmbeddedExitentials(const ProtocolConformance *c) {
130+
return isEmbedded(c) && !c->getType()->getASTContext().
131+
LangOpts.hasFeature(Feature::EmbeddedExistentials);
132+
}
133+
129134
/// A link entity is some sort of named declaration, combined with all
130135
/// the information necessary to distinguish specific implementations
131136
/// of the declaration from each other.
@@ -1137,7 +1142,7 @@ class LinkEntity {
11371142
}
11381143

11391144
static LinkEntity forProtocolWitnessTable(const ProtocolConformance *C) {
1140-
if (isEmbedded(C)) {
1145+
if (isEmbeddedWithoutEmbeddedExitentials(C)) {
11411146
assert(C->getProtocol()->requiresClass());
11421147
}
11431148

lib/IRGen/GenProto.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2731,7 +2731,8 @@ static void addWTableTypeMetadata(IRGenModule &IGM,
27312731
void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) {
27322732
if (Context.LangOpts.hasFeature(Feature::Embedded)) {
27332733
// In Embedded Swift, only class-bound wtables are allowed.
2734-
if (!wt->getConformance()->getProtocol()->requiresClass())
2734+
if (!wt->getConformance()->getProtocol()->requiresClass() &&
2735+
!Context.LangOpts.hasFeature(Feature::EmbeddedExistentials))
27352736
return;
27362737
}
27372738

@@ -3752,7 +3753,9 @@ llvm::Value *irgen::emitWitnessTableRef(IRGenFunction &IGF,
37523753
auto proto = conformance.getProtocol();
37533754

37543755
// In Embedded Swift, only class-bound wtables are allowed.
3755-
if (srcType->getASTContext().LangOpts.hasFeature(Feature::Embedded)) {
3756+
auto &langOpts = srcType->getASTContext().LangOpts;
3757+
if (langOpts.hasFeature(Feature::Embedded) &&
3758+
!langOpts.hasFeature(Feature::EmbeddedExistentials)) {
37563759
assert(proto->requiresClass());
37573760
}
37583761

lib/IRGen/IRGenModule.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1486,7 +1486,9 @@ bool IRGenerator::canEmitWitnessTableLazily(SILWitnessTable *wt) {
14861486

14871487
void IRGenerator::addLazyWitnessTable(const ProtocolConformance *Conf) {
14881488
// In Embedded Swift, only class-bound wtables are allowed.
1489-
if (SIL.getASTContext().LangOpts.hasFeature(Feature::Embedded)) {
1489+
auto &langOpts = SIL.getASTContext().LangOpts;
1490+
if (langOpts.hasFeature(Feature::Embedded) &&
1491+
!langOpts.hasFeature(Feature::EmbeddedExistentials)) {
14901492
assert(Conf->getProtocol()->requiresClass());
14911493
}
14921494

test/embedded/existential.swift

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,70 @@ func test() {
7070
let _: any Any = (StructWithClass(), StructWithClass())
7171
}
7272

73+
protocol Basic {
74+
func a()
75+
}
76+
77+
protocol Derived : Basic {
78+
func b()
79+
}
80+
81+
class Implementor : Derived {
82+
func a() { print("a") }
83+
func b() { print("b") }
84+
}
85+
86+
extension Int : Derived {
87+
func a() { print("a Int \(self)") }
88+
func b() { print("b Int \(self)") }
89+
}
90+
91+
struct MyStruct : Derived {
92+
var x = 5
93+
func a() { print("a MyStruct \(self.x)") }
94+
func b() { print("b MyStruct") }
95+
}
96+
97+
enum MyEnum : Derived {
98+
case a
99+
case b(Int)
100+
101+
func a() {
102+
print("a MyEnum ")
103+
switch self {
104+
case .a: break
105+
case .b(let x):
106+
print(x)
107+
}
108+
}
109+
110+
func b() {
111+
print("b MyEnum ")
112+
}
113+
}
114+
115+
func test2(_ p: any Derived) {
116+
p.a()
117+
p.b()
118+
}
119+
73120
@main
74121
struct Main {
75-
static func main() {
76-
test()
77-
}
122+
static func main() {
123+
test()
124+
125+
// OUTPUT: a
126+
// OUTPUT: b
127+
// OUTPUT: a Int 5
128+
// OUTPUT: b Int 5
129+
// OUTPUT: a MyStruct 5
130+
// OUTPUT: b MyStruct
131+
// OUTPUT: a MyEnum
132+
// OUTPUT: 5
133+
// OUTPUT: b MyEnum
134+
test2(Implementor())
135+
test2(5)
136+
test2(MyStruct())
137+
test2(MyEnum.b(5))
138+
}
78139
}

0 commit comments

Comments
 (0)