Skip to content

Commit ec9db3f

Browse files
committed
[move-only] Borrow copyable typed arguments contained within a move only struct/enum.
Otherwise, we down the normal load [copy] path which will cause us to have a tight exclusivity scope. One thing to note is that if one accesses a field of a moveonly class one will still get the tight exclusivity scope issue since SILGenLValue will emit the moveonly class as a base of the field causing us to use the non-borrow codegen. rdar://102746971
1 parent c40a98a commit ec9db3f

File tree

4 files changed

+361
-66
lines changed

4 files changed

+361
-66
lines changed

lib/SILGen/ArgumentSource.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ class ArgumentSource {
223223
}
224224

225225
Expr *findStorageReferenceExprForBorrow() &&;
226-
Expr *findStorageReferenceExprForMoveOnlyBorrow() &&;
226+
Expr *findStorageReferenceExprForMoveOnlyBorrow(SILGenFunction &SGF) &&;
227227

228228
/// Given that this source is an expression, extract and clear
229229
/// that expression.

lib/SILGen/SILGenApply.cpp

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2926,7 +2926,8 @@ static Expr *findStorageReferenceExprForBorrow(Expr *e) {
29262926
return nullptr;
29272927
}
29282928

2929-
Expr *ArgumentSource::findStorageReferenceExprForMoveOnlyBorrow() && {
2929+
Expr *ArgumentSource::findStorageReferenceExprForMoveOnlyBorrow(
2930+
SILGenFunction &SGF) && {
29302931
if (!isExpr())
29312932
return nullptr;
29322933

@@ -2935,10 +2936,32 @@ Expr *ArgumentSource::findStorageReferenceExprForMoveOnlyBorrow() && {
29352936
if (!li)
29362937
return nullptr;
29372938

2938-
auto lvExpr = ::findStorageReferenceExprForBorrow(li->getSubExpr());
2939+
auto *lvExpr = ::findStorageReferenceExprForBorrow(li->getSubExpr());
29392940

2940-
// Claim the value of this argument if we found a storage reference.
2941+
// Claim the value of this argument if we found a storage reference that has a
2942+
// move only base.
29412943
if (lvExpr) {
2944+
// We want to perform a borrow if our initial type is a pure move only /or/
2945+
// if after looking through multiple copyable member ref expr, we get to a
2946+
// move only member ref expr or a move only decl ref expr.
2947+
//
2948+
// NOTE: We purposely do not look through load implying that if we have
2949+
// copyable types extracted from a move only class, we will not borrow.
2950+
auto *iterExpr = lvExpr;
2951+
while (true) {
2952+
SILType ty = SGF.getLoweredType(
2953+
iterExpr->getType()->getWithoutSpecifierType()->getCanonicalType());
2954+
if (ty.isPureMoveOnly())
2955+
break;
2956+
2957+
if (auto *mre = dyn_cast<MemberRefExpr>(iterExpr)) {
2958+
iterExpr = mre->getBase();
2959+
continue;
2960+
}
2961+
2962+
return nullptr;
2963+
}
2964+
29422965
(void)std::move(*this).asKnownExpr();
29432966
}
29442967

@@ -3081,7 +3104,11 @@ class ArgEmitter {
30813104
return;
30823105
}
30833106

3084-
if (loweredSubstArgType.isPureMoveOnly() && param.isGuaranteed()) {
3107+
// If we have a guaranteed paramter, see if we have a move only type and can
3108+
// emit it borrow.
3109+
//
3110+
// We check for move only in tryEmitBorrowedMoveOnly.
3111+
if (param.isGuaranteed()) {
30853112
if (tryEmitBorrowedMoveOnly(std::move(arg), loweredSubstArgType,
30863113
loweredSubstParamType, origParamType,
30873114
paramSlice))
@@ -3264,13 +3291,14 @@ class ArgEmitter {
32643291
ClaimedParamsRef paramsSlice) {
32653292
assert(paramsSlice.size() == 1);
32663293

3267-
// Try to find an expression we can emit as an l-value.
3268-
auto lvExpr = std::move(arg).findStorageReferenceExprForMoveOnlyBorrow();
3294+
// Try to find an expression we can emit as a borrowed l-value.
3295+
auto lvExpr = std::move(arg).findStorageReferenceExprForMoveOnlyBorrow(SGF);
32693296
if (!lvExpr)
32703297
return false;
32713298

32723299
emitBorrowed(lvExpr, loweredSubstArgType, loweredSubstParamType,
32733300
origParamType, paramsSlice);
3301+
32743302
return true;
32753303
}
32763304

0 commit comments

Comments
 (0)