-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implicit calls to deref
and deref_mut
are a footgun with raw pointers
#131847
Comments
I think, it should call derefs only this way:
|
While an unfortunate footgun, this is not a soundness issue. Removing the |
It would make sense to have a lint for this still (clippy or rustc). |
Might get caught by #123239, haven't checked. |
This is not unsound, so I'm gonna untag it as such. |
@rustbot labels -C-bug +C-discussion |
deref
and deref_mut
must be forbidden in raw pointer operations.deref
and deref_mut
are a footgun with raw pointers
I would argue you asked for trouble by writing that fn main() {
let a = A { b: MaybeUninit::uninit() };
let val = &a.field;
println!("{val}");
} So, the fix is to not write such |
Cc @rust-lang/opsem |
@RalfJung The problem (AFAIK) is not that Rust is unsound. Rust is behaving correctly. The problem is that it's too easy to make mistakes. Making a safe |
Your example is possible only inside module that declares By your logic, let my_vec: Vec<i32> = Vec { len: 200, buf: RawVec::new() };
let slice: &[i32] = &*my_vec; However, we actually know that deref implementation of Vec is sound because we know that fields Similarly, @ChayimFriedman2 Argues same thing as me, but more eloquently. |
Yes we use minimal examples, but this was too minimal. ;) The safety invariant and abstraction barrier are a key part of the argument here. Given the example has neither and there were no comments to indicate anything like that, it is reasonable to assume there is no such invariant. (Well, there is a SAFETY comment, but it didn't explain why this invariant is supposed to hold, given that the code clearly breaks it. Thanks for clarifying! Would be good to add a comment in |
I added comments. |
I tried this code (which models library code with invariants for all valid instances of A but without all the details):
I expected to see this happen: this code should be rejected because it causes implicit calls to
Deref::deref
which assumes*p
to be initialized.Instead, this happened: code compiles and prints
Called deref!
when executed.Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: