Skip to content

Commit 3d8607a

Browse files
authored
Merge pull request #68950 from tbkka/tbkka-rdar116406504-RemoteMirror-voidpayload
[RemoteInspection] Allow enums to be trivial even with a formal payload
2 parents 151950d + 8bb3a55 commit 3d8607a

File tree

2 files changed

+156
-3
lines changed

2 files changed

+156
-3
lines changed

stdlib/public/RemoteInspection/TypeLowering.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,9 @@ class UnsupportedEnumTypeInfo: public EnumTypeInfo {
395395
}
396396
};
397397

398+
// An Enum with no cases has no values, requires no storage,
399+
// and cannot be instantiated.
400+
// It is an uninhabited type (similar to Never).
398401
class EmptyEnumTypeInfo: public EnumTypeInfo {
399402
public:
400403
EmptyEnumTypeInfo(const std::vector<FieldInfo> &Cases)
@@ -418,7 +421,9 @@ class EmptyEnumTypeInfo: public EnumTypeInfo {
418421
}
419422
};
420423

421-
// Enum with a single non-payload case
424+
// Non-generic Enum with a single non-payload case
425+
// This enum requires no storage, since it only has
426+
// one possible value.
422427
class TrivialEnumTypeInfo: public EnumTypeInfo {
423428
public:
424429
TrivialEnumTypeInfo(EnumKind Kind, const std::vector<FieldInfo> &Cases)
@@ -430,8 +435,8 @@ class TrivialEnumTypeInfo: public EnumTypeInfo {
430435
Kind, Cases) {
431436
// Exactly one case
432437
assert(Cases.size() == 1);
433-
// The only case has no payload
434-
assert(Cases[0].TR == 0);
438+
// The only case has no payload, or a zero-sized payload
439+
assert(Cases[0].TR == 0 || Cases[0].TI.getSize() == 0);
435440
}
436441

437442
bool readExtraInhabitantIndex(remote::MemoryReader &reader,
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift -g -lswiftSwiftReflectionTest %s -o %t/reflect_Enum_SingleCaseVoidPayload
3+
// RUN: %target-codesign %t/reflect_Enum_SingleCaseVoidPayload
4+
5+
// RUN: %target-run %target-swift-reflection-test %t/reflect_Enum_SingleCaseVoidPayload | %FileCheck %s --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK
6+
7+
// REQUIRES: reflection_test_support
8+
// REQUIRES: executable_test
9+
// UNSUPPORTED: use_os_stdlib
10+
11+
import SwiftReflectionTest
12+
13+
struct Marker {
14+
let value = 1
15+
}
16+
17+
enum Trivial {
18+
case only
19+
}
20+
21+
enum SingleCaseVoidPayloadEnum {
22+
case `default`(Trivial)
23+
}
24+
25+
class ClassWithSingleCaseVoidPayloadEnum {
26+
var e1: SingleCaseVoidPayloadEnum?
27+
var e2: SingleCaseVoidPayloadEnum = .`default`(Trivial.only)
28+
var e3: SingleCaseVoidPayloadEnum? = .`default`(Trivial.only)
29+
var e4: SingleCaseVoidPayloadEnum??
30+
let marker = Marker()
31+
}
32+
33+
reflect(object: ClassWithSingleCaseVoidPayloadEnum())
34+
35+
// CHECK-64: Reflecting an object.
36+
// CHECK-64-NEXT: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
37+
// CHECK-64-NEXT: Type reference:
38+
// CHECK-64-NEXT: (class reflect_Enum_SingleCaseVoidPayload.ClassWithSingleCaseVoidPayloadEnum)
39+
40+
// CHECK-64: Type info:
41+
// CHECK-64-NEXT: (class_instance size=32 alignment=8 stride=32 num_extra_inhabitants=0 bitwise_takable=1
42+
// CHECK-64-NEXT: (field name=e1 offset=16
43+
// CHECK-64-NEXT: (single_payload_enum size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
44+
// CHECK-64-NEXT: (case name=some index=0 offset=0
45+
// CHECK-64-NEXT: (single_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
46+
// CHECK-64-NEXT: (case name=default index=0 offset=0
47+
// CHECK-64-NEXT: (no_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
48+
// CHECK-64-NEXT: (case name=only index=0)))))
49+
// CHECK-64-NEXT: (case name=none index=1)))
50+
// CHECK-64-NEXT: (field name=e2 offset=17
51+
// CHECK-64-NEXT: (single_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
52+
// CHECK-64-NEXT: (case name=default index=0 offset=0
53+
// CHECK-64-NEXT: (no_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
54+
// CHECK-64-NEXT: (case name=only index=0)))))
55+
// CHECK-64-NEXT: (field name=e3 offset=17
56+
// CHECK-64-NEXT: (single_payload_enum size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
57+
// CHECK-64-NEXT: (case name=some index=0 offset=0
58+
// CHECK-64-NEXT: (single_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
59+
// CHECK-64-NEXT: (case name=default index=0
60+
// CHECK-64-NEXT: (no_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
61+
// CHECK-64-NEXT: (case name=only index=0)))))
62+
// CHECK-64-NEXT: (case name=none index=1)))
63+
// CHECK-64-NEXT: (field name=e4 offset=18
64+
// CHECK-64-NEXT: (single_payload_enum size=2 alignment=1 stride=2 num_extra_inhabitants=0 bitwise_takable=1
65+
// CHECK-64-NEXT: (case name=some index=0 offset=0
66+
// CHECK-64-NEXT: (single_payload_enum size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
67+
// CHECK-64-NEXT: (case name=some index=0 offset=0
68+
// CHECK-64-NEXT: (single_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
69+
// CHECK-64-NEXT: (case name=default index=0
70+
// CHECK-64-NEXT: (no_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
71+
// CHECK-64-NEXT: (case name=only index=0)))))
72+
// CHECK-64-NEXT: (case name=none index=1)))
73+
// CHECK-64-NEXT: (case name=none index=1)))
74+
// CHECK-64-NEXT: (field name=marker offset=24
75+
// CHECK-64-NEXT: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
76+
// CHECK-64-NEXT: (field name=value offset=0
77+
// CHECK-64-NEXT: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1
78+
// CHECK-64-NEXT: (field name=_value offset=0
79+
// CHECK-64-NEXT: (builtin size=8 alignment=8 stride=8 num_extra_inhabitants=0 bitwise_takable=1)))))))
80+
81+
// CHECK-32: Reflecting an object.
82+
// CHECK-32-NEXT: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
83+
// CHECK-32-NEXT: Type reference:
84+
// CHECK-32-NEXT: (class reflect_Enum_SingleCaseVoidPayload.ClassWithSingleCaseVoidPayloadEnum)
85+
86+
// CHECK-32: Type info:
87+
// CHECK-32-NEXT: (class_instance size=16 alignment=4 stride=16 num_extra_inhabitants=0 bitwise_takable=1
88+
// CHECK-32-NEXT: (field name=e1 offset=8
89+
// CHECK-32-NEXT: (single_payload_enum size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
90+
// CHECK-32-NEXT: (case name=some index=0 offset=0
91+
// CHECK-32-NEXT: (single_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
92+
// CHECK-32-NEXT: (case name=default index=0
93+
// CHECK-32-NEXT: (no_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
94+
// CHECK-32-NEXT: (case name=only index=0)))))
95+
// CHECK-32-NEXT: (case name=none index=1)))
96+
// CHECK-32-NEXT: (field name=e2 offset=9
97+
// CHECK-32-NEXT: (single_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
98+
// CHECK-32-NEXT: (case name=default index=0
99+
// CHECK-32-NEXT: (no_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
100+
// CHECK-32-NEXT: (case name=only index=0)))))
101+
// CHECK-32-NEXT: (field name=e3 offset=9
102+
// CHECK-32-NEXT: (single_payload_enum size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
103+
// CHECK-32-NEXT: (case name=some index=0 offset=0
104+
// CHECK-32-NEXT: (single_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
105+
// CHECK-32-NEXT: (case name=default index=0
106+
// CHECK-32-NEXT: (no_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
107+
// CHECK-32-NEXT: (case name=only index=0)))))
108+
// CHECK-32-NEXT: (case name=none index=1)))
109+
// CHECK-32-NEXT: (field name=e4 offset=10
110+
// CHECK-32-NEXT: (single_payload_enum size=2 alignment=1 stride=2 num_extra_inhabitants=0 bitwise_takable=1
111+
// CHECK-32-NEXT: (case name=some index=0 offset=0
112+
// CHECK-32-NEXT: (single_payload_enum size=1 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
113+
// CHECK-32-NEXT: (case name=some index=0 offset=0
114+
// CHECK-32-NEXT: (single_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
115+
// CHECK-32-NEXT: (case name=default index=0
116+
// CHECK-32-NEXT: (no_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
117+
// CHECK-32-NEXT: (case name=only index=0)))))
118+
// CHECK-32-NEXT: (case name=none index=1)))
119+
// CHECK-32-NEXT: (case name=none index=1)))
120+
// CHECK-32-NEXT: (field name=marker offset=12
121+
// CHECK-32-NEXT: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
122+
// CHECK-32-NEXT: (field name=value offset=0
123+
// CHECK-32-NEXT: (struct size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1
124+
// CHECK-32-NEXT: (field name=_value offset=0
125+
// CHECK-32-NEXT: (builtin size=4 alignment=4 stride=4 num_extra_inhabitants=0 bitwise_takable=1)))))))
126+
127+
reflect(enum: SingleCaseVoidPayloadEnum.`default`(Trivial.only))
128+
129+
// CHECK: Reflecting an enum.
130+
// CHECK-NEXT: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}}
131+
// CHECK-NEXT: Type reference:
132+
// CHECK-NEXT: (enum reflect_Enum_SingleCaseVoidPayload.SingleCaseVoidPayloadEnum)
133+
134+
// CHECK: Type info:
135+
// CHECK-NEXT: (single_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
136+
// CHECK-NEXT: (case name=default index=0
137+
// CHECK-NEXT: (no_payload_enum size=0 alignment=1 stride=1 num_extra_inhabitants=0 bitwise_takable=1
138+
// CHECK-NEXT: (case name=only index=0))))
139+
140+
141+
// CHECK: Enum value:
142+
// CHECK-NEXT: (enum_value name=default index=0
143+
// CHECK-NEXT: (enum reflect_Enum_SingleCaseVoidPayload.Trivial)
144+
// CHECK-NEXT: )
145+
146+
doneReflecting()
147+
148+
// CHECK: Done.

0 commit comments

Comments
 (0)