Skip to content

Commit 4d9d38d

Browse files
authored
Merge pull request #36609 from xedin/rdar-75409111
[CSGen] Avoid failing due to invalid explicit closure parameters
2 parents 54006fd + a51e3da commit 4d9d38d

File tree

5 files changed

+63
-23
lines changed

5 files changed

+63
-23
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7199,10 +7199,17 @@ bool MissingContextualTypeForNil::diagnoseAsError() {
71997199
}
72007200

72017201
bool ReferenceToInvalidDeclaration::diagnoseAsError() {
7202+
auto &DE = getASTContext().Diags;
7203+
7204+
// `resolveType` caches results, so there is no way
7205+
// to suppress and then re-request the diagnostic
7206+
// via calling `resolveType` on the same `TypeRepr`.
7207+
if (getAsDecl<ParamDecl>(getAnchor()))
7208+
return DE.hadAnyError();
7209+
72027210
auto *decl = castToExpr<DeclRefExpr>(getAnchor())->getDecl();
72037211
assert(decl);
72047212

7205-
auto &DE = getASTContext().Diags;
72067213
// This problem should have been already diagnosed during
72077214
// validation of the declaration.
72087215
if (DE.hadAnyError())

lib/Sema/CSGen.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,6 +1984,18 @@ namespace {
19841984
Type externalType;
19851985
if (param->getTypeRepr()) {
19861986
auto declaredTy = CS.getVarType(param);
1987+
1988+
// If closure parameter couldn't be resolved, let's record
1989+
// a fix to make sure that type resolution diagnosed the
1990+
// problem and replace it with a placeholder, so that solver
1991+
// can make forward progress (especially important for result
1992+
// builders).
1993+
if (declaredTy->hasError()) {
1994+
CS.recordFix(AllowRefToInvalidDecl::create(
1995+
CS, CS.getConstraintLocator(param)));
1996+
declaredTy = PlaceholderType::get(CS.getASTContext(), param);
1997+
}
1998+
19871999
externalType = CS.replaceInferableTypesWithTypeVars(declaredTy,
19882000
paramLoc);
19892001
} else {

lib/Sema/PreCheckExpr.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,22 +1391,6 @@ namespace {
13911391
/// Perform prechecking of a ClosureExpr before we dive into it. This returns
13921392
/// true when we want the body to be considered part of this larger expression.
13931393
bool PreCheckExpression::walkToClosureExprPre(ClosureExpr *closure) {
1394-
auto *PL = closure->getParameters();
1395-
1396-
// Validate the parameters.
1397-
bool hadParameterError = false;
1398-
1399-
// If we encounter an error validating the parameter list, don't bail.
1400-
// Instead, go on to validate any potential result type, and bail
1401-
// afterwards. This allows for better diagnostics, and keeps the
1402-
// closure expression type well-formed.
1403-
for (auto param : *PL) {
1404-
hadParameterError |= param->isInvalid();
1405-
}
1406-
1407-
if (hadParameterError)
1408-
return false;
1409-
14101394
// If we won't be checking the body of the closure, don't walk into it here.
14111395
if (!shouldTypeCheckInEnclosingExpression(closure))
14121396
return false;

test/Constraints/result_builder_diags.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,3 +675,41 @@ do {
675675
throw MyError.boom
676676
}
677677
}
678+
679+
struct TuplifiedStructWithInvalidClosure {
680+
var condition: Bool
681+
682+
@TupleBuilder var unknownParameter: some Any {
683+
if let cond = condition {
684+
let _ = { (arg: UnknownType) in // expected-error {{cannot find type 'UnknownType' in scope}}
685+
}
686+
42
687+
} else {
688+
0
689+
}
690+
}
691+
692+
@TupleBuilder var unknownResult: some Any {
693+
if let cond = condition {
694+
let _ = { () -> UnknownType in // expected-error {{cannot find type 'UnknownType' in scope}}
695+
}
696+
42
697+
} else {
698+
0
699+
}
700+
}
701+
702+
@TupleBuilder var multipleLevelsDeep: some Any {
703+
if let cond = condition {
704+
switch MyError.boom {
705+
case .boom:
706+
let _ = { () -> UnknownType in // expected-error {{cannot find type 'UnknownType' in scope}}
707+
}
708+
}
709+
710+
42
711+
} else {
712+
0
713+
}
714+
}
715+
}

test/Constraints/tuple_arguments.swift

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1468,11 +1468,11 @@ let _ = sr4745.enumerated().map { (count, element) in "\(count): \(element)" }
14681468
// SR-4738
14691469

14701470
let sr4738 = (1, (2, 3))
1471-
[sr4738].map { (x, (y, z)) -> Int in x + y + z }
1471+
[sr4738].map { (x, (y, z)) -> Int in x + y + z } // expected-note 2 {{'x' declared here}}
14721472
// expected-error@-1 {{closure tuple parameter does not support destructuring}} {{20-26=arg1}} {{38-38=let (y, z) = arg1; }}
14731473
// expected-warning@-2 {{unnamed parameters must be written with the empty name '_'}} {{20-20=_: }}
1474-
// expected-error@-3 {{cannot find type 'y' in scope}}
1475-
// expected-error@-4 {{cannot find type 'z' in scope}}
1474+
// expected-error@-3 {{cannot find 'y' in scope; did you mean 'x'?}}
1475+
// expected-error@-4 {{cannot find 'z' in scope; did you mean 'x'?}}
14761476

14771477
// rdar://problem/31892961
14781478
let r31892961_1 = [1: 1, 2: 2]
@@ -1482,9 +1482,8 @@ let r31892961_2 = [1, 2, 3]
14821482
let _: [Int] = r31892961_2.enumerated().map { ((index, val)) in
14831483
// expected-error@-1 {{closure tuple parameter does not support destructuring}} {{48-60=arg0}} {{3-3=\n let (index, val) = arg0\n }}
14841484
// expected-warning@-2 {{unnamed parameters must be written with the empty name '_'}} {{48-48=_: }}
1485-
// expected-error@-3 {{cannot find type 'index' in scope}}
1486-
// expected-error@-4 {{cannot find type 'val' in scope}}
14871485
val + 1
1486+
// expected-error@-1 {{cannot find 'val' in scope}}
14881487
}
14891488

14901489
let r31892961_3 = (x: 1, y: 42)
@@ -1695,7 +1694,7 @@ class Mappable<T> {
16951694
}
16961695

16971696
let x = Mappable(())
1698-
// expected-note@-1 2{{'x' declared here}}
1697+
// expected-note@-1 4{{'x' declared here}}
16991698
x.map { (_: Void) in return () }
17001699
x.map { (_: ()) in () }
17011700

0 commit comments

Comments
 (0)