Skip to content

Commit 06bbc70

Browse files
committed
Module printing and serialization support for @unchecked Sendable
1 parent 29f5d7a commit 06bbc70

31 files changed

+269
-252
lines changed

include/swift/AST/ASTPrinter.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/Basic/QuotedString.h"
1818
#include "swift/Basic/UUID.h"
1919
#include "swift/AST/Identifier.h"
20+
#include "swift/AST/Decl.h"
2021
#include "llvm/ADT/SmallString.h"
2122
#include "llvm/ADT/StringRef.h"
2223
#include "llvm/ADT/DenseSet.h"
@@ -351,8 +352,9 @@ void printEnumElementsAsCases(
351352
llvm::DenseSet<EnumElementDecl *> &UnhandledElements,
352353
llvm::raw_ostream &OS);
353354

354-
void getInheritedForPrinting(const Decl *decl, const PrintOptions &options,
355-
llvm::SmallVectorImpl<TypeLoc> &Results);
355+
void getInheritedForPrinting(
356+
const Decl *decl, const PrintOptions &options,
357+
llvm::SmallVectorImpl<InheritedEntry> &Results);
356358

357359
StringRef getAccessorKindString(AccessorKind value);
358360

include/swift/AST/Decl.h

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,17 @@ class ImportDecl final : public Decl,
12091209
}
12101210
};
12111211

1212+
/// An entry in the "inherited" list of a type or extension.
1213+
struct InheritedEntry : public TypeLoc {
1214+
/// Whether there was an @unchecked attribute.
1215+
bool isUnchecked = false;
1216+
1217+
InheritedEntry(const TypeLoc &typeLoc);
1218+
1219+
InheritedEntry(const TypeLoc &typeLoc, bool isUnchecked)
1220+
: TypeLoc(typeLoc), isUnchecked(isUnchecked) { }
1221+
};
1222+
12121223
/// ExtensionDecl - This represents a type extension containing methods
12131224
/// associated with the type. This is not a ValueDecl and has no Type because
12141225
/// there are no runtime values of the Extension's type.
@@ -1227,7 +1238,7 @@ class ExtensionDecl final : public GenericContext, public Decl,
12271238
/// extended nominal.
12281239
llvm::PointerIntPair<NominalTypeDecl *, 1, bool> ExtendedNominal;
12291240

1230-
ArrayRef<TypeLoc> Inherited;
1241+
ArrayRef<InheritedEntry> Inherited;
12311242

12321243
/// The next extension in the linked list of extensions.
12331244
///
@@ -1246,7 +1257,7 @@ class ExtensionDecl final : public GenericContext, public Decl,
12461257
friend class IterableDeclContext;
12471258

12481259
ExtensionDecl(SourceLoc extensionLoc, TypeRepr *extendedType,
1249-
ArrayRef<TypeLoc> inherited,
1260+
ArrayRef<InheritedEntry> inherited,
12501261
DeclContext *parent,
12511262
TrailingWhereClause *trailingWhereClause);
12521263

@@ -1271,7 +1282,7 @@ class ExtensionDecl final : public GenericContext, public Decl,
12711282
/// Create a new extension declaration.
12721283
static ExtensionDecl *create(ASTContext &ctx, SourceLoc extensionLoc,
12731284
TypeRepr *extendedType,
1274-
ArrayRef<TypeLoc> inherited,
1285+
ArrayRef<InheritedEntry> inherited,
12751286
DeclContext *parent,
12761287
TrailingWhereClause *trailingWhereClause,
12771288
ClangNode clangNode = ClangNode());
@@ -1326,9 +1337,9 @@ class ExtensionDecl final : public GenericContext, public Decl,
13261337

13271338
/// Retrieve the set of protocols that this type inherits (i.e,
13281339
/// explicitly conforms to).
1329-
ArrayRef<TypeLoc> getInherited() const { return Inherited; }
1340+
ArrayRef<InheritedEntry> getInherited() const { return Inherited; }
13301341

1331-
void setInherited(ArrayRef<TypeLoc> i) { Inherited = i; }
1342+
void setInherited(ArrayRef<InheritedEntry> i) { Inherited = i; }
13321343

