void ArgumentSource::forwardInto(SILGenFunction &SGF, AbstractionPattern origFormalType, Initialization *dest, const TypeLowering &destTL) && { auto substFormalType = getSubstRValueType(); assert(destTL.getLoweredType() == SGF.getLoweredType(origFormalType, substFormalType)); // If there are no abstraction changes, we can just forward // normally. if (origFormalType.isExactType(substFormalType) || destTL.getLoweredType() == SGF.getLoweredType(substFormalType)) { std::move(*this).forwardInto(SGF, dest); return; } // Otherwise, emit as a single independent value. SILLocation loc = getLocation(); ManagedValue outputValue = std::move(*this).getAsSingleValue(SGF, origFormalType, SGFContext(dest)); if (outputValue.isInContext()) return; // Use RValue's forward-into-initialization code. We have to lie to // RValue about the formal type (by using the lowered type) because // we're emitting into an abstracted value, which RValue doesn't // really handle. auto substLoweredType = destTL.getLoweredType().getASTType(); RValue(SGF, loc, substLoweredType, outputValue).forwardInto(SGF, loc, dest); }
ManagedValue ArgumentSource::materialize(SILGenFunction &SGF, AbstractionPattern origFormalType, SILType destType) && { auto substFormalType = getSubstRValueType(); assert(!destType || destType.getObjectType() == SGF.getLoweredType(origFormalType, substFormalType).getObjectType()); // Fast path: if the types match exactly, no abstraction difference // is possible and we can just materialize as normal. if (origFormalType.isExactType(substFormalType)) return std::move(*this).materialize(SGF); auto &destTL = (destType ? SGF.getTypeLowering(destType) : SGF.getTypeLowering(origFormalType, substFormalType)); if (!destType) destType = destTL.getLoweredType(); // If there's no abstraction difference, we can just materialize as normal. if (destTL.getLoweredType() == SGF.getLoweredType(substFormalType)) { return std::move(*this).materialize(SGF); } // Emit a temporary at the given address. auto temp = SGF.emitTemporary(getLocation(), destTL); // Forward into it. std::move(*this).forwardInto(SGF, origFormalType, temp.get(), destTL); return temp->getManagedAddress(); }