Skip to content

Commit 15a3ff6

Browse files
authored
Merge pull request #60849 from hborla/5.7-generic-result-builder
[5.7][ConstraintSystem] Before applying the result builder transform to a function body, map the result builder type into context.
2 parents 1e80674 + e974dd2 commit 15a3ff6

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
@@ -5301,6 +5301,9 @@ class ConstraintSystem {
53015301

53025302
/// Apply the given result builder to the closure expression.
53035303
///
5304+
/// \note builderType must be a contexutal type - callers should
5305+
/// open the builder type or map it into context as appropriate.
5306+
///
53045307
/// \returns \c None when the result builder cannot be applied at all,
53055308
/// otherwise the result of applying the result builder.
53065309
Optional<TypeMatchResult>

lib/Sema/BuilderTransform.cpp

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

1695+
// Map type parameters into context. We don't want type
1696+
// parameters to appear in the result builder type, because
1697+
// the result builder type will only be used inside the body
1698+
// of this decl; it's not part of the interface type.
1699+
builderType = func->mapTypeIntoContext(builderType);
1700+
16951701
if (auto result = cs.matchResultBuilder(
16961702
func, builderType, resultContextType, resultConstraintKind,
16971703
cs.getConstraintLocator(func->getBody()))) {
@@ -1781,6 +1787,7 @@ ConstraintSystem::matchResultBuilder(AnyFunctionRef fn, Type builderType,
17811787
auto builder = builderType->getAnyNominal();
17821788
assert(builder && "Bad result builder type");
17831789
assert(builder->getAttrs().hasAttribute<ResultBuilderAttr>());
1790+
assert(!builderType->hasTypeParameter());
17841791

17851792
if (InvalidResultBuilderBodies.count(fn)) {
17861793
(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)