Skip to content

Commit 6bcdc4b

Browse files
committed
Sema: Move some work from typeCheckPatternBinding() to DeclChecker::visitPatternBindingDecl()
The following only needs to happen in primary files: - The weak/unowned immediate deallocation warning - Checking error handling - Re-contextualizing autoclosures
1 parent 2e635e9 commit 6bcdc4b

File tree

2 files changed

+38
-25
lines changed

2 files changed

+38
-25
lines changed

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2506,23 +2506,8 @@ bool TypeChecker::typeCheckPatternBinding(PatternBindingDecl *PBD,
25062506
PBD->setPattern(patternNumber, pattern, initContext);
25072507
PBD->setInit(patternNumber, init);
25082508

2509-
if (!hadError) {
2510-
// If we're performing an binding to a weak or unowned variable from a
2511-
// constructor call, emit a warning that the instance will be immediately
2512-
// deallocated.
2513-
diagnoseUnownedImmediateDeallocation(*this, pattern, pbe.getEqualLoc(),
2514-
init);
2515-
2516-
// If we entered an initializer context, contextualize any
2517-
// auto-closures we might have created.
2518-
if (initContext) {
2519-
// Check safety of error-handling in the declaration, too.
2520-
checkInitializerErrorHandling(initContext, init);
2521-
(void)contextualizeInitializer(initContext, init);
2522-
}
2523-
} else {
2509+
if (hadError)
25242510
PBD->setInvalid();
2525-
}
25262511

25272512
PBD->setInitializerChecked(patternNumber);
25282513
return hadError;

lib/Sema/TypeCheckDecl.cpp

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "swift/AST/ForeignErrorConvention.h"
3131
#include "swift/AST/GenericEnvironment.h"
3232
#include "swift/AST/GenericSignatureBuilder.h"
33+
#include "swift/AST/Initializer.h"
3334
#include "swift/AST/NameLookup.h"
3435
#include "swift/AST/PrettyStackTrace.h"
3536
#include "swift/AST/ProtocolConformance.h"
@@ -2236,6 +2237,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
22362237
}
22372238

22382239
void visitPatternBindingDecl(PatternBindingDecl *PBD) {
2240+
DeclContext *DC = PBD->getDeclContext();
2241+
22392242
// Check all the pattern/init pairs in the PBD.
22402243
validatePatternBindingEntries(TC, PBD);
22412244

@@ -2296,9 +2299,9 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
22962299
}
22972300

22982301
bool isInSILMode = false;
2299-
if (auto sourceFile = PBD->getDeclContext()->getParentSourceFile())
2302+
if (auto sourceFile = DC->getParentSourceFile())
23002303
isInSILMode = sourceFile->Kind == SourceFileKind::SIL;
2301-
bool isTypeContext = PBD->getDeclContext()->isTypeContext();
2304+
bool isTypeContext = DC->isTypeContext();
23022305

23032306
// If this is a declaration without an initializer, reject code if
23042307
// uninitialized vars are not allowed.
@@ -2315,8 +2318,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
23152318
if (var->isInvalid() || PBD->isInvalid())
23162319
return;
23172320

2318-
auto *varDC = var->getDeclContext();
2319-
23202321
auto markVarAndPBDInvalid = [PBD, var] {
23212322
PBD->setInvalid();
23222323
var->setInvalid();
@@ -2334,9 +2335,9 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
23342335

23352336
// Static/class declarations require an initializer unless in a
23362337
// protocol.
2337-
if (var->isStatic() && !isa<ProtocolDecl>(varDC)) {
2338+
if (var->isStatic() && !isa<ProtocolDecl>(DC)) {
23382339
// ...but don't enforce this for SIL or parseable interface files.
2339-
switch (varDC->getParentSourceFile()->Kind) {
2340+
switch (DC->getParentSourceFile()->Kind) {
23402341
case SourceFileKind::Interface:
23412342
case SourceFileKind::SIL:
23422343
return;
@@ -2353,8 +2354,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
23532354
}
23542355

23552356
// Global variables require an initializer in normal source files.
2356-
if (varDC->isModuleScopeContext()) {
2357-
switch (varDC->getParentSourceFile()->Kind) {
2357+
if (DC->isModuleScopeContext()) {
2358+
switch (DC->getParentSourceFile()->Kind) {
23582359
case SourceFileKind::Main:
23592360
case SourceFileKind::REPL:
23602361
case SourceFileKind::Interface:
@@ -2378,8 +2379,35 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
23782379

23792380
// If the initializers in the PBD aren't checked yet, do so now.
23802381
for (unsigned i = 0, e = PBD->getNumPatternEntries(); i != e; ++i) {
2381-
if (!PBD->isInitializerChecked(i) && PBD->getInit(i))
2382+
if (!PBD->getInit(i))
2383+
continue;
2384+
2385+
if (!PBD->isInitializerChecked(i))
23822386
TC.typeCheckPatternBinding(PBD, i);
2387+
2388+
if (!PBD->isInvalid()) {
2389+
auto &entry = PBD->getPatternList()[i];
2390+
auto *init = PBD->getInit(i);
2391+
2392+
// If we're performing an binding to a weak or unowned variable from a
2393+
// constructor call, emit a warning that the instance will be immediately
2394+
// deallocated.
2395+
diagnoseUnownedImmediateDeallocation(TC, PBD->getPattern(i),
2396+
entry.getEqualLoc(),
2397+
init);
2398+
2399+
// If we entered an initializer context, contextualize any
2400+
// auto-closures we might have created.
2401+
if (!DC->isLocalContext()) {
2402+
auto *initContext = cast_or_null<PatternBindingInitializer>(
2403+
entry.getInitContext());
2404+
if (initContext) {
2405+
// Check safety of error-handling in the declaration, too.
2406+
TC.checkInitializerErrorHandling(initContext, init);
2407+
(void) TC.contextualizeInitializer(initContext, init);
2408+
}
2409+
}
2410+
}
23832411
}
23842412
}
23852413

0 commit comments

Comments
 (0)