Skip to content

Commit 7934190

Browse files
author
Davide Italiano
committed
[ExistentialLayout] Introduce getKind() and use it.
Suggested by John McCall.
1 parent d36ae32 commit 7934190

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

include/swift/AST/ExistentialLayout.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ namespace swift {
2828
class ProtocolCompositionType;
2929

3030
struct ExistentialLayout {
31+
enum Kind { Class, Error, Opaque };
32+
3133
ExistentialLayout() {
3234
hasExplicitAnyObject = false;
3335
containsNonObjCProtocol = false;
@@ -46,6 +48,19 @@ struct ExistentialLayout {
4648
/// Whether any protocol members are non-@objc.
4749
bool containsNonObjCProtocol : 1;
4850

51+
/// Return the kind of this existential (class/error/opaque).
52+
Kind getKind() {
53+
if (requiresClass())
54+
return Kind::Class;
55+
if (isErrorExistential())
56+
return Kind::Error;
57+
58+
// The logic here is that opaque is the complement of class + error,
59+
// i.e. we don't have more concrete information guiding the layout
60+
// and it doesn't fall into the special-case Error representation.
61+
return Kind::Opaque;
62+
}
63+
4964
bool isAnyObject() const;
5065

5166
bool isObjC() const {

lib/SIL/SILType.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -356,20 +356,22 @@ SILType::canUseExistentialRepresentation(SILModule &M,
356356

357357
auto layout = getASTType().getExistentialLayout();
358358

359+
switch (layout.getKind()) {
360+
// A class-constrained composition uses ClassReference representation;
361+
// otherwise, we use a fixed-sized buffer.
362+
case ExistentialLayout::Kind::Class:
363+
return repr == ExistentialRepresentation::Class;
359364
// The (uncomposed) Error existential uses a special boxed
360-
// representation. It can also adopt class references of bridged error types
361-
// directly.
362-
if (layout.isErrorExistential())
365+
// representation. It can also adopt class references of bridged
366+
// error types directly.
367+
case ExistentialLayout::Kind::Error:
363368
return repr == ExistentialRepresentation::Boxed
364369
|| (repr == ExistentialRepresentation::Class
365370
&& isBridgedErrorClass(M, containedType));
366-
367-
// A class-constrained composition uses ClassReference representation;
368-
// otherwise, we use a fixed-sized buffer.
369-
if (layout.requiresClass())
370-
return repr == ExistentialRepresentation::Class;
371-
372-
return repr == ExistentialRepresentation::Opaque;
371+
case ExistentialLayout::Kind::Opaque:
372+
return repr == ExistentialRepresentation::Opaque;
373+
}
374+
llvm_unreachable("unknown existential kind!");
373375
}
374376
case ExistentialRepresentation::Metatype:
375377
return is<ExistentialMetatypeType>();

0 commit comments

Comments
 (0)