Skip to content

Commit 85d203c

Browse files
committed
[Diagnostics] Result Builders: Improve diagnostic for unsupported lazy/wrapped/computed vars
1 parent 6737721 commit 85d203c

File tree

3 files changed

+38
-5
lines changed

3 files changed

+38
-5
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5885,6 +5885,9 @@ NOTE(result_builder_missing_build_limited_availability, none,
58855885
ERROR(result_builder_requires_explicit_var_initialization,none,
58865886
"local variable%select{| '%1'}0 requires explicit initializer to be used with "
58875887
"result builder %2", (bool, StringRef, DeclName))
5888+
ERROR(cannot_declare_computed_var_in_result_builder,none,
5889+
"cannot declare local %select{lazy|wrapped|computed}0 variable "
5890+
"in result builder", (unsigned))
58885891

58895892
//------------------------------------------------------------------------------
58905893
// MARK: Tuple Shuffle Diagnostics

lib/Sema/CSDiagnostics.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5875,14 +5875,44 @@ void SkipUnhandledConstructInResultBuilderFailure::diagnosePrimary(
58755875

58765876
if (auto *decl = unhandled.dyn_cast<Decl *>()) {
58775877
if (auto *PB = dyn_cast<PatternBindingDecl>(decl)) {
5878+
// Tailored diagnostics for computed properties.
5879+
if (!PB->hasStorage()) {
5880+
}
5881+
5882+
enum class PropertyKind : unsigned { lazy, wrapped, computed };
5883+
58785884
// Diagnose all of the patterns without explicit initializers.
58795885
bool diagnosed = false;
58805886
for (unsigned i : range(PB->getNumPatternEntries())) {
5887+
auto *pattern = PB->getPattern(i);
5888+
5889+
// Each variable bound by the pattern must be stored.
5890+
SmallVector<VarDecl *, 8> variables;
5891+
pattern->collectVariables(variables);
5892+
5893+
for (auto *var : variables) {
5894+
if (var->getImplInfo().isSimpleStored())
5895+
continue;
5896+
5897+
PropertyKind kind;
5898+
if (var->getAttrs().hasAttribute<LazyAttr>()) {
5899+
kind = PropertyKind::lazy;
5900+
} else if (var->hasAttachedPropertyWrapper()) {
5901+
kind = PropertyKind::wrapped;
5902+
} else {
5903+
kind = PropertyKind::computed;
5904+
}
5905+
5906+
emitDiagnosticAt(PB->getLoc(),
5907+
diag::cannot_declare_computed_var_in_result_builder,
5908+
static_cast<unsigned>(kind));
5909+
5910+
diagnosed = true;
5911+
}
5912+
58815913
if (PB->isExplicitlyInitialized(i))
58825914
continue;
58835915

5884-
auto *pattern = PB->getPattern(i);
5885-
58865916
StringRef name;
58875917

58885918
if (auto *TP = dyn_cast<TypedPattern>(pattern)) {

test/Constraints/result_builder_invalid_vars.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ struct DummyBuilder { // expected-note 5 {{struct 'DummyBuilder' declared here}}
1010
func dummy<T>(@DummyBuilder _: () -> T) {}
1111

1212
dummy {
13-
var computedVar: Int { return 123 } // expected-error {{closure containing a declaration cannot be used with result builder 'DummyBuilder'}}
13+
var computedVar: Int { return 123 } // expected-error {{cannot declare local computed variable in result builder}}
1414
()
1515
}
1616

1717
dummy {
18-
lazy var lazyVar: Int = 123 // expected-error {{closure containing a declaration cannot be used with result builder 'DummyBuilder'}}
18+
lazy var lazyVar: Int = 123 // expected-error {{cannot declare local lazy variable in result builder}}
1919
()
2020
}
2121

@@ -40,7 +40,7 @@ dummy {
4040
}
4141

4242
dummy {
43-
@Wrapper var wrappedVar: Int = 123 // expected-error {{closure containing a declaration cannot be used with result builder 'DummyBuilder'}}
43+
@Wrapper var wrappedVar: Int = 123 // expected-error {{cannot declare local wrapped variable in result builder}}
4444
()
4545
}
4646

0 commit comments

Comments
 (0)