@@ -1671,9 +1671,6 @@ class SyntacticElementSolutionApplication
1671
1671
SyntacticElementContext context;
1672
1672
SyntacticElementTargetRewriter &rewriter;
1673
1673
1674
- // / All `func`s declared in the body of the closure.
1675
- SmallVector<FuncDecl *, 4 > LocalFuncs;
1676
-
1677
1674
public:
1678
1675
// / Whether an error was encountered while generating constraints.
1679
1676
bool hadError = false ;
@@ -1729,44 +1726,37 @@ class SyntacticElementSolutionApplication
1729
1726
return rewritten;
1730
1727
}
1731
1728
1729
+ bool visitPatternBindingDecl (PatternBindingDecl *PBD) {
1730
+ // If this is a placeholder variable with an initializer, we just need to
1731
+ // set the inferred type.
1732
+ if (isPlaceholderVar (PBD) && PBD->getInit (0 )) {
1733
+ auto *pattern = PBD->getPattern (0 );
1734
+ pattern->setType (solution.getResolvedType (PBD->getSingleVar ()));
1735
+ return false ;
1736
+ }
1737
+
1738
+ SyntacticElementTarget target (PBD);
1739
+ return !rewriter.rewriteTarget (target).has_value ();
1740
+ }
1741
+
1732
1742
void visitDecl (Decl *decl) {
1733
1743
if (isa<IfConfigDecl>(decl))
1734
1744
return ;
1735
1745
1736
- // Generate constraints for pattern binding declarations.
1737
- if (auto patternBinding = dyn_cast<PatternBindingDecl>(decl)) {
1738
- SyntacticElementTarget target (patternBinding);
1739
-
1740
- // If this is a placeholder varaible with an initializer, let's set
1741
- // the inferred type, and ask `typeCheckDecl` to type-check initializer.
1742
- if (isPlaceholderVar (patternBinding) && patternBinding->getInit (0 )) {
1743
- auto *pattern = patternBinding->getPattern (0 );
1744
- pattern->setType (
1745
- solution.getResolvedType (patternBinding->getSingleVar ()));
1746
-
1747
- TypeChecker::typeCheckDecl (decl);
1748
- return ;
1749
- }
1750
-
1751
- if (!rewriter.rewriteTarget (target)) {
1746
+ if (auto *PBD = dyn_cast<PatternBindingDecl>(decl)) {
1747
+ if (visitPatternBindingDecl (PBD)) {
1752
1748
hadError = true ;
1753
1749
return ;
1754
1750
}
1755
-
1756
- // Allow `typeCheckDecl` to be called after solution is applied
1757
- // to a pattern binding. That would materialize required
1751
+ // Fall through to allow `typeCheckDecl` to be called after solution is
1752
+ // applied to a pattern binding. That will materialize required
1758
1753
// information e.g. accessors and do access/availability checks.
1759
1754
}
1760
1755
1761
- // Local functions cannot be type-checked in-order because they can
1762
- // capture variables declared after them. Let's save them to be
1763
- // processed after the solution has been applied to the body.
1764
- if (auto *func = dyn_cast<FuncDecl>(decl)) {
1765
- LocalFuncs.push_back (func);
1766
- return ;
1767
- }
1768
-
1769
- TypeChecker::typeCheckDecl (decl);
1756
+ // Delay the type-checking of local decls to ensure that parent closures
1757
+ // have solutions applied, which is needed by MiscDiagnostics passes such as
1758
+ // `diagnoseImplicitSelfUseInClosure`
1759
+ rewriter.addLocalDeclToTypeCheck (decl);
1770
1760
}
1771
1761
1772
1762
ASTNode visitBreakStmt (BreakStmt *breakStmt) {
@@ -1792,7 +1782,7 @@ class SyntacticElementSolutionApplication
1792
1782
}
1793
1783
1794
1784
ASTNode visitDeferStmt (DeferStmt *deferStmt) {
1795
- TypeChecker::typeCheckDecl (deferStmt->getTempDecl ());
1785
+ rewriter. addLocalDeclToTypeCheck (deferStmt->getTempDecl ());
1796
1786
1797
1787
Expr *theCall = deferStmt->getCallExpr ();
1798
1788
TypeChecker::typeCheckExpression (theCall, context.getAsDeclContext ());
@@ -2234,13 +2224,6 @@ class SyntacticElementSolutionApplication
2234
2224
// / Apply the solution to the context and return updated statement.
2235
2225
Stmt *apply () {
2236
2226
auto body = visit (context.getStmt ());
2237
-
2238
- // Since local functions can capture variables that are declared
2239
- // after them, let's type-check them after all of the pattern
2240
- // bindings have been resolved by applying solution to the body.
2241
- for (auto *func : LocalFuncs)
2242
- TypeChecker::typeCheckDecl (func);
2243
-
2244
2227
return body ? body.get <Stmt *>() : nullptr ;
2245
2228
}
2246
2229
};
0 commit comments