@@ -1837,8 +1837,7 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
18371837 static const AbstractClosureExpr *
18381838 parentClosureDisallowingImplicitSelf (const ValueDecl *selfDecl,
18391839 const Type captureType,
1840- const AbstractClosureExpr *inClosure,
1841- bool validateOutermostCapture = true ) {
1840+ const AbstractClosureExpr *inClosure) {
18421841 // Find the outer decl that determines what self refers to in this
18431842 // closure.
18441843 // - If this is an escaping closure that captured self, then `selfDecl`
@@ -1861,7 +1860,7 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
18611860 // potentially also validating all intermediate closures.
18621861 auto outerClosure = inClosure;
18631862 bool validateIntermediateParents = true ;
1864- do {
1863+ while ( true ) {
18651864 // We have to validate all intermediate parent closures
18661865 // to prevent cases like this from succeeding, which is
18671866 // invalid because the outer closure doesn't have an
@@ -1894,8 +1893,9 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
18941893 }
18951894 }
18961895
1897- auto parent = parentClosure (outerClosure);
1898- if (!parent) {
1896+ outerClosure = parentClosure (outerClosure);
1897+
1898+ if (!outerClosure) {
18991899 // Once we reach a parent context that isn't a closure,
19001900 // the only valid self capture is the self parameter.
19011901 // This disallows cases like:
@@ -1905,26 +1905,22 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
19051905 // method()
19061906 // }
19071907 //
1908- if (validateOutermostCapture) {
1909- auto VD = dyn_cast<VarDecl>(outerSelfDecl);
1910- if (!VD) {
1911- return inClosure;
1912- }
1908+ auto VD = dyn_cast<VarDecl>(outerSelfDecl);
1909+ if (!VD) {
1910+ return inClosure;
1911+ }
19131912
1914- if (!VD->isSelfParameter ()) {
1915- return inClosure;
1916- }
1913+ if (!VD->isSelfParameter ()) {
1914+ return inClosure;
19171915 }
19181916
19191917 return nullptr ;
19201918 }
19211919
1922- outerClosure = parent;
1923-
19241920 // Check if this closure contains the self decl.
19251921 // - If the self decl is defined in the closure's body, its
19261922 // decl context will be the closure itself.
1927- // - If the self decl is defined in the closure's capture list, =
1923+ // - If the self decl is defined in the closure's capture list,
19281924 // its parent capture list will reference the closure.
19291925 auto selfDeclInOuterClosureContext =
19301926 outerSelfDecl->getDeclContext () == outerClosure;
@@ -1938,7 +1934,8 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
19381934 }
19391935
19401936 // We can stop searching because we found the first outer closure
1941- // that contains the outer self decl.
1937+ // that contains the outer self decl. Otherwise we continue searching
1938+ // any parent closures in the next loop iteration.
19421939 if (selfDeclInOuterClosureContext ||
19431940 selfDeclInOuterClosureCaptureList) {
19441941 // Check whether implicit self is disallowed due to this specific
@@ -1952,8 +1949,7 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
19521949 }
19531950
19541951 return parentClosureDisallowingImplicitSelf (
1955- outerSelfDecl, captureType, outerClosure,
1956- /* validateOutermostCapture:*/ validateOutermostCapture);
1952+ outerSelfDecl, captureType, outerClosure);
19571953 }
19581954
19591955 // Optionally validate this intermediate closure before continuing
@@ -1966,7 +1962,7 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
19661962 return outerClosure;
19671963 }
19681964 }
1969- } while ( true );
1965+ }
19701966 }
19711967
19721968 static bool
0 commit comments