3 ms·
unsafe just means that you take responsibility for the safety of the code contained within. Calling into non-Rust libraries has to be wrapped in unsafe. Making
by Aurornis 6mo ago
unsafe just means that you take responsibility for the safety of the code contained within. Calling into non-Rust libraries has to be wrapped in unsafe. Making syscalls has to be wrapped in unsafe.
Bun needs to interact with FFI code. This gets wrapped in unsafe blocks.
There are many places where a JavaScript interpreter and library would need to make unsafe calls and operations.
It doesn't literally mean the code is unsafe. It means the code contained within is not something that can be checked by the compiler, so the writer takes responsibility for it.
There are many low-level data munging and other benign operations that a human can demonstrate are safe, but need to be wrapped in safe because they do things outside of what the compiler can check.
- SkiFire13 6mo ago> a JavaScript interpreter Bun is not a Javascript interpreter. But I do see the point.
- 12_throw_away 6mo agoThere's actually a good example of this in the rewrite [1], in `PathString::slice`. They are doing an unsafe operation to return a slice that could be a use-after-free, if the caller had not already guaranteed that an invariant will remain true. Following proper rust idiomatic practices, claude has added a SAFETY comment to the unsafe block to explain why it's safe: "caller guarantees the borrowed memory outlives this". Now, normally, you'd communicate this contract to your API users by marking the type's constructor (PathString::init) as "unsafe", and including the contract in its documentation. Unfortunately in this case, this invariant does not exist - it appears to have been fabricated out of thin air by the LLM [2]. So, not only does this particular codebase have UB problems caused by unsafe code, the SAFETY blocks for the unsafe code are also, well, lies. [1] https://github.com/oven-sh/bun/blob/63035b3e37/src/bun_core/string/PathString.rs#L94-L95 https://github.com/oven-sh/bun/blob/63035b3e37/src/bun_core/... [2] https://github.com/oven-sh/bun/blob/63035b3e37/src/bun_core/string/PathString.rs#L112-L113 https://github.com/oven-sh/bun/blob/63035b3e37/src/bun_core/...
- zozbot234 6mo agoOne potential way to solve this in a principled manner is to turn at least some "unsafe" annotations into ghost capability tokens that are explicitly threaded through the code and consistently checked by the compiler. Manufacturing the capability could itself be left as an unsafe operation, or require a runtime check of some kind. You already see this in some cases, for example the NonZero<T> generic type can be viewed as a T endowed with a capability or token that just says "this particular value of type T is nonzero, so the zero value is available for niche purposes". But this could be expanded a lot, especially with some AI assistance.
- 12_throw_away 6mo agoYes, or you could review the code.
- baq 6mo agoIt’d only take an hour if you reviewed a million lines per hour
- cyanydeez 6mo ago[Sorry guys, I couldn't review this code because I generated it all]
- frde_me 6mo agoEven before AI, deterministic checks by compilers are almost always better than "review the code" "review the code" as a solution will eventually fail and cause a problem, even pre-AI.
- 12_throw_away 6mo agoThe entire point of unsafe blocks and SAFETY comments is that they are easy for humans to find and audit, but not compiler checkable. If it can be compiler-checked by some clever token system, then ... it's just plain safe rust, and you don't need to document any special safety invariants in the first place
- boothby 6mo ago> unsafe just means that you take responsibility for the safety of the code contained within. In this case it means you delegated the responsibility to a notably flaky heuristic.