Skip to content

Commit 3742da7

Browse files
committed
Sema: Result builder inference from dynamically replaced decl should look at getter, not storage
1 parent daf69f2 commit 3742da7

File tree

2 files changed

+19
-24
lines changed

2 files changed

+19
-24
lines changed

lib/Sema/TypeCheckRequestFunctions.cpp

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -321,11 +321,25 @@ static Type inferResultBuilderType(ValueDecl *decl) {
321321
// The set of matches from which we can infer result builder types.
322322
SmallVector<Match, 2> matches;
323323

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+
324337
// Determine all of the conformances within the same context as
325338
// this declaration. If this declaration is a witness to any
326339
// requirement within one of those protocols that has a result builder
327340
// attached, use that result builder type.
328-
auto addConformanceMatches = [&matches](ValueDecl *lookupDecl) {
341+
auto addConformanceMatches = [&matches, &getInferenceSourceResultBuilderType](
342+
ValueDecl *lookupDecl) {
329343
DeclContext *dc = lookupDecl->getDeclContext();
330344
auto idc = cast<IterableDeclContext>(dc->getAsDecl());
331345
auto conformances = idc->getLocalConformances(
@@ -341,22 +355,8 @@ static Type inferResultBuilderType(ValueDecl *decl) {
341355
if (!requirement)
342356
continue;
343357

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);
360360
if (!resultBuilderType)
361361
continue;
362362

@@ -391,7 +391,8 @@ static Type inferResultBuilderType(ValueDecl *decl) {
391391

392392
// Look for result builder types inferred through dynamic replacements.
393393
if (auto replaced = lookupDecl->getDynamicallyReplacedDecl()) {
394-
if (auto resultBuilderType = replaced->getResultBuilderType()) {
394+
if (auto resultBuilderType =
395+
getInferenceSourceResultBuilderType(replaced)) {
395396
matches.push_back(
396397
Match::forDynamicReplacement(replaced, resultBuilderType));
397398
} else {

test/Constraints/result_builder_infer.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,11 @@ extension Test1 {
113113
var replacement_property1: Result { 1 }
114114
@_dynamicReplacement(for: property2)
115115
var replacement_property2: Result { 1 }
116-
// FIXME: expected-error@-1 {{cannot convert return expression}}
117116

118117
@_dynamicReplacement(for: subscript(subscript1:))
119118
subscript(replacement_subscript1 _: Int) -> Result { 1 }
120119
@_dynamicReplacement(for: subscript(subscript2:))
121120
subscript(replacement_subscript2 _: Int) -> Result { 1 }
122-
// FIXME: expected-error@-1 {{cannot convert return expression}}
123121
}
124122

125123
// Edge case: context is a protocol extension.
@@ -498,15 +496,13 @@ extension Test9 {
498496

499497
@_dynamicReplacement(for: property1)
500498
var replacement_property1: Result { 1 }
501-
// FIXME: expected-error@-1 {{cannot convert value of type 'Int' to expected argument type 'String'}}
502499
@_dynamicReplacement(for: property2)
503500
var replacement_property2: Result { 1 }
504501

505502
@_dynamicReplacement(for: subscript(subscript1:))
506503
subscript(replacement_subscript1 _: Int) -> Result { 1 }
507504
@_dynamicReplacement(for: subscript(subscript2:))
508505
subscript(replacement_subscript2 _: Int) -> Result { 1 }
509-
// FIXME: expected-error@-1 {{cannot convert value of type 'Int' to expected argument type 'String'}}
510506
}
511507

512508
struct Test10: P_Builder_Int1, P_Builder_String {
@@ -648,13 +644,11 @@ extension Test13 {
648644
var replacement_property1: Result { 1 }
649645
@_dynamicReplacement(for: property2)
650646
var replacement_property2: Result { 1 }
651-
// FIXME: expected-error@-1 {{cannot convert return expression}}
652647

653648
@_dynamicReplacement(for: subscript(subscript1:))
654649
subscript(replacement_subscript1 _: Int) -> Result { 1 }
655650
@_dynamicReplacement(for: subscript(subscript2:))
656651
subscript(replacement_subscript2 _: Int) -> Result { 1 }
657-
// FIXME: expected-error@-1 {{cannot convert return expression}}
658652
}
659653

660654
struct Test14: P_Builder_Int1 {

0 commit comments

Comments
 (0)