@@ -1780,24 +1780,37 @@ class ImplicitSelfUsageChecker : public BaseDiagnosticWalker {
17801780 if (!conditionalStmt) {
17811781 return false ;
17821782 }
1783-
1784- // Require that the RHS of the `let self = self` condition
1785- // refers to a variable defined in a capture list.
1786- // This lets us reject invalid examples like:
1787- //
1788- // var `self` = self ?? .somethingElse
1789- // guard let self = self else { return }
1790- // method() // <- implicit self is not allowed
1791- //
1792- // In 5.10, instead of this check, compiler was checking that RHS of the
1793- // self binding is loaded from a mutable variable. This is incorrect, but
1794- // before SE-0481 compiler was trying to maintain this behavior in Swift 5
1795- // mode for source compatibility. After SE-0481 this does not work
1796- // anymore, because even in Swift 5 mode `weak self` capture is not mutable.
1797- // So we have to introduce a breaking change as part of the SE-0481, and use
1798- // proper check for capture list even in Swift 5 mode.
1799- //
1800- return conditionalStmt->rebindsSelf (Ctx, /* requiresCaptureListRef*/ true );
1783+
1784+ if (Ctx.LangOpts .hasFeature (Feature::WeakLet)) {
1785+ // Require that the RHS of the `let self = self` condition
1786+ // refers to a variable defined in a capture list.
1787+ // This lets us reject invalid examples like:
1788+ //
1789+ // var `self` = self ?? .somethingElse
1790+ // guard let self = self else { return }
1791+ // method() // <- implicit self is not allowed
1792+ //
1793+ // In 5.10, instead of this check, compiler was checking that RHS of the
1794+ // self binding is loaded from a mutable variable. This is incorrect, but
1795+ // before SE-0481 compiler was trying to maintain this behavior in Swift 5
1796+ // mode for source compatibility. After SE-0481 this does not work
1797+ // anymore, because even in Swift 5 mode `weak self` capture is not mutable.
1798+ // So we have to introduce a breaking change as part of the SE-0481, and use
1799+ // proper check for capture list even in Swift 5 mode.
1800+ //
1801+ return conditionalStmt->rebindsSelf (Ctx, /* requiresCaptureListRef*/ true );
1802+ } else {
1803+ // Require `LoadExpr`s when validating the self binding.
1804+ // This lets us reject invalid examples like:
1805+ //
1806+ // let `self` = self ?? .somethingElse
1807+ // guard let self = self else { return }
1808+ // method() // <- implicit self is not allowed
1809+ //
1810+ return conditionalStmt->rebindsSelf (Ctx, /* requiresCaptureListRef*/ false ,
1811+ /* requireLoadExpr*/ true );
1812+
1813+ }
18011814 }
18021815
18031816 static bool
@@ -4093,6 +4106,11 @@ VarDeclUsageChecker::~VarDeclUsageChecker() {
40934106 access &= ~RK_Written;
40944107 }
40954108
4109+ // If this variable has WeakStorageType, then it can be mutated in ways we
4110+ // don't know.
4111+ if (var->getInterfaceType ()->is <WeakStorageType>() && !DC->getASTContext ().LangOpts .hasFeature (Feature::WeakLet))
4112+ access |= RK_Written;
4113+
40964114 // Diagnose variables that were never used (other than their
40974115 // initialization).
40984116 //
0 commit comments