@@ -1148,21 +1148,27 @@ SILGenFunction::ForceTryEmission::ForceTryEmission(SILGenFunction &SGF,
11481148 // Set up a "catch" block for when an error occurs.
11491149 SILBasicBlock *catchBB = SGF.createBasicBlock (FunctionSection::Postmatter);
11501150
1151+ SILValue indirectError;
11511152 auto &errorTL = SGF.getTypeLowering (loc->getThrownError ());
11521153 if (!errorTL.isAddressOnly ()) {
11531154 (void ) catchBB->createPhiArgument (errorTL.getLoweredType (),
11541155 OwnershipKind::Owned);
1156+ } else {
1157+ indirectError = SGF.B .createAllocStack (loc, errorTL.getLoweredType ());
1158+ SGF.enterDeallocStackCleanup (indirectError);
1159+
11551160 }
11561161
11571162 SGF.ThrowDest = JumpDest (catchBB, SGF.Cleanups .getCleanupsDepth (),
11581163 CleanupLocation (loc),
1159- ThrownErrorInfo::forDiscard ( ));
1164+ ThrownErrorInfo (indirectError, /* discard= */ true ));
11601165}
11611166
11621167void SILGenFunction::ForceTryEmission::finish () {
11631168 assert (Loc && " emission already finished" );
11641169
11651170 auto catchBB = SGF.ThrowDest .getBlock ();
1171+ auto indirectError = SGF.ThrowDest .getThrownError ().IndirectErrorResult ;
11661172 SGF.ThrowDest = OldThrowDest;
11671173
11681174 // If there are no uses of the catch block, just drop it.
@@ -1175,29 +1181,64 @@ void SILGenFunction::ForceTryEmission::finish() {
11751181 ASTContext &ctx = SGF.getASTContext ();
11761182
11771183 // Consume the thrown error.
1184+ ManagedValue error;
11781185 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;
11991219 }
1220+ #else
1221+ error = SGF.emitSubstToOrigValue (Loc, error,
1222+ AbstractionPattern::getOpaque (),
1223+ error.getType ().getASTType ());
1224+ #endif
12001225 }
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);
12011242 }
12021243
12031244 SGF.B .createUnreachable (Loc);
0 commit comments