Skip to content

Commit 9698770

Browse files
authored
Merge pull request swiftlang#38344 from DougGregor/unchecked-sendable-5.5
[SE-0302] Implement '@unchecked Sendable' syntax.
2 parents be5c13c + 02470cf commit 9698770

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+460
-310
lines changed

include/swift/AST/ASTContext.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -987,7 +987,8 @@ class ASTContext final {
987987
ProtocolDecl *protocol,
988988
SourceLoc loc,
989989
DeclContext *dc,
990-
ProtocolConformanceState state);
990+
ProtocolConformanceState state,
991+
bool isUnchecked);
991992

992993
/// Produce a self-conformance for the given protocol.
993994
SelfProtocolConformance *

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/Attr.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ TYPE_ATTR(differentiable)
5555
TYPE_ATTR(noDerivative)
5656
TYPE_ATTR(async)
5757
TYPE_ATTR(Sendable)
58+
TYPE_ATTR(unchecked)
5859

5960
// SIL-specific attributes
6061
TYPE_ATTR(block_storage)

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/DiagnosticsSema.def

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4490,16 +4490,17 @@ ERROR(concurrent_value_class_mutable_property,none,
44904490
(DeclName, DescriptiveDeclKind, DeclName))
44914491
ERROR(concurrent_value_outside_source_file,none,
44924492
"conformance to 'Sendable' must occur in the same source file as "
4493-
"%0 %1; use 'UnsafeSendable' for retroactive conformance",
4493+
"%0 %1; use '@unchecked Sendable' for retroactive conformance",
44944494
(DescriptiveDeclKind, DeclName))
44954495
ERROR(concurrent_value_nonfinal_class,none,
44964496
"non-final class %0 cannot conform to `Sendable`; "
4497-
"use `UnsafeSendable`", (DeclName))
4497+
"use `@unchecked Sendable`", (DeclName))
44984498
ERROR(concurrent_value_inherit,none,
44994499
"`Sendable` class %1 cannot inherit from another class"
45004500
"%select{| other than 'NSObject'}0",
45014501
(bool, DeclName))
45024502

