Skip to content

Commit 451cf44

Browse files
authored
Merge pull request #11786 from slavapestov/fix-class-anyobject-4.0
Fix printing of class-constrained protocols [4.0]
2 parents 6b45c4a + 21fa797 commit 451cf44

File tree

17 files changed

+61
-75
lines changed

17 files changed

+61
-75
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 : 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 : 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
@@ -763,7 +763,7 @@ class Parser {
763763
ParserResult<ImportDecl> parseDeclImport(ParseDeclOptions Flags,
764764
DeclAttributes &Attributes);
765765
ParserStatus parseInheritance(SmallVectorImpl<TypeLoc> &Inherited,
766-
SourceLoc *classRequirementLoc);
766+
bool allowClassRequirement);
767767
ParserStatus parseDeclItem(bool &PreviousHadSemi,
768768
Parser::ParseDeclOptions Options,
769769
llvm::function_ref<void(Decl*)> handler);

lib/AST/ASTPrinter.cpp

Lines changed: 14 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -989,11 +989,9 @@ class PrintAST : public ASTVisitor<PrintAST> {
989989
void printInherited(const Decl *decl,
990990
ArrayRef<TypeLoc> inherited,
991991
ArrayRef<ProtocolDecl *> protos,
992-
Type superclass = {},
993-
bool explicitClass = false);
992+
Type superclass = {});
994993

