Skip to content

Commit c932140

Browse files
committed
Module printing and serialization support for @unchecked Sendable
(cherry picked from commit 06bbc70)
1 parent 8092420 commit c932140

31 files changed

+270
-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
@@ -1212,6 +1212,17 @@ class ImportDecl final : public Decl,
12121212
}
12131213
};
12141214

1215+
/// An entry in the "inherited" list of a type or extension.
1216+
struct InheritedEntry : public TypeLoc {
1217+
/// Whether there was an @unchecked attribute.
1218+
bool isUnchecked = false;
1219+
1220+
InheritedEntry(const TypeLoc &typeLoc);
1221+
1222+
InheritedEntry(const TypeLoc &typeLoc, bool isUnchecked)
1223+
: TypeLoc(typeLoc), isUnchecked(isUnchecked) { }
1224+
};
1225+
12151226
/// ExtensionDecl - This represents a type extension containing methods
12161227
/// associated with the type. This is not a ValueDecl and has no Type because
12171228
/// there are no runtime values of the Extension's type.
@@ -1230,7 +1241,7 @@ class ExtensionDecl final : public GenericContext, public Decl,
12301241
/// extended nominal.
12311242
llvm::PointerIntPair<NominalTypeDecl *, 1, bool> ExtendedNominal;
12321243

1233-
ArrayRef<TypeLoc> Inherited;
1244+
ArrayRef<InheritedEntry> Inherited;
12341245

12351246
/// The next extension in the linked list of extensions.
12361247
///
@@ -1249,7 +1260,7 @@ class ExtensionDecl final : public GenericContext, public Decl,
12491260
friend class IterableDeclContext;
12501261

12511262
ExtensionDecl(SourceLoc extensionLoc, TypeRepr *extendedType,
1252-
ArrayRef<TypeLoc> inherited,
1263+
ArrayRef<InheritedEntry> inherited,
12531264
DeclContext *parent,
12541265
TrailingWhereClause *trailingWhereClause);
12551266

