Skip to content

Commit 1e05bd8

Browse files
authored
Merge pull request #62833 from ahoppen/ahoppen/allow-closure-with-error
[Sema] Don’t fail constraint generation if a closure contains an ErrorExpr
2 parents ab8b4a2 + 17d47bb commit 1e05bd8

File tree

6 files changed

+9
-26
lines changed

6 files changed

+9
-26
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4926,7 +4926,9 @@ bool MissingArgumentsFailure::diagnoseClosure(const ClosureExpr *closure) {
49264926

49274927
auto *locator = getLocator();
49284928
if (locator->isForContextualType()) {
4929-
funcType = getContextualType(locator->getAnchor())->getAs<FunctionType>();
4929+
if (auto contextualType = getContextualType(locator->getAnchor())) {
4930+
funcType = contextualType->getAs<FunctionType>();
4931+
}
49304932
} else if (auto info = getFunctionArgApplyInfo(locator)) {
49314933
auto paramType = info->getParamType();
49324934
// Drop a single layer of optionality because argument could get injected

lib/Sema/CSGen.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2901,18 +2901,12 @@ namespace {
29012901
struct CollectVarRefs : public ASTWalker {
29022902
ConstraintSystem &cs;
29032903
llvm::SmallPtrSet<TypeVariableType *, 4> varRefs;
2904-
bool hasErrorExprs = false;
29052904

29062905
CollectVarRefs(ConstraintSystem &cs) : cs(cs) { }
29072906

29082907
bool shouldWalkCaptureInitializerExpressions() override { return true; }
29092908

29102909
PreWalkResult<Expr *> walkToExprPre(Expr *expr) override {
2911-
// If there are any error expressions in this closure
2912-
// it wouldn't be possible to infer its type.
2913-
if (isa<ErrorExpr>(expr))
2914-
hasErrorExprs = true;
2915-
29162910
// Retrieve type variables from references to var decls.
29172911
if (auto *declRef = dyn_cast<DeclRefExpr>(expr)) {
29182912
if (auto *varDecl = dyn_cast<VarDecl>(declRef->getDecl())) {
@@ -2954,15 +2948,6 @@ namespace {
29542948

29552949
closure->walk(collectVarRefs);
29562950

2957-
// If walker discovered error expressions, let's fail constraint
2958-
// generation only if closure is going to participate
2959-
// in the type-check. This allows us to delay validation of
2960-
// multi-statement closures until body is opened.
2961-
if (CS.participatesInInference(closure) &&
2962-
collectVarRefs.hasErrorExprs) {
2963-
return Type();
2964-
}
2965-
29662951
auto inferredType = inferClosureType(closure);
29672952
if (!inferredType || inferredType->hasError())
29682953
return Type();

test/Constraints/result_builder_diags.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ struct TupleBuilderWithoutIf { // expected-note 3{{struct 'TupleBuilderWithoutIf
7878
static func buildDo<T>(_ value: T) -> T { return value }
7979
}
8080

81-
func tuplify<T>(_ cond: Bool, @TupleBuilder body: (Bool) -> T) {
81+
func tuplify<T>(_ cond: Bool, @TupleBuilder body: (Bool) -> T) { // expected-note 2{{in call to function 'tuplify(_:body:)'}}
8282
print(body(cond))
8383
}
8484

@@ -88,7 +88,7 @@ func tuplifyWithoutIf<T>(_ cond: Bool, @TupleBuilderWithoutIf body: (Bool) -> T)
8888

8989
func testDiags() {
9090
// For loop
91-
tuplify(true) { _ in
91+
tuplify(true) { _ in // expected-error {{generic parameter 'T' could not be inferred}}
9292
17
9393
for c in name {
9494
// expected-error@-1 {{cannot find 'name' in scope}}
@@ -464,7 +464,7 @@ struct TestConstraintGenerationErrors {
464464
}
465465

466466
func buildTupleClosure() {
467-
tuplify(true) { _ in
467+
tuplify(true) { _ in // expected-error {{generic parameter 'T' could not be inferred}}
468468
let a = nothing // expected-error {{cannot find 'nothing' in scope}}
469469
String(nothing) // expected-error {{cannot find 'nothing' in scope}}
470470
}

test/Parse/recovery.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,7 @@ class r22240342 {
775775
lazy var xx: Int = {
776776
foo { // expected-error {{cannot find 'foo' in scope}}
777777
let issueView = 42
778-
issueView.delegate = 12
778+
issueView.delegate = 12 // expected-error {{value of type 'Int' has no member 'delegate'}}
779779

780780
}
781781
return 42

test/StringProcessing/Sema/regex_builder_fix_import_top_level.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,7 @@ Regex { // expected-error {{regex builder requires the 'RegexBuilder' module be
1919
/g(h)(i)/
2020
}
2121

22-
// FIXME: Unfortunately we bail from CSGen if we end up with an ErrorExpr, so
23-
// don't get a chance to diagnose. We ought to try solving with holes.
24-
// For now at least, this error should at least hopefully nudge users into
25-
// realizing they have a missing import.
26-
Regex {
22+
Regex { // expected-error {{regex builder requires the 'RegexBuilder' module be imported'}}
2723
Capture { // expected-error {{cannot find 'Capture' in scope}}
2824
/abc/
2925
}

test/stmt/statements.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ func matching_pattern_recursion(zs: [Int]) { // expected-note {{'zs' declared he
409409
}
410410

411411
switch 42 {
412-
case {
412+
case { // expected-error {{expression pattern of type '() -> ()' cannot match values of type 'Int'}}
413413
for i in ws { // expected-error {{cannot find 'ws' in scope; did you mean 'zs'?}}
414414
}
415415
}: break

0 commit comments

Comments
 (0)