One of the last ones was the actix debacle, which was contained and accidental and ended up badly.
This is IMO infinitely worse.
One of the last ones was the actix debacle, which was contained and accidental and ended up badly.
This is IMO infinitely worse.
Rust code author knowingly exposes unsound safe Rust APIs.
The details are different. Actix did so in their own project and were willing to fix it (the debacle was mostly social, and in some sense even accidental), while here exposing unsound safe Rust APIs is the whole raison d'etre of the project.
AutoCXX doesn't even check that the underlying C++ code does not change. So even if an autogenerated safe Rust API happens to be "accidentally safe", that can change any time without Rust users knowing.
This is where we disagree. I 100% agree that knowingly exposing an unsound API to safe Rust is a bad thing. However, what I see is the user of cxx/autocxx saying "I am asserting that this API is sound."
> AutoCXX doesn't even check that the underlying C++ code does not change
This is no different than any other Rust code calling into C++ code. The author has to declare that they believe it is safe either way.
And since the API of this library allows this assertion to be performed in safe Rust code, when it fails, safe Rust code has UB, which according to the Rust language reference makes the API of this crate unsound.
Unsound safe Rust APIs are broken Rust code. The Rust language spec and toolchain make no guarantees about what the behavior of these APIs is.
So that's what I see here. Just another safe Rust API that is broken by design. Maybe with the twist that this crate is actually a factory to generates thousands of those broken safe Rust APIs in masse, which kind of makes it worse than your usual "broken API" bug (which is what these are, these are soundness bugs in Rust libraries).
This assertion is always performed in safe Rust code. That's how you turn unsafe code into safe code: you write "unsafe { }" in safe code. That this does this in the body of a macro is not material.
(I know you disagree and don't think we're going to get anywhere, and frankly, find your aggressiveness really offputting.)
Safe Rust code performs these assertions by using the "unsafe" keyword. This library API allows safe Rust to perform these assertions _without_ writing "unsafe".
That's the problem.
If so, why? How is that materially different from calling a function with unsafe in its body? If not, why is this particular macro different?
No. Exported macros (as opposed to private ones) are only sound if they do not allow safe Rust to introduce undefined behavior.
Whether these macros use "unsafe" internally or not is irrelevant. For example, `pin_mut!` uses unsafe internally, but it does not allow safe Rust calling it to introduce UB.
A macro that allows safe Rust to introduce undefined behavior is unsound. An example of such an unsound macro would be `offset_of!`.
---
That is, I do not differentiate Rust abstractions when it comes to soundness. Whether its a function, a trait method, a macro, or a function pointer, it does not matter. If an abstraction its safe to use it shall not introduce UB. If it does, it is an unsound abstraction.
There is no debate about this.
You didn't really answer my question. I'm also not really gonna continue this argument.
Of course there is, for example, the offset_of! macro was unsound for a long time:
* https://internals.rust-lang.org/t/pre-rfc-add-a-new-offset-o...
* https://github.com/rust-lang/unsafe-code-guidelines/issues/1...
* https://github.com/rust-lang/unsafe-code-guidelines/issues/2...
* https://github.com/rust-lang/rust-memory-model/issues/35
> You didn't really answer my question.
I literally wrote "No.". To your follow up questions starting with "If so ..." i did not reply, because the assumption these questions were based on (that I would reply to the previous question with "yes") did not hold.
To expand on this. Rust does not have "unsafe macros", so all exported macros must be sound. Whether a macro is sound or not is orthogonal to whether the macro itself uses `unsafe` (and your original claim was whether I thought that macros containing unsafe should be rejected by the compiler, to which I replied "No.", `pin_mut!` is an example of a macro that uses `unsafe` and is sound).
Whoever invokes the macro asserts that doing so is sound / cannot cause UB, and having "unsafe" in the macro name draws attention to that in the same way that the unsafe keyword itself does.
Right now that's very implicit, and I bet there are users of the library that don't think they're asserting that. They expect you to follow the documented rules about invariants.
Requiring people to write 'unsafe' at the import site makes that a lot clearer, but if it's mandatory then people are probably going to write it whether the API is sound or not.
I'd be more comfortable if you could either declare an API sound when you import it or write 'unsafe' everywhere you call it.