@@ -1080,6 +1080,33 @@ class ParamInfo {
10801080 IndirectSlot slot;
10811081 ParameterConvention convention;
10821082
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+
10831110public:
10841111 ParamInfo (IndirectSlot slot, ParameterConvention convention)
10851112 : slot(slot), convention(convention) {}
@@ -1088,11 +1115,26 @@ class ParamInfo {
10881115 return slot.allocate (SGF, loc);
10891116 }
10901117
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;
10961138 }
10971139
10981140 SILType getType () const {
@@ -1904,8 +1946,8 @@ class TranslateArguments : public ExpanderBase<TranslateArguments, ParamInfo> {
19041946 ManagedValue outerArg,
19051947 ParamInfo innerSlot) {
19061948 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 );
19091951 processSingleInto (innerOrigType, innerSubstType,
19101952 outerOrigType, outerSubstType,
19111953 outerArg, innerResultTy.getAddressType (),
@@ -2139,7 +2181,7 @@ class TranslateArguments : public ExpanderBase<TranslateArguments, ParamInfo> {
21392181 outer, innerTy,
21402182 SGFContext (&init));
21412183 if (!innerArg.isInContext ()) {
2142- if (innerArg.isPlusOneOrTrivial (SGF)) {
2184+ if (innerArg.isPlusOneOrTrivial (SGF) || init. isBorrow () ) {
21432185 innerArg.forwardInto (SGF, Loc, &init);
21442186 } else {
21452187 innerArg.copyInto (SGF, Loc, &init);
0 commit comments