- Whether or not a library calls unsafe code internally
- Whether or not a library declares its public API to be unsafe (https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html#call...)
It's very much possible (essential, even) to be able to present a safe API to external callers of your code, despite using unsafe code under the hood. In this case you're making a human-checked assertion of safety, which is not guaranteed to be without bugs, but the important thing is that you're minimizing the surface area of un-safety and declaring a contract with your users. You're "stopping the buck" of unsafety rather than passing it on. The parts that really have to be unsafe can enjoy extra scrutiny, and everything else (including the caller's code) can be checked by the compiler. This is not uncommon in the standard library and other low-level libraries.
More information here: https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html#crea...
Now that it’s released, library authors can wrap this with another library, which abstracts over win32, reexposing it in safe rust. Wrapper libraries like that almost certainly won’t cover 100% of the api surface area - there are so many functions in the windows APIs.
Anyway, give it time. People will wrap this with safe rust.
let event = CreateEventW(
std::ptr::null_mut(),
true.into(),
false.into(),
std::ptr::null(),
);
The .into() is silly but tolerable. But the first parameter is a pointer to a struct, and it’s clear enough from the signature that a reference would work. It could be mut to be on the safe side. (Yes, this involves someone making sure that the API doesn’t retain the pointer.). The last argument is, per the prototype, is a string. Admittedly, the Windows API has a truly horrible idea of what a string is, but surely they could do better than using a pointer.(They could remove the intos if they wanted to, I agree it feels kind of weird but I'm not actually sure if doing it is better or worse, I am conflicted.)
No matter how many heuristics they apply to make a somewhat more idiomatic mapping, it'll never feel right until it's manually designed to fit with Rust conventions. So I'm okay with it as it is now and can hope for a much thicker abstraction in the future.
My comment was trying to be pretty narrowly scoped to "why not use a reference here." You and your sibling are both right in ways!
This makes no sense to me, what you’re saying here. You pass raw pointers to the Windows API for one, for which it makes no safety guarantees. Short of rewriting Windows from scratch I don’t see how this isn’t a fundamentally unsafe domain. Sure you could put more and more wrappers up on top (it’s not an even an issue of one-to-one translation, but how resources such as memory are wrapped), but whatever binding there is pretty much must be unsafe.
That it’s possible to write a safe wrapper is kind of obvious.
Forever, and not "unfortunately" but rather as expected and necessary. Windows API is unsafe (C/C++) itself, and this is a wrapper for it.
How could they "patch" that with a wrapper?
I'm not sure I follow this. Are you saying the unsafe APIs somehow treat memory differently than any other C API that has been wrapped with a safe C wrapper?
In any case, I'm saying their current unsafe wrapper can sit under another layer, which provides a safe API. Of course, if there's a bug somewhere in the lower layers, it could still be unsafe, but that's true of all C bindings.
> This is the safe abstraction! I mean it's a pretty mechanical translation but it's nonetheless as safe as Rust will ever consider it.
No, it's not safe. Assuming I understand Rust correctly: if your bindings allow Rust programmers to trigger undefined behaviour even when they restrict themselves to the safe subset of Rust, that means that either your bindings have a defect, or the underlying (wrapped) library has a defect.
Even if a sanitizer, linker, review by the absolute most skilled developer on earth check every line.
Because C/C++ is designed without safety. So, Rust can't "believe" the external world is safe because the external world is made unsafe.
But the thing is only a human could, manually, check the code and consider it safe.
Rust can't decide it.
Is marking the apis unsafe going to make people choose an alternative? No. Does it prevent something bad from happening? No. Do users even know what unsafe means, other than that it sounds scary? No. If they did know, would it have imparted useful knowledge to them (that documentation wouldn't have provided more specifically)? I don't think so, for most users.