Skip to content

Commit 8ba5188

Browse files
committed
[ConstraintSystem] Before applying the result builder transform to a
function body, map the result builder type into context. This was already done for inferred result builder attributes; now, the constraint system will map the builder type into context for all result builder attributes applied to computed properties/functions.
1 parent e5a35f9 commit 8ba5188

File tree

4 files changed

+27
-7
lines changed

4 files changed

+27
-7
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5528,6 +5528,9 @@ class ConstraintSystem {
55285528

55295529
/// Apply the given result builder to the closure expression.
55305530
///
5531+
/// \note builderType must be a contexutal type - callers should
5532+
/// open the builder type or map it into context as appropriate.
5533+
///
55315534
/// \returns \c None when the result builder cannot be applied at all,
55325535
/// otherwise the result of applying the result builder.
55335536
Optional<TypeMatchResult>

lib/Sema/BuilderTransform.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2335,6 +2335,12 @@ Optional<BraceStmt *> TypeChecker::applyResultBuilderBodyTransform(
23352335
log << '\n';
23362336
}
23372337

2338+
// Map type parameters into context. We don't want type
2339+
// parameters to appear in the result builder type, because
2340+
// the result builder type will only be used inside the body
2341+
// of this decl; it's not part of the interface type.
2342+
builderType = func->mapTypeIntoContext(builderType);
2343+
23382344
if (auto result = cs.matchResultBuilder(
23392345
func, builderType, resultContextType, resultConstraintKind,
23402346
cs.getConstraintLocator(func->getBody()))) {
@@ -2425,6 +2431,7 @@ ConstraintSystem::matchResultBuilder(AnyFunctionRef fn, Type builderType,
24252431
auto builder = builderType->getAnyNominal();
24262432
assert(builder && "Bad result builder type");
24272433
assert(builder->getAttrs().hasAttribute<ResultBuilderAttr>());
2434+
assert(!builderType->hasTypeParameter());
24282435

24292436
if (InvalidResultBuilderBodies.count(fn)) {
24302437
(void)recordFix(IgnoreInvalidResultBuilderBody::create(

lib/Sema/TypeCheckRequestFunctions.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -287,16 +287,13 @@ static Type inferResultBuilderType(ValueDecl *decl) {
287287
continue;
288288

289289
// Substitute Self and associated type witnesses into the
290-
// result builder type. Then, map all type parameters from
291-
// the conforming type into context. We don't want type
292-
// parameters to appear in the result builder type, because
293-
// the result builder type will only be used inside the body
294-
// of this decl; it's not part of the interface type.
290+
// result builder type. Type parameters will be mapped
291+
// into context when applying the result builder to the
292+
// function body in the constraint system.
295293
auto subs = SubstitutionMap::getProtocolSubstitutions(
296294
protocol, dc->getSelfInterfaceType(),
297295
ProtocolConformanceRef(conformance));
298-
Type subResultBuilderType = dc->mapTypeIntoContext(
299-
resultBuilderType.subst(subs));
296+
Type subResultBuilderType = resultBuilderType.subst(subs);
300297

301298
matches.push_back(
302299
Match::forConformance(

test/Constraints/result_builder_generic_infer.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,19 @@ struct ArchetypeSubstitution<A>: P {
4141
var x2: [S] { S() }
4242
}
4343

44+
// CHECK-LABEL: struct_decl{{.*}}ExplicitGenericAttribute
45+
struct ExplicitGenericAttribute<T: P> {
46+
// CHECK: var_decl{{.*}}x1
47+
// CHECK: Builder.buildBlock{{.*}}(substitution_map generic_signature=<T> (substitution T -> T))
48+
@Builder<T>
49+
var x1: [S] { S() }
50+
51+
// CHECK: var_decl{{.*}}x2
52+
// CHECK: Builder.buildBlock{{.*}}(substitution_map generic_signature=<T> (substitution T -> T.A))
53+
@Builder<T.A>
54+
var x2: [S] { S() }
55+
}
56+
4457
// CHECK: struct_decl{{.*}}ConcreteTypeSubstitution
4558
struct ConcreteTypeSubstitution<Value> {}
4659

0 commit comments

Comments
 (0)