@@ -200,13 +200,8 @@ AttachedResultBuilderRequest::evaluate(Evaluator &evaluator,
200
200
201
201
// / Attempt to infer the result builder type for a declaration.
202
202
static Type inferResultBuilderType (ValueDecl *decl) {
203
- auto dc = decl->getDeclContext ();
204
- if (isa<ProtocolDecl>(dc))
205
- return Type ();
206
-
207
203
auto funcDecl = dyn_cast<FuncDecl>(decl);
208
- if (!funcDecl || !funcDecl->hasBody () ||
209
- !decl->getDeclContext ()->getParentSourceFile ())
204
+ if (!funcDecl)
210
205
return Type ();
211
206
212
207
// For a getter, always favor the result builder type of its storage
@@ -220,16 +215,20 @@ static Type inferResultBuilderType(ValueDecl *decl) {
220
215
}
221
216
}
222
217
218
+ auto *dc = decl->getDeclContext ();
219
+ if (isa<ProtocolDecl>(dc)) {
220
+ return Type ();
221
+ }
222
+
223
223
// FIXME: We could infer from a dynamically replaced decl in non-type contexts too.
224
224
if (!dc->isTypeContext ()) {
225
225
return Type ();
226
226
}
227
227
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 ()) {
232
230
return Type ();
231
+ }
233
232
234
233
// Find all of the potentially inferred result builder types.
235
234
struct Match {
@@ -305,7 +304,22 @@ static Type inferResultBuilderType(ValueDecl *decl) {
305
304
if (!requirement)
306
305
continue ;
307
306
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
+
309
323
if (!resultBuilderType)
310
324
continue ;
311
325
0 commit comments