SIL: Preliminary support for 'apply [noasync]' calls

Refactor SILGen's ApplyOptions into an OptionSet, add a
DoesNotAwait flag to go with DoesNotThrow, and sink it
all down into SILInstruction.h.

Then, replace the isNonThrowing() flag in ApplyInst and
BeginApplyInst with getApplyOptions(), and plumb it
through to TryApplyInst as well.

Set the flag when SILGen emits a sync call to a reasync
function.

When set, this disables the SIL verifier check against
calling async functions from sync functions.

Finally, this allows us to add end-to-end tests for
rdar://problem/71098795.
This commit is contained in:
Slava Pestov
2021-03-02 02:26:07 -05:00
parent 9216af8b04
commit 7ccc41a7b7
48 changed files with 413 additions and 200 deletions

View File

@@ -1555,10 +1555,16 @@ public:
"apply instruction cannot call function with error result");
}
if (AI->isNonAsync()) {
require(calleeConv.funcTy->isAsync(),
"noasync flag used for sync callee");
} else {
require(!calleeConv.funcTy->isAsync() || AI->getFunction()->isAsync(),
"cannot call an async function from a non async function");
}
require(!calleeConv.funcTy->isCoroutine(),
"cannot call coroutine with normal apply");
require(!calleeConv.funcTy->isAsync() || AI->getFunction()->isAsync(),
"cannot call an async function from a non async function");
}
void checkTryApplyInst(TryApplyInst *AI) {
@@ -1569,8 +1575,13 @@ public:
require(!calleeConv.funcTy->isCoroutine(),
"cannot call coroutine with normal apply");
require(!calleeConv.funcTy->isAsync() || AI->getFunction()->isAsync(),
"cannot call an async function from a non async function");
if (AI->isNonAsync()) {
require(calleeConv.funcTy->isAsync(),
"noasync flag used for sync callee");
} else {
require(!calleeConv.funcTy->isAsync() || AI->getFunction()->isAsync(),
"cannot call an async function from a non async function");
}
auto normalBB = AI->getNormalBB();
require(normalBB->args_size() == 1,