995-
void printInherited(const NominalTypeDecl *decl,
996-
bool explicitClass = false);
994+
void printInherited(const NominalTypeDecl *decl);
997995
void printInherited(const EnumDecl *D);
998996
void printInherited(const ExtensionDecl *decl);
999997
void printInherited(const GenericTypeParamDecl *D);
@@ -1312,8 +1310,12 @@ bestRequirementPrintLocation(ProtocolDecl *proto, const Requirement &req) {
13121310

13131311
// A requirement like Self : Protocol or Self.T : Class might be from an
13141312
// inheritance, or might be a where clause.
1315-
if (req.getKind() != RequirementKind::Layout && result.second) {
1316-
auto inherited = req.getSecondType();
1313+
if (result.second) {
1314+
Type inherited;
1315+
if (req.getKind() == RequirementKind::Layout)
1316+
inherited = proto->getASTContext().getAnyObjectType();
1317+
else
1318+
inherited = req.getSecondType();
13171319
inWhereClause =
13181320
none_of(result.first->getInherited(), [&](const TypeLoc &loc) {
13191321
return loc.getType()->isEqual(inherited);
@@ -2049,9 +2051,8 @@ void PrintAST::printNominalDeclGenericRequirements(NominalTypeDecl *decl) {
20492051
void PrintAST::printInherited(const Decl *decl,
20502052
ArrayRef<TypeLoc> inherited,
20512053
ArrayRef<ProtocolDecl *> protos,
2052-
Type superclass,
2053-
bool explicitClass) {
2054-
if (inherited.empty() && superclass.isNull() && !explicitClass) {
2054+
Type superclass) {
2055+
if (inherited.empty() && superclass.isNull()) {
20552056
if (protos.empty())
20562057
return;
20572058
}
@@ -2060,10 +2061,7 @@ void PrintAST::printInherited(const Decl *decl,
20602061
bool PrintedColon = false;
20612062
bool PrintedInherited = false;
20622063

2063-
if (explicitClass) {
2064-
Printer << " : " << tok::kw_class;
2065-
PrintedInherited = true;
2066-
} else if (superclass) {
2064+
if (superclass) {
20672065
bool ShouldPrintSuper = true;
20682066
if (auto NTD = superclass->getAnyNominal()) {
20692067
ShouldPrintSuper = shouldPrint(NTD);
@@ -2115,9 +2113,6 @@ void PrintAST::printInherited(const Decl *decl,
21152113

21162114
Printer << " : ";
21172115

2118-
if (explicitClass)
2119-
Printer << " " << tok::kw_class << ", ";
2120-
21212116
interleave(TypesToPrint, [&](TypeLoc TL) {
21222117
printTypeLoc(TL);
21232118
}, [&]() {
@@ -2126,9 +2121,8 @@ void PrintAST::printInherited(const Decl *decl,
21262121
}
21272122
}
21282123

2129-
void PrintAST::printInherited(const NominalTypeDecl *decl,
2130-
bool explicitClass) {
2131-
printInherited(decl, decl->getInherited(), { }, nullptr, explicitClass);
2124+
void PrintAST::printInherited(const NominalTypeDecl *decl) {
2125+
printInherited(decl, decl->getInherited(), { }, nullptr);
21322126
}
21332127

21342128
void PrintAST::printInherited(const EnumDecl *decl) {
@@ -2539,23 +2533,7 @@ void PrintAST::visitProtocolDecl(ProtocolDecl *decl) {
25392533
Printer.printName(decl->getName());
25402534
});
25412535

2542-
// Figure out whether we need an explicit 'class' in the inheritance.
2543-
bool explicitClass = false;
2544-
if (decl->requiresClass() && !decl->isObjC()) {
2545-
bool inheritsRequiresClass = false;
2546-
for (auto proto : decl->getLocalProtocols(
2547-
ConformanceLookupKind::OnlyExplicit)) {
2548-
if (proto->requiresClass()) {
2549-
inheritsRequiresClass = true;
2550-
break;
2551-
}
2552-
}
2553-
2554-
if (!inheritsRequiresClass)
2555-
explicitClass = true;
2556-
}
2557-
2558-
printInherited(decl, explicitClass);
2536+
printInherited(decl);
25592537

25602538
// The trailing where clause is a syntactic thing, which isn't serialized
25612539
// (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
@@ -2630,13 +2630,11 @@ ParserResult<ImportDecl> Parser::parseDeclImport(ParseDeclOptions Flags,
26302630
/// type-identifier
26312631
/// \endverbatim
26322632
ParserStatus Parser::parseInheritance(SmallVectorImpl<TypeLoc> &Inherited,
2633-
SourceLoc *classRequirementLoc) {
2633+
bool allowClassRequirement) {
26342634
Scope S(this, ScopeKind::InheritanceClause);
26352635
consumeToken(tok::colon);
26362636

2637-
// Clear out the class requirement location.
2638-
if (classRequirementLoc)
2639-
*classRequirementLoc = SourceLoc();
2637+
SourceLoc classRequirementLoc;
26402638

26412639
ParserStatus Status;
26422640
SourceLoc prevComma;
@@ -2645,17 +2643,17 @@ ParserStatus Parser::parseInheritance(SmallVectorImpl<TypeLoc> &Inherited,
26452643
if (Tok.is(tok::kw_class)) {
26462644
// If we aren't allowed to have a class requirement here, complain.
26472645
auto classLoc = consumeToken();
2648-
if (!classRequirementLoc) {
2646+
if (!allowClassRequirement) {
26492647
SourceLoc endLoc = Tok.is(tok::comma) ? Tok.getLoc() : classLoc;
26502648
diagnose(classLoc, diag::invalid_class_requirement)
26512649
.fixItRemove(SourceRange(classLoc, endLoc));
26522650
continue;
26532651
}
26542652

26552653
// If we already saw a class requirement, complain.
2656-
if (classRequirementLoc->isValid()) {
2654+
if (classRequirementLoc.isValid()) {
26572655
diagnose(classLoc, diag::redundant_class_requirement)
2658-
.highlight(*classRequirementLoc)
2656+
.highlight(classRequirementLoc)
26592657
.fixItRemove(SourceRange(prevComma, classLoc));
26602658
continue;
26612659
}
@@ -2669,7 +2667,12 @@ ParserStatus Parser::parseInheritance(SmallVectorImpl<TypeLoc> &Inherited,
26692667
}
26702668

26712669
// Record the location of the 'class' keyword.
2672-
*classRequirementLoc = classLoc;
2670+
classRequirementLoc = classLoc;
2671+
2672+
// Add 'AnyObject' to the inherited list.
2673+
Inherited.push_back(
2674+
new (Context) SimpleIdentTypeRepr(classLoc,
2675+
Context.getIdentifier("AnyObject")));
26732676
continue;
26742677
}
26752678

@@ -2933,7 +2936,7 @@ Parser::parseDeclExtension(ParseDeclOptions Flags, DeclAttributes &Attributes) {
29332936
// Parse optional inheritance clause.
29342937
SmallVector<TypeLoc, 2> Inherited;
29352938
if (Tok.is(tok::colon))
2936-
status |= parseInheritance(Inherited, /*classRequirementLoc=*/nullptr);
2939+
status |= parseInheritance(Inherited, /*allowClassRequirement=*/false);
29372940

29382941
// Parse the optional where-clause.
29392942
TrailingWhereClause *trailingWhereClause = nullptr;
@@ -3270,7 +3273,7 @@ ParserResult<TypeDecl> Parser::parseDeclAssociatedType(Parser::ParseDeclOptions
32703273
// FIXME: Allow class requirements here.
32713274
SmallVector<TypeLoc, 2> Inherited;
32723275
if (Tok.is(tok::colon))
3273-
Status |= parseInheritance(Inherited, /*classRequirementLoc=*/nullptr);
3276+
Status |= parseInheritance(Inherited, /*allowClassRequirement=*/false);
32743277

32753278
ParserResult<TypeRepr> UnderlyingTy;
32763279
if (Tok.is(tok::equal)) {
@@ -5000,7 +5003,7 @@ ParserResult<EnumDecl> Parser::parseDeclEnum(ParseDeclOptions Flags,
50005003
if (Tok.is(tok::colon)) {
50015004
ContextChange CC(*this, ED);
50025005
SmallVector<TypeLoc, 2> Inherited;
5003-
Status |= parseInheritance(Inherited, /*classRequirementLoc=*/nullptr);
5006+
Status |= parseInheritance(Inherited, /*allowClassRequirement=*/false);
50045007
ED->setInherited(Context.AllocateCopy(Inherited));
50055008
}
50065009

@@ -5263,7 +5266,7 @@ ParserResult<StructDecl> Parser::parseDeclStruct(ParseDeclOptions Flags,
52635266
if (Tok.is(tok::colon)) {
52645267
ContextChange CC(*this, SD);
52655268
SmallVector<TypeLoc, 2> Inherited;
5266-
Status |= parseInheritance(Inherited, /*classRequirementLoc=*/nullptr);
5269+
Status |= parseInheritance(Inherited, /*allowClassRequirement=*/false);
52675270
SD->setInherited(Context.AllocateCopy(Inherited));
52685271
}
52695272

@@ -5351,7 +5354,7 @@ ParserResult<ClassDecl> Parser::parseDeclClass(SourceLoc ClassLoc,
53515354
if (Tok.is(tok::colon)) {
53525355
ContextChange CC(*this, CD);
53535356
SmallVector<TypeLoc, 2> Inherited;
5354-
Status |= parseInheritance(Inherited, /*classRequirementLoc=*/nullptr);
5357+
Status |= parseInheritance(Inherited, /*allowClassRequirement=*/false);
53555358
CD->setInherited(Context.AllocateCopy(Inherited));
53565359
}
53575360

@@ -5439,11 +5442,11 @@ parseDeclProtocol(ParseDeclOptions Flags, DeclAttributes &Attributes) {
54395442

54405443
// Parse optional inheritance clause.
54415444
SmallVector<TypeLoc, 4> InheritedProtocols;
5442-
SourceLoc classRequirementLoc;
54435445
SourceLoc colonLoc;
54445446
if (Tok.is(tok::colon)) {
54455447
colonLoc = Tok.getLoc();
5446-
Status |= parseInheritance(InheritedProtocols, &classRequirementLoc);
5448+
Status |= parseInheritance(InheritedProtocols,
5449+
/*allowClassRequirement=*/true);
54475450
}
54485451

54495452
TrailingWhereClause *TrailingWhere = nullptr;
@@ -5460,10 +5463,6 @@ parseDeclProtocol(ParseDeclOptions Flags, DeclAttributes &Attributes) {
54605463
Context.AllocateCopy(InheritedProtocols), TrailingWhere);
54615464
// No need to setLocalDiscriminator: protocols can't appear in local contexts.
54625465

5463-
// If there was a 'class' requirement, mark this as a class-bounded protocol.
5464-
if (classRequirementLoc.isValid())
5465-
Proto->setClassBounded(classRequirementLoc);
5466-
54675466
Proto->getAttrs() = Attributes;
54685467

54695468
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 {{{$}}
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/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
@@ -600,7 +600,7 @@ func hasLocalizationKey2() {}
600600
// FIXME: ref.class - rdar://problem/25014968
601601

602602
// 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
603-
// 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>
603+
// 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>
604604

605605
// 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
606606
// 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)