Skip to content

Commit 76dc890

Browse files
authored
Merge pull request #17166 from slavapestov/without-actually-escaping-fix-4.2-06-11
Sema: Propagate noescape bit into closure passed to withoutActuallyEscaping [4.2 6/11]
2 parents d7ee6d2 + 3eea623 commit 76dc890

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

lib/Sema/CSApply.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6085,6 +6085,12 @@ static bool applyTypeToClosureExpr(ConstraintSystem &cs,
60856085
// If we found an explicit ClosureExpr, update its type.
60866086
if (auto CE = dyn_cast<ClosureExpr>(expr)) {
60876087
cs.setType(CE, toType);
6088+
6089+
// If this is not a single-expression closure, write the type into the
6090+
// ClosureExpr directly here, since the visitor won't.
6091+
if (!CE->hasSingleExpressionBody())
6092+
CE->setType(toType);
6093+
60886094
return true;
60896095
}
60906096

@@ -7427,7 +7433,7 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
74277433
}
74287434

74297435
case DeclTypeCheckingSemantics::WithoutActuallyEscaping: {
7430-
// Resolve into a MakeTemporarilyEscapingExpr.
7436+
// Resolve into a MakeTemporarilyEscapableExpr.
74317437
auto arg = cast<TupleExpr>(apply->getArg());
74327438
assert(arg->getNumElements() == 2 && "should have two arguments");
74337439
auto nonescaping = arg->getElements()[0];

test/Constraints/without_actually_escaping.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,29 @@ func rethrowThroughWAE(_ zz: (Int, Int, Int) throws -> Int, _ value: Int) throws
6464
let _: ((Int) -> Int, (@escaping (Int) -> Int) -> ()) -> ()
6565
= withoutActuallyEscaping(_:do:) // expected-error{{}}
6666

67+
68+
// Failing to propagate @noescape into non-single-expression
69+
// closure passed to withoutActuallyEscaping
70+
71+
// https://bugs.swift.org/browse/SR-7886
72+
73+
class Box<T> {
74+
let value: T
75+
76+
init(_ value: T) {
77+
self.value = value
78+
}
79+
80+
func map1<U>(_ transform: (T) -> U) -> Box<U> {
81+
return withoutActuallyEscaping(transform) { transform in
82+
return Box<U>(transform(value))
83+
}
84+
}
85+
86+
func map2<U>(_ transform: (T) -> U) -> Box<U> {
87+
return withoutActuallyEscaping(transform) { transform in
88+
let v = Box<U>(transform(value))
89+
return v
90+
}
91+
}
92+
}

0 commit comments

Comments
 (0)