Skip to content

Commit a51e3da

Browse files
committed
[CSGen] Avoid failing due to invalid explicit closure parameters
If closure parameter has an explicit type, type resolution would diagnose the issue and cache the resulting error type for future use. Invalid types currently fail constraint generation, which doesn't play well with result builders because constraint generation for their bodies happens during solving. Let's handle invalid parameters gracefully, replace them with placeholders and let constraint generation proceed. Resolves: rdar://75409111
1 parent 84857b6 commit a51e3da

File tree

3 files changed

+58
-1
lines changed

3 files changed

+58
-1
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 {

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+
}

0 commit comments

Comments
 (0)