@@ -1274,7 +1285,7 @@ class ExtensionDecl final : public GenericContext, public Decl,
12741285
/// Create a new extension declaration.
12751286
static ExtensionDecl *create(ASTContext &ctx, SourceLoc extensionLoc,
12761287
TypeRepr *extendedType,
1277-
ArrayRef<TypeLoc> inherited,
1288+
ArrayRef<InheritedEntry> inherited,
12781289
DeclContext *parent,
12791290
TrailingWhereClause *trailingWhereClause,
12801291
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;
@@ -2536,12 +2547,12 @@ class ValueDecl : public Decl {
25362547

25372548
/// This is a common base class for declarations which declare a type.
25382549
class TypeDecl : public ValueDecl {
2539-
ArrayRef<TypeLoc> Inherited;
2550+
ArrayRef<InheritedEntry> Inherited;
25402551

25412552
protected:
25422553
TypeDecl(DeclKind K, llvm::PointerUnion<DeclContext *, ASTContext *> context,
25432554
Identifier name, SourceLoc NameLoc,
2544-
ArrayRef<TypeLoc> inherited) :
2555+
ArrayRef<InheritedEntry> inherited) :
25452556
ValueDecl(K, context, name, NameLoc), Inherited(inherited) {}
25462557

25472558
public:
@@ -2559,9 +2570,9 @@ class TypeDecl : public ValueDecl {
25592570

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

2564-
void setInherited(ArrayRef<TypeLoc> i) { Inherited = i; }
2575+
void setInherited(ArrayRef<InheritedEntry> i) { Inherited = i; }
25652576

25662577
static bool classof(const Decl *D) {
25672578
return D->getKind() >= DeclKind::First_TypeDecl &&
@@ -2586,7 +2597,7 @@ class GenericTypeDecl : public GenericContext, public TypeDecl {
25862597
public:
25872598
GenericTypeDecl(DeclKind K, DeclContext *DC,
25882599
Identifier name, SourceLoc nameLoc,
2589-
ArrayRef<TypeLoc> inherited,
2600+
ArrayRef<InheritedEntry> inherited,
25902601
GenericParamList *GenericParams);
25912602

25922603
// Resolve ambiguity due to multiple base classes.
@@ -3113,7 +3124,7 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
31133124

31143125
NominalTypeDecl(DeclKind K, DeclContext *DC, Identifier name,
31153126
SourceLoc NameLoc,
3116-
ArrayRef<TypeLoc> inherited,
3127+
ArrayRef<InheritedEntry> inherited,
31173128
GenericParamList *GenericParams) :
31183129
GenericTypeDecl(K, DC, name, NameLoc, inherited, GenericParams),
31193130
IterableDeclContext(IterableDeclContextKind::NominalTypeDecl)
@@ -3392,7 +3403,7 @@ class EnumDecl final : public NominalTypeDecl {
33923403

33933404
public:
33943405
EnumDecl(SourceLoc EnumLoc, Identifier Name, SourceLoc NameLoc,
3395-
ArrayRef<TypeLoc> Inherited,
3406+
ArrayRef<InheritedEntry> Inherited,
33963407
GenericParamList *GenericParams, DeclContext *DC);
33973408

33983409
SourceLoc getStartLoc() const { return EnumLoc; }
@@ -3560,7 +3571,7 @@ class StructDecl final : public NominalTypeDecl {
35603571

35613572
public:
35623573
StructDecl(SourceLoc StructLoc, Identifier Name, SourceLoc NameLoc,
3563-
ArrayRef<TypeLoc> Inherited,
3574+
ArrayRef<InheritedEntry> Inherited,
35643575
GenericParamList *GenericParams, DeclContext *DC);
35653576

35663577
SourceLoc getStartLoc() const { return StructLoc; }
@@ -3706,7 +3717,7 @@ class ClassDecl final : public NominalTypeDecl {
37063717

37073718
public:
37083719
ClassDecl(SourceLoc ClassLoc, Identifier Name, SourceLoc NameLoc,
3709-
ArrayRef<TypeLoc> Inherited,
3720+
ArrayRef<InheritedEntry> Inherited,
37103721
GenericParamList *GenericParams, DeclContext *DC,
37113722
bool isActor);
37123723

@@ -4134,7 +4145,7 @@ class ProtocolDecl final : public NominalTypeDecl {
41344145

41354146
public:
41364147
ProtocolDecl(DeclContext *DC, SourceLoc ProtocolLoc, SourceLoc NameLoc,
4137-
Identifier Name, ArrayRef<TypeLoc> Inherited,
4148+
Identifier Name, ArrayRef<InheritedEntry> Inherited,
41384149
TrailingWhereClause *TrailingWhere);
41394150

41404151
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
@@ -1119,7 +1119,7 @@ class Parser {
11191119

11201120
ParserResult<ImportDecl> parseDeclImport(ParseDeclOptions Flags,
11211121
DeclAttributes &Attributes);
1122-
ParserStatus parseInheritance(SmallVectorImpl<TypeLoc> &Inherited,
1122+
ParserStatus parseInheritance(SmallVectorImpl<InheritedEntry> &Inherited,
11231123
bool allowClassRequirement,
11241124
bool allowAnyObject);
11251125
ParserStatus parseDeclItem(bool &PreviousHadSemi,

lib/AST/ASTDumper.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -601,11 +601,12 @@ namespace {
601601
PrintWithColorRAII(OS, DeclModifierColor) << " trailing_semi";
602602
}
603603

604-
void printInherited(ArrayRef<TypeLoc> Inherited) {
604+
void printInherited(ArrayRef<InheritedEntry> Inherited) {
605605
if (Inherited.empty())
606606
return;
607607
OS << " inherits: ";
608-
interleave(Inherited, [&](TypeLoc Super) { Super.getType().print(OS); },
608+
interleave(Inherited,
609+
[&](InheritedEntry Super) { Super.getType().print(OS); },
609610
[&] { OS << ", "; });
610611
}
611612

lib/AST/ASTPrinter.cpp

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

10061006
if (haveFeatureChecks) {
1007-
// If we guarded a marker protocol, print an alternative typealias
1008-
// for Any.
1009-
if (auto proto = dyn_cast<ProtocolDecl>(D)) {
1010-
if (proto->isMarkerProtocol()) {
1011-
Printer.printNewline();
1012-
Printer << "#else";
1013-
Printer.printNewline();
1014-
printAccess(proto);
1015-
Printer << "typealias " << proto->getName() << " = Any";
1016-
}
1017-
}
1018-
10191007
printCompatibilityFeatureChecksPost(Printer);
10201008
}
10211009

@@ -1824,7 +1812,7 @@ bool ShouldPrintChecker::shouldPrint(const Decl *D,
18241812
auto Ext = cast<ExtensionDecl>(D);
18251813
// If the extension doesn't add protocols or has no members that we should
18261814
// print then skip printing it.
1827-
SmallVector<TypeLoc, 8> ProtocolsToPrint;
1815+
SmallVector<InheritedEntry, 8> ProtocolsToPrint;
18281816
getInheritedForPrinting(Ext, Options, ProtocolsToPrint);
18291817
if (ProtocolsToPrint.empty()) {
18301818
bool HasMemberToPrint = false;
@@ -2242,15 +2230,18 @@ void PrintAST::printInherited(const Decl *decl) {
22422230
if (!Options.PrintInherited) {
22432231
return;
22442232
}
2245-
SmallVector<TypeLoc, 6> TypesToPrint;
2233+
SmallVector<InheritedEntry, 6> TypesToPrint;
22462234
getInheritedForPrinting(decl, Options, TypesToPrint);
22472235
if (TypesToPrint.empty())
22482236
return;
22492237

22502238
Printer << " : ";
22512239

2252-
interleave(TypesToPrint, [&](TypeLoc TL) {
2253-
printTypeLoc(TL);
2240+
interleave(TypesToPrint, [&](InheritedEntry inherited) {
2241+
if (inherited.isUnchecked)
2242+
Printer << "@unchecked ";
2243+
2244+
printTypeLoc(inherited);
22542245
}, [&]() {
22552246
Printer << ", ";
22562247
});
@@ -2520,60 +2511,6 @@ static bool usesFeatureAsyncAwait(Decl *decl) {
25202511
}
25212512

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

@@ -2650,7 +2587,7 @@ static bool usesFeatureRethrowsProtocol(
26502587
return false;
26512588

26522589
// Check an inheritance clause for a marker protocol.
2653-
auto checkInherited = [&](ArrayRef<TypeLoc> inherited) -> bool {
2590+
auto checkInherited = [&](ArrayRef<InheritedEntry> inherited) -> bool {
26542591
for (const auto &inheritedEntry : inherited) {
26552592
if (auto inheritedType = inheritedEntry.getType()) {
26562593
if (inheritedType->isExistentialType()) {
@@ -5809,39 +5746,33 @@ void swift::printEnumElementsAsCases(
58095746
}
58105747

58115748
void
5812-
swift::getInheritedForPrinting(const Decl *decl, const PrintOptions &options,
5813-
llvm::SmallVectorImpl<TypeLoc> &Results) {
5814-
ArrayRef<TypeLoc> inherited;
5749+
swift::getInheritedForPrinting(
5750+
const Decl *decl, const PrintOptions &options,
5751+
llvm::SmallVectorImpl<InheritedEntry> &Results) {
5752+
ArrayRef<InheritedEntry> inherited;
58155753
if (auto td = dyn_cast<TypeDecl>(decl)) {
58165754
inherited = td->getInherited();
58175755
} else if (auto ed = dyn_cast<ExtensionDecl>(decl)) {
58185756
inherited = ed->getInherited();
58195757
}
58205758

58215759
// Collect explicit inherited types.
5822-
for (auto TL: inherited) {
5823-
if (auto ty = TL.getType()) {
5760+
for (auto entry: inherited) {
5761+
if (auto ty = entry.getType()) {
58245762
bool foundUnprintable = ty.findIf([&](Type subTy) {
58255763
if (auto aliasTy = dyn_cast<TypeAliasType>(subTy.getPointer()))
58265764
return !options.shouldPrint(aliasTy->getDecl());
58275765
if (auto NTD = subTy->getAnyNominal()) {
58285766
if (!options.shouldPrint(NTD))
58295767
return true;
5830-
5831-
if (auto PD = dyn_cast<ProtocolDecl>(NTD)) {
5832-
// Marker protocols are unprintable on concrete types, but they're
5833-
// okay on extension declarations and protocols.
5834-
if (PD->isMarkerProtocol() && !isa<ExtensionDecl>(decl) &&
5835-
!isa<ProtocolDecl>(decl))
5836-
return true;
5837-
}
58385768
}
58395769
return false;
58405770
});
58415771
if (foundUnprintable)
58425772
continue;
58435773
}
5844-
Results.push_back(TL);
5774+
5775+
Results.push_back(entry);
58455776
}
58465777

58475778
// Collect synthesized conformances.
@@ -5859,7 +5790,8 @@ swift::getInheritedForPrinting(const Decl *decl, const PrintOptions &options,
58595790
isa<EnumDecl>(decl) &&
58605791
cast<EnumDecl>(decl)->hasRawType())
58615792
continue;
5862-
Results.push_back(TypeLoc::withoutLoc(proto->getDeclaredInterfaceType()));
5793+
Results.push_back({TypeLoc::withoutLoc(proto->getDeclaredInterfaceType()),
5794+
/*isUnchecked=*/false});
58635795
}
58645796
}
58655797
}

0 commit comments

Comments
 (0)