Skip to content

Commit 9d9b4c9

Browse files
committed
[Sema] Sink Pattern invalidation into SyntacticElementTarget::markInvalid
Rather than handling this in the callers of `typeCheckExpression`, handle it in the constraint system's invalidation logic. This also ensures we set a type for sub-pattern nodes.
1 parent ce9028f commit 9d9b4c9

File tree

3 files changed

+9
-38
lines changed

3 files changed

+9
-38
lines changed

lib/AST/Stmt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ Type DoCatchStmt::getCaughtErrorType() const {
493493
->getCaseLabelItems()
494494
.front()
495495
.getPattern();
496-
if (firstPattern->hasType())
496+
if (firstPattern->hasType() && !firstPattern->getType()->hasError())
497497
return firstPattern->getType();
498498

499499
return Type();

lib/Sema/SyntacticElementTarget.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,11 @@ void SyntacticElementTarget::markInvalid() const {
308308
return Action::Continue(E);
309309
}
310310

311+
PreWalkResult<Pattern *> walkToPatternPre(Pattern *P) override {
312+
P->setType(ErrorType::get(Ctx));
313+
return Action::Continue(P);
314+
}
315+
311316
PreWalkAction walkToDeclPre(Decl *D) override {
312317
// Mark any VarDecls and PatternBindingDecls as invalid.
313318
if (auto *VD = dyn_cast<VarDecl>(D)) {

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -852,31 +852,8 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer,
852852
return false;
853853
}
854854

855-
auto &Context = DC->getASTContext();
856855
initializer = target.getAsExpr();
857856
pattern = target.getInitializationPattern();
858-
859-
if (!initializer->getType())
860-
initializer->setType(ErrorType::get(Context));
861-
862-
// Assign error types to the pattern and its variables, to prevent it from
863-
// being referenced by the constraint system.
864-
if (patternType->hasUnresolvedType() ||
865-
patternType->hasPlaceholder() ||
866-
patternType->hasUnboundGenericType()) {
867-
pattern->setType(ErrorType::get(Context));
868-
}
869-
870-
pattern->forEachVariable([&](VarDecl *var) {
871-
// Don't change the type of a variable that we've been able to
872-
// compute a type for.
873-
if (var->hasInterfaceType() &&
874-
!var->getTypeInContext()->hasUnboundGenericType() &&
875-
!var->isInvalid())
876-
return;
877-
878-
var->setInvalid();
879-
});
880857
return true;
881858
}
882859

@@ -928,25 +905,14 @@ bool TypeChecker::typeCheckForEachPreamble(DeclContext *dc, ForEachStmt *stmt) {
928905
FrontendStatsTracer statsTracer(Context.Stats, "typecheck-for-each", stmt);
929906
PrettyStackTraceStmt stackTrace(Context, "type-checking-for-each", stmt);
930907

931-
auto failed = [&]() -> bool {
932-
// Invalidate the pattern and the var decl.
933-
stmt->getPattern()->setType(ErrorType::get(Context));
934-
stmt->getPattern()->forEachVariable([&](VarDecl *var) {
935-
if (var->hasInterfaceType() && !var->isInvalid())
936-
return;
937-
var->setInvalid();
938-
});
939-
return true;
940-
};
941-
942908
auto target = SyntacticElementTarget::forForEachPreamble(stmt, dc);
943909
if (!typeCheckTarget(target))
944-
return failed();
910+
return true;
945911

946912
if (auto *where = stmt->getWhere()) {
947913
auto boolType = dc->getASTContext().getBoolType();
948914
if (!boolType)
949-
return failed();
915+
return true;
950916

951917
SyntacticElementTarget whereClause(where, dc, {boolType, CTP_Condition},
952918
/*isDiscarded=*/false);
@@ -960,7 +926,7 @@ bool TypeChecker::typeCheckForEachPreamble(DeclContext *dc, ForEachStmt *stmt) {
960926
// Check to see if the sequence expr is throwing (in async context),
961927
// if so require the stmt to have a `try`.
962928
if (diagnoseUnhandledThrowsInAsyncContext(dc, stmt))
963-
return failed();
929+
return true;
964930

965931
return false;
966932
}

0 commit comments

Comments
 (0)