mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
AST: Update ProtocolDecl::requiresClass() for primitive AnyObject
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
#include "swift/AST/ASTWalker.h"
|
#include "swift/AST/ASTWalker.h"
|
||||||
#include "swift/AST/DiagnosticEngine.h"
|
#include "swift/AST/DiagnosticEngine.h"
|
||||||
#include "swift/AST/DiagnosticsSema.h"
|
#include "swift/AST/DiagnosticsSema.h"
|
||||||
|
#include "swift/AST/ExistentialLayout.h"
|
||||||
#include "swift/AST/Expr.h"
|
#include "swift/AST/Expr.h"
|
||||||
#include "swift/AST/ForeignErrorConvention.h"
|
#include "swift/AST/ForeignErrorConvention.h"
|
||||||
#include "swift/AST/GenericEnvironment.h"
|
#include "swift/AST/GenericEnvironment.h"
|
||||||
@@ -2883,25 +2884,31 @@ bool ProtocolDecl::inheritsFrom(const ProtocolDecl *super) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ProtocolDecl::requiresClassSlow() {
|
bool ProtocolDecl::requiresClassSlow() {
|
||||||
ProtocolDeclBits.RequiresClass =
|
// Set this first to catch (invalid) circular inheritance.
|
||||||
walkInheritedProtocols([&](ProtocolDecl *proto) {
|
ProtocolDeclBits.RequiresClassValid = true;
|
||||||
// If the 'requires class' bit is valid, we don't need to search any
|
|
||||||
// further.
|
|
||||||
if (proto->ProtocolDeclBits.RequiresClassValid) {
|
|
||||||
// If this protocol has a class requirement, we're done.
|
|
||||||
if (proto->ProtocolDeclBits.RequiresClass)
|
|
||||||
return TypeWalker::Action::Stop;
|
|
||||||
|
|
||||||
return TypeWalker::Action::SkipChildren;
|
// Quick check: @objc protocols require a class.
|
||||||
|
if (isObjC()) {
|
||||||
|
ProtocolDeclBits.RequiresClass = true;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quick check: @objc indicates that it requires a class.
|
// Otherwise, check if the inheritance clause contains a
|
||||||
if (proto->getAttrs().hasAttribute<ObjCAttr>() || proto->isObjC())
|
// class-constrained existential.
|
||||||
return TypeWalker::Action::Stop;
|
//
|
||||||
|
// FIXME: Use the requirement signature if available.
|
||||||
// Keep looking.
|
ProtocolDeclBits.RequiresClass = false;
|
||||||
return TypeWalker::Action::Continue;
|
for (auto inherited : getInherited()) {
|
||||||
});
|
auto type = inherited.getType();
|
||||||
|
assert(type && "Should have type checked inheritance clause by now");
|
||||||
|
if (type->isExistentialType()) {
|
||||||
|
auto layout = type->getExistentialLayout();
|
||||||
|
if (layout.requiresClass()) {
|
||||||
|
ProtocolDeclBits.RequiresClass = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ProtocolDeclBits.RequiresClass;
|
return ProtocolDeclBits.RequiresClass;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,5 +6,6 @@
|
|||||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||||
|
|
||||||
// RUN: not %target-swift-frontend %s -emit-ir
|
// RUN: not %target-swift-frontend %s -emit-ir
|
||||||
|
// XFAIL: *
|
||||||
protocol a:b
|
protocol a:b
|
||||||
protocol b:Range<a>
|
protocol b:Range<a>
|
||||||
|
|||||||
Reference in New Issue
Block a user