Merge pull request #11786 from slavapestov/fix-class-anyobject-4.0
Fix printing of class-constrained protocols [4.0]
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 3f00d4d..0d1ab3a 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -3489,9 +3489,6 @@
class ProtocolDecl : public NominalTypeDecl {
SourceLoc ProtocolLoc;
- /// The location of the 'class' keyword for class-bound protocols.
- SourceLoc ClassRequirementLoc;
-
/// The syntactic representation of the where clause in a protocol like
/// `protocol ... where ... { ... }`.
TrailingWhereClause *TrailingWhere;
@@ -3571,17 +3568,6 @@
ProtocolDeclBits.RequiresClass = requiresClass;
}
- /// Specify that this protocol is class-bounded, recording the location of
- /// the 'class' keyword.
- void setClassBounded(SourceLoc loc) {
- ClassRequirementLoc = loc;
- ProtocolDeclBits.RequiresClassValid = true;
- ProtocolDeclBits.RequiresClass = true;
- }
-
- /// Retrieve the source location of the 'class' keyword.
- SourceLoc getClassBoundedLoc() const { return ClassRequirementLoc; }
-
/// Determine whether an existential conforming to this protocol can be
/// matched with a generic type parameter constrained to this protocol.
/// This is only permitted if there is nothing "non-trivial" that we
diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h
index 1fc0fd1..d7fa4ce 100644
--- a/include/swift/Parse/Parser.h
+++ b/include/swift/Parse/Parser.h
@@ -763,7 +763,7 @@
ParserResult<ImportDecl> parseDeclImport(ParseDeclOptions Flags,
DeclAttributes &Attributes);
ParserStatus parseInheritance(SmallVectorImpl<TypeLoc> &Inherited,
- SourceLoc *classRequirementLoc);
+ bool allowClassRequirement);
ParserStatus parseDeclItem(bool &PreviousHadSemi,
Parser::ParseDeclOptions Options,
llvm::function_ref<void(Decl*)> handler);
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index b9918cb..e1ea1f0 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -989,11 +989,9 @@
void printInherited(const Decl *decl,
ArrayRef<TypeLoc> inherited,
ArrayRef<ProtocolDecl *> protos,
- Type superclass = {},
- bool explicitClass = false);
+ Type superclass = {});
- void printInherited(const NominalTypeDecl *decl,
- bool explicitClass = false);
+ void printInherited(const NominalTypeDecl *decl);
void printInherited(const EnumDecl *D);
void printInherited(const ExtensionDecl *decl);
void printInherited(const GenericTypeParamDecl *D);
@@ -1312,8 +1310,12 @@
// A requirement like Self : Protocol or Self.T : Class might be from an
// inheritance, or might be a where clause.
- if (req.getKind() != RequirementKind::Layout && result.second) {
- auto inherited = req.getSecondType();
+ if (result.second) {
+ Type inherited;
+ if (req.getKind() == RequirementKind::Layout)
+ inherited = proto->getASTContext().getAnyObjectType();
+ else
+ inherited = req.getSecondType();
inWhereClause =
none_of(result.first->getInherited(), [&](const TypeLoc &loc) {
return loc.getType()->isEqual(inherited);
@@ -2049,9 +2051,8 @@
void PrintAST::printInherited(const Decl *decl,
ArrayRef<TypeLoc> inherited,
ArrayRef<ProtocolDecl *> protos,
- Type superclass,
- bool explicitClass) {
- if (inherited.empty() && superclass.isNull() && !explicitClass) {
+ Type superclass) {
+ if (inherited.empty() && superclass.isNull()) {
if (protos.empty())
return;
}
@@ -2060,10 +2061,7 @@
bool PrintedColon = false;
bool PrintedInherited = false;
- if (explicitClass) {
- Printer << " : " << tok::kw_class;
- PrintedInherited = true;
- } else if (superclass) {
+ if (superclass) {
bool ShouldPrintSuper = true;
if (auto NTD = superclass->getAnyNominal()) {
ShouldPrintSuper = shouldPrint(NTD);
@@ -2115,9 +2113,6 @@
Printer << " : ";
- if (explicitClass)
- Printer << " " << tok::kw_class << ", ";
-
interleave(TypesToPrint, [&](TypeLoc TL) {
printTypeLoc(TL);
}, [&]() {
@@ -2126,9 +2121,8 @@
}
}
-void PrintAST::printInherited(const NominalTypeDecl *decl,
- bool explicitClass) {
- printInherited(decl, decl->getInherited(), { }, nullptr, explicitClass);
+void PrintAST::printInherited(const NominalTypeDecl *decl) {
+ printInherited(decl, decl->getInherited(), { }, nullptr);
}
void PrintAST::printInherited(const EnumDecl *decl) {
@@ -2539,23 +2533,7 @@
Printer.printName(decl->getName());
});
- // Figure out whether we need an explicit 'class' in the inheritance.
- bool explicitClass = false;
- if (decl->requiresClass() && !decl->isObjC()) {
- bool inheritsRequiresClass = false;
- for (auto proto : decl->getLocalProtocols(
- ConformanceLookupKind::OnlyExplicit)) {
- if (proto->requiresClass()) {
- inheritsRequiresClass = true;
- break;
- }
- }
-
- if (!inheritsRequiresClass)
- explicitClass = true;
- }
-
- printInherited(decl, explicitClass);
+ printInherited(decl);
// The trailing where clause is a syntactic thing, which isn't serialized
// (etc.) and thus isn't available for printing things out of
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 17bcc7e..fedd8ee 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2630,13 +2630,11 @@
/// type-identifier
/// \endverbatim
ParserStatus Parser::parseInheritance(SmallVectorImpl<TypeLoc> &Inherited,
- SourceLoc *classRequirementLoc) {
+ bool allowClassRequirement) {
Scope S(this, ScopeKind::InheritanceClause);
consumeToken(tok::colon);
- // Clear out the class requirement location.
- if (classRequirementLoc)
- *classRequirementLoc = SourceLoc();
+ SourceLoc classRequirementLoc;
ParserStatus Status;
SourceLoc prevComma;
@@ -2645,7 +2643,7 @@
if (Tok.is(tok::kw_class)) {
// If we aren't allowed to have a class requirement here, complain.
auto classLoc = consumeToken();
- if (!classRequirementLoc) {
+ if (!allowClassRequirement) {
SourceLoc endLoc = Tok.is(tok::comma) ? Tok.getLoc() : classLoc;
diagnose(classLoc, diag::invalid_class_requirement)
.fixItRemove(SourceRange(classLoc, endLoc));
@@ -2653,9 +2651,9 @@
}
// If we already saw a class requirement, complain.
- if (classRequirementLoc->isValid()) {
+ if (classRequirementLoc.isValid()) {
diagnose(classLoc, diag::redundant_class_requirement)
- .highlight(*classRequirementLoc)
+ .highlight(classRequirementLoc)
.fixItRemove(SourceRange(prevComma, classLoc));
continue;
}
@@ -2669,7 +2667,12 @@
}
// Record the location of the 'class' keyword.
- *classRequirementLoc = classLoc;
+ classRequirementLoc = classLoc;
+
+ // Add 'AnyObject' to the inherited list.
+ Inherited.push_back(
+ new (Context) SimpleIdentTypeRepr(classLoc,
+ Context.getIdentifier("AnyObject")));
continue;
}
@@ -2933,7 +2936,7 @@
// Parse optional inheritance clause.
SmallVector<TypeLoc, 2> Inherited;
if (Tok.is(tok::colon))
- status |= parseInheritance(Inherited, /*classRequirementLoc=*/nullptr);
+ status |= parseInheritance(Inherited, /*allowClassRequirement=*/false);
// Parse the optional where-clause.
TrailingWhereClause *trailingWhereClause = nullptr;
@@ -3270,7 +3273,7 @@
// FIXME: Allow class requirements here.
SmallVector<TypeLoc, 2> Inherited;
if (Tok.is(tok::colon))
- Status |= parseInheritance(Inherited, /*classRequirementLoc=*/nullptr);
+ Status |= parseInheritance(Inherited, /*allowClassRequirement=*/false);
ParserResult<TypeRepr> UnderlyingTy;
if (Tok.is(tok::equal)) {
@@ -5000,7 +5003,7 @@
if (Tok.is(tok::colon)) {
ContextChange CC(*this, ED);
SmallVector<TypeLoc, 2> Inherited;
- Status |= parseInheritance(Inherited, /*classRequirementLoc=*/nullptr);
+ Status |= parseInheritance(Inherited, /*allowClassRequirement=*/false);
ED->setInherited(Context.AllocateCopy(Inherited));
}
@@ -5263,7 +5266,7 @@
if (Tok.is(tok::colon)) {
ContextChange CC(*this, SD);
SmallVector<TypeLoc, 2> Inherited;
- Status |= parseInheritance(Inherited, /*classRequirementLoc=*/nullptr);
+ Status |= parseInheritance(Inherited, /*allowClassRequirement=*/false);
SD->setInherited(Context.AllocateCopy(Inherited));
}
@@ -5351,7 +5354,7 @@
if (Tok.is(tok::colon)) {
ContextChange CC(*this, CD);
SmallVector<TypeLoc, 2> Inherited;
- Status |= parseInheritance(Inherited, /*classRequirementLoc=*/nullptr);
+ Status |= parseInheritance(Inherited, /*allowClassRequirement=*/false);
CD->setInherited(Context.AllocateCopy(Inherited));
}
@@ -5439,11 +5442,11 @@
// Parse optional inheritance clause.
SmallVector<TypeLoc, 4> InheritedProtocols;
- SourceLoc classRequirementLoc;
SourceLoc colonLoc;
if (Tok.is(tok::colon)) {
colonLoc = Tok.getLoc();
- Status |= parseInheritance(InheritedProtocols, &classRequirementLoc);
+ Status |= parseInheritance(InheritedProtocols,
+ /*allowClassRequirement=*/true);
}
TrailingWhereClause *TrailingWhere = nullptr;
@@ -5460,10 +5463,6 @@
Context.AllocateCopy(InheritedProtocols), TrailingWhere);
// No need to setLocalDiscriminator: protocols can't appear in local contexts.
- // If there was a 'class' requirement, mark this as a class-bounded protocol.
- if (classRequirementLoc.isValid())
- Proto->setClassBounded(classRequirementLoc);
-
Proto->getAttrs() = Attributes;
ContextChange CC(*this, Proto);
diff --git a/test/IDE/print_ast_tc_decls.swift b/test/IDE/print_ast_tc_decls.swift
index 34d62ee..406d888 100644
--- a/test/IDE/print_ast_tc_decls.swift
+++ b/test/IDE/print_ast_tc_decls.swift
@@ -486,7 +486,7 @@
}
protocol d0150_TestClassProtocol : class {}
-// PASS_COMMON-LABEL: {{^}}protocol d0150_TestClassProtocol : class {{{$}}
+// PASS_COMMON-LABEL: {{^}}protocol d0150_TestClassProtocol : AnyObject {{{$}}
@objc protocol d0151_TestClassProtocol {}
// PASS_COMMON-LABEL: {{^}}@objc protocol d0151_TestClassProtocol {{{$}}
diff --git a/test/IRGen/existentials_objc.sil b/test/IRGen/existentials_objc.sil
index 3a64d16..d84dfb3 100644
--- a/test/IRGen/existentials_objc.sil
+++ b/test/IRGen/existentials_objc.sil
@@ -7,8 +7,11 @@
sil_stage canonical
+import Builtin
import gizmo
+typealias AnyObject = Builtin.AnyObject
+
// rdar://16621578
sil @init_opaque_existential : $@convention(thin) <T where T : Gizmo> (@owned T) -> @out Any {
diff --git a/test/IRGen/fixlifetime.sil b/test/IRGen/fixlifetime.sil
index c6d0d6a..5127d73 100644
--- a/test/IRGen/fixlifetime.sil
+++ b/test/IRGen/fixlifetime.sil
@@ -28,8 +28,12 @@
// CHECK-native: call void @__swift_fixLifetime(%swift.refcounted*
// CHECK-native: call void bitcast (void (%swift.refcounted*)* @__swift_fixLifetime to void (%T11fixlifetime1CC**)*)(%T11fixlifetime1CC**
+import Builtin
+
sil_stage canonical
+typealias AnyObject = Builtin.AnyObject
+
class C {}
sil_vtable C {}
protocol P : class {}
diff --git a/test/IRGen/unowned.sil b/test/IRGen/unowned.sil
index 65a21b5..4eb5253 100644
--- a/test/IRGen/unowned.sil
+++ b/test/IRGen/unowned.sil
@@ -7,8 +7,12 @@
// CHECK: [[OPAQUE:%swift.opaque]] = type opaque
// CHECK: [[A:%T7unowned1AV]] = type <{ %swift.unowned }>
+import Builtin
+
class C {}
sil_vtable C {}
+
+typealias AnyObject = Builtin.AnyObject
protocol P : class {
func explode()
}
diff --git a/test/IRGen/unowned_objc.sil b/test/IRGen/unowned_objc.sil
index 2abf376..5231f96 100644
--- a/test/IRGen/unowned_objc.sil
+++ b/test/IRGen/unowned_objc.sil
@@ -3,6 +3,8 @@
// REQUIRES: CPU=x86_64
// XFAIL: linux
+import Builtin
+
// These types end up in a completely different order with interop disabled.
// CHECK: [[TYPE:%swift.type]] = type
// CHECK: [[OPAQUE:%swift.opaque]] = type opaque
@@ -12,6 +14,7 @@
class C {}
sil_vtable C {}
+typealias AnyObject = Builtin.AnyObject
protocol P : class {
func explode()
}
diff --git a/test/SIL/clone_init_existential.sil b/test/SIL/clone_init_existential.sil
index 5233544..b718fa1 100644
--- a/test/SIL/clone_init_existential.sil
+++ b/test/SIL/clone_init_existential.sil
@@ -7,6 +7,8 @@
import Builtin
+typealias AnyObject = Builtin.AnyObject
+
protocol ClassProto1 : class {
}
diff --git a/test/SIL/ownership-verifier/use_verifier.sil b/test/SIL/ownership-verifier/use_verifier.sil
index 782008b..247dad9 100644
--- a/test/SIL/ownership-verifier/use_verifier.sil
+++ b/test/SIL/ownership-verifier/use_verifier.sil
@@ -15,7 +15,7 @@
sil @allocate_object : $@convention(thin) () -> @owned Builtin.NativeObject
-public protocol AnyObject : class {}
+typealias AnyObject = Builtin.AnyObject
public protocol Error {}
diff --git a/test/SILGen/class_bound_protocols.swift b/test/SILGen/class_bound_protocols.swift
index d65989d..6b4f90f 100644
--- a/test/SILGen/class_bound_protocols.swift
+++ b/test/SILGen/class_bound_protocols.swift
@@ -7,6 +7,8 @@
precedencegroup AssignmentPrecedence {}
+typealias AnyObject = Builtin.AnyObject
+
// -- Class-bound archetypes and existentials are *not* address-only and can
// be manipulated using normal reference type value semantics.
diff --git a/test/SILGen/objc_imported_generic.swift b/test/SILGen/objc_imported_generic.swift
index b343828..b89c683 100644
--- a/test/SILGen/objc_imported_generic.swift
+++ b/test/SILGen/objc_imported_generic.swift
@@ -89,9 +89,9 @@
}
// CHECK-LABEL: sil @_T021objc_imported_generic0C13BlockBridging{{[_0-9a-zA-Z]*}}F
-// CHECK: [[BLOCK_TO_FUNC:%.*]] = function_ref @_T0xxIyBya_xxIxxo_RlzC21objc_imported_generic7AnsibleRzlTR
+// CHECK: [[BLOCK_TO_FUNC:%.*]] = function_ref @_T0xxIyBya_xxIxxo_21objc_imported_generic7AnsibleRzlTR
// CHECK: partial_apply [[BLOCK_TO_FUNC]]<T>
-// CHECK: [[FUNC_TO_BLOCK:%.*]] = function_ref @_T0xxIxxo_xxIyBya_RlzC21objc_imported_generic7AnsibleRzlTR
+// CHECK: [[FUNC_TO_BLOCK:%.*]] = function_ref @_T0xxIxxo_xxIyBya_21objc_imported_generic7AnsibleRzlTR
// CHECK: init_block_storage_header {{.*}} invoke [[FUNC_TO_BLOCK]]<T>
// CHECK-LABEL: sil @_T021objc_imported_generic20arraysOfGenericParam{{[_0-9a-zA-Z]*}}F
diff --git a/test/SILOptimizer/address_projection.sil b/test/SILOptimizer/address_projection.sil
index 2c03a65..b4413f2 100644
--- a/test/SILOptimizer/address_projection.sil
+++ b/test/SILOptimizer/address_projection.sil
@@ -5,6 +5,7 @@
sil_stage canonical
// CHECK: sil_stage lowered
+typealias AnyObject = Builtin.AnyObject
typealias Int = Builtin.Int64
// CHECK-LABEL: sil hidden @f010_addrlower_identity : $@convention(thin) <T> (@in T) -> @out T {
diff --git a/test/SILOptimizer/rcidentity.sil b/test/SILOptimizer/rcidentity.sil
index ef73830..ebea583 100644
--- a/test/SILOptimizer/rcidentity.sil
+++ b/test/SILOptimizer/rcidentity.sil
@@ -6,6 +6,8 @@
// NonTest Utilities //
///////////////////////
+typealias AnyObject = Builtin.AnyObject
+
protocol FakeAnyObject : class {}
class C : FakeAnyObject {
diff --git a/test/SourceKit/CursorInfo/cursor_info.swift b/test/SourceKit/CursorInfo/cursor_info.swift
index d207eb6..28ad7ac 100644
--- a/test/SourceKit/CursorInfo/cursor_info.swift
+++ b/test/SourceKit/CursorInfo/cursor_info.swift
@@ -600,7 +600,7 @@
// FIXME: ref.class - rdar://problem/25014968
// RUN: %sourcekitd-test -req=cursor -pos=150:10 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck %s -check-prefix=CHECK66
-// CHECK66: <decl.protocol><syntaxtype.keyword>protocol</syntaxtype.keyword> <decl.name>P2</decl.name> : <syntaxtype.keyword>class</syntaxtype.keyword>, <ref.protocol usr="s:11cursor_info2P1P">P1</ref.protocol></decl.protocol>
+// CHECK66: <decl.protocol><syntaxtype.keyword>protocol</syntaxtype.keyword> <decl.name>P2</decl.name> : <ref.typealias usr="s:s9AnyObjecta">AnyObject</ref.typealias>, <ref.protocol usr="s:11cursor_info2P1P">P1</ref.protocol></decl.protocol>
// RUN: %sourcekitd-test -req=cursor -pos=114:18 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | %FileCheck %s -check-prefix=CHECK67
// CHECK67: source.lang.swift.decl.associatedtype (114:18-114:19)
diff --git a/test/decl/protocol/req/class.swift b/test/decl/protocol/req/class.swift
index 3767479..b7d1487 100644
--- a/test/decl/protocol/req/class.swift
+++ b/test/decl/protocol/req/class.swift
@@ -5,5 +5,7 @@
protocol P2 : class, class { } // expected-error{{redundant 'class' requirement}}{{20-27=}}
protocol P3 : P2, class { } // expected-error{{'class' must come first in the requirement list}}{{15-15=class, }}{{17-24=}}
+// expected-warning@-1 {{redundant layout constraint 'Self' : 'AnyObject'}}
+// expected-note@-2 {{layout constraint constraint 'Self' : 'AnyObject' implied here}}
struct X : class { } // expected-error{{'class' requirement only applies to protocols}} {{12-18=}}