Skip to content

Commit 89f8f8b

Browse files
Wrap only changes related to the closure frontend logic
1 parent ae48446 commit 89f8f8b

27 files changed

+82
-153
lines changed

include/swift/AST/Stmt.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,8 @@ class alignas(1 << PatternAlignInBits) StmtConditionElement {
715715
/// RHS of the self condition references a var defined in a capture list.
716716
/// - If `requireLoadExpr` is `true`, additionally requires that the RHS of
717717
/// the self condition is a `LoadExpr`.
718-
/// TODO: Remove `requireLoadExpr` after full-on of the WeakLet feature
718+
/// TODO: Remove `requireLoadExpr` after full-on of the ImmutableWeakCaptures
719+
/// feature
719720
bool rebindsSelf(ASTContext &Ctx, bool requiresCaptureListRef = false,
720721
bool requireLoadExpr = false) const;
721722

include/swift/Basic/Features.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ UPCOMING_FEATURE(InternalImportsByDefault, 409, 7)
296296
MIGRATABLE_UPCOMING_FEATURE(MemberImportVisibility, 444, 7)
297297
MIGRATABLE_UPCOMING_FEATURE(InferIsolatedConformances, 470, 7)
298298
MIGRATABLE_UPCOMING_FEATURE(NonisolatedNonsendingByDefault, 461, 7)
299-
UPCOMING_FEATURE(WeakLet, 481, 7)
299+
UPCOMING_FEATURE(ImmutableWeakCaptures, 481, 7)
300300

301301
// Optional language features / modes
302302

lib/AST/Expr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1373,7 +1373,8 @@ CaptureListEntry CaptureListEntry::createParsed(
13731373
SourceRange ownershipRange, Identifier name, SourceLoc nameLoc,
13741374
SourceLoc equalLoc, Expr *initializer, DeclContext *DC) {
13751375

1376-
bool forceVar = ownershipKind == ReferenceOwnership::Weak && !Ctx.LangOpts.hasFeature(Feature::WeakLet);
1376+
bool forceVar = ownershipKind == ReferenceOwnership::Weak &&
1377+
!Ctx.LangOpts.hasFeature(Feature::ImmutableWeakCaptures);
13771378
auto introducer = forceVar ? VarDecl::Introducer::Var : VarDecl::Introducer::Let;
13781379
auto *VD =
13791380
new (Ctx) VarDecl(/*isStatic==*/false, introducer, nameLoc, name, DC);

lib/AST/FeatureSet.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -441,15 +441,7 @@ UNINTERESTING_FEATURE(BuiltinSelect)
441441
UNINTERESTING_FEATURE(BuiltinInterleave)
442442
UNINTERESTING_FEATURE(BuiltinVectorsExternC)
443443
UNINTERESTING_FEATURE(AddressOfProperty2)
444-
445-
static bool usesFeatureWeakLet(Decl *decl) {
446-
if (auto *VD = dyn_cast<VarDecl>(decl)) {
447-
if (auto *refAttr = VD->getAttrs().getAttribute<ReferenceOwnershipAttr>()) {
448-
return VD->isLet() && refAttr->get() == ReferenceOwnership::Weak;
449-
}
450-
}
451-
return false;
452-
}
444+
UNINTERESTING_FEATURE(ImmutableWeakCaptures)
453445

454446
// ----------------------------------------------------------------------------
455447
// MARK: - FeatureSet

lib/SIL/IR/TypeLowering.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -170,15 +170,6 @@ CaptureKind TypeConverter::getDeclCaptureKind(CapturedValue capture,
170170
return CaptureKind::StorageAddress;
171171
}
172172

173-
// Reference storage types can appear in a capture list, which means
174-
// we might allocate boxes to store the captures. However, those boxes
175-
// have the same lifetime as the closure itself, so we must capture
176-
// the box itself and not the payload, even if the closure is noescape,
177-
// otherwise they will be destroyed when the closure is formed.
178-
if (var->getInterfaceType()->is<ReferenceStorageType>() && !Context.LangOpts.hasFeature(Feature::WeakLet)) {
179-
return CaptureKind::Box;
180-
}
181-
182173
// For 'let' constants
183174
if (!var->supportsMutation()) {
184175
assert(getTypeProperties(

lib/Sema/MiscDiagnostics.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,8 +1780,8 @@ class ImplicitSelfUsageChecker : public BaseDiagnosticWalker {
17801780
if (!conditionalStmt) {
17811781
return false;
17821782
}
1783-
1784-
if (Ctx.LangOpts.hasFeature(Feature::WeakLet)) {
1783+
1784+
if (Ctx.LangOpts.hasFeature(Feature::ImmutableWeakCaptures)) {
17851785
// Require that the RHS of the `let self = self` condition
17861786
// refers to a variable defined in a capture list.
17871787
// This lets us reject invalid examples like:
@@ -1809,7 +1809,6 @@ class ImplicitSelfUsageChecker : public BaseDiagnosticWalker {
18091809
//
18101810
return conditionalStmt->rebindsSelf(Ctx, /*requiresCaptureListRef*/ false,
18111811
/*requireLoadExpr*/ true);
1812-
18131812
}
18141813
}
18151814

@@ -4108,9 +4107,12 @@ VarDeclUsageChecker::~VarDeclUsageChecker() {
41084107

41094108
// If this variable has WeakStorageType, then it can be mutated in ways we
41104109
// don't know.
4111-
if (var->getInterfaceType()->is<WeakStorageType>() && !DC->getASTContext().LangOpts.hasFeature(Feature::WeakLet))
4110+
if (var->getInterfaceType()->is<WeakStorageType>() &&
4111+
(access & RK_CaptureList) &&
4112+
!DC->getASTContext().LangOpts.hasFeature(
4113+
Feature::ImmutableWeakCaptures))
41124114
access |= RK_Written;
4113-
4115+
41144116
// Diagnose variables that were never used (other than their
41154117
// initialization).
41164118
//

lib/Sema/TypeCheckAttr.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5406,11 +5406,6 @@ Type TypeChecker::checkReferenceOwnershipAttr(VarDecl *var, Type type,
54065406
case ReferenceOwnershipOptionality::Allowed:
54075407
break;
54085408
case ReferenceOwnershipOptionality::Required:
5409-
if (var->isLet() && !ctx.LangOpts.hasFeature(Feature::WeakLet)) {
5410-
var->diagnose(diag::invalid_ownership_is_let, ownershipKind);
5411-
attr->setInvalid();
5412-
}
5413-
54145409
if (!isOptional) {
54155410
attr->setInvalid();
54165411

test/Concurrency/weak_ref_sendability.swift

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// RUN: %target-swift-frontend -emit-sil -swift-version 6 -target %target-swift-5.1-abi-triple -verify -verify-additional-prefix old- %s -o /dev/null
2-
// RUN: %target-swift-frontend -emit-sil -swift-version 6 -target %target-swift-5.1-abi-triple -verify -verify-additional-prefix new- -enable-upcoming-feature WeakLet %s -o /dev/null
2+
// RUN: %target-swift-frontend -emit-sil -swift-version 6 -target %target-swift-5.1-abi-triple -verify -verify-additional-prefix new- -enable-upcoming-feature ImmutableWeakCaptures %s -o /dev/null
33

44
// This test validates the behavior of transfer non sendable around ownership
55
// constructs like non copyable types, consuming/borrowing parameters, and inout
66
// parameters.
77

88
// REQUIRES: concurrency
9-
// REQUIRES: swift_feature_WeakLet
9+
// REQUIRES: swift_feature_ImmutableWeakCaptures
1010

1111
final class S: Sendable {
1212
func foo() {}
@@ -30,15 +30,12 @@ final class CheckOptionality1: Sendable {
3030
}
3131

3232
final class CheckOptionality2: Sendable {
33-
// expected-old-error@+3 {{'weak' must be a mutable variable, because it may change at runtime}}
34-
// expected-old-error@+2 {{'weak' variable should have optional type 'S?'}}
35-
// expected-new-error@+1 {{'weak' variable should have optional type 'S?'}}
33+
// expected-error@+1 {{'weak' variable should have optional type 'S?'}}
3634
weak let x: S = getS()
3735
}
3836

3937
final class CheckSendability1: Sendable {
40-
// expected-old-error@+2 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability1' is mutable}}
41-
// expected-new-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability1' is mutable}}
38+
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability1' is mutable}}
4239
weak var x: S? = nil
4340

4441
weak var y: S? {
@@ -48,32 +45,26 @@ final class CheckSendability1: Sendable {
4845
}
4946

5047
final class CheckSendability2: Sendable {
51-
// expected-old-error@+2 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability2' is mutable}}
52-
// expected-new-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability2' is mutable}}
48+
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability2' is mutable}}
5349
weak var x: NS? = nil
5450
}
5551

5652
final class CheckSendability3: Sendable {
57-
// expected-old-error@+1 {{'weak' must be a mutable variable, because it may change at runtime}}
5853
weak let x: S? = nil
5954
}
6055

6156
final class CheckSendability4: Sendable {
62-
// expected-old-error@+3 {{'weak' must be a mutable variable, because it may change at runtime}}
63-
// expected-old-error@+2 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability4' contains non-Sendable type 'NS'}}
64-
// expected-new-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability4' contains non-Sendable type 'NS'}}
57+
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability4' contains non-Sendable type 'NS'}}
6558
weak let x: NS? = nil
6659
}
6760

6861
final class CheckSendability5: Sendable {
69-
// expected-old-error@+2 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability5' is mutable}}
70-
// expected-new-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability5' is mutable}}
62+
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability5' is mutable}}
7163
unowned var x: S = getS()
7264
}
7365

7466
final class CheckSendability6: Sendable {
75-
// expected-old-error@+2 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability6' is mutable}}
76-
// expected-new-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability6' is mutable}}
67+
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability6' is mutable}}
7768
unowned var x: NS = getNS()
7869
}
7970

@@ -87,14 +78,12 @@ final class CheckSendability8: Sendable {
8778
}
8879

8980
final class CheckSendability9: Sendable {
90-
// expected-old-error@+2 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability9' is mutable}}
91-
// expected-new-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability9' is mutable}}
81+
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability9' is mutable}}
9282
unowned(unsafe) var x: S = getS()
9383
}
9484

9585
final class CheckSendability10: Sendable {
96-
// expected-old-error@+2 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability10' is mutable}}
97-
// expected-new-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability10' is mutable}}
86+
// expected-error@+1 {{stored property 'x' of 'Sendable'-conforming class 'CheckSendability10' is mutable}}
9887
unowned(unsafe) var x: NS = getNS()
9988
}
10089

@@ -109,17 +98,15 @@ final class CheckSendability12: Sendable {
10998

11099

111100
func checkWeakCapture1(_ strongRef: S) -> @Sendable () -> Void {
112-
// expected-new-warning@+1 {{variable 'weakRef' was never mutated; consider changing to 'let' constant}}
101+
// expected-warning@+1 {{variable 'weakRef' was never mutated; consider changing to 'let' constant}}
113102
weak var weakRef: S? = strongRef
114103
return {
115-
// expected-old-error@+2 {{reference to captured var 'weakRef' in concurrently-executing code}}
116-
// expected-new-error@+1 {{reference to captured var 'weakRef' in concurrently-executing code}}
104+
// expected-error@+1 {{reference to captured var 'weakRef' in concurrently-executing code}}
117105
weakRef?.foo()
118106
}
119107
}
120108

121109
func checkWeakCapture2(_ strongRef: S) -> @Sendable () -> Void {
122-
// expected-old-error@+1 {{'weak' must be a mutable variable, because it may change at runtime}}
123110
weak let weakRef: S? = strongRef
124111
return {
125112
weakRef?.foo()
@@ -137,7 +124,7 @@ func checkWeakCapture3(_ strongRef: S) -> @Sendable () -> Void {
137124
}
138125

139126
func checkWeakCapture4(_ strongRef: NS) -> @Sendable () -> Void {
140-
// expected-new-warning@+1 {{variable 'weakRef' was never mutated; consider changing to 'let' constant}}
127+
// expected-warning@+1 {{variable 'weakRef' was never mutated; consider changing to 'let' constant}}
141128
weak var weakRef: NS? = strongRef
142129
return {
143130
// expected-error@+2 {{capture of 'weakRef' with non-Sendable type 'NS?' in a '@Sendable' closure}}
@@ -147,7 +134,6 @@ func checkWeakCapture4(_ strongRef: NS) -> @Sendable () -> Void {
147134
}
148135

149136
func checkWeakCapture5(_ strongRef: NS) -> @Sendable () -> Void {
150-
// expected-old-error@+1 {{'weak' must be a mutable variable, because it may change at runtime}}
151137
weak let weakRef: NS? = strongRef
152138
return {
153139
// expected-error@+1 {{capture of 'weakRef' with non-Sendable type 'NS?' in a '@Sendable' closure}}

test/DebugInfo/WeakCapture.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %target-swift-frontend %s -emit-ir -g -o - | %FileCheck %s
2-
// RUN: %target-swift-frontend %s -enable-upcoming-feature WeakLet -emit-ir -g -o - | %FileCheck %s
2+
// RUN: %target-swift-frontend %s -enable-upcoming-feature ImmutableWeakCaptures -emit-ir -g -o - | %FileCheck %s
33

4-
// REQUIRES: swift_feature_WeakLet
4+
// REQUIRES: swift_feature_ImmutableWeakCaptures
55

66
class A {
77
init(handler: (() -> ())) { }

test/DebugInfo/guard-let-scope4.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %target-swift-frontend -g -Xllvm -sil-print-types -emit-sil %s -parse-as-library -module-name a | %FileCheck %s
2-
// RUN: %target-swift-frontend -g -Xllvm -sil-print-types -emit-sil %s -parse-as-library -module-name a -enable-upcoming-feature WeakLet | %FileCheck %s --check-prefixes=CHECK,CHECK-HAS-WEAK-LET
3-
// REQUIRES: swift_feature_WeakLet
2+
// RUN: %target-swift-frontend -g -Xllvm -sil-print-types -emit-sil %s -parse-as-library -module-name a -enable-upcoming-feature ImmutableWeakCaptures | %FileCheck %s --check-prefixes=CHECK,CHECK-HAS-WEAK-LET
3+
// REQUIRES: swift_feature_ImmutableWeakCaptures
44
open class C {
55
public func run() {
66
{ [weak self] in

0 commit comments

Comments
 (0)