@@ -1080,6 +1080,33 @@ class ParamInfo {
1080
1080
IndirectSlot slot;
1081
1081
ParameterConvention convention;
1082
1082
1083
+ bool temporaryShouldBorrow (SILGenFunction &SGF, bool forceAllocation) {
1084
+ if (slot.hasAddress () && !forceAllocation) {
1085
+ // An address has already been allocated via some projection. It is not
1086
+ // currently supported to store_borrow to such projections.
1087
+ return false ;
1088
+ }
1089
+ auto &tl = getTypeLowering (SGF);
1090
+ if (tl.isAddressOnly () && SGF.silConv .useLoweredAddresses ()) {
1091
+ // In address-lowered mode, address-only types can't be loaded in the
1092
+ // first place before being store_borrow'd.
1093
+ return false ;
1094
+ }
1095
+ if (convention != ParameterConvention::Indirect_In_Guaranteed) {
1096
+ // Can only store_borrow into a temporary allocation for @in_guaranteed.
1097
+ return false ;
1098
+ }
1099
+ if (tl.isTrivial ()) {
1100
+ // Can't store_borrow a trivial type.
1101
+ return false ;
1102
+ }
1103
+ return true ;
1104
+ }
1105
+
1106
+ TypeLowering const &getTypeLowering (SILGenFunction &SGF) {
1107
+ return SGF.getTypeLowering (getType ());
1108
+ }
1109
+
1083
1110
public:
1084
1111
ParamInfo (IndirectSlot slot, ParameterConvention convention)
1085
1112
: slot(slot), convention(convention) {}
@@ -1088,11 +1115,26 @@ class ParamInfo {
1088
1115
return slot.allocate (SGF, loc);
1089
1116
}
1090
1117
1091
- std::unique_ptr<TemporaryInitialization>
1092
- allocateForInitialization (SILGenFunction &SGF, SILLocation loc) const {
1093
- auto addr = slot.allocate (SGF, loc);
1094
- auto &addrTL = SGF.getTypeLowering (addr->getType ());
1095
- return SGF.useBufferAsTemporary (addr, addrTL);
1118
+ std::unique_ptr<AnyTemporaryInitialization>
1119
+ allocateForInitialization (SILGenFunction &SGF, SILLocation loc,
1120
+ bool forceAllocation = false ) {
1121
+ auto &lowering = getTypeLowering (SGF);
1122
+ SILValue address;
1123
+ if (forceAllocation) {
1124
+ address = SGF.emitTemporaryAllocation (loc, lowering.getLoweredType ());
1125
+ } else {
1126
+ address = allocate (SGF, loc);
1127
+ }
1128
+ if (address->getType ().isMoveOnly ())
1129
+ address = SGF.B .createMarkUnresolvedNonCopyableValueInst (
1130
+ loc, address,
1131
+ MarkUnresolvedNonCopyableValueInst::CheckKind::
1132
+ ConsumableAndAssignable);
1133
+ if (temporaryShouldBorrow (SGF, forceAllocation)) {
1134
+ return std::make_unique<StoreBorrowInitialization>(address);
1135
+ }
1136
+ auto innerTemp = SGF.useBufferAsTemporary (address, lowering);
1137
+ return innerTemp;
1096
1138
}
1097
1139
1098
1140
SILType getType () const {
@@ -1904,8 +1946,8 @@ class TranslateArguments : public ExpanderBase<TranslateArguments, ParamInfo> {
1904
1946
ManagedValue outerArg,
1905
1947
ParamInfo innerSlot) {
1906
1948
auto innerResultTy = innerSlot.getType ();
1907
- auto &innerTL = SGF. getTypeLowering (innerResultTy);
1908
- auto innerTemp = SGF. emitTemporary ( Loc, innerTL );
1949
+ auto innerTemp =
1950
+ innerSlot. allocateForInitialization (SGF, Loc, /* forceAllocation= */ true );
1909
1951
processSingleInto (innerOrigType, innerSubstType,
1910
1952
outerOrigType, outerSubstType,
1911
1953
outerArg, innerResultTy.getAddressType (),
@@ -2139,7 +2181,7 @@ class TranslateArguments : public ExpanderBase<TranslateArguments, ParamInfo> {
2139
2181
outer, innerTy,
2140
2182
SGFContext (&init));
2141
2183
if (!innerArg.isInContext ()) {
2142
- if (innerArg.isPlusOneOrTrivial (SGF)) {
2184
+ if (innerArg.isPlusOneOrTrivial (SGF) || init. isBorrow () ) {
2143
2185
innerArg.forwardInto (SGF, Loc, &init);
2144
2186
} else {
2145
2187
innerArg.copyInto (SGF, Loc, &init);
0 commit comments