4503+
45034504
ERROR(actorindependent_let,none,
45044505
"'@actorIndependent' is meaningless on 'let' declarations because "
45054506
"they are immutable",
@@ -4511,6 +4512,13 @@ ERROR(actorindependent_local_var,none,
45114512
"'@actorIndependent' can not be applied to local variables",
45124513
())
45134514

4515+
WARNING(unchecked_conformance_not_special,none,
4516+
"@unchecked conformance to %0 has no meaning", (Type))
4517+
ERROR(unchecked_not_inheritance_clause,none,
4518+
"'unchecked' attribute only applies in inheritance clauses", ())
4519+
ERROR(unchecked_not_existential,none,
4520+
"'unchecked' attribute cannot apply to non-protocol type %0", (Type))
4521+
45144522
ERROR(nonisolated_let,none,
45154523
"'nonisolated' is meaningless on 'let' declarations because "
45164524
"they are immutable",

include/swift/AST/NameLookup.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,19 @@ void filterForDiscriminator(SmallVectorImpl<Result> &results,
503503

504504
} // end namespace namelookup
505505

506+
/// Describes an inherited nominal entry.
507+
struct InheritedNominalEntry : Located<NominalTypeDecl *> {
508+
/// The location of the "unchecked" attribute, if present.
509+
SourceLoc uncheckedLoc;
510+
511+
InheritedNominalEntry() { }
512+
513+
InheritedNominalEntry(
514+
NominalTypeDecl *item, SourceLoc loc,
515+
SourceLoc uncheckedLoc
516+
) : Located(item, loc), uncheckedLoc(uncheckedLoc) { }
517+
};
518+
506519
/// Retrieve the set of nominal type declarations that are directly
507520
/// "inherited" by the given declaration at a particular position in the
508521
/// list of "inherited" types.
@@ -511,15 +524,15 @@ void filterForDiscriminator(SmallVectorImpl<Result> &results,
511524
/// AnyObject type, set \c anyObject true.
512525
void getDirectlyInheritedNominalTypeDecls(
513526
llvm::PointerUnion<const TypeDecl *, const ExtensionDecl *> decl,
514-
unsigned i, llvm::SmallVectorImpl<Located<NominalTypeDecl *>> &result,
527+
unsigned i, llvm::SmallVectorImpl<InheritedNominalEntry> &result,
515528
bool &anyObject);
516529

517530
/// Retrieve the set of nominal type declarations that are directly
518531
/// "inherited" by the given declaration, looking through typealiases
519532
/// and splitting out the components of compositions.
520533
///
521534
/// If we come across the AnyObject type, set \c anyObject true.
522-
SmallVector<Located<NominalTypeDecl *>, 4> getDirectlyInheritedNominalTypeDecls(
535+
SmallVector<InheritedNominalEntry, 4> getDirectlyInheritedNominalTypeDecls(
523536
llvm::PointerUnion<const TypeDecl *, const ExtensionDecl *> decl,
524537
bool &anyObject);
525538

include/swift/AST/ProtocolConformance.h

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -412,11 +412,20 @@ class NormalProtocolConformance : public RootProtocolConformance,
412412
/// The location of this protocol conformance in the source.
413413
SourceLoc Loc;
414414

415+
// Flag bits used in ContextAndBits.
416+
enum {
417+
/// The conformance is invalid.
418+
InvalidFlag = 0x01,
419+
420+
/// The conformance was labeled with @unchecked.
421+
UncheckedFlag = 0x02,
422+
};
423+
415424
/// The declaration context containing the ExtensionDecl or
416425
/// NominalTypeDecl that declared the conformance.
417426
///
418-
/// Also stores the "invalid" bit.
419-
llvm::PointerIntPair<DeclContext *, 1, bool> ContextAndInvalid;
427+
/// Also stores the "invalid" and "unchecked" bits.
428+
llvm::PointerIntPair<DeclContext *, 2, unsigned> ContextAndBits;
420429

421430
/// The reason that this conformance exists.
422431
///
@@ -457,11 +466,12 @@ class NormalProtocolConformance : public RootProtocolConformance,
457466
public:
458467
NormalProtocolConformance(Type conformingType, ProtocolDecl *protocol,
459468
SourceLoc loc, DeclContext *dc,
460-
ProtocolConformanceState state)
469+
ProtocolConformanceState state,
470+
bool isUnchecked)
461471
: RootProtocolConformance(ProtocolConformanceKind::Normal,
462472
conformingType),
463473
ProtocolAndState(protocol, state), Loc(loc),
464-
ContextAndInvalid(dc, false) {
474+
ContextAndBits(dc, isUnchecked ? UncheckedFlag : 0) {
465475
assert(!conformingType->hasArchetype() &&
466476
"ProtocolConformances should store interface types");
467477
}
@@ -475,7 +485,7 @@ class NormalProtocolConformance : public RootProtocolConformance,
475485
/// Get the declaration context that contains the conforming extension or
476486
/// nominal type declaration.
477487
DeclContext *getDeclContext() const {
478-
return ContextAndInvalid.getPointer();
488+
return ContextAndBits.getPointer();
479489
}
480490

481491
/// Get any additional requirements that are required for this conformance to
@@ -497,15 +507,20 @@ class NormalProtocolConformance : public RootProtocolConformance,
497507

498508
/// Determine whether this conformance is invalid.
499509
bool isInvalid() const {
500-
return ContextAndInvalid.getInt();
510+
return ContextAndBits.getInt() & InvalidFlag;
501511
}
502512

503513
/// Mark this conformance as invalid.
504514
void setInvalid() {
505-
ContextAndInvalid.setInt(true);
515+
ContextAndBits.setInt(ContextAndBits.getInt() | InvalidFlag);
506516
SignatureConformances = {};
507517
}
508518

519+
/// Whether this is an "unchecked" conformance.
520+
bool isUnchecked() const {
521+
return ContextAndBits.getInt() & UncheckedFlag;
522+
}
523+
509524
/// Get the kind of source from which this conformance comes.
510525
ConformanceEntryKind getSourceKind() const {
511526
return SourceKindAndImplyingConformance.getInt();

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,

0 commit comments

Comments
 (0)