@@ -2968,6 +2968,29 @@ Expr *ArgumentSource::findStorageReferenceExprForMoveOnlyBorrow(
2968
2968
return lvExpr;
2969
2969
}
2970
2970
2971
+ Expr *
2972
+ ArgumentSource::findStorageReferenceExprForBorrowExpr (SILGenFunction &SGF) && {
2973
+ if (!isExpr ())
2974
+ return nullptr ;
2975
+
2976
+ auto argExpr = asKnownExpr ();
2977
+ auto *li = dyn_cast<LoadExpr>(argExpr);
2978
+ if (!li)
2979
+ return nullptr ;
2980
+ auto *borrowExpr = dyn_cast<BorrowExpr>(li->getSubExpr ());
2981
+ if (!borrowExpr)
2982
+ return nullptr ;
2983
+
2984
+ auto *lvExpr = ::findStorageReferenceExprForBorrow (borrowExpr->getSubExpr ());
2985
+
2986
+ // Claim the value of this argument.
2987
+ if (lvExpr) {
2988
+ (void )std::move (*this ).asKnownExpr ();
2989
+ }
2990
+
2991
+ return lvExpr;
2992
+ }
2993
+
2971
2994
Expr *ArgumentSource::findStorageReferenceExprForBorrow () && {
2972
2995
if (!isExpr ()) return nullptr ;
2973
2996
@@ -3097,18 +3120,23 @@ class ArgEmitter {
3097
3120
return ;
3098
3121
}
3099
3122
3100
- // If this is a yield, and the yield is borrowed, emit a borrowed r-value.
3101
- if (IsYield && param.isGuaranteed ()) {
3102
- if (tryEmitBorrowed (std::move (arg), loweredSubstArgType,
3103
- loweredSubstParamType, origParamType, paramSlice))
3123
+ // If we have a guaranteed +0 parameter...
3124
+ if (param.isGuaranteed ()) {
3125
+ // And this is a yield, emit a borrowed r-value.
3126
+ if (IsYield) {
3127
+ if (tryEmitBorrowed (std::move (arg), loweredSubstArgType,
3128
+ loweredSubstParamType, origParamType, paramSlice))
3129
+ return ;
3130
+ }
3131
+
3132
+ if (tryEmitBorrowExpr (std::move (arg), loweredSubstArgType,
3133
+ loweredSubstParamType, origParamType, paramSlice))
3104
3134
return ;
3105
- }
3106
3135
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 ()) {
3136
+ // If we have a guaranteed paramter, see if we have a move only type and
3137
+ // can emit it borrow.
3138
+ //
3139
+ // We check for move only in tryEmitBorrowedMoveOnly.
3112
3140
if (tryEmitBorrowedMoveOnly (std::move (arg), loweredSubstArgType,
3113
3141
loweredSubstParamType, origParamType,
3114
3142
paramSlice))
@@ -3302,6 +3330,23 @@ class ArgEmitter {
3302
3330
return true ;
3303
3331
}
3304
3332
3333
+ bool tryEmitBorrowExpr (ArgumentSource &&arg, SILType loweredSubstArgType,
3334
+ SILType loweredSubstParamType,
3335
+ AbstractionPattern origParamType,
3336
+ ClaimedParamsRef paramsSlice) {
3337
+ assert (paramsSlice.size () == 1 );
3338
+
3339
+ // Try to find an expression we can emit as a borrowed l-value.
3340
+ auto lvExpr = std::move (arg).findStorageReferenceExprForBorrowExpr (SGF);
3341
+ if (!lvExpr)
3342
+ return false ;
3343
+
3344
+ emitBorrowed (lvExpr, loweredSubstArgType, loweredSubstParamType,
3345
+ origParamType, paramsSlice);
3346
+
3347
+ return true ;
3348
+ }
3349
+
3305
3350
void emitBorrowed (Expr *arg, SILType loweredSubstArgType,
3306
3351
SILType loweredSubstParamType,
3307
3352
AbstractionPattern origParamType,
0 commit comments