@@ -1560,24 +1560,57 @@ void SILGenFunction::emitThrow(SILLocation loc, ManagedValue exnMV,
15601560
15611561 SILValue exn;
15621562 if (!exnMV.isInContext ()) {
1563- // Claim the exception value. If we need to handle throwing
1564- // cleanups, the correct thing to do here is to recreate the
1565- // exception's cleanup when emitting each cleanup we branch through.
1566- // But for now we aren't bothering.
1567- exn = exnMV.forward (*this );
1568-
15691563 // Whether the thrown exception is already an Error existential box.
15701564 SILType existentialBoxType = SILType::getExceptionType (getASTContext ());
1571- bool isExistentialBox = exn->getType () == existentialBoxType;
1572-
1573- // FIXME: Right now, we suppress emission of the willThrow builtin if the
1574- // error isn't already the error existential, because swift_willThrow expects
1575- // the existential box.
1576- if (emitWillThrow && isExistentialBox) {
1577- // Generate a call to the 'swift_willThrow' runtime function to allow the
1578- // debugger to catch the throw event.
1579- B.createBuiltin (loc, SGM.getASTContext ().getIdentifier (" willThrow" ),
1580- SGM.Types .getEmptyTupleType (), {}, {exn});
1565+ bool isExistentialBox = exnMV.getType () == existentialBoxType;
1566+
1567+ // If we are supposed to emit a call to swift_willThrow(Typed), do so now.
1568+ if (emitWillThrow) {
1569+ ASTContext &ctx = SGM.getASTContext ();
1570+ if (isExistentialBox) {
1571+ // Generate a call to the 'swift_willThrow' runtime function to allow the
1572+ // debugger to catch the throw event.
1573+
1574+ // Claim the exception value.
1575+ exn = exnMV.forward (*this );
1576+
1577+ B.createBuiltin (loc,
1578+ ctx.getIdentifier (" willThrow" ),
1579+ SGM.Types .getEmptyTupleType (), {}, {exn});
1580+ } else {
1581+ // Call the _willThrowTyped entrypoint, which handles
1582+ // arbitrary error types.
1583+ SILValue tmpBuffer;
1584+ SILValue error;
1585+
1586+ FuncDecl *entrypoint = ctx.getWillThrowTyped ();
1587+ auto genericSig = entrypoint->getGenericSignature ();
1588+ SubstitutionMap subMap = SubstitutionMap::get (
1589+ genericSig, [&](SubstitutableType *dependentType) {
1590+ return exnMV.getType ().getASTType ();
1591+ }, LookUpConformanceInModule (getModule ().getSwiftModule ()));
1592+
1593+ // Generic errors are passed indirectly.
1594+ if (!exnMV.getType ().isAddress ()) {
1595+ // Materialize the error so we can pass the address down to the
1596+ // swift_willThrowTyped.
1597+ exnMV = exnMV.materialize (*this , loc);
1598+ error = exnMV.getValue ();
1599+ exn = exnMV.forward (*this );
1600+ } else {
1601+ // Claim the exception value.
1602+ exn = exnMV.forward (*this );
1603+ error = exn;
1604+ }
1605+
1606+ emitApplyOfLibraryIntrinsic (
1607+ loc, entrypoint, subMap,
1608+ { ManagedValue::forForwardedRValue (*this , error) },
1609+ SGFContext ());
1610+ }
1611+ } else {
1612+ // Claim the exception value.
1613+ exn = exnMV.forward (*this );
15811614 }
15821615 }
15831616
0 commit comments