@@ -200,13 +200,8 @@ AttachedResultBuilderRequest::evaluate(Evaluator &evaluator,
200200
201201// / Attempt to infer the result builder type for a declaration.
202202static Type inferResultBuilderType (ValueDecl *decl) {
203- auto dc = decl->getDeclContext ();
204- if (isa<ProtocolDecl>(dc))
205- return Type ();
206-
207203 auto funcDecl = dyn_cast<FuncDecl>(decl);
208- if (!funcDecl || !funcDecl->hasBody () ||
209- !decl->getDeclContext ()->getParentSourceFile ())
204+ if (!funcDecl)
210205 return Type ();
211206
212207 // For a getter, always favor the result builder type of its storage
@@ -220,16 +215,20 @@ static Type inferResultBuilderType(ValueDecl *decl) {
220215 }
221216 }
222217
218+ auto *dc = decl->getDeclContext ();
219+ if (isa<ProtocolDecl>(dc)) {
220+ return Type ();
221+ }
222+
223223 // FIXME: We could infer from a dynamically replaced decl in non-type contexts too.
224224 if (!dc->isTypeContext ()) {
225225 return Type ();
226226 }
227227
228- // Check whether there are any return statements in the function's body.
229- // If there are, the result builder transform will be disabled,
230- // so don't infer a result builder.
231- if (!TypeChecker::findReturnStatements (funcDecl).empty ())
228+ if (!funcDecl->hasBody () || !dc->getParentSourceFile () ||
229+ !TypeChecker::findReturnStatements (funcDecl).empty ()) {
232230 return Type ();
231+ }
233232
234233 // Find all of the potentially inferred result builder types.
235234 struct Match {
@@ -305,7 +304,22 @@ static Type inferResultBuilderType(ValueDecl *decl) {
305304 if (!requirement)
306305 continue ;
307306
308- Type resultBuilderType = requirement->getResultBuilderType ();
307+ Type resultBuilderType;
308+ {
309+ auto *inferenceSource = requirement;
310+
311+ // If the given declaration is a witness to a storage declaration
312+ // requirement, then we are inferring for a getter and, hence, should
313+ // infer from the getter requirement.
314+ if (auto *storage = dyn_cast<AbstractStorageDecl>(requirement)) {
315+ if (auto *getter = storage->getAccessor (AccessorKind::Get)) {
316+ inferenceSource = getter;
317+ }
318+ }
319+
320+ resultBuilderType = inferenceSource->getResultBuilderType ();
321+ }
322+
309323 if (!resultBuilderType)
310324 continue ;
311325
0 commit comments