Skip to content

Commit b84df92

Browse files
committed
SIL: Type lowering support for indirect error results
1 parent 1d05c35 commit b84df92

File tree

2 files changed

+46
-28
lines changed

2 files changed

+46
-28
lines changed

lib/SIL/IR/AbstractionPattern.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2627,14 +2627,28 @@ class SubstFunctionTypePatternVisitor
26272627
if (yieldType) {
26282628
substYieldType = visit(yieldType, yieldPattern);
26292629
}
2630-
2630+
2631+
CanType newErrorType;
2632+
2633+
if (auto optPair = pattern.getFunctionThrownErrorType(func)) {
2634+
auto errorPattern = optPair->first;
2635+
auto errorType = optPair->second;
2636+
newErrorType = visit(errorType, errorPattern);
2637+
}
2638+
26312639
auto newResultTy = visit(func.getResult(),
26322640
pattern.getFunctionResultType());
26332641

26342642
llvm::Optional<FunctionType::ExtInfo> extInfo;
26352643
if (func->hasExtInfo())
26362644
extInfo = func->getExtInfo();
2637-
2645+
2646+
if (newErrorType) {
2647+
if (!extInfo)
2648+
extInfo = FunctionType::ExtInfo();
2649+
extInfo = extInfo->withThrows(true, newErrorType);
2650+
}
2651+
26382652
return CanFunctionType::get(FunctionType::CanParamArrayRef(newParams),
26392653
newResultTy, extInfo);
26402654
}

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2190,32 +2190,6 @@ static CanSILFunctionType getSILFunctionType(
21902190
isAsync = true;
21912191
}
21922192

2193-
// Map 'throws' to the appropriate error convention.
2194-
// Give the type an error argument whether the substituted type semantically
2195-
// `throws` or if the abstraction pattern specifies a Swift function type
2196-
// that also throws. This prevents the need for a second possibly-thunking
2197-
// conversion when using a non-throwing function in more abstract throwing
2198-
// context.
2199-
bool isThrowing = substFnInterfaceType->getExtInfo().isThrowing();
2200-
if (auto origFnType = origType.getAs<AnyFunctionType>()) {
2201-
isThrowing |= origFnType->getExtInfo().isThrowing();
2202-
}
2203-
if (isThrowing && !foreignInfo.error &&
2204-
!foreignInfo.async) {
2205-
assert(!origType.isForeign()
2206-
&& "using native Swift error convention for foreign type!");
2207-
SILType exnType;
2208-
if (CanType thrownError = substFnInterfaceType.getThrownError()) {
2209-
exnType = TC.getLoweredType(thrownError, expansionContext);
2210-
} else {
2211-
// Untyped error throws the exception type.
2212-
exnType = SILType::getExceptionType(TC.Context);
2213-
}
2214-
assert(exnType.isObject());
2215-
errorResult = SILResultInfo(exnType.getASTType(),
2216-
ResultConvention::Owned);
2217-
}
2218-
22192193
// Get the yield type for an accessor coroutine.
22202194
SILCoroutineKind coroutineKind = SILCoroutineKind::None;
22212195
AbstractionPattern coroutineOrigYieldType = AbstractionPattern::getInvalid();
@@ -2308,6 +2282,36 @@ static CanSILFunctionType getSILFunctionType(
23082282
}
23092283
}
23102284

2285+
// Map 'throws' to the appropriate error convention.
2286+
// Give the type an error argument whether the substituted type semantically
2287+
// `throws` or if the abstraction pattern specifies a Swift function type
2288+
// that also throws. This prevents the need for a second possibly-thunking
2289+
// conversion when using a non-throwing function in more abstract throwing
2290+
// context.
2291+
bool isThrowing = substFnInterfaceType->getExtInfo().isThrowing();
2292+
if (auto origFnType = origType.getAs<AnyFunctionType>()) {
2293+
isThrowing |= origFnType->getExtInfo().isThrowing();
2294+
}
2295+
2296+
if (isThrowing && !foreignInfo.error &&
2297+
!foreignInfo.async) {
2298+
assert(!origType.isForeign()
2299+
&& "using native Swift error convention for foreign type!");
2300+
auto optPair = origType.getFunctionThrownErrorType(substFnInterfaceType);
2301+
assert(optPair &&
2302+
"Lowering a throwing function type against non-throwing pattern");
2303+
2304+
auto origErrorType = optPair->first;
2305+
auto errorType = optPair->second;
2306+
auto &errorTLConv = TC.getTypeLowering(origErrorType, errorType,
2307+
TypeExpansionContext::minimal());
2308+
2309+
errorResult = SILResultInfo(errorTLConv.getLoweredType().getASTType(),
2310+
errorTLConv.isAddressOnly()
2311+
? ResultConvention::Indirect
2312+
: ResultConvention::Owned);
2313+
}
2314+
23112315
// Lower the result type.
23122316
AbstractionPattern origResultType = origType.getFunctionResultType();
23132317
CanType substFormalResultType = substFnInterfaceType.getResult();

0 commit comments

Comments
 (0)