Skip to content

Commit 409603c

Browse files
authored
Merge pull request #32305 from DougGregor/function-builder-one-way-params
[Function builders] Use one-way constraints for closure parameters.
2 parents d9073c8 + f60d17b commit 409603c

File tree

3 files changed

+46
-24
lines changed

3 files changed

+46
-24
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7222,6 +7222,24 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
72227222
auto *closure = castToExpr<ClosureExpr>(closureLocator->getAnchor());
72237223
auto *inferredClosureType = getClosureType(closure);
72247224

7225+
// Determine whether a function builder will be applied.
7226+
Type functionBuilderType;
7227+
ConstraintLocator *calleeLocator = nullptr;
7228+
if (auto last = locator.last()) {
7229+
if (auto argToParam = last->getAs<LocatorPathElt::ApplyArgToParam>()) {
7230+
calleeLocator = getCalleeLocator(getConstraintLocator(locator));
7231+
functionBuilderType = getFunctionBuilderTypeFor(
7232+
*this, argToParam->getParamIdx(), calleeLocator);
7233+
}
7234+
}
7235+
7236+
// Determine whether to introduce one-way constraints between the parameter's
7237+
// type as seen in the body of the closure and the external parameter
7238+
// type.
7239+
bool oneWayConstraints =
7240+
getASTContext().TypeCheckerOpts.EnableOneWayClosureParameters ||
7241+
functionBuilderType;
7242+
72257243
auto *paramList = closure->getParameters();
72267244
SmallVector<AnyFunctionType::Param, 4> parameters;
72277245
for (unsigned i = 0, n = paramList->size(); i != n; ++i) {
@@ -7235,9 +7253,6 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
72357253
}
72367254

72377255
Type internalType;
7238-
7239-
bool oneWayConstraints =
7240-
getASTContext().TypeCheckerOpts.EnableOneWayClosureParameters;
72417256
if (paramList->get(i)->getTypeRepr()) {
72427257
// Internal type is the type used in the body of the closure,
72437258
// so "external" type translates to it as follows:
@@ -7288,17 +7303,12 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
72887303
inferredClosureType->getExtInfo());
72897304
assignFixedType(typeVar, closureType, closureLocator);
72907305

7291-
if (auto last = locator.last()) {
7292-
if (auto argToParam = last->getAs<LocatorPathElt::ApplyArgToParam>()) {
7293-
auto *calleeLocator = getCalleeLocator(getConstraintLocator(locator));
7294-
if (auto functionBuilderType = getFunctionBuilderTypeFor(
7295-
*this, argToParam->getParamIdx(), calleeLocator)) {
7296-
if (auto result = matchFunctionBuilder(
7297-
closure, functionBuilderType, closureType->getResult(),
7298-
ConstraintKind::Conversion, calleeLocator, locator)) {
7299-
return result->isSuccess();
7300-
}
7301-
}
7306+
// If there is a function builder to apply, do so now.
7307+
if (functionBuilderType) {
7308+
if (auto result = matchFunctionBuilder(
7309+
closure, functionBuilderType, closureType->getResult(),
7310+
ConstraintKind::Conversion, calleeLocator, locator)) {
7311+
return result->isSuccess();
73027312
}
73037313
}
73047314

test/Constraints/function_builder_diags.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,3 +558,14 @@ func rdar61347993() {
558558
func test_closure(_: () -> Result) {}
559559
test_closure {} // expected-error {{cannot convert value of type '()' to closure result type 'Result'}}
560560
}
561+
562+
// One-way constraints through parameters.
563+
func wrapperifyInfer<T, U>(_ cond: Bool, @WrapperBuilder body: (U) -> T) -> T {
564+
fatalError("boom")
565+
}
566+
567+
let intValue = 17
568+
wrapperifyInfer(true) { x in // expected-error{{unable to infer type of a closure parameter 'x' in the current context}}
569+
intValue + x
570+
}
571+

test/Constraints/function_builder_one_way.swift

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,17 @@ func tuplify<C: Collection, T>(_ collection: C, @TupleBuilder body: (C.Element)
4949
}
5050

5151
// CHECK: ---Connected components---
52-
// CHECK-NEXT: 0: $T1 $T2 $T3 $T5 $T6 $T7 $T8 $T10 $T77 $T78 depends on 2
53-
// CHECK-NEXT: 2: $T12 $T17 $T28 $T42 $T53 $T54 $T55 $T56 $T57 $T58 $T59 $T60 $T61 $T62 $T63 $T64 $T65 $T66 $T68 $T69 $T70 $T71 $T72 $T73 $T74 $T75 $T76 depends on 1, 3, 4, 6, 9
54-
// CHECK-NEXT: 9: $T48 $T49 $T50 $T51 $T52 depends on 8
55-
// CHECK-NEXT: 8: $T43 $T44 $T45 $T46 $T47
56-
// CHECK-NEXT: 6: $T31 $T35 $T36 $T37 $T38 $T39 $T40 $T41 depends on 5, 7
57-
// CHECK-NEXT: 7: $T32 $T33 $T34
58-
// CHECK-NEXT: 5: $T30
59-
// CHECK-NEXT: 4: $T18 $T19 $T20 $T21 $T22 $T23 $T24 $T25 $T26 $T27
60-
// CHECK-NEXT: 3: $T15 $T16
61-
// CHECK-NEXT: 1: $T11
52+
// CHECK-NEXT: 1: $T10 depends on 0
53+
// CHECK-NEXT: 0: $T1 $T2 $T3 $T5 $T6 $T7 $T8 $T77 $T78 depends on 3
54+
// CHECK-NEXT: 3: $T12 $T17 $T28 $T42 $T53 $T54 $T55 $T56 $T57 $T58 $T59 $T60 $T61 $T62 $T63 $T64 $T65 $T66 $T68 $T69 $T70 $T71 $T72 $T73 $T74 $T75 $T76 depends on 2, 4, 5, 7, 10
55+
// CHECK-NEXT: 10: $T48 $T49 $T50 $T51 $T52 depends on 9
56+
// CHECK-NEXT: 9: $T43 $T44 $T45 $T46 $T47
57+
// CHECK-NEXT: 7: $T31 $T35 $T36 $T37 $T38 $T39 $T40 $T41 depends on 6, 8
58+
// CHECK-NEXT: 8: $T32 $T33 $T34
59+
// CHECK-NEXT: 6: $T30
60+
// CHECK-NEXT: 5: $T18 $T19 $T20 $T21 $T22 $T23 $T24 $T25 $T26 $T27
61+
// CHECK-NEXT: 4: $T15 $T16
62+
// CHECK-NEXT: 2: $T11
6263
let names = ["Alice", "Bob", "Charlie"]
6364
let b = true
6465
var number = 17

0 commit comments

Comments
 (0)