-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Preliminary Sema and AST support for subclass existentials (SE-0156) #8650
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b9494b0
efb3d42
143c91a
011fb81
6b4c877
ed4c681
819dfd5
54883e8
95e2802
9c3b514
d7c1d81
32a7505
ad417c9
30cd0a9
473faf1
b1d22ff
4efa9ea
2e5b3b6
1b2252f
de323b5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
//===--- ExistentialLayout.h - Existential type decomposition ---*- C++ -*-===// | ||
// | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See https://swift.org/LICENSE.txt for license information | ||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file defines the ExistentialLayout struct. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef SWIFT_EXISTENTIAL_LAYOUT_H | ||
#define SWIFT_EXISTENTIAL_LAYOUT_H | ||
|
||
#include "swift/AST/ASTContext.h" | ||
#include "swift/AST/Type.h" | ||
#include "llvm/ADT/SmallVector.h" | ||
|
||
namespace swift { | ||
class ProtocolDecl; | ||
class ProtocolType; | ||
class ProtocolCompositionType; | ||
|
||
struct ExistentialLayout { | ||
ExistentialLayout() { | ||
requiresClass = false; | ||
requiresClassImplied = false; | ||
containsNonObjCProtocol = false; | ||
singleProtocol = nullptr; | ||
} | ||
|
||
ExistentialLayout(ProtocolType *type); | ||
ExistentialLayout(ProtocolCompositionType *type); | ||
|
||
/// The superclass constraint, if any. | ||
Type superclass; | ||
|
||
/// Whether the existential requires a class, either via an explicit | ||
/// '& AnyObject' member or because of a superclass or protocol constraint. | ||
bool requiresClass : 1; | ||
|
||
/// Whether the class constraint was implied by another constraint and therefore | ||
/// does not need to be stated explicitly. | ||
bool requiresClassImplied : 1; | ||
|
||
/// Whether any protocol members are non-@objc. | ||
bool containsNonObjCProtocol : 1; | ||
|
||
bool isAnyObject() const; | ||
|
||
bool isObjC() const { | ||
// FIXME: Does the superclass have to be @objc? | ||
return requiresClass && !containsNonObjCProtocol; | ||
} | ||
|
||
bool isExistentialWithError(ASTContext &ctx) const; | ||
|
||
ArrayRef<ProtocolType *> getProtocols() const { | ||
if (singleProtocol) | ||
return ArrayRef<ProtocolType *>{&singleProtocol, 1}; | ||
return multipleProtocols; | ||
} | ||
|
||
private: | ||
// Inline storage for 'protocols' member above when computing | ||
// layout of a single ProtocolType | ||
ProtocolType *singleProtocol; | ||
|
||
/// Zero or more protocol constraints. | ||
ArrayRef<ProtocolType *> multipleProtocols; | ||
}; | ||
|
||
} | ||
|
||
#endif // SWIFT_EXISTENTIAL_LAYOUT_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2727,16 +2727,16 @@ ProtocolDecl::getInheritedProtocols() const { | |
// FIXME: Gather inherited protocols from the "inherited" list. | ||
// We shouldn't need this, but it shows up in recursive invocations. | ||
if (!isRequirementSignatureComputed()) { | ||
SmallPtrSet<ProtocolDecl *, 4> known; | ||
for (auto inherited : getInherited()) { | ||
SmallPtrSet<ProtocolDecl *, 4> known; | ||
if (auto type = inherited.getType()) { | ||
if (type->isExistentialType()) { | ||
SmallVector<ProtocolDecl *, 4> protocols; | ||
type->getExistentialTypeProtocols(protocols); | ||
for (auto proto : protocols) { | ||
if (known.insert(proto).second) | ||
result.push_back(proto); | ||
} | ||
// Only protocols can appear in the inheritance clause | ||
// of a protocol -- anything else should get diagnosed | ||
// elsewhere. | ||
if (auto *protoTy = type->getAs<ProtocolType>()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wait, really? I thought we could have typealiases of protocol compositions, as well as superclass types, in this list? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll add more tests and see what we support exactly. |
||
auto *protoDecl = protoTy->getDecl(); | ||
if (known.insert(protoDecl).second) | ||
result.push_back(protoDecl); | ||
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this more generally have a
LayoutConstraintKind
?