@@ -1148,21 +1148,27 @@ SILGenFunction::ForceTryEmission::ForceTryEmission(SILGenFunction &SGF,
1148
1148
// Set up a "catch" block for when an error occurs.
1149
1149
SILBasicBlock *catchBB = SGF.createBasicBlock (FunctionSection::Postmatter);
1150
1150
1151
+ SILValue indirectError;
1151
1152
auto &errorTL = SGF.getTypeLowering (loc->getThrownError ());
1152
1153
if (!errorTL.isAddressOnly ()) {
1153
1154
(void ) catchBB->createPhiArgument (errorTL.getLoweredType (),
1154
1155
OwnershipKind::Owned);
1156
+ } else {
1157
+ indirectError = SGF.B .createAllocStack (loc, errorTL.getLoweredType ());
1158
+ SGF.enterDeallocStackCleanup (indirectError);
1159
+
1155
1160
}
1156
1161
1157
1162
SGF.ThrowDest = JumpDest (catchBB, SGF.Cleanups .getCleanupsDepth (),
1158
1163
CleanupLocation (loc),
1159
- ThrownErrorInfo::forDiscard ( ));
1164
+ ThrownErrorInfo (indirectError, /* discard= */ true ));
1160
1165
}
1161
1166
1162
1167
void SILGenFunction::ForceTryEmission::finish () {
1163
1168
assert (Loc && " emission already finished" );
1164
1169
1165
1170
auto catchBB = SGF.ThrowDest .getBlock ();
1171
+ auto indirectError = SGF.ThrowDest .getThrownError ().IndirectErrorResult ;
1166
1172
SGF.ThrowDest = OldThrowDest;
1167
1173
1168
1174
// If there are no uses of the catch block, just drop it.
@@ -1175,29 +1181,64 @@ void SILGenFunction::ForceTryEmission::finish() {
1175
1181
ASTContext &ctx = SGF.getASTContext ();
1176
1182
1177
1183
// Consume the thrown error.
1184
+ ManagedValue error;
1178
1185
if (catchBB->getNumArguments () == 1 ) {
1179
- auto error = ManagedValue::forForwardedRValue (SGF, catchBB->getArgument (0 ));
1180
-
1181
- // FIXME: for typed throws, we need a new version of this entry point that
1182
- // takes a generic rather than an existential.
1183
- if (error.getType () == SILType::getExceptionType (ctx)) {
1184
- if (auto diagnoseError = ctx.getDiagnoseUnexpectedError ()) {
1185
- auto args = SGF.emitSourceLocationArgs (Loc->getExclaimLoc (), Loc);
1186
-
1187
- SGF.emitApplyOfLibraryIntrinsic (
1188
- Loc,
1189
- diagnoseError,
1190
- SubstitutionMap (),
1191
- {
1192
- error,
1193
- args.filenameStartPointer ,
1194
- args.filenameLength ,
1195
- args.filenameIsAscii ,
1196
- args.line
1197
- },
1198
- SGFContext ());
1186
+ error = ManagedValue::forForwardedRValue (SGF, catchBB->getArgument (0 ));
1187
+ } else {
1188
+ error = ManagedValue::forForwardedRValue (SGF, indirectError);
1189
+ }
1190
+
1191
+ // If we have 'any Error', use the older entrypoint that takes an
1192
+ // existential error directly. Otherwise, use the newer generic entrypoint.
1193
+ auto diagnoseError = error.getType ().getASTType ()->isErrorExistentialType ()
1194
+ ? ctx.getDiagnoseUnexpectedError ()
1195
+ : ctx.getDiagnoseUnexpectedErrorTyped ();
1196
+ if (diagnoseError) {
1197
+ SILValue tmpBuffer;
1198
+ auto args = SGF.emitSourceLocationArgs (Loc->getExclaimLoc (), Loc);
1199
+
1200
+ SubstitutionMap subMap;
1201
+ if (auto genericSig = diagnoseError->getGenericSignature ()) {
1202
+ // FIXME: The conformance of the thrown error type to the Error
1203
+ // protocol should be provided to us by the type checker.
1204
+ subMap = SubstitutionMap::get (
1205
+ genericSig, [&](SubstitutableType *dependentType) {
1206
+ return error.getType ().getObjectType ().getASTType ();
1207
+ }, LookUpConformanceInModule (SGF.getModule ().getSwiftModule ()));
1208
+
1209
+ // Generic errors are passed indirectly.
1210
+ #if true
1211
+ if (!error.getType ().isAddress ()) {
1212
+ auto *tmp = SGF.B .createAllocStack (Loc,
1213
+ error.getType ().getObjectType (),
1214
+ llvm::None);
1215
+ error.forwardInto (SGF, Loc, tmp);
1216
+ error = ManagedValue::forForwardedRValue (SGF, tmp);
1217
+
1218
+ tmpBuffer = tmp;
1199
1219
}
1220
+ #else
1221
+ error = SGF.emitSubstToOrigValue (Loc, error,
1222
+ AbstractionPattern::getOpaque (),
1223
+ error.getType ().getASTType ());
1224
+ #endif
1200
1225
}
1226
+
1227
+ SGF.emitApplyOfLibraryIntrinsic (
1228
+ Loc,
1229
+ diagnoseError,
1230
+ subMap,
1231
+ {
1232
+ error,
1233
+ args.filenameStartPointer ,
1234
+ args.filenameLength ,
1235
+ args.filenameIsAscii ,
1236
+ args.line
1237
+ },
1238
+ SGFContext ());
1239
+
1240
+ if (tmpBuffer)
1241
+ SGF.B .createDeallocStack (Loc, tmpBuffer);
1201
1242
}
1202
1243
1203
1244
SGF.B .createUnreachable (Loc);
0 commit comments