Skip to content

Commit 275dff8

Browse files
authored
Merge branch 'release/6.0' into pick-6-pick-concurrency-isCurrent-more-fixes
2 parents 6b2e9b1 + ea51b29 commit 275dff8

Some content is hidden

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

42 files changed

+2505
-474
lines changed

CHANGELOG.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,40 @@
55
66
## Swift 6.0
77

8+
* [SE-0427][]:
9+
You can now suppress `Copyable` on protocols, generic parameters,
10+
and existentials:
11+
12+
```swift
13+
// Protocol does not require conformers to be Copyable.
14+
protocol Flower: ~Copyable {
15+
func bloom()
16+
}
17+
18+
// Noncopyable type
19+
struct Marigold: Flower, ~Copyable {
20+
func bloom() { print("Marigold blooming!") }
21+
}
22+
23+
// Copyable type
24+
struct Hibiscus: Flower {
25+
func bloom() { print("Hibiscus blooming!") }
26+
}
27+
28+
func startSeason(_ flower: borrowing some Flower & ~Copyable) {
29+
flower.bloom()
30+
}
31+
32+
startSeason(Marigold())
33+
startSeason(Hibiscus())
34+
```
35+
36+
By writing `~Copyable` on a generic type, you're suppressing a default
37+
`Copyable` constraint that would otherwise appear on that type. This permits
38+
noncopyable types, which have no `Copyable` conformance, to conform to such
39+
protocols and be substituted for those generic types. Full functionality of this
40+
feature requires the newer Swift 6 runtime.
41+
842
* Since its introduction in Swift 5.1 the @TaskLocal property wrapper was used to
943
create and access task-local value bindings. Property wrappers introduce mutable storage,
1044
which was now properly flagged as potential source of concurrency unsafety.
@@ -10252,6 +10286,7 @@ using the `.dynamicType` member to retrieve the type of an expression should mig
1025210286
[SE-0412]: https://github.com/apple/swift-evolution/blob/main/proposals/0412-strict-concurrency-for-global-variables.md
1025310287
[SE-0413]: https://github.com/apple/swift-evolution/blob/main/proposals/0413-typed-throws.md
1025410288
[SE-0422]: https://github.com/apple/swift-evolution/blob/main/proposals/0422-caller-side-default-argument-macro-expression.md
10289+
[SE-0427]: https://github.com/apple/swift-evolution/blob/main/proposals/0427-noncopyable-generics.md
1025510290
[#64927]: <https://github.com/apple/swift/issues/64927>
1025610291
[#42697]: <https://github.com/apple/swift/issues/42697>
1025710292
[#42728]: <https://github.com/apple/swift/issues/42728>

include/swift/AST/DeclContext.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ namespace swift {
8282
class SerializedTopLevelCodeDecl;
8383
class StructDecl;
8484
class AccessorDecl;
85+
class ClosureExpr;
8586

8687
template <typename T>
8788
struct AvailableDuringLoweringDeclFilter;
@@ -504,6 +505,14 @@ class alignas(1 << DeclContextAlignInBits) DeclContext
504505
const_cast<DeclContext *>(this)->getInnermostSkippedFunctionContext();
505506
}
506507

508+
/// Returns the innermost context that is a ClosureExpr, which defines how
509+
/// self behaves, unless within a type context that redefines self.
510+
LLVM_READONLY
511+
ClosureExpr *getInnermostClosureForSelfCapture();
512+
const ClosureExpr *getInnermostClosureForSelfCapture() const {
513+
return const_cast<DeclContext *>(this)->getInnermostClosureForSelfCapture();
514+
}
515+
507516
/// Returns the semantic parent of this context. A context has a
508517
/// parent if and only if it is not a module context.
509518
DeclContext *getParent() const {

include/swift/AST/DistributedDecl.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,29 @@ Type getDistributedActorSystemResultHandlerType(NominalTypeDecl *system);
102102
/// Get the 'ActorID' type of a specific distributed actor system.
103103
Type getDistributedActorSystemActorIDType(NominalTypeDecl *system);
104104

105+
/// Retrieve a protocol conformance to the `Actor` protocol for a
106+
/// distributed actor type that is described via a substitution map for
107+
/// the generic signature `<T: DistributedActor>`.
108+
///
109+
/// The protocol conformance is a special one that is currently
110+
/// only used by the `distributedActorAsAnyActor` builtin.
111+
NormalProtocolConformance *
112+
getDistributedActorAsActorConformance(ASTContext &C);
113+
114+
ProtocolConformanceRef
115+
getDistributedActorAsActorConformanceRef(ASTContext &C);
116+
117+
/// Find the extension that defines the methods necessary for creating the
118+
/// the DistributedActor-as-Actor conformance.
119+
ExtensionDecl *
120+
findDistributedActorAsActorExtension(
121+
ProtocolDecl *distributedActorProto, ModuleDecl *module);
122+
123+
bool isDistributedActorAsLocalActorComputedProperty(VarDecl *var);
124+
125+
/// Get the ``DistributedActor/asLocalActor`` computed property.
126+
VarDecl *getDistributedActorAsLocalActorComputedProperty(ModuleDecl *module);
127+
105128
/// Check if the `allRequirements` represent *exactly* the
106129
/// `Encodable & Decodable` (also known as `Codable`) requirement.
107130
///

include/swift/AST/Expr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4380,7 +4380,7 @@ struct CaptureListEntry {
43804380
explicit CaptureListEntry(PatternBindingDecl *PBD);
43814381

43824382
VarDecl *getVar() const;
4383-
bool isSimpleSelfCapture() const;
4383+
bool isSimpleSelfCapture(bool excludeWeakCaptures = true) const;
43844384
};
43854385

43864386
/// CaptureListExpr - This expression represents the capture list on an explicit

include/swift/AST/Stmt.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -709,9 +709,13 @@ class alignas(1 << PatternAlignInBits) StmtConditionElement {
709709
}
710710

711711
/// Whether or not this conditional stmt rebinds self with a `let self`
712-
/// or `let self = self` condition. If `requireLoadExpr` is `true`,
713-
/// additionally requires that the RHS of the self condition is a `LoadExpr`.
714-
bool rebindsSelf(ASTContext &Ctx, bool requireLoadExpr = false) const;
712+
/// or `let self = self` condition.
713+
/// - If `requiresCaptureListRef` is `true`, additionally requires that the
714+
/// RHS of the self condition references a var defined in a capture list.
715+
/// - If `requireLoadExpr` is `true`, additionally requires that the RHS of
716+
/// the self condition is a `LoadExpr`.
717+
bool rebindsSelf(ASTContext &Ctx, bool requiresCaptureListRef = false,
718+
bool requireLoadExpr = false) const;
715719

716720
SourceLoc getStartLoc() const;
717721
SourceLoc getEndLoc() const;
@@ -817,9 +821,13 @@ class LabeledConditionalStmt : public LabeledStmt {
817821
StmtCondition *getCondPointer() { return &Cond; }
818822

819823
/// Whether or not this conditional stmt rebinds self with a `let self`
820-
/// or `let self = self` condition. If `requireLoadExpr` is `true`,
821-
/// additionally requires that the RHS of the self condition is a `LoadExpr`.
822-
bool rebindsSelf(ASTContext &Ctx, bool requireLoadExpr = false) const;
824+
/// or `let self = self` condition.
825+
/// - If `requiresCaptureListRef` is `true`, additionally requires that the
826+
/// RHS of the self condition references a var defined in a capture list.
827+
/// - If `requireLoadExpr` is `true`, additionally requires that the RHS of
828+
/// the self condition is a `LoadExpr`.
829+
bool rebindsSelf(ASTContext &Ctx, bool requiresCaptureListRef = false,
830+
bool requireLoadExpr = false) const;
823831

824832
static bool classof(const Stmt *S) {
825833
return S->getKind() >= StmtKind::First_LabeledConditionalStmt &&

include/swift/AST/TypeCheckRequests.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,25 @@ class CanSynthesizeDistributedActorCodableConformanceRequest :
11381138
bool isCached() const { return true; }
11391139
};
11401140

1141+
/// Get a special conformance of the DistributedActor protocol to the Actor protocol.
1142+
class GetDistributedActorAsActorConformanceRequest
1143+
: public SimpleRequest<GetDistributedActorAsActorConformanceRequest,
1144+
NormalProtocolConformance *(ProtocolDecl *),
1145+
RequestFlags::Cached> {
1146+
public:
1147+
using SimpleRequest::SimpleRequest;
1148+
1149+
private:
1150+
friend SimpleRequest;
1151+
1152+
NormalProtocolConformance *
1153+
evaluate(Evaluator &evaluator, ProtocolDecl *distributedActorProto) const;
1154+
1155+
public:
1156+
// Caching
1157+
bool isCached() const { return true; }
1158+
};
1159+
11411160
/// Retrieve the implicit conformance for the given distributed actor type to
11421161
/// the Codable protocol protocol.
11431162
///

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,14 @@ SWIFT_REQUEST(TypeChecker, CheckDistributedFunctionRequest,
118118
SWIFT_REQUEST(TypeChecker, IsDistributedActorRequest, bool(NominalTypeDecl *),
119119
Cached, NoLocationInfo)
120120
SWIFT_REQUEST(TypeChecker, GetDistributedActorImplicitCodableRequest,
121-
NormalProtocolConformance *(NominalTypeDecl *, KnownProtocolKind),
122-
Cached, NoLocationInfo)
121+
NormalProtocolConformance *(NominalTypeDecl *, KnownProtocolKind),
122+
Cached, NoLocationInfo)
123123
SWIFT_REQUEST(TypeChecker, CanSynthesizeDistributedActorCodableConformanceRequest,
124-
bool (NominalTypeDecl *),
125-
Cached, NoLocationInfo)
124+
bool (NominalTypeDecl *),
125+
Cached, NoLocationInfo)
126+
SWIFT_REQUEST(TypeChecker, GetDistributedActorAsActorConformanceRequest,
127+
NormalProtocolConformance *(ProtocolDecl *),
128+
Cached, NoLocationInfo)
126129
SWIFT_REQUEST(TypeChecker, GetDistributedActorSystemRemoteCallFunctionRequest,
127130
AbstractFunctionDecl *(NominalTypeDecl *, bool),
128131
Cached, NoLocationInfo)

include/swift/Sema/ConstraintSystem.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4406,7 +4406,7 @@ class ConstraintSystem {
44064406
/// \param UseDC The context of the access. Some variables have different
44074407
/// types depending on where they are used.
44084408
///
4409-
/// \param memberLocator The locator anchored at this value reference, when
4409+
/// \param locator The locator anchored at this value reference, when
44104410
/// it is a member reference.
44114411
///
44124412
/// \param wantInterfaceType Whether we want the interface type, if available.
@@ -4424,7 +4424,7 @@ class ConstraintSystem {
44244424
/// \param UseDC The context of the access. Some variables have different
44254425
/// types depending on where they are used.
44264426
///
4427-
/// \param memberLocator The locator anchored at this value reference, when
4427+
/// \param locator The locator anchored at this value reference, when
44284428
/// it is a member reference.
44294429
///
44304430
/// \param wantInterfaceType Whether we want the interface type, if available.

lib/AST/DeclContext.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,25 @@ DeclContext *DeclContext::getInnermostSkippedFunctionContext() {
263263
return nullptr;
264264
}
265265

266+
ClosureExpr *DeclContext::getInnermostClosureForSelfCapture() {
267+
auto dc = this;
268+
if (auto closure = dyn_cast<ClosureExpr>(dc)) {
269+
return closure;
270+
}
271+
272+
// Stop searching if we find a type decl, since types always
273+
// redefine what 'self' means, even when nested inside a closure.
274+
if (dc->isTypeContext()) {
275+
return nullptr;
276+
}
277+
278+
if (auto parent = dc->getParent()) {
279+
return parent->getInnermostClosureForSelfCapture();
280+
}
281+
282+
return nullptr;
283+
}
284+
266285
DeclContext *DeclContext::getParentForLookup() const {
267286
if (isa<ExtensionDecl>(this)) {
268287
// If we are inside an extension, skip directly

lib/AST/DistributedDecl.cpp

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
using namespace swift;
6262

6363
/******************************************************************************/
64-
/************* Implicit Distributed Actor Codable Conformance *****************/
64+
/******************* Distributed Actor Conformances ***************************/
6565
/******************************************************************************/
6666

6767
bool swift::canSynthesizeDistributedActorCodableConformance(NominalTypeDecl *actor) {
@@ -76,6 +76,68 @@ bool swift::canSynthesizeDistributedActorCodableConformance(NominalTypeDecl *act
7676
false);
7777
}
7878

79+
ExtensionDecl *
80+
swift::findDistributedActorAsActorExtension(
81+
ProtocolDecl *distributedActorProto, ModuleDecl *module) {
82+
ASTContext &C = distributedActorProto->getASTContext();
83+
auto name = C.getIdentifier("__actorUnownedExecutor");
84+
auto results = distributedActorProto->lookupDirect(
85+
name, SourceLoc(),
86+
NominalTypeDecl::LookupDirectFlags::IncludeAttrImplements);
87+
for (auto result : results) {
88+
if (auto var = dyn_cast<VarDecl>(result)) {
89+
return dyn_cast<ExtensionDecl>(var->getDeclContext());
90+
}
91+
}
92+
93+
return nullptr;
94+
}
95+
96+
bool swift::isDistributedActorAsLocalActorComputedProperty(VarDecl *var) {
97+
auto &C = var->getASTContext();
98+
return var->getName() == C.Id_asLocalActor &&
99+
var->getDeclContext()->getSelfProtocolDecl() &&
100+
var->getDeclContext()->getSelfProtocolDecl()->isSpecificProtocol(
101+
KnownProtocolKind::DistributedActor);
102+
}
103+
104+
VarDecl *
105+
swift::getDistributedActorAsLocalActorComputedProperty(ModuleDecl *module) {
106+
auto &C = module->getASTContext();
107+
auto DA = C.getDistributedActorDecl();
108+
auto extension = findDistributedActorAsActorExtension(DA, module);
109+
110+
if (!extension)
111+
return nullptr;
112+
113+
for (auto decl : extension->getMembers()) {
114+
if (auto var = dyn_cast<VarDecl>(decl)) {
115+
if (isDistributedActorAsLocalActorComputedProperty(var)) {
116+
return var;
117+
}
118+
}
119+
}
120+
121+
return nullptr;
122+
}
123+
124+
ProtocolConformanceRef
125+
swift::getDistributedActorAsActorConformanceRef(ASTContext &C) {
126+
auto distributedActorAsActorConformance =
127+
getDistributedActorAsActorConformance(C);
128+
129+
auto actorProto = C.getProtocol(KnownProtocolKind::Actor);
130+
return ProtocolConformanceRef(actorProto, distributedActorAsActorConformance);
131+
}
132+
NormalProtocolConformance *
133+
swift::getDistributedActorAsActorConformance(ASTContext &C) {
134+
auto distributedActorProtocol = C.getProtocol(KnownProtocolKind::DistributedActor);
135+
136+
return evaluateOrDefault(
137+
C.evaluator,
138+
GetDistributedActorAsActorConformanceRequest{distributedActorProtocol},
139+
nullptr);
140+
}
79141

80142
/******************************************************************************/
81143
/************** Distributed Actor System Associated Types *********************/

lib/AST/Expr.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,22 +1353,29 @@ VarDecl *CaptureListEntry::getVar() const {
13531353
return PBD->getSingleVar();
13541354
}
13551355

1356-
bool CaptureListEntry::isSimpleSelfCapture() const {
1356+
bool CaptureListEntry::isSimpleSelfCapture(bool excludeWeakCaptures) const {
13571357
auto *Var = getVar();
13581358
auto &ctx = Var->getASTContext();
13591359

13601360
if (Var->getName() != ctx.Id_self)
13611361
return false;
13621362

1363-
if (auto *attr = Var->getAttrs().getAttribute<ReferenceOwnershipAttr>())
1364-
if (attr->get() == ReferenceOwnership::Weak)
1365-
return false;
1366-
13671363
if (PBD->getPatternList().size() != 1)
13681364
return false;
13691365

13701366
auto *expr = PBD->getInit(0);
13711367

1368+
if (auto *attr = Var->getAttrs().getAttribute<ReferenceOwnershipAttr>()) {
1369+
if (attr->get() == ReferenceOwnership::Weak && excludeWeakCaptures) {
1370+
return false;
1371+
}
1372+
}
1373+
1374+
// Look through any ImplicitConversionExpr that may contain the DRE
1375+
if (auto conversion = dyn_cast_or_null<ImplicitConversionExpr>(expr)) {
1376+
expr = conversion->getSubExpr();
1377+
}
1378+
13721379
if (auto *DRE = dyn_cast<DeclRefExpr>(expr)) {
13731380
if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
13741381
return VD->getName() == ctx.Id_self;

lib/AST/ProtocolConformance.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1142,9 +1142,40 @@ void NominalTypeDecl::prepareConformanceTable() const {
11421142
}
11431143
}
11441144

1145+
/// Handle special cased protocol-to-protocol conformances, such as e.g.
1146+
/// DistributedActor-to-Actor.
1147+
///
1148+
/// \returns true when the conformance lookup was handled successfully
1149+
static bool lookupSpecialProtocolToProtocolConformance(
1150+
const ProtocolDecl *thisProtocol, ProtocolDecl *toProtocol,
1151+
SmallVectorImpl<ProtocolConformance *> &conformances) {
1152+
auto &C = toProtocol->getASTContext();
1153+
1154+
// DistributedActor-to-Actor
1155+
if (thisProtocol->isSpecificProtocol(KnownProtocolKind::DistributedActor) &&
1156+
toProtocol->isSpecificProtocol(KnownProtocolKind::Actor)) {
1157+
if (auto conformance = getDistributedActorAsActorConformance(C)) {
1158+
conformances.push_back(conformance);
1159+
return true;
1160+
}
1161+
}
1162+
1163+
return false;
1164+
}
1165+
11451166
bool NominalTypeDecl::lookupConformance(
11461167
ProtocolDecl *protocol,
11471168
SmallVectorImpl<ProtocolConformance *> &conformances) const {
1169+
1170+
// In general, protocols cannot conform to other protocols, however there are
1171+
// exceptions, special handle those.
1172+
if (auto thisProtocol = dyn_cast<ProtocolDecl>(this)) {
1173+
if (lookupSpecialProtocolToProtocolConformance(thisProtocol, protocol,
1174+
conformances)) {
1175+
return true;
1176+
}
1177+
}
1178+
11481179
assert(!isa<ProtocolDecl>(this) &&
11491180
"Self-conformances are only found by the higher-level "
11501181
"ModuleDecl::lookupConformance() entry point");
@@ -1187,7 +1218,7 @@ void NominalTypeDecl::getImplicitProtocols(
11871218
}
11881219

11891220
void NominalTypeDecl::registerProtocolConformance(
1190-
NormalProtocolConformance *conformance, bool synthesized) {
1221+
NormalProtocolConformance *conformance, bool synthesized) {
11911222
prepareConformanceTable();
11921223
auto *dc = conformance->getDeclContext();
11931224
ConformanceTable->registerProtocolConformance(dc, conformance, synthesized);

0 commit comments

Comments
 (0)