Two things come to mind for that:
-
Because it's affecting a block, not a value. This is the same way that it's
async { ... }
, not{ ... }.async
-- it's telling you context you need to understand the block. Similarly,{ ... break x ... }.loop
would be surprising because there wasn't the signpost warning you that thebreak
was coming the way there is inloop { ... break x ... }
. (And though I'm probably not in favour of actually doing this for break, note thatloop { ... x.break ... }
doesn't have the same "surprise" factor, the same way thatasync { ... x.await ... }
doesn't.) -
Because async/await is a delayable effect, but unsafe isn't. With async/await, you can call the function to get the
impl Future
outside anasync
block, then later choose whether or not to call.await
on it. Similarly, you can get yourResult
, put it in aVec
, and later decide to?
on it. On the contrary,unsafe
needs to be "proven" before the call -- you of course can't call the unsafe function from safe code then later somehow only use the result if it was sound. (const
also happens like this, where you can't make somethingconst
later; it has to beconst
from the beginning.)