Skip to content

Commit 87e536e

Browse files
Merge pull request #80440 from nickolas-pohilets/mpokhylets/weak-let
2 parents b016f13 + 847a7d2 commit 87e536e

23 files changed

+634
-101
lines changed

include/swift/AST/Stmt.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -727,10 +727,7 @@ class alignas(1 << PatternAlignInBits) StmtConditionElement {
727727
/// or `let self = self` condition.
728728
/// - If `requiresCaptureListRef` is `true`, additionally requires that the
729729
/// RHS of the self condition references a var defined in a capture list.
730-
/// - If `requireLoadExpr` is `true`, additionally requires that the RHS of
731-
/// the self condition is a `LoadExpr`.
732-
bool rebindsSelf(ASTContext &Ctx, bool requiresCaptureListRef = false,
733-
bool requireLoadExpr = false) const;
730+
bool rebindsSelf(ASTContext &Ctx, bool requiresCaptureListRef = false) const;
734731

735732
SourceLoc getStartLoc() const;
736733
SourceLoc getEndLoc() const;
@@ -839,10 +836,7 @@ class LabeledConditionalStmt : public LabeledStmt {
839836
/// or `let self = self` condition.
840837
/// - If `requiresCaptureListRef` is `true`, additionally requires that the
841838
/// RHS of the self condition references a var defined in a capture list.
842-
/// - If `requireLoadExpr` is `true`, additionally requires that the RHS of
843-
/// the self condition is a `LoadExpr`.
844-
bool rebindsSelf(ASTContext &Ctx, bool requiresCaptureListRef = false,
845-
bool requireLoadExpr = false) const;
839+
bool rebindsSelf(ASTContext &Ctx, bool requiresCaptureListRef = false) const;
846840

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

lib/AST/Expr.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,11 +1366,8 @@ CaptureListEntry CaptureListEntry::createParsed(
13661366
SourceRange ownershipRange, Identifier name, SourceLoc nameLoc,
13671367
SourceLoc equalLoc, Expr *initializer, DeclContext *DC) {
13681368

1369-
auto introducer =
1370-
(ownershipKind != ReferenceOwnership::Weak ? VarDecl::Introducer::Let
1371-
: VarDecl::Introducer::Var);
13721369
auto *VD =
1373-
new (Ctx) VarDecl(/*isStatic==*/false, introducer, nameLoc, name, DC);
1370+
new (Ctx) VarDecl(/*isStatic==*/false, VarDecl::Introducer::Let, nameLoc, name, DC);
13741371

13751372
if (ownershipKind != ReferenceOwnership::Strong)
13761373
VD->getAttrs().add(

lib/AST/Stmt.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -514,26 +514,19 @@ void LabeledConditionalStmt::setCond(StmtCondition e) {
514514
/// or `let self = self` condition.
515515
/// - If `requiresCaptureListRef` is `true`, additionally requires that the
516516
/// RHS of the self condition references a var defined in a capture list.
517-
/// - If `requireLoadExpr` is `true`, additionally requires that the RHS of
518-
/// the self condition is a `LoadExpr`.
519517
bool LabeledConditionalStmt::rebindsSelf(ASTContext &Ctx,
520-
bool requiresCaptureListRef,
521-
bool requireLoadExpr) const {
522-
return llvm::any_of(getCond(), [&Ctx, requiresCaptureListRef,
523-
requireLoadExpr](const auto &cond) {
524-
return cond.rebindsSelf(Ctx, requiresCaptureListRef, requireLoadExpr);
518+
bool requiresCaptureListRef) const {
519+
return llvm::any_of(getCond(), [&Ctx, requiresCaptureListRef](const auto &cond) {
520+
return cond.rebindsSelf(Ctx, requiresCaptureListRef);
525521
});
526522
}
527523

528524
/// Whether or not this conditional stmt rebinds self with a `let self`
529525
/// or `let self = self` condition.
530526
/// - If `requiresCaptureListRef` is `true`, additionally requires that the
531527
/// RHS of the self condition references a var defined in a capture list.
532-
/// - If `requireLoadExpr` is `true`, additionally requires that the RHS of
533-
/// the self condition is a `LoadExpr`.
534528
bool StmtConditionElement::rebindsSelf(ASTContext &Ctx,
535-
bool requiresCaptureListRef,
536-
bool requireLoadExpr) const {
529+
bool requiresCaptureListRef) const {
537530
auto pattern = getPatternOrNull();
538531
if (!pattern) {
539532
return false;
@@ -561,10 +554,6 @@ bool StmtConditionElement::rebindsSelf(ASTContext &Ctx,
561554
return false;
562555
}
563556

564-
if (requireLoadExpr && !isa<LoadExpr>(exprToCheckForDRE)) {
565-
return false;
566-
}
567-
568557
if (auto *load = dyn_cast<LoadExpr>(exprToCheckForDRE)) {
569558
exprToCheckForDRE = load->getSubExpr();
570559
}

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>()) {
179-
return CaptureKind::Box;
180-
}
181-
182173
// For 'let' constants
183174
if (!var->supportsMutation()) {
184175
assert(getTypeLowering(

lib/Sema/MiscDiagnostics.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,15 +1748,23 @@ class ImplicitSelfUsageChecker : public BaseDiagnosticWalker {
17481748
return false;
17491749
}
17501750

1751-
// Require `LoadExpr`s when validating the self binding.
1751+
// Require that the RHS of the `let self = self` condition
1752+
// refers to a variable defined in a capture list.
17521753
// This lets us reject invalid examples like:
17531754
//
1754-
// let `self` = self ?? .somethingElse
1755+
// var `self` = self ?? .somethingElse
17551756
// guard let self = self else { return }
17561757
// method() // <- implicit self is not allowed
17571758
//
1758-
return conditionalStmt->rebindsSelf(Ctx, /*requiresCaptureListRef*/ false,
1759-
/*requireLoadExpr*/ true);
1759+
// In 5.10, instead of this check, compiler was checking that RHS of the
1760+
// self binding is loaded from a mutable variable. This is incorrect, but
1761+
// before SE-0481 compiler was trying to maintain this behavior in Swift 5
1762+
// mode for source compatibility. After SE-0481 this does not work
1763+
// anymore, because even in Swift 5 mode `weak self` capture is not mutable.
1764+
// So we have to introduce a breaking change as part of the SE-0481, and use
1765+
// proper check for capture list even in Swift 5 mode.
1766+
//
1767+
return conditionalStmt->rebindsSelf(Ctx, /*requiresCaptureListRef*/ true);
17601768
}
17611769

17621770
static bool
@@ -4003,11 +4011,6 @@ VarDeclUsageChecker::~VarDeclUsageChecker() {
40034011
access &= ~RK_Written;
40044012
}
40054013

4006-
// If this variable has WeakStorageType, then it can be mutated in ways we
4007-
// don't know.
4008-
if (var->getInterfaceType()->is<WeakStorageType>())
4009-
access |= RK_Written;
4010-
40114014
// Diagnose variables that were never used (other than their
40124015
// initialization).
40134016
//

lib/Sema/TypeCheckAttr.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5302,11 +5302,6 @@ Type TypeChecker::checkReferenceOwnershipAttr(VarDecl *var, Type type,
53025302
case ReferenceOwnershipOptionality::Allowed:
53035303
break;
53045304
case ReferenceOwnershipOptionality::Required:
5305-
if (var->isLet()) {
5306-
var->diagnose(diag::invalid_ownership_is_let, ownershipKind);
5307-
attr->setInvalid();
5308-
}
5309-
53105305
if (!isOptional) {
53115306
attr->setInvalid();
53125307

0 commit comments

Comments
 (0)