Skip to content

Commit 8ca5483

Browse files
committed
[Typed throws] Narrow typed throws conversions to existential erasure in calls
Match what we do in `emitThrow`. Both of these should be unified and generalized, relying on the AST to provide the necessary conversions rather than having SILGen re-derive them.
1 parent bcf02f7 commit 8ca5483

File tree

1 file changed

+31
-13
lines changed

1 file changed

+31
-13
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5754,25 +5754,43 @@ SILValue SILGenFunction::emitApplyWithRethrow(SILLocation loc, SILValue fn,
57545754
outerError = innerError;
57555755
} else {
57565756
// The error requires some kind of translation.
5757-
5758-
// Load the inner error, if it was returned indirectly.
5759-
if (innerError->getType().isAddress()) {
5760-
innerError = emitLoad(loc, innerError, getTypeLowering(innerErrorType),
5761-
SGFContext(), IsTake).forward(*this);
5762-
}
5757+
outerErrorType = outerErrorType.getObjectType();
57635758

57645759
// If we need to convert the error type, do so now.
57655760
if (innerErrorType != outerErrorType) {
5766-
auto conversion = Conversion::getOrigToSubst(
5767-
AbstractionPattern(innerErrorType.getASTType()),
5768-
outerErrorType.getASTType(),
5769-
outerErrorType);
5770-
outerError = emitConvertedRValue(loc, conversion, SGFContext(),
5771-
[innerError](SILGenFunction &SGF, SILLocation loc, SGFContext C) {
5772-
return ManagedValue::forForwardedRValue(SGF, innerError);
5761+
assert(outerErrorType == SILType::getExceptionType(getASTContext()));
5762+
5763+
ProtocolConformanceRef conformances[1] = {
5764+
getModule().getSwiftModule()->conformsToProtocol(
5765+
innerError->getType().getASTType(),
5766+
getASTContext().getErrorDecl())
5767+
};
5768+
5769+
outerError = emitExistentialErasure(
5770+
loc,
5771+
innerErrorType.getASTType(),
5772+
getTypeLowering(innerErrorType),
5773+
getTypeLowering(outerErrorType),
5774+
getASTContext().AllocateCopy(conformances),
5775+
SGFContext(),
5776+
[&](SGFContext C) -> ManagedValue {
5777+
if (innerError->getType().isAddress()) {
5778+
return emitLoad(loc, innerError,
5779+
getTypeLowering(innerErrorType), SGFContext(),
5780+
IsTake);
5781+
}
5782+
5783+
return ManagedValue::forForwardedRValue(*this, innerError);
57735784
}).forward(*this);
5785+
} else if (innerError->getType().isAddress()) {
5786+
// Load the inner error, if it was returned indirectly.
5787+
outerError = emitLoad(loc, innerError, getTypeLowering(innerErrorType),
5788+
SGFContext(), IsTake).forward(*this);
5789+
} else {
5790+
outerError = innerError;
57745791
}
57755792

5793+
57765794
// If the outer error is returned indirectly, copy from the converted
57775795
// inner error to the outer error slot.
57785796
if (IndirectErrorResult) {

0 commit comments

Comments
 (0)