Skip to content

Commit 17def18

Browse files
committed
[Result Builders] When inferring result builder attributes on value witnesses,
always map type parameters into context. For result builders applied to function/variable/subscript bodies, the builder type will only be used for calls to `buildBlock` and friends inside the body, for which we always want the contextual type of the builder, not the interface type.
1 parent 89e0f45 commit 17def18

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

lib/Sema/TypeCheckRequestFunctions.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,11 +298,16 @@ static Type inferResultBuilderType(ValueDecl *decl) {
298298
continue;
299299

300300
// Substitute Self and associated type witnesses into the
301-
// result builder type.
301+
// result builder type. Then, map all type parameters from
302+
// the conforming type into context. We don't want type
303+
// parameters to appear in the result builder type, because
304+
// the result builder type will only be used inside the body
305+
// of this decl; it's not part of the interface type.
302306
auto subs = SubstitutionMap::getProtocolSubstitutions(
303-
protocol, dc->getSelfTypeInContext(),
307+
protocol, dc->getSelfInterfaceType(),
304308
ProtocolConformanceRef(conformance));
305-
Type subResultBuilderType = resultBuilderType.subst(subs);
309+
Type subResultBuilderType = dc->mapTypeIntoContext(
310+
resultBuilderType.subst(subs));
306311

307312
matches.push_back(
308313
Match::forConformance(

test/Constraints/result_builder_generic_infer.swift

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,41 @@ enum Builder<T> {
1717

1818
struct S {}
1919

20-
// CHECK: struct_decl{{.*}}TestGenericBuilderInference
21-
struct TestGenericBuilderInference: P {
20+
// CHECK: struct_decl{{.*}}ProtocolSubstitution
21+
struct ProtocolSubstitution: P {
2222
typealias A = Int
2323

2424
// CHECK: var_decl{{.*}}x1
2525
// CHECK: Builder.buildBlock{{.*}}(substitution_map generic_signature=<T> (substitution T -> Int))
2626
var x1: [S] { S() }
2727

2828
// CHECK: var_decl{{.*}}x2
29-
// CHECK: Builder.buildBlock{{.*}}(substitution_map generic_signature=<T> (substitution T -> TestGenericBuilderInference))
29+
// CHECK: Builder.buildBlock{{.*}}(substitution_map generic_signature=<T> (substitution T -> ProtocolSubstitution))
30+
var x2: [S] { S() }
31+
}
32+
33+
// CHECK: struct_decl{{.*}}ArchetypeSubstitution
34+
struct ArchetypeSubstitution<A>: P {
35+
// CHECK: var_decl{{.*}}x1
36+
// CHECK: Builder.buildBlock{{.*}}(substitution_map generic_signature=<T> (substitution T -> A))
37+
var x1: [S] { S() }
38+
39+
// CHECK: var_decl{{.*}}x2
40+
// CHECK: Builder.buildBlock{{.*}}(substitution_map generic_signature=<T> (substitution T -> ArchetypeSubstitution<A>))
41+
var x2: [S] { S() }
42+
}
43+
44+
// CHECK: struct_decl{{.*}}ConcreteTypeSubstitution
45+
struct ConcreteTypeSubstitution<Value> {}
46+
47+
extension ConcreteTypeSubstitution: P where Value == Int {
48+
typealias A = Value
49+
50+
// CHECK: var_decl{{.*}}x1
51+
// CHECK: Builder.buildBlock{{.*}}(substitution_map generic_signature=<T> (substitution T -> Int))
52+
var x1: [S] { S() }
53+
54+
// CHECK: var_decl{{.*}}x2
55+
// CHECK: Builder.buildBlock{{.*}}(substitution_map generic_signature=<T> (substitution T -> ConcreteTypeSubstitution<Int>))
3056
var x2: [S] { S() }
3157
}

0 commit comments

Comments
 (0)