Skip to content

Commit 0f30cdf

Browse files
committed
Allow Builtin.emplace to have typed throws
1 parent b9487d1 commit 0f30cdf

File tree

2 files changed

+53
-9
lines changed

2 files changed

+53
-9
lines changed

lib/AST/Builtins.cpp

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ enum class BuiltinThrowsKind : uint8_t {
442442
static FuncDecl *getBuiltinGenericFunction(
443443
Identifier Id, ArrayRef<AnyFunctionType::Param> ArgParamTypes, Type ResType,
444444
GenericParamList *GenericParams, GenericSignature Sig, bool Async,
445-
BuiltinThrowsKind Throws, bool SendingResult) {
445+
BuiltinThrowsKind Throws, Type ThrownError, bool SendingResult) {
446446
assert(GenericParams && "Missing generic parameters");
447447
auto &Context = ResType->getASTContext();
448448

@@ -471,7 +471,7 @@ static FuncDecl *getBuiltinGenericFunction(
471471
Context, StaticSpellingKind::None, Name,
472472
/*NameLoc=*/SourceLoc(),
473473
Async,
474-
Throws != BuiltinThrowsKind::None, /*thrownType=*/Type(),
474+
Throws != BuiltinThrowsKind::None, ThrownError,
475475
GenericParams, paramList, ResType, DC);
476476

477477
func->setSendingResult(SendingResult);
@@ -696,6 +696,7 @@ namespace {
696696
Type InterfaceResult;
697697
bool Async = false;
698698
BuiltinThrowsKind Throws = BuiltinThrowsKind::None;
699+
Type ThrownError;
699700
bool SendingResult = false;
700701

701702
// Accumulate params and requirements here, so that we can call
@@ -740,6 +741,11 @@ namespace {
740741
InterfaceResult = generator.build(*this);
741742
}
742743

744+
template <class G>
745+
void setThrownError(const G &generator) {
746+
ThrownError = generator.build(*this);
747+
}
748+
743749
template <class G>
744750
void addConformanceRequirement(const G &generator, KnownProtocolKind kp) {
745751
addConformanceRequirement(generator, Context.getProtocol(kp));
@@ -776,7 +782,7 @@ namespace {
776782
/*allowInverses=*/false);
777783
return getBuiltinGenericFunction(name, InterfaceParams, InterfaceResult,
778784
TheGenericParamList, GenericSig, Async,
779-
Throws, SendingResult);
785+
Throws, ThrownError, SendingResult);
780786
}
781787

782788
// Don't use these generator classes directly; call the make{...}
@@ -2231,17 +2237,31 @@ static ValueDecl *getAddressOfRawLayout(ASTContext &ctx, Identifier id) {
22312237
}
22322238

22332239
static ValueDecl *getEmplace(ASTContext &ctx, Identifier id) {
2234-
BuiltinFunctionBuilder builder(ctx, /* genericParamCount */ 1);
2240+
BuiltinFunctionBuilder builder(ctx, /* genericParamCount */ 2);
22352241

2236-
auto T = makeGenericParam();
2242+
// <T: ~Copyable, E: Error>(
2243+
// _: (Builtin.RawPointer) throws(E) -> ()
2244+
// ) throws(E) -> T
2245+
2246+
auto T = makeGenericParam(0);
22372247
builder.addConformanceRequirement(T, KnownProtocolKind::Escapable);
22382248

2249+
auto E = makeGenericParam(1);
2250+
builder.addConformanceRequirement(E, KnownProtocolKind::Error);
2251+
2252+
auto extInfo = ASTExtInfoBuilder()
2253+
.withNoEscape()
2254+
.withThrows(/* throws */ true, E.build(builder))
2255+
.build();
2256+
22392257
auto fnParamTy = FunctionType::get(FunctionType::Param(ctx.TheRawPointerType),
22402258
ctx.TheEmptyTupleType,
2241-
ASTExtInfo().withNoEscape());
2259+
extInfo);
22422260

22432261
builder.addParameter(makeConcrete(fnParamTy), ParamSpecifier::Borrowing);
22442262
builder.setResult(T);
2263+
builder.setThrows();
2264+
builder.setThrownError(E);
22452265

22462266
return builder.build(id);
22472267
}

lib/SILGen/SILGenBuiltin.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2133,12 +2133,36 @@ static ManagedValue emitBuiltinEmplace(SILGenFunction &SGF,
21332133
SILValue bufferPtr = SGF.B.createAddressToPointer(loc, buffer,
21342134
SILType::getPrimitiveObjectType(SGF.getASTContext().TheRawPointerType),
21352135
/*needs stack protection*/ true);
2136-
SGF.B.createApply(loc, args[0].getValue(), {}, bufferPtr);
2137-
2136+
2137+
auto fnType = args[0].getValue()->getType().castTo<SILFunctionType>();
2138+
2139+
if (fnType->hasErrorResult()) {
2140+
auto normalBB = SGF.createBasicBlock();
2141+
auto errorBB = SGF.createBasicBlock();
2142+
2143+
SGF.B.createTryApply(loc, args[0].getValue(), {},
2144+
{SGF.IndirectErrorResult, bufferPtr}, normalBB, errorBB);
2145+
2146+
// Error branch
2147+
{
2148+
SGF.B.emitBlock(errorBB);
2149+
2150+
SGF.Cleanups.emitCleanupsForReturn(CleanupLocation(loc), IsForUnwind);
2151+
2152+
SGF.B.createThrowAddr(loc);
2153+
}
2154+
2155+
SGF.B.emitBlock(normalBB);
2156+
2157+
normalBB->createPhiArgument(SILType::getEmptyTupleType(Ctx),
2158+
OwnershipKind::Owned);
2159+
} else {
2160+
SGF.B.createApply(loc, args[0].getValue(), {}, bufferPtr);
2161+
}
2162+
21382163
dest->finishInitialization(SGF);
21392164

21402165
if (didEmitInto) {
2141-
C.getEmitInto()->finishInitialization(SGF);
21422166
return ManagedValue::forInContext();
21432167
}
21442168

0 commit comments

Comments
 (0)