Skip to content

Commit 50e7c06

Browse files
committed
Parse: Simpler handling of 'class' in protocol inheritance list
Instead of treating this as its own thing, just parse it as if the user wrote 'AnyObject'.
1 parent 4174519 commit 50e7c06

20 files changed

+58
-76
lines changed

include/swift/AST/Decl.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3489,9 +3489,6 @@ struct SelfReferenceKind {
34893489
class ProtocolDecl final : public NominalTypeDecl {
34903490
SourceLoc ProtocolLoc;
34913491

3492-
/// The location of the 'class' keyword for class-bound protocols.
3493-
SourceLoc ClassRequirementLoc;
3494-
34953492
/// The syntactic representation of the where clause in a protocol like
34963493
/// `protocol ... where ... { ... }`.
34973494
TrailingWhereClause *TrailingWhere;
@@ -3571,17 +3568,6 @@ class ProtocolDecl final : public NominalTypeDecl {
35713568
ProtocolDeclBits.RequiresClass = requiresClass;
35723569
}
35733570

3574-
/// Specify that this protocol is class-bounded, recording the location of
3575-
/// the 'class' keyword.
3576-
void setClassBounded(SourceLoc loc) {
3577-
ClassRequirementLoc = loc;
3578-
ProtocolDeclBits.RequiresClassValid = true;
3579-
ProtocolDeclBits.RequiresClass = true;
3580-
}
3581-
3582-
/// Retrieve the source location of the 'class' keyword.
3583-
SourceLoc getClassBoundedLoc() const { return ClassRequirementLoc; }
3584-
35853571
/// Determine whether an existential conforming to this protocol can be
35863572
/// matched with a generic type parameter constrained to this protocol.
35873573
/// This is only permitted if there is nothing "non-trivial" that we

include/swift/Parse/Parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ class Parser {
773773
ParserResult<ImportDecl> parseDeclImport(ParseDeclOptions Flags,
774774
DeclAttributes &Attributes);
775775
ParserStatus parseInheritance(SmallVectorImpl<TypeLoc> &Inherited,
776-
SourceLoc *classRequirementLoc);
776+
bool allowClassRequirement);
777777
ParserStatus parseDeclItem(bool &PreviousHadSemi,
778778
Parser::ParseDeclOptions Options,
779779
llvm::function_ref<void(Decl*)> handler);

lib/AST/ASTPrinter.cpp

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -594,11 +594,9 @@ class PrintAST : public ASTVisitor<PrintAST> {
594594
void printInherited(const Decl *decl,
595595
ArrayRef<TypeLoc> inherited,
596596
ArrayRef<ProtocolDecl *> protos,
597-
Type superclass = {},
598-
bool explicitClass = false);
597+
Type superclass = {});
599598

600-
void printInherited(const NominalTypeDecl *decl,
601-
bool explicitClass = false);
599+
void printInherited(const NominalTypeDecl *decl);
602600
void printInherited(const EnumDecl *D);
603601
void printInherited(const ExtensionDecl *decl);
604602
void printInherited(const GenericTypeParamDecl *D);
@@ -1635,9 +1633,8 @@ void PrintAST::printNominalDeclGenericRequirements(NominalTypeDecl *decl) {
16351633
void PrintAST::printInherited(const Decl *decl,
16361634
ArrayRef<TypeLoc> inherited,
16371635
ArrayRef<ProtocolDecl *> protos,
1638-
Type superclass,
1639-
bool explicitClass) {
1640-
if (inherited.empty() && superclass.isNull() && !explicitClass) {
1636+
Type superclass) {
1637+
if (inherited.empty() && superclass.isNull()) {
16411638
if (protos.empty())
16421639
return;
16431640
}
@@ -1646,10 +1643,7 @@ void PrintAST::printInherited(const Decl *decl,
16461643
bool PrintedColon = false;
16471644
bool PrintedInherited = false;
16481645

1649-
if (explicitClass) {
1650-
Printer << " : " << tok::kw_class;
1651-
PrintedInherited = true;
1652-
} else if (superclass) {
1646+
if (superclass) {
16531647
bool ShouldPrintSuper = true;
16541648
if (auto NTD = superclass->getAnyNominal()) {
16551649
ShouldPrintSuper = shouldPrint(NTD);
@@ -1701,9 +1695,6 @@ void PrintAST::printInherited(const Decl *decl,
17011695

17021696
Printer << " : ";
17031697

1704-
if (explicitClass)
1705-
Printer << " " << tok::kw_class << ", ";
1706-
17071698
interleave(TypesToPrint, [&](TypeLoc TL) {
17081699
printTypeLoc(TL);
17091700
}, [&]() {
@@ -1712,9 +1703,8 @@ void PrintAST::printInherited(const Decl *decl,
17121703
}
17131704
}
17141705

1715-
void PrintAST::printInherited(const NominalTypeDecl *decl,
1716-
bool explicitClass) {
1717-
printInherited(decl, decl->getInherited(), { }, nullptr, explicitClass);
1706+
void PrintAST::printInherited(const NominalTypeDecl *decl) {
1707+
printInherited(decl, decl->getInherited(), { }, nullptr);
17181708
}
17191709

17201710
void PrintAST::printInherited(const EnumDecl *decl) {
@@ -2139,23 +2129,7 @@ void PrintAST::visitProtocolDecl(ProtocolDecl *decl) {
21392129
Printer.printName(decl->getName());
21402130
});
21412131

2142-
// Figure out whether we need an explicit 'class' in the inheritance.
2143-
bool explicitClass = false;
2144-
if (decl->requiresClass() && !decl->isObjC()) {
2145-
bool inheritsRequiresClass = false;
2146-
for (auto proto : decl->getLocalProtocols(
2147-
ConformanceLookupKind::OnlyExplicit)) {
2148-
if (proto->requiresClass()) {
2149-
inheritsRequiresClass = true;
2150-
break;
2151-
}
2152-
}
2153-
2154-
if (!inheritsRequiresClass)
2155-
explicitClass = true;
2156-
}
2157-
2158-
printInherited(decl, explicitClass);
2132+
printInherited(decl);
21592133

21602134
// The trailing where clause is a syntactic thing, which isn't serialized
21612135
// (etc.) and thus isn't available for printing things out of

lib/Parse/ParseDecl.cpp

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2651,13 +2651,11 @@ ParserResult<ImportDecl> Parser::parseDeclImport(ParseDeclOptions Flags,
26512651
/// type-identifier
26522652
/// \endverbatim
26532653
ParserStatus Parser::parseInheritance(SmallVectorImpl<TypeLoc> &Inherited,
2654-
SourceLoc *classRequirementLoc) {
2654+
bool allowClassRequirement) {
26552655
Scope S(this, ScopeKind::InheritanceClause);
26562656
consumeToken(tok::colon);
26572657

2658-
// Clear out the class requirement location.
2659-
if (classRequirementLoc)
2660-
*classRequirementLoc = SourceLoc();
2658+
SourceLoc classRequirementLoc;
26612659

26622660
ParserStatus Status;
26632661
SourceLoc prevComma;
@@ -2666,17 +2664,17 @@ ParserStatus Parser::parseInheritance(SmallVectorImpl<TypeLoc> &Inherited,
26662664
if (Tok.is(tok::kw_class)) {
26672665
// If we aren't allowed to have a class requirement here, complain.
26682666
auto classLoc = consumeToken();
2669-
if (!classRequirementLoc) {
2667+
if (!allowClassRequirement) {
26702668
SourceLoc endLoc = Tok.is(tok::comma) ? Tok.getLoc() : classLoc;
26712669
diagnose(classLoc, diag::invalid_class_requirement)
26722670
.fixItRemove(SourceRange(classLoc, endLoc));
26732671
continue;
26742672
}
26752673

26762674
// If we already saw a class requirement, complain.
2677-
if (classRequirementLoc->isValid()) {
2675+
if (classRequirementLoc.isValid()) {
26782676
diagnose(classLoc, diag::redundant_class_requirement)
2679-
.highlight(*classRequirementLoc)
2677+
.highlight(classRequirementLoc)
26802678
.fixItRemove(SourceRange(prevComma, classLoc));
26812679
continue;
26822680
}
@@ -2690,7 +2688,12 @@ ParserStatus Parser::parseInheritance(SmallVectorImpl<TypeLoc> &Inherited,
26902688
}
26912689

26922690
// Record the location of the 'class' keyword.
2693-
*classRequirementLoc = classLoc;
2691+
classRequirementLoc = classLoc;
2692+
2693+
// Add 'AnyObject' to the inherited list.
2694+
Inherited.push_back(
2695+
new (Context) SimpleIdentTypeRepr(classLoc,
2696+
Context.getIdentifier("AnyObject")));
26942697
continue;
26952698
}
26962699

@@ -2954,7 +2957,7 @@ Parser::parseDeclExtension(ParseDeclOptions Flags, DeclAttributes &Attributes) {
29542957
// Parse optional inheritance clause.
29552958
SmallVector<TypeLoc, 2> Inherited;
29562959
if (Tok.is(tok::colon))
2957-
status |= parseInheritance(Inherited, /*classRequirementLoc=*/nullptr);
2960+
status |= parseInheritance(Inherited, /*allowClassRequirement=*/false);
29582961

29592962
// Parse the optional where-clause.
29602963
TrailingWhereClause *trailingWhereClause = nullptr;
@@ -3293,7 +3296,7 @@ ParserResult<TypeDecl> Parser::parseDeclAssociatedType(Parser::ParseDeclOptions
32933296
// FIXME: Allow class requirements here.
32943297
SmallVector<TypeLoc, 2> Inherited;
32953298
if (Tok.is(tok::colon))
3296-
Status |= parseInheritance(Inherited, /*classRequirementLoc=*/nullptr);
3299+
Status |= parseInheritance(Inherited, /*allowClassRequirement=*/false);
32973300

32983301
ParserResult<TypeRepr> UnderlyingTy;
32993302
if (Tok.is(tok::equal)) {
@@ -5033,7 +5036,7 @@ ParserResult<EnumDecl> Parser::parseDeclEnum(ParseDeclOptions Flags,
50335036
// Parse optional inheritance clause within the context of the enum.
50345037
if (Tok.is(tok::colon)) {
50355038
SmallVector<TypeLoc, 2> Inherited;
5036-
Status |= parseInheritance(Inherited, /*classRequirementLoc=*/nullptr);
5039+
Status |= parseInheritance(Inherited, /*allowClassRequirement=*/false);
50375040
ED->setInherited(Context.AllocateCopy(Inherited));
50385041
}
50395042

@@ -5293,7 +5296,7 @@ ParserResult<StructDecl> Parser::parseDeclStruct(ParseDeclOptions Flags,
52935296
// Parse optional inheritance clause within the context of the struct.
52945297
if (Tok.is(tok::colon)) {
52955298
SmallVector<TypeLoc, 2> Inherited;
5296-
Status |= parseInheritance(Inherited, /*classRequirementLoc=*/nullptr);
5299+
Status |= parseInheritance(Inherited, /*allowClassRequirement=*/false);
52975300
SD->setInherited(Context.AllocateCopy(Inherited));
52985301
}
52995302

@@ -5378,7 +5381,7 @@ ParserResult<ClassDecl> Parser::parseDeclClass(SourceLoc ClassLoc,
53785381
// Parse optional inheritance clause within the context of the class.
53795382
if (Tok.is(tok::colon)) {
53805383
SmallVector<TypeLoc, 2> Inherited;
5381-
Status |= parseInheritance(Inherited, /*classRequirementLoc=*/nullptr);
5384+
Status |= parseInheritance(Inherited, /*allowClassRequirement=*/false);
53825385
CD->setInherited(Context.AllocateCopy(Inherited));
53835386
}
53845387

@@ -5462,11 +5465,11 @@ parseDeclProtocol(ParseDeclOptions Flags, DeclAttributes &Attributes) {
54625465

54635466
// Parse optional inheritance clause.
54645467
SmallVector<TypeLoc, 4> InheritedProtocols;
5465-
SourceLoc classRequirementLoc;
54665468
SourceLoc colonLoc;
54675469
if (Tok.is(tok::colon)) {
54685470
colonLoc = Tok.getLoc();
5469-
Status |= parseInheritance(InheritedProtocols, &classRequirementLoc);
5471+
Status |= parseInheritance(InheritedProtocols,
5472+
/*allowClassRequirement=*/true);
54705473
}
54715474

54725475
TrailingWhereClause *TrailingWhere = nullptr;
@@ -5483,10 +5486,6 @@ parseDeclProtocol(ParseDeclOptions Flags, DeclAttributes &Attributes) {
54835486
Context.AllocateCopy(InheritedProtocols), TrailingWhere);
54845487
// No need to setLocalDiscriminator: protocols can't appear in local contexts.
54855488

5486-
// If there was a 'class' requirement, mark this as a class-bounded protocol.
5487-
if (classRequirementLoc.isValid())
5488-
Proto->setClassBounded(classRequirementLoc);
5489-
54905489
Proto->getAttrs() = Attributes;
54915490

54925491
ContextChange CC(*this, Proto);

test/IDE/print_ast_tc_decls.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ protocol d0130_TestProtocol {
486486
}
487487

488488
protocol d0150_TestClassProtocol : class {}
489-
// PASS_COMMON-LABEL: {{^}}protocol d0150_TestClassProtocol : class {{{$}}
489+
// PASS_COMMON-LABEL: {{^}}protocol d0150_TestClassProtocol : AnyObject where Self : AnyObject {{{$}}
490490

491491
@objc protocol d0151_TestClassProtocol {}
492492
// PASS_COMMON-LABEL: {{^}}@objc protocol d0151_TestClassProtocol {{{$}}

test/IRGen/existentials_objc.sil

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77

88
sil_stage canonical
99

10+
import Builtin
1011
import gizmo
1112

13+
typealias AnyObject = Builtin.AnyObject
14+
1215
// rdar://16621578
1316

1417
sil @init_opaque_existential : $@convention(thin) <T where T : Gizmo> (@owned T) -> @out Any {

test/IRGen/fixlifetime.sil

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,12 @@
2828
// CHECK-native: call void @__swift_fixLifetime(%swift.refcounted*
2929
// CHECK-native: call void bitcast (void (%swift.refcounted*)* @__swift_fixLifetime to void (%T11fixlifetime1CC**)*)(%T11fixlifetime1CC**
3030

31+
import Builtin
32+
3133
sil_stage canonical
3234

35+
typealias AnyObject = Builtin.AnyObject
36+
3337
class C {}
3438
sil_vtable C {}
3539
protocol P : class {}

test/IRGen/unowned.sil

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@
77
// CHECK: [[OPAQUE:%swift.opaque]] = type opaque
88
// CHECK: [[A:%T7unowned1AV]] = type <{ %swift.unowned }>
99

10+
import Builtin
11+
1012
class C {}
1113
sil_vtable C {}
14+
15+
typealias AnyObject = Builtin.AnyObject
1216
protocol P : class {
1317
func explode()
1418
}

test/IRGen/unowned_objc.sil

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// REQUIRES: CPU=x86_64
44
// XFAIL: linux
55

6+
import Builtin
7+
68
// These types end up in a completely different order with interop disabled.
79
// CHECK: [[TYPE:%swift.type]] = type
810
// CHECK: [[OPAQUE:%swift.opaque]] = type opaque
@@ -12,6 +14,7 @@
1214

1315
class C {}
1416
sil_vtable C {}
17+
typealias AnyObject = Builtin.AnyObject
1518
protocol P : class {
1619
func explode()
1720
}

test/SIL/clone_init_existential.sil

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ sil_stage canonical
77

88
import Builtin
99

10+
typealias AnyObject = Builtin.AnyObject
11+
1012
protocol ClassProto1 : class {
1113
}
1214

test/SIL/ownership-verifier/objc_use_verifier.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// REQUIRES: asserts
33
// REQUIRES: objc_interop
44

5-
@objc protocol NSBurrito : class {}
5+
@objc protocol NSBurrito {}
66

77
class Protocol : NSBurrito {}
88

test/SIL/ownership-verifier/opaque_use_verifier.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ bb0(%0 : @guaranteed $T):
5858
return %4 : $T
5959
}
6060

61-
public protocol AnyObject : class {}
61+
typealias AnyObject = Builtin.AnyObject
6262

6363
sil @takeType : $@convention(thin) (@thick AnyObject.Type) -> () {
6464
bb0(%0 : @trivial $@thick AnyObject.Type):

test/SIL/ownership-verifier/use_verifier.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import Builtin
1515

1616
sil @allocate_object : $@convention(thin) () -> @owned Builtin.NativeObject
1717

18-
public protocol AnyObject : class {}
18+
typealias AnyObject = Builtin.AnyObject
1919

2020
public protocol Error {}
2121

test/SILGen/class_bound_protocols.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ enum Optional<T> {
77

88
precedencegroup AssignmentPrecedence {}
99

10+
typealias AnyObject = Builtin.AnyObject
11+
1012
// -- Class-bound archetypes and existentials are *not* address-only and can
1113
// be manipulated using normal reference type value semantics.
1214

test/SILGen/objc_imported_generic.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ public func genericBlockBridging<T: Ansible>(x: GenericClass<T>) {
8989
}
9090

9191
// CHECK-LABEL: sil @_T021objc_imported_generic0C13BlockBridging{{[_0-9a-zA-Z]*}}F
92-
// CHECK: [[BLOCK_TO_FUNC:%.*]] = function_ref @_T0xxIyBya_xxIxxo_RlzC21objc_imported_generic7AnsibleRzlTR
92+
// CHECK: [[BLOCK_TO_FUNC:%.*]] = function_ref @_T0xxIyBya_xxIxxo_21objc_imported_generic7AnsibleRzlTR
9393
// CHECK: partial_apply [[BLOCK_TO_FUNC]]<T>
94-
// CHECK: [[FUNC_TO_BLOCK:%.*]] = function_ref @_T0xxIxxo_xxIyBya_RlzC21objc_imported_generic7AnsibleRzlTR
94+
// CHECK: [[FUNC_TO_BLOCK:%.*]] = function_ref @_T0xxIxxo_xxIyBya_21objc_imported_generic7AnsibleRzlTR
9595
// CHECK: init_block_storage_header {{.*}} invoke [[FUNC_TO_BLOCK]]<T>
9696

9797
// CHECK-LABEL: sil @_T021objc_imported_generic20arraysOfGenericParam{{[_0-9a-zA-Z]*}}F

test/SILOptimizer/address_projection.sil

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Builtin
55
sil_stage canonical
66
// CHECK: sil_stage lowered
77

8+
typealias AnyObject = Builtin.AnyObject
89
typealias Int = Builtin.Int64
910

1011
// CHECK-LABEL: sil hidden @f010_addrlower_identity : $@convention(thin) <T> (@in T) -> @out T {

test/SILOptimizer/rcidentity.sil

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import Builtin
66
// NonTest Utilities //
77
///////////////////////
88

9+
typealias AnyObject = Builtin.AnyObject
10+
911
protocol FakeAnyObject : class {}
1012

1113
class C : FakeAnyObject {

test/SourceKit/CursorInfo/cursor_info.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ func hasLocalizationKey2() {}
599599
// FIXME: ref.class - rdar://problem/25014968
600600

601601
// 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
602-
// 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>
602+
// 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> <syntaxtype.keyword>where</syntaxtype.keyword> <decl.generic_type_requirement><ref.generic_type_param usr="s:11cursor_info2P2P4Selfxmfp">Self</ref.generic_type_param> : AnyObject</decl.generic_type_requirement></decl.protocol>
603603

604604
// 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
605605
// CHECK67: source.lang.swift.decl.associatedtype (114:18-114:19)

test/decl/protocol/req/class.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@ protocol P1 : class { }
55
protocol P2 : class, class { } // expected-error{{redundant 'class' requirement}}{{20-27=}}
66

77
protocol P3 : P2, class { } // expected-error{{'class' must come first in the requirement list}}{{15-15=class, }}{{17-24=}}
8+
// expected-warning@-1 {{redundant layout constraint 'Self' : 'AnyObject'}}
9+
// expected-note@-2 {{layout constraint constraint 'Self' : 'AnyObject' implied here}}
810

911
struct X : class { } // expected-error{{'class' requirement only applies to protocols}} {{12-18=}}

0 commit comments

Comments
 (0)