-
Notifications
You must be signed in to change notification settings - Fork 13.4k
try_cast_aligned: avoid bare int-to-ptr casts #141381
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
try_cast_aligned: avoid bare int-to-ptr casts #141381
Conversation
I totally missed that.. |
The best way is to do something like let x = &0i32; // guaranteed 4-aligned
let ptr = (x as *const i32).cast::<u8>().add(1); // guaranteed not 4-aligned |
Maybe they do, but the original example is not representative of how we want anyone to write Rust code. int2ptr casts are extremely rarely needed. This is the only test (across all doc tests, unit tests, integration tests) in all of core, alloc, and the parts of std that Miri can run that uses them! |
it is less expressive than raw adresses that are obviously well/not aligned.
I totally agree. According to you, how big of a problem is it ? Maybe we should totally remove such a cast to be more idiomatic? |
It's a problem because it causes CI in https://github.com/rust-lang/miri-test-libstd/ to fail. We don't have a good way of allowing such casts in a single test -- and even if we did, I don't think we should, since we consider such casts to be very unidiomatic (except in special situations such as MMIO accesses to hardware registers at fixed addresses). So I think everything is better than using int2ptr casts. If you think the examples I proposed are too unreadable, I'd encourage you to write alternative examples that also avoid int2ptr casts. Then we can see which one @tgross35 prefers. :) |
this is confusing to me. offsetting a pointer to a 4-byte object by 1 byte feels quite expressive, because it expresses it without drawing attention to irrelevant minutiae like the specific address. |
What I wanted to say is that I found the without_provenance example more readable than using references and cast+add, but it is unclear to me wether without_provenance is included in the unidiomatic int2ptr casts. |
I think that settles it? What about something like this (directly using what @RalfJung wrote): let x = 0;
let aligned: *const i32 = &x;
let unaligned = unsafe { aligned.byte_add(1) };
assert!(aligned.try_cast_aligned::<u32>().is_some());
assert!(unaligned.try_cast_aligned::<u32>().is_none()); I like because the pointer-creation part doesn't bloat the example (especially since |
The without_provenance example is still very unrealistic - nobody is going to use the API like that. It is probably easier to follow than the example with "real" pointers, but we could mitigate that to some extent with comments.
In the end it boils down to the usual trade-off in docs: make them simple vs make them realistic.
|
Yeah, that seems good. With pointers it can be easy to wander pretty far into the weeds, away from real code that people actually write, so "simplest example that reuses code people actually want to write" seems most helpful to me. The "fact" that pointers "are integers" usually only comes up when you have two of them and then try to do math on their addresses. Alone, each is mostly just its offset from an origin, because you can't actually usefully interact with their address (since it's unstable). |
Ahk sorry for missing this. I think I have a slight preference for the example using real pointers rather than magic numbers since I agree that seems more realistic.
One note to this example is it would make more sense as |
c2adb49
to
204d174
Compare
@bors r+ rollup |
204d174
to
09ae053
Compare
That resolves my one concern with the example, so I went for that. The last push changes a @bors r=tgross35 |
…iaskrgr Rollup of 8 pull requests Successful merges: - rust-lang#141355 (ci: improve citool job db errors) - rust-lang#141359 (Fix `FnOnce` impl for `AsyncFn`/`AsyncFnMut` self-borrowing closures in new solver) - rust-lang#141362 (Normalize aliases to correct kind of error term) - rust-lang#141377 (Remove unnecessary `is_empty` checks) - rust-lang#141381 (try_cast_aligned: avoid bare int-to-ptr casts) - rust-lang#141382 (ci: convert distcheck to free runner) - rust-lang#141389 (ci: prepare aws access keys for migration) - rust-lang#141390 (Don't allow `poly_select` in new solver) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#141381 - RalfJung:try_cast_aligned-strict-provenance, r=tgross35 try_cast_aligned: avoid bare int-to-ptr casts This fixes a CI failure in https://github.com/rust-lang/miri-test-libstd caused by strict provenance violations in doctests added in rust-lang#141222. r? `@tgross35` Cc `@mathisbot`
This fixes a CI failure in https://github.com/rust-lang/miri-test-libstd caused by strict provenance violations in doctests added in #141222.
r? @tgross35
Cc @mathisbot