@@ -321,11 +321,25 @@ static Type inferResultBuilderType(ValueDecl *decl) {
321
321
// The set of matches from which we can infer result builder types.
322
322
SmallVector<Match, 2 > matches;
323
323
324
+ const auto getInferenceSourceResultBuilderType = [](ValueDecl *source) {
325
+ // We always infer for either a getter or freestanding function, so if the
326
+ // inference source is a storage declaration, inference should draw from
327
+ // the getter.
328
+ if (auto *storage = dyn_cast<AbstractStorageDecl>(source)) {
329
+ if (auto *getter = storage->getAccessor (AccessorKind::Get)) {
330
+ source = getter;
331
+ }
332
+ }
333
+
334
+ return source->getResultBuilderType ();
335
+ };
336
+
324
337
// Determine all of the conformances within the same context as
325
338
// this declaration. If this declaration is a witness to any
326
339
// requirement within one of those protocols that has a result builder
327
340
// attached, use that result builder type.
328
- auto addConformanceMatches = [&matches](ValueDecl *lookupDecl) {
341
+ auto addConformanceMatches = [&matches, &getInferenceSourceResultBuilderType](
342
+ ValueDecl *lookupDecl) {
329
343
DeclContext *dc = lookupDecl->getDeclContext ();
330
344
auto idc = cast<IterableDeclContext>(dc->getAsDecl ());
331
345
auto conformances = idc->getLocalConformances (
@@ -341,22 +355,8 @@ static Type inferResultBuilderType(ValueDecl *decl) {
341
355
if (!requirement)
342
356
continue ;
343
357
344
- Type resultBuilderType;
345
- {
346
- auto *inferenceSource = requirement;
347
-
348
- // If the given declaration is a witness to a storage declaration
349
- // requirement, then we are inferring for a getter and, hence, should
350
- // infer from the getter requirement.
351
- if (auto *storage = dyn_cast<AbstractStorageDecl>(requirement)) {
352
- if (auto *getter = storage->getAccessor (AccessorKind::Get)) {
353
- inferenceSource = getter;
354
- }
355
- }
356
-
357
- resultBuilderType = inferenceSource->getResultBuilderType ();
358
- }
359
-
358
+ const Type resultBuilderType =
359
+ getInferenceSourceResultBuilderType (requirement);
360
360
if (!resultBuilderType)
361
361
continue ;
362
362
@@ -391,7 +391,8 @@ static Type inferResultBuilderType(ValueDecl *decl) {
391
391
392
392
// Look for result builder types inferred through dynamic replacements.
393
393
if (auto replaced = lookupDecl->getDynamicallyReplacedDecl ()) {
394
- if (auto resultBuilderType = replaced->getResultBuilderType ()) {
394
+ if (auto resultBuilderType =
395
+ getInferenceSourceResultBuilderType (replaced)) {
395
396
matches.push_back (
396
397
Match::forDynamicReplacement (replaced, resultBuilderType));
397
398
} else {
0 commit comments