@@ -5870,8 +5870,84 @@ static bool hasMissingElseInChain(IfStmt *ifStmt) {
58705870 return false ;
58715871}
58725872
5873+ bool SkipUnhandledConstructInResultBuilderFailure::diagnosePatternBinding (
5874+ PatternBindingDecl *PB) const {
5875+ bool diagnosed = false ;
5876+
5877+ for (unsigned i : range (PB->getNumPatternEntries ())) {
5878+ auto *pattern = PB->getPattern (i);
5879+
5880+ // Each variable bound by the pattern must be stored and cannot have
5881+ // observers.
5882+ {
5883+ SmallVector<VarDecl *, 8 > variables;
5884+ pattern->collectVariables (variables);
5885+
5886+ bool diagnosedStorage = false ;
5887+ for (auto *var : variables)
5888+ diagnosedStorage |= diagnoseStorage (var);
5889+
5890+ // if storage has been diagnosed, let's move to the next entry.
5891+ if (diagnosedStorage) {
5892+ diagnosed = true ;
5893+ continue ;
5894+ }
5895+ }
5896+
5897+ // Diagnose all of the patterns without explicit initializers.
5898+ if (PB->isExplicitlyInitialized (i))
5899+ continue ;
5900+
5901+ StringRef name;
5902+
5903+ if (auto *TP = dyn_cast<TypedPattern>(pattern)) {
5904+ if (auto *NP = dyn_cast<NamedPattern>(TP->getSubPattern ()))
5905+ name = NP->getNameStr ();
5906+ }
5907+
5908+ emitDiagnosticAt (pattern->getLoc (),
5909+ diag::result_builder_requires_explicit_var_initialization,
5910+ !name.empty (), name, builder->getName ())
5911+ .fixItInsertAfter (pattern->getEndLoc (), " = <#value#>" );
5912+
5913+ diagnosed = true ;
5914+ }
5915+
5916+ return diagnosed;
5917+ }
5918+
5919+ bool SkipUnhandledConstructInResultBuilderFailure::diagnoseStorage (
5920+ VarDecl *var) const {
5921+ enum class PropertyKind : unsigned { lazy, wrapped, computed, observed };
5922+
5923+ if (var->getImplInfo ().isSimpleStored ())
5924+ return false ;
5925+
5926+ PropertyKind kind;
5927+ if (var->getAttrs ().hasAttribute <LazyAttr>()) {
5928+ kind = PropertyKind::lazy;
5929+ } else if (var->hasAttachedPropertyWrapper ()) {
5930+ kind = PropertyKind::wrapped;
5931+ } else if (var->hasObservers ()) {
5932+ kind = PropertyKind::observed;
5933+ } else {
5934+ kind = PropertyKind::computed;
5935+ }
5936+
5937+ emitDiagnosticAt (var, diag::cannot_declare_computed_var_in_result_builder,
5938+ static_cast <unsigned >(kind));
5939+ return true ;
5940+ }
5941+
58735942void SkipUnhandledConstructInResultBuilderFailure::diagnosePrimary (
58745943 bool asNote) {
5944+
5945+ if (auto *decl = unhandled.dyn_cast <Decl *>()) {
5946+ auto *PB = dyn_cast<PatternBindingDecl>(decl);
5947+ if (PB && diagnosePatternBinding (PB))
5948+ return ;
5949+ }
5950+
58755951 if (auto stmt = unhandled.dyn_cast <Stmt *>()) {
58765952 emitDiagnostic (asNote ? diag::note_result_builder_control_flow
58775953 : diag::result_builder_control_flow,
0 commit comments