Uh oh!
There was an error while loading. Please reload this page.
add llvm writable attribute conditionally - #155207
Conversation
rustbot
commented
Apr 12, 2026
Some changes occurred in compiler/rustc_passes/src/check_attr.rs cc @jdonszelmann, @JonathanBrouwer Some changes occurred in compiler/rustc_hir/src/attrs cc @jdonszelmann, @JonathanBrouwer Some changes occurred in compiler/rustc_attr_parsing |
rustbot
commented
Apr 12, 2026
r? @mati865 rustbot has assigned @mati865. Use Why was this reviewer chosen?The reviewer was selected based on:
|
quiode
commented
Apr 12, 2026
r? @RalfJung |
rustbot
commented
Apr 12, 2026
|
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
This generally looks good, thanks! I just hope this larger ArgAttribute won't cause us problems. Cc @nikic for the LLVM parts, in case you want to take a 2nd look.
I am not sure if there's anything special to look out for in the new attribute infrastructure; @jdonszelmann would be great if you could take a brief look at that part.
@rustbot author
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| // The subset of llvm::Attribute needed for arguments, packed into a bitfield. | ||
| #[derive(Clone, Copy, Default, Hash, PartialEq, Eq, HashStable_Generic)] | ||
| pub struct ArgAttribute(u8); | ||
| pub struct ArgAttribute(u16); |
There was a problem hiding this comment.
Ah, this is unfortunate. We should benchmark this to ensure the larger bitfield isn't a problem.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
rustbot
commented
Apr 14, 2026
Reminder, once the PR becomes ready for a review, use |
Uh oh!
There was an error while loading. Please reload this page.
JonathanBrouwer
commented
Apr 14, 2026
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
add llvm writable attribute conditionally
💔 Test for 37fa495 failed: CI. Failed job:
|
JonathanBrouwer
commented
Apr 14, 2026
^ The PR needs to be rebased |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
RalfJung
commented
Apr 16, 2026
That looks good! This is just a secondary benchmark that has been rather noisy recently already, nothing to worry about IMO. @bors r+ |
This comment has been minimized.
This comment has been minimized.
Uh oh!
There was an error while loading. Please reload this page.
What is this?This is an experimental post-merge analysis report that shows differences in test outcomes between the merged PR and its parent PR.Comparing 0204aca (parent) -> 1b8f2e4 (this PR) Test differencesShow 930 test diffsStage 1
Stage 2
Additionally, 928 doctest diffs were found. These are ignored, as they are noisy. Job group index
Test dashboardRun cargo run --manifest-path src/ci/citool/Cargo.toml -- \
test-dashboard 1b8f2e46e14b08208a53585570edd9206374aae8 --output-dir test-dashboardAnd then open Job duration changes
How to interpret the job duration changes?Job durations can vary a lot, based on the actual runner instance |
rust-timer
commented
Apr 17, 2026
Finished benchmarking commit (1b8f2e4): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis perf run didn't have relevant results for this metric. Max RSS (memory usage)Results (primary 2.1%, secondary -1.3%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (primary 8.7%, secondary 6.0%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeResults (primary 0.1%, secondary 0.1%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Bootstrap: 490.004s -> 504.175s (2.89%) |
This PR tries to address rust-lang/unsafe-code-guidelines#584 (comment). It is part of a bachelor thesis supervised by @JoJoDeveloping and @RalfJung, for more information, see: https://github.com/user-attachments/files/26537277/Project_Description.pdf. This implements the checking for implicit writes for Tree Borrows. It is disabled by default but can be enabled using the `-Zmiri-tree-borrows-implicit-writes` flag. When it is enabled, Miri inserts a write for all mutable borrows on function entry. This enables the optimization implemented here: rust-lang/rust#155207
This PR tries to address rust-lang/unsafe-code-guidelines#584 (comment). It is part of a bachelor thesis supervised by @JoJoDeveloping and @RalfJung, for more information, see: https://github.com/user-attachments/files/26537277/Project_Description.pdf. This implements the checking for implicit writes for Tree Borrows. It is disabled by default but can be enabled using the `-Zmiri-tree-borrows-implicit-writes` flag. When it is enabled, Miri inserts a write for all mutable borrows on function entry. This enables the optimization implemented here: rust-lang#155207
…fns, r=RalfJung add #[rustc_no_writable] to slice::get_unchecked_mut This PR adds the `#[rustc_no_writable]` attribute introduced in rust-lang#155207 to the `slice::get_unchecked_mut` function. Two library functions already received this attribute, as they were known to cause problems with the llvm writable attribute and tree borrows. Since that PR, I ran Miri on the 30'000 most downloaded crates to see what kind of code is now UB under Tree Borrows + implicit writes, using the detection implemented in rust-lang/miri#4947. Adding this attribute to ignore checking for this function reduced the new UB introduced by more than 75%, meaning that instead of 19000 tests in 1700 crates having a difference, now only 3500 in 350 crates show a difference (measurement still running).
…fns, r=RalfJung add #[rustc_no_writable] to slice::get_unchecked_mut This PR adds the `#[rustc_no_writable]` attribute introduced in rust-lang#155207 to the `slice::get_unchecked_mut` function. Two library functions already received this attribute, as they were known to cause problems with the llvm writable attribute and tree borrows. Since that PR, I ran Miri on the 30'000 most downloaded crates to see what kind of code is now UB under Tree Borrows + implicit writes, using the detection implemented in rust-lang/miri#4947. Adding this attribute to ignore checking for this function reduced the new UB introduced by more than 75%, meaning that instead of 19000 tests in 1700 crates having a difference, now only 3500 in 350 crates show a difference (measurement still running).
…fns, r=RalfJung add #[rustc_no_writable] to slice::get_unchecked_mut This PR adds the `#[rustc_no_writable]` attribute introduced in rust-lang#155207 to the `slice::get_unchecked_mut` function. Two library functions already received this attribute, as they were known to cause problems with the llvm writable attribute and tree borrows. Since that PR, I ran Miri on the 30'000 most downloaded crates to see what kind of code is now UB under Tree Borrows + implicit writes, using the detection implemented in rust-lang/miri#4947. Adding this attribute to ignore checking for this function reduced the new UB introduced by more than 75%, meaning that instead of 19000 tests in 1700 crates having a difference, now only 3500 in 350 crates show a difference (measurement still running).
…fns, r=RalfJung add #[rustc_no_writable] to slice::get_unchecked_mut This PR adds the `#[rustc_no_writable]` attribute introduced in rust-lang#155207 to the `slice::get_unchecked_mut` function. Two library functions already received this attribute, as they were known to cause problems with the llvm writable attribute and tree borrows. Since that PR, I ran Miri on the 30'000 most downloaded crates to see what kind of code is now UB under Tree Borrows + implicit writes, using the detection implemented in rust-lang/miri#4947. Adding this attribute to ignore checking for this function reduced the new UB introduced by more than 75%, meaning that instead of 19000 tests in 1700 crates having a difference, now only 3500 in 350 crates show a difference (measurement still running).
…fns, r=RalfJung add #[rustc_no_writable] to slice::get_unchecked_mut This PR adds the `#[rustc_no_writable]` attribute introduced in rust-lang#155207 to the `slice::get_unchecked_mut` function. Two library functions already received this attribute, as they were known to cause problems with the llvm writable attribute and tree borrows. Since that PR, I ran Miri on the 30'000 most downloaded crates to see what kind of code is now UB under Tree Borrows + implicit writes, using the detection implemented in rust-lang/miri#4947. Adding this attribute to ignore checking for this function reduced the new UB introduced by more than 75%, meaning that instead of 19000 tests in 1700 crates having a difference, now only 3500 in 350 crates show a difference (measurement still running).
…lfJung add #[rustc_no_writable] to slice::get_unchecked_mut This PR adds the `#[rustc_no_writable]` attribute introduced in rust-lang/rust#155207 to the `slice::get_unchecked_mut` function. Two library functions already received this attribute, as they were known to cause problems with the llvm writable attribute and tree borrows. Since that PR, I ran Miri on the 30'000 most downloaded crates to see what kind of code is now UB under Tree Borrows + implicit writes, using the detection implemented in rust-lang#4947. Adding this attribute to ignore checking for this function reduced the new UB introduced by more than 75%, meaning that instead of 19000 tests in 1700 crates having a difference, now only 3500 in 350 crates show a difference (measurement still running).
…, r=RalfJung add rustc_no_writable to mem::forget and structs it uses This builds upon rust-lang#155207 and is similar to rust-lang#157202. It adds the `#[rustc_no_writable]` attribute to `mem::forget` and the `MaybeDangling` and `ManuallyDrop`. This makes Miri with Tree Borrows and implicit writes no longer report UB for a test in `derive_more`. As the pattern itself is quite unclean, and I have not seen `mem::forget` to cause trouble before with implicit writes, I'm not sure how much sense it makes to add it to `mem::forget`. The test works unter Tree Borrows, but fails already for Stacked Borrows. Thus I would be happy for some guidance if the attribute makes sense here @RalfJung@JoJoDeveloping.
Rollup merge of #159181 - quiode:mem--forget-implicit-writes, r=RalfJung add rustc_no_writable to mem::forget and structs it uses This builds upon #155207 and is similar to #157202. It adds the `#[rustc_no_writable]` attribute to `mem::forget` and the `MaybeDangling` and `ManuallyDrop`. This makes Miri with Tree Borrows and implicit writes no longer report UB for a test in `derive_more`. As the pattern itself is quite unclean, and I have not seen `mem::forget` to cause trouble before with implicit writes, I'm not sure how much sense it makes to add it to `mem::forget`. The test works unter Tree Borrows, but fails already for Stacked Borrows. Thus I would be happy for some guidance if the attribute makes sense here @RalfJung@JoJoDeveloping.
add rustc_no_writable to mem::forget and structs it uses This builds upon rust-lang/rust#155207 and is similar to rust-lang/rust#157202. It adds the `#[rustc_no_writable]` attribute to `mem::forget` and the `MaybeDangling` and `ManuallyDrop`. This makes Miri with Tree Borrows and implicit writes no longer report UB for a test in `derive_more`. As the pattern itself is quite unclean, and I have not seen `mem::forget` to cause trouble before with implicit writes, I'm not sure how much sense it makes to add it to `mem::forget`. The test works unter Tree Borrows, but fails already for Stacked Borrows. Thus I would be happy for some guidance if the attribute makes sense here @RalfJung@JoJoDeveloping.
View all comments
This PR tries to address rust-lang/unsafe-code-guidelines#584 (comment). It is part of a bachelor thesis supervised by @JoJoDeveloping and @RalfJung, for more information, see: Project_Description.pdf.
If the new
-Zllvm-writableflag is set, the llvm writable attribute is inserted for all mutable borrows. This can be conditionally turned off on a per-function basis using the#[rustc_no_writable]attribute. The new Undefined Behaviour introduced by this can detected by Miri, which is implemented here: rust-lang/miri#4947.Two library functions already received the
#[rustc_no_writable]attribute, as they are known to cause problems under the Tree Borrows aliasing model with implicit writes enabled.