Skip to content

Commit 0074adc

Browse files
committed
[Diagnostics] Result Builders: Extract pattern binding and var storage diagnostics into methods
1 parent 85d203c commit 0074adc

File tree

2 files changed

+66
-48
lines changed

2 files changed

+66
-48
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 59 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5870,68 +5870,79 @@ static bool hasMissingElseInChain(IfStmt *ifStmt) {
58705870
return false;
58715871
}
58725872

5873-
void SkipUnhandledConstructInResultBuilderFailure::diagnosePrimary(
5874-
bool asNote) {
5873+
bool SkipUnhandledConstructInResultBuilderFailure::diagnosePatternBinding(
5874+
PatternBindingDecl *PB) const {
5875+
bool diagnosed = false;
58755876

5876-
if (auto *decl = unhandled.dyn_cast<Decl *>()) {
5877-
if (auto *PB = dyn_cast<PatternBindingDecl>(decl)) {
5878-
// Tailored diagnostics for computed properties.
5879-
if (!PB->hasStorage()) {
5880-
}
5877+
for (unsigned i : range(PB->getNumPatternEntries())) {
5878+
auto *pattern = PB->getPattern(i);
5879+
5880+
// Each variable bound by the pattern must be stored.
5881+
{
5882+
SmallVector<VarDecl *, 8> variables;
5883+
pattern->collectVariables(variables);
58815884

5882-
enum class PropertyKind : unsigned { lazy, wrapped, computed };
5885+
bool diagnosedStorage = false;
5886+
for (auto *var : variables)
5887+
diagnosedStorage |= diagnoseStorage(var);
5888+
5889+
// if storage has been diagnosed, let's move to the next entry.
5890+
if (diagnosedStorage) {
5891+
diagnosed = true;
5892+
continue;
5893+
}
5894+
}
58835895

5884-
// Diagnose all of the patterns without explicit initializers.
5885-
bool diagnosed = false;
5886-
for (unsigned i : range(PB->getNumPatternEntries())) {
5887-
auto *pattern = PB->getPattern(i);
5896+
// Diagnose all of the patterns without explicit initializers.
5897+
if (PB->isExplicitlyInitialized(i))
5898+
continue;
58885899

5889-
// Each variable bound by the pattern must be stored.
5890-
SmallVector<VarDecl *, 8> variables;
5891-
pattern->collectVariables(variables);
5900+
StringRef name;
58925901

5893-
for (auto *var : variables) {
5894-
if (var->getImplInfo().isSimpleStored())
5895-
continue;
5902+
if (auto *TP = dyn_cast<TypedPattern>(pattern)) {
5903+
if (auto *NP = dyn_cast<NamedPattern>(TP->getSubPattern()))
5904+
name = NP->getNameStr();
5905+
}
58965906

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-
}
5907+
emitDiagnosticAt(pattern->getLoc(),
5908+
diag::result_builder_requires_explicit_var_initialization,
5909+
!name.empty(), name, builder->getName())
5910+
.fixItInsertAfter(pattern->getEndLoc(), " = <#value#>");
59055911

5906-
emitDiagnosticAt(PB->getLoc(),
5907-
diag::cannot_declare_computed_var_in_result_builder,
5908-
static_cast<unsigned>(kind));
5912+
diagnosed = true;
5913+
}
59095914

5910-
diagnosed = true;
5911-
}
5915+
return diagnosed;
5916+
}
59125917

5913-
if (PB->isExplicitlyInitialized(i))
5914-
continue;
5918+
bool SkipUnhandledConstructInResultBuilderFailure::diagnoseStorage(
5919+
VarDecl *var) const {
5920+
enum class PropertyKind : unsigned { lazy, wrapped, computed };
59155921

5916-
StringRef name;
5922+
if (var->getImplInfo().isSimpleStored())
5923+
return false;
59175924

5918-
if (auto *TP = dyn_cast<TypedPattern>(pattern)) {
5919-
if (auto *NP = dyn_cast<NamedPattern>(TP->getSubPattern()))
5920-
name = NP->getNameStr();
5921-
}
5925+
PropertyKind kind;
5926+
if (var->getAttrs().hasAttribute<LazyAttr>()) {
5927+
kind = PropertyKind::lazy;
5928+
} else if (var->hasAttachedPropertyWrapper()) {
5929+
kind = PropertyKind::wrapped;
5930+
} else {
5931+
kind = PropertyKind::computed;
5932+
}
59225933

5923-
emitDiagnosticAt(
5924-
pattern->getLoc(),
5925-
diag::result_builder_requires_explicit_var_initialization,
5926-
!name.empty(), name, builder->getName())
5927-
.fixItInsertAfter(pattern->getEndLoc(), " = <#value#>");
5934+
emitDiagnosticAt(var, diag::cannot_declare_computed_var_in_result_builder,
5935+
static_cast<unsigned>(kind));
5936+
return true;
5937+
}
59285938

5929-
diagnosed = true;
5930-
}
5939+
void SkipUnhandledConstructInResultBuilderFailure::diagnosePrimary(
5940+
bool asNote) {
59315941

5932-
if (diagnosed)
5933-
return;
5934-
}
5942+
if (auto *decl = unhandled.dyn_cast<Decl *>()) {
5943+
auto *PB = dyn_cast<PatternBindingDecl>(decl);
5944+
if (PB && diagnosePatternBinding(PB))
5945+
return;
59355946
}
59365947

59375948
if (auto stmt = unhandled.dyn_cast<Stmt *>()) {

lib/Sema/CSDiagnostics.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1862,6 +1862,13 @@ class SkipUnhandledConstructInResultBuilderFailure final
18621862

18631863
bool diagnoseAsError() override;
18641864
bool diagnoseAsNote() override;
1865+
1866+
private:
1867+
/// Tailored diagnostics for an unsupported variable declaration.
1868+
bool diagnosePatternBinding(PatternBindingDecl *PB) const;
1869+
1870+
/// Tailored diagnostics for lazy/wrapped/computed variable declarations.
1871+
bool diagnoseStorage(VarDecl *var) const;
18651872
};
18661873

18671874
/// Diagnose situation when a single "tuple" parameter is given N arguments e.g.

0 commit comments

Comments
 (0)