@@ -1837,8 +1837,7 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
1837
1837
static const AbstractClosureExpr *
1838
1838
parentClosureDisallowingImplicitSelf (const ValueDecl *selfDecl,
1839
1839
const Type captureType,
1840
- const AbstractClosureExpr *inClosure,
1841
- bool validateOutermostCapture = true ) {
1840
+ const AbstractClosureExpr *inClosure) {
1842
1841
// Find the outer decl that determines what self refers to in this
1843
1842
// closure.
1844
1843
// - If this is an escaping closure that captured self, then `selfDecl`
@@ -1861,7 +1860,7 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
1861
1860
// potentially also validating all intermediate closures.
1862
1861
auto outerClosure = inClosure;
1863
1862
bool validateIntermediateParents = true ;
1864
- do {
1863
+ while ( true ) {
1865
1864
// We have to validate all intermediate parent closures
1866
1865
// to prevent cases like this from succeeding, which is
1867
1866
// invalid because the outer closure doesn't have an
@@ -1894,8 +1893,9 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
1894
1893
}
1895
1894
}
1896
1895
1897
- auto parent = parentClosure (outerClosure);
1898
- if (!parent) {
1896
+ outerClosure = parentClosure (outerClosure);
1897
+
1898
+ if (!outerClosure) {
1899
1899
// Once we reach a parent context that isn't a closure,
1900
1900
// the only valid self capture is the self parameter.
1901
1901
// This disallows cases like:
@@ -1905,26 +1905,22 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
1905
1905
// method()
1906
1906
// }
1907
1907
//
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
+ }
1913
1912
1914
- if (!VD->isSelfParameter ()) {
1915
- return inClosure;
1916
- }
1913
+ if (!VD->isSelfParameter ()) {
1914
+ return inClosure;
1917
1915
}
1918
1916
1919
1917
return nullptr ;
1920
1918
}
1921
1919
1922
- outerClosure = parent;
1923
-
1924
1920
// Check if this closure contains the self decl.
1925
1921
// - If the self decl is defined in the closure's body, its
1926
1922
// 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,
1928
1924
// its parent capture list will reference the closure.
1929
1925
auto selfDeclInOuterClosureContext =
1930
1926
outerSelfDecl->getDeclContext () == outerClosure;
@@ -1938,7 +1934,8 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
1938
1934
}
1939
1935
1940
1936
// 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.
1942
1939
if (selfDeclInOuterClosureContext ||
1943
1940
selfDeclInOuterClosureCaptureList) {
1944
1941
// Check whether implicit self is disallowed due to this specific
@@ -1952,8 +1949,7 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
1952
1949
}
1953
1950
1954
1951
return parentClosureDisallowingImplicitSelf (
1955
- outerSelfDecl, captureType, outerClosure,
1956
- /* validateOutermostCapture:*/ validateOutermostCapture);
1952
+ outerSelfDecl, captureType, outerClosure);
1957
1953
}
1958
1954
1959
1955
// Optionally validate this intermediate closure before continuing
@@ -1966,7 +1962,7 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
1966
1962
return outerClosure;
1967
1963
}
1968
1964
}
1969
- } while ( true );
1965
+ }
1970
1966
}
1971
1967
1972
1968
static bool
0 commit comments