From d7958fa9761bd17c9db7edf442d479e2bc948cd7 Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Fri, 10 Dec 2021 14:44:39 -0800 Subject: [PATCH] Fully Check Decls in Result Builders In particular, this turns redeclaration checking on for variables in pattern bindings. rdar://85784090 --- lib/Sema/BuilderTransform.cpp | 9 ++++++++- test/Constraints/result_builder_diags.swift | 11 +++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/Sema/BuilderTransform.cpp b/lib/Sema/BuilderTransform.cpp index 5b6260ed84d08..82a4a8b9ef92e 100644 --- a/lib/Sema/BuilderTransform.cpp +++ b/lib/Sema/BuilderTransform.cpp @@ -1122,10 +1122,15 @@ class BuilderClosureRewriter if (!resultTarget) continue; + // FIXME: It's unfortunate that we're duplicating code from CSApply here. + // If there were a request for the fully-typechecked initializer of a + // pattern binding we may be able to eliminate the duplication here. patternBinding->setPattern( index, resultTarget->getInitializationPattern(), - resultTarget->getDeclContext()); + resultTarget->getDeclContext(), + /*isFullyValidated=*/true); patternBinding->setInit(index, resultTarget->getAsExpr()); + patternBinding->setInitializerChecked(index); } } @@ -1226,6 +1231,7 @@ class BuilderClosureRewriter // Skip variable declarations; they're always part of a pattern // binding. if (isa(decl)) { + TypeChecker::typeCheckDecl(decl); newElements.push_back(decl); continue; } @@ -1233,6 +1239,7 @@ class BuilderClosureRewriter // Handle pattern bindings. if (auto patternBinding = dyn_cast(decl)) { finishPatternBindingDecl(patternBinding); + TypeChecker::typeCheckDecl(decl); newElements.push_back(decl); continue; } diff --git a/test/Constraints/result_builder_diags.swift b/test/Constraints/result_builder_diags.swift index 396047f1a0c58..6be029e292806 100644 --- a/test/Constraints/result_builder_diags.swift +++ b/test/Constraints/result_builder_diags.swift @@ -815,3 +815,14 @@ func test_missing_member_in_optional_context() { } } } + +func test_redeclations() { + tuplify(true) { c in + let foo = 0 // expected-note {{'foo' previously declared here}} + let foo = foo // expected-error {{invalid redeclaration of 'foo'}} + } + + tuplify(true) { c in + let (foo, foo) = (5, 6) // expected-error {{invalid redeclaration of 'foo'}} expected-note {{'foo' previously declared here}} + } +}