13331344
bool hasDefaultAccessLevel() const {
13341345
return Bits.ExtensionDecl.DefaultAndMaxAccessLevel != 0;
@@ -2538,12 +2549,12 @@ class ValueDecl : public Decl {
25382549

25392550
/// This is a common base class for declarations which declare a type.
25402551
class TypeDecl : public ValueDecl {
2541-
ArrayRef<TypeLoc> Inherited;
2552+
ArrayRef<InheritedEntry> Inherited;
25422553

25432554
protected:
25442555
TypeDecl(DeclKind K, llvm::PointerUnion<DeclContext *, ASTContext *> context,
25452556
Identifier name, SourceLoc NameLoc,
2546-
ArrayRef<TypeLoc> inherited) :
2557+
ArrayRef<InheritedEntry> inherited) :
25472558
ValueDecl(K, context, name, NameLoc), Inherited(inherited) {}
25482559

25492560
public:
@@ -2561,9 +2572,9 @@ class TypeDecl : public ValueDecl {
25612572

25622573
/// Retrieve the set of protocols that this type inherits (i.e,
25632574
/// explicitly conforms to).
2564-
ArrayRef<TypeLoc> getInherited() const { return Inherited; }
2575+
ArrayRef<InheritedEntry> getInherited() const { return Inherited; }
25652576

2566-
void setInherited(ArrayRef<TypeLoc> i) { Inherited = i; }
2577+
void setInherited(ArrayRef<InheritedEntry> i) { Inherited = i; }
25672578

25682579
static bool classof(const Decl *D) {
25692580
return D->getKind() >= DeclKind::First_TypeDecl &&
@@ -2588,7 +2599,7 @@ class GenericTypeDecl : public GenericContext, public TypeDecl {
25882599
public:
25892600
GenericTypeDecl(DeclKind K, DeclContext *DC,
25902601
Identifier name, SourceLoc nameLoc,
2591-
ArrayRef<TypeLoc> inherited,
2602+
ArrayRef<InheritedEntry> inherited,
25922603
GenericParamList *GenericParams);
25932604

25942605
// Resolve ambiguity due to multiple base classes.
@@ -3115,7 +3126,7 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
31153126

31163127
NominalTypeDecl(DeclKind K, DeclContext *DC, Identifier name,
31173128
SourceLoc NameLoc,
3118-
ArrayRef<TypeLoc> inherited,
3129+
ArrayRef<InheritedEntry> inherited,
31193130
GenericParamList *GenericParams) :
31203131
GenericTypeDecl(K, DC, name, NameLoc, inherited, GenericParams),
31213132
IterableDeclContext(IterableDeclContextKind::NominalTypeDecl)
@@ -3411,7 +3422,7 @@ class EnumDecl final : public NominalTypeDecl {
34113422

34123423
public:
34133424
EnumDecl(SourceLoc EnumLoc, Identifier Name, SourceLoc NameLoc,
3414-
ArrayRef<TypeLoc> Inherited,
3425+
ArrayRef<InheritedEntry> Inherited,
34153426
GenericParamList *GenericParams, DeclContext *DC);
34163427

34173428
SourceLoc getStartLoc() const { return EnumLoc; }
@@ -3579,7 +3590,7 @@ class StructDecl final : public NominalTypeDecl {
35793590

35803591
public:
35813592
StructDecl(SourceLoc StructLoc, Identifier Name, SourceLoc NameLoc,
3582-
ArrayRef<TypeLoc> Inherited,
3593+
ArrayRef<InheritedEntry> Inherited,
35833594
GenericParamList *GenericParams, DeclContext *DC);
35843595

35853596
SourceLoc getStartLoc() const { return StructLoc; }
@@ -3725,7 +3736,7 @@ class ClassDecl final : public NominalTypeDecl {
37253736

37263737
public:
37273738
ClassDecl(SourceLoc ClassLoc, Identifier Name, SourceLoc NameLoc,
3728-
ArrayRef<TypeLoc> Inherited,
3739+
ArrayRef<InheritedEntry> Inherited,
37293740
GenericParamList *GenericParams, DeclContext *DC,
37303741
bool isActor);
37313742

@@ -4160,7 +4171,7 @@ class ProtocolDecl final : public NominalTypeDecl {
41604171

41614172
public:
41624173
ProtocolDecl(DeclContext *DC, SourceLoc ProtocolLoc, SourceLoc NameLoc,
4163-
Identifier Name, ArrayRef<TypeLoc> Inherited,
4174+
Identifier Name, ArrayRef<InheritedEntry> Inherited,
41644175
TrailingWhereClause *TrailingWhere);
41654176

41664177
using Decl::getASTContext;

include/swift/AST/TypeLoc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class TypeRepr;
2929

3030
/// TypeLoc - Provides source location information for a parsed type.
3131
/// A TypeLoc is stored in AST nodes which use an explicitly written type.
32-
class alignas(1 << TypeReprAlignInBits) TypeLoc final {
32+
class alignas(1 << TypeReprAlignInBits) TypeLoc {
3333
Type Ty;
3434
TypeRepr *TyR = nullptr;
3535

include/swift/AST/TypeRepr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ class alignas(1 << TypeReprAlignInBits) TypeRepr {
135135
SourceLoc getEndLoc() const;
136136
SourceRange getSourceRange() const;
137137

138+
/// Find an @unchecked attribute and return its source location, or return
139+
/// an invalid source location if there is no such attribute.
140+
SourceLoc findUncheckedAttrLoc() const;
141+
138142
/// Is this type grammatically a type-simple?
139143
inline bool isSimple() const; // bottom of this file
140144

include/swift/Parse/Parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,7 @@ class Parser {
11271127

11281128
ParserResult<ImportDecl> parseDeclImport(ParseDeclOptions Flags,
11291129
DeclAttributes &Attributes);
1130-
ParserStatus parseInheritance(SmallVectorImpl<TypeLoc> &Inherited,
1130+
ParserStatus parseInheritance(SmallVectorImpl<InheritedEntry> &Inherited,
11311131
bool allowClassRequirement,
11321132
bool allowAnyObject);
11331133
ParserStatus parseDeclItem(bool &PreviousHadSemi,

lib/AST/ASTDumper.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -499,11 +499,12 @@ namespace {
499499
PrintWithColorRAII(OS, DeclModifierColor) << " trailing_semi";
500500
}
501501

502-
void printInherited(ArrayRef<TypeLoc> Inherited) {
502+
void printInherited(ArrayRef<InheritedEntry> Inherited) {
503503
if (Inherited.empty())
504504
return;
505505
OS << " inherits: ";
506-
interleave(Inherited, [&](TypeLoc Super) { Super.getType().print(OS); },
506+
interleave(Inherited,
507+
[&](InheritedEntry Super) { Super.getType().print(OS); },
507508
[&] { OS << ", "; });
508509
}
509510

lib/AST/ASTPrinter.cpp

Lines changed: 18 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -999,18 +999,6 @@ class PrintAST : public ASTVisitor<PrintAST> {
999999
ASTVisitor::visit(D);
10001000

10011001
if (haveFeatureChecks) {
1002-
// If we guarded a marker protocol, print an alternative typealias
1003-
// for Any.
1004-
if (auto proto = dyn_cast<ProtocolDecl>(D)) {
1005-
if (proto->isMarkerProtocol()) {
1006-
Printer.printNewline();
1007-
Printer << "#else";
1008-
Printer.printNewline();
1009-
printAccess(proto);
1010-
Printer << "typealias " << proto->getName() << " = Any";
1011-
}
1012-
}
1013-
10141002
printCompatibilityFeatureChecksPost(Printer);
10151003
}
10161004

@@ -1819,7 +1807,7 @@ bool ShouldPrintChecker::shouldPrint(const Decl *D,
18191807
auto Ext = cast<ExtensionDecl>(D);
18201808
// If the extension doesn't add protocols or has no members that we should
18211809
// print then skip printing it.
1822-
SmallVector<TypeLoc, 8> ProtocolsToPrint;
1810+
SmallVector<InheritedEntry, 8> ProtocolsToPrint;
18231811
getInheritedForPrinting(Ext, Options, ProtocolsToPrint);
18241812
if (ProtocolsToPrint.empty()) {
18251813
bool HasMemberToPrint = false;
@@ -2237,15 +2225,18 @@ void PrintAST::printInherited(const Decl *decl) {
22372225
if (!Options.PrintInherited) {
22382226
return;
22392227
}
2240-
SmallVector<TypeLoc, 6> TypesToPrint;
2228+
SmallVector<InheritedEntry, 6> TypesToPrint;
22412229
getInheritedForPrinting(decl, Options, TypesToPrint);
22422230
if (TypesToPrint.empty())
22432231
return;
22442232

22452233
Printer << " : ";
22462234

2247-
interleave(TypesToPrint, [&](TypeLoc TL) {
2248-
printTypeLoc(TL);
2235+
interleave(TypesToPrint, [&](InheritedEntry inherited) {
2236+
if (inherited.isUnchecked)
2237+
Printer << "@unchecked ";
2238+
2239+
printTypeLoc(inherited);
22492240
}, [&]() {
22502241
Printer << ", ";
22512242
});
@@ -2515,60 +2506,6 @@ static bool usesFeatureAsyncAwait(Decl *decl) {
25152506
}
25162507

25172508
static bool usesFeatureMarkerProtocol(Decl *decl) {
2518-
// Check an inheritance clause for a marker protocol.
2519-
auto checkInherited = [&](ArrayRef<TypeLoc> inherited) -> bool {
2520-
for (const auto &inheritedEntry : inherited) {
2521-
if (auto inheritedType = inheritedEntry.getType()) {
2522-
if (inheritedType->isExistentialType()) {
2523-
auto layout = inheritedType->getExistentialLayout();
2524-
for (ProtocolType *protoTy : layout.getProtocols()) {
2525-
if (protoTy->getDecl()->isMarkerProtocol())
2526-
return true;
2527-
}
2528-
}
2529-
}
2530-
}
2531-
2532-
return false;
2533-
};
2534-
2535-
// Check generic requirements for a marker protocol.
2536-
auto checkRequirements = [&](ArrayRef<Requirement> requirements) -> bool {
2537-
for (const auto &req: requirements) {
2538-
if (req.getKind() == RequirementKind::Conformance &&
2539-
req.getSecondType()->castTo<ProtocolType>()->getDecl()
2540-
->isMarkerProtocol())
2541-
return true;
2542-
}
2543-
2544-
return false;
2545-
};
2546-
2547-
if (auto proto = dyn_cast<ProtocolDecl>(decl)) {
2548-
if (proto->isMarkerProtocol())
2549-
return true;
2550-
2551-
// Swift.Error and Swift.CodingKey "don't" use the marker protocol.
2552-
if (proto->isSpecificProtocol(KnownProtocolKind::Error) ||
2553-
proto->isSpecificProtocol(KnownProtocolKind::CodingKey)) {
2554-
return false;
2555-
}
2556-
2557-
if (checkInherited(proto->getInherited()))
2558-
return true;
2559-
2560-
if (checkRequirements(proto->getRequirementSignature()))
2561-
return true;
2562-
}
2563-
2564-
if (auto ext = dyn_cast<ExtensionDecl>(decl)) {
2565-
if (checkRequirements(ext->getGenericRequirements()))
2566-
return true;
2567-
2568-
if (checkInherited(ext->getInherited()))
2569-
return true;
2570-
}
2571-
25722509
return false;
25732510
}
25742511

@@ -2645,7 +2582,7 @@ static bool usesFeatureRethrowsProtocol(
26452582
return false;
26462583

26472584
// Check an inheritance clause for a marker protocol.
2648-
auto checkInherited = [&](ArrayRef<TypeLoc> inherited) -> bool {
2585+
auto checkInherited = [&](ArrayRef<InheritedEntry> inherited) -> bool {
26492586
for (const auto &inheritedEntry : inherited) {
26502587
if (auto inheritedType = inheritedEntry.getType()) {
26512588
if (inheritedType->isExistentialType()) {
@@ -5802,39 +5739,33 @@ void swift::printEnumElementsAsCases(
58025739
}
58035740

58045741
void
5805-
swift::getInheritedForPrinting(const Decl *decl, const PrintOptions &options,
5806-
llvm::SmallVectorImpl<TypeLoc> &Results) {
5807-
ArrayRef<TypeLoc> inherited;
5742+
swift::getInheritedForPrinting(
5743+
const Decl *decl, const PrintOptions &options,
5744+
llvm::SmallVectorImpl<InheritedEntry> &Results) {
5745+
ArrayRef<InheritedEntry> inherited;
58085746
if (auto td = dyn_cast<TypeDecl>(decl)) {
58095747
inherited = td->getInherited();
58105748
} else if (auto ed = dyn_cast<ExtensionDecl>(decl)) {
58115749
inherited = ed->getInherited();
58125750
}
58135751

58145752
// Collect explicit inherited types.
5815-
for (auto TL: inherited) {
5816-
if (auto ty = TL.getType()) {
5753+
for (auto entry: inherited) {
5754+
if (auto ty = entry.getType()) {
58175755
bool foundUnprintable = ty.findIf([&](Type subTy) {
58185756
if (auto aliasTy = dyn_cast<TypeAliasType>(subTy.getPointer()))
58195757
return !options.shouldPrint(aliasTy->getDecl());
58205758
if (auto NTD = subTy->getAnyNominal()) {
58215759
if (!options.shouldPrint(NTD))
58225760
return true;
5823-
5824-
if (auto PD = dyn_cast<ProtocolDecl>(NTD)) {
5825-
// Marker protocols are unprintable on concrete types, but they're
5826-
// okay on extension declarations and protocols.
5827-
if (PD->isMarkerProtocol() && !isa<ExtensionDecl>(decl) &&
5828-
!isa<ProtocolDecl>(decl))
5829-
return true;
5830-
}
58315761
}
58325762
return false;
58335763
});
58345764
if (foundUnprintable)
58355765
continue;
58365766
}
5837-
Results.push_back(TL);
5767+
5768+
Results.push_back(entry);
58385769
}
58395770

58405771
// Collect synthesized conformances.
@@ -5852,7 +5783,8 @@ swift::getInheritedForPrinting(const Decl *decl, const PrintOptions &options,
58525783
isa<EnumDecl>(decl) &&
58535784
cast<EnumDecl>(decl)->hasRawType())
58545785
continue;
5855-
Results.push_back(TypeLoc::withoutLoc(proto->getDeclaredInterfaceType()));
5786+
Results.push_back({TypeLoc::withoutLoc(proto->getDeclaredInterfaceType()),
5787+
/*isUnchecked=*/false});
58565788
}
58575789
}
58585790
}

0 commit comments

Comments
 (0)