Skip to content

large_assignments: Unactionable diagnostics with -Zinline-mir #121672

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

Open
Enselic opened this issue Feb 27, 2024 · 5 comments
Open

large_assignments: Unactionable diagnostics with -Zinline-mir #121672

Enselic opened this issue Feb 27, 2024 · 5 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. A-mir-opt-inlining Area: MIR inlining C-bug Category: This is a bug. D-confusing Diagnostics: Confusing error or lint that should be reworked. L-large_assignments Lint: large_assignments requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Enselic
Copy link
Member

Enselic commented Feb 27, 2024

Tracking issue #83518.

Doing cargo build --release will activate -Zinline-mir under the hood (through -Copt-level=3). But it makes large_assignments diagnostics unhelpful, because it can make diagnostics point to library code that the user can't change.

How to reproduce

src/main.rs

#![feature(large_assignments)]
#![deny(large_assignments)]
#![move_size_limit = "1000"]

pub fn main() {
    let data = [10u8; 9999];
    let cell = std::cell::UnsafeCell::new(data);
    std::hint::black_box(cell);
}
# One of:
cargo +nightly build --release
cargo +nightly rustc -- -Zmir-opt-level=1 -Zinline-mir

Actual

   Compiling minimal v0.1.0 (/home/martin/src/bin)
error: moving 9999 bytes
    --> /home/martin/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/cell.rs:2054:9
     |
2054 |         UnsafeCell { value }
     |         ^^^^^^^^^^^^^^^^^^^^ value moved from here
     |

Expected

   Compiling minimal v0.1.0 (/home/martin/src/bin)
error: moving 9999 bytes
 --> src/main.rs:7:43
  |
7 |     let cell = std::cell::UnsafeCell::new(data);
  |                                           ^^^^ value moved from here
  |

Remarks

The expected diagnostics is given with these commands. Note how -Zinline-mir is deactivated in both cases:

# One of:
cargo +nightly build
cargo +nightly rustc -- -Zmir-opt-level=1

The above test case is ui-testified here.

CC E-mentor @oli-obk who maybe have an idea on how to fix this? (I currently don't.)

@Enselic Enselic added A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. requires-nightly This issue requires a nightly compiler in some way. D-confusing Diagnostics: Confusing error or lint that should be reworked. labels Feb 27, 2024
@Enselic Enselic added the A-mir-opt-inlining Area: MIR inlining label Feb 27, 2024
@oli-obk
Copy link
Contributor

oli-obk commented Mar 1, 2024

heh. we used to have a marker in spans that signaled that something got inlined. That was a bit funky though, so we removed it (#111950).

You can check the source scopes nowadays to see if https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/struct.SourceScopeData.html#structfield.inlined has been set. If it is set, don't emit the lint on that span, but instead emit it on the span within that option

@jieyouxu jieyouxu added the L-large_assignments Lint: large_assignments label May 13, 2024
@jogru0
Copy link
Contributor

jogru0 commented Apr 8, 2025

@rustbot claim

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Apr 9, 2025
report call site of inlined scopes for large assignment lints

Addressed issue: rust-lang#121672
Tracking issue: rust-lang#83518

r? `@oli-obk`

I tried to follow your comment about what to do [here](rust-lang#121672 (comment)). However, I'm totally unfamiliar with the code so far (this is my first contribution touching compiler code), so I apologize in advance if I did something stupid 😅

In particular, I'm not sure I use the _correct_ source scope to look for inline data, as there is a whole `IndexVec` of them. My changes definitely did something, as can be seen by the added ui test. However, the result is not as anticipated in the issue:
```
LL |     let cell = std::cell::UnsafeCell::new(data);
   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ value moved from here
```
instead of
```
LL |     let cell = std::cell::UnsafeCell::new(data);
   |                                           ^^^^ value moved from here
```
raising my suspicion that maybe I got the wrong source scope.
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Apr 10, 2025
Rollup merge of rust-lang#139551 - jogru0:121672, r=oli-obk

report call site of inlined scopes for large assignment lints

Addressed issue: rust-lang#121672
Tracking issue: rust-lang#83518

r? `@oli-obk`

I tried to follow your comment about what to do [here](rust-lang#121672 (comment)). However, I'm totally unfamiliar with the code so far (this is my first contribution touching compiler code), so I apologize in advance if I did something stupid 😅

In particular, I'm not sure I use the _correct_ source scope to look for inline data, as there is a whole `IndexVec` of them. My changes definitely did something, as can be seen by the added ui test. However, the result is not as anticipated in the issue:
```
LL |     let cell = std::cell::UnsafeCell::new(data);
   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ value moved from here
```
instead of
```
LL |     let cell = std::cell::UnsafeCell::new(data);
   |                                           ^^^^ value moved from here
```
raising my suspicion that maybe I got the wrong source scope.
github-actions bot pushed a commit to rust-lang/rustc-dev-guide that referenced this issue Apr 10, 2025
report call site of inlined scopes for large assignment lints

Addressed issue: #121672
Tracking issue: #83518

r? `@oli-obk`

I tried to follow your comment about what to do [here](rust-lang/rust#121672 (comment)). However, I'm totally unfamiliar with the code so far (this is my first contribution touching compiler code), so I apologize in advance if I did something stupid 😅

In particular, I'm not sure I use the _correct_ source scope to look for inline data, as there is a whole `IndexVec` of them. My changes definitely did something, as can be seen by the added ui test. However, the result is not as anticipated in the issue:
```
LL |     let cell = std::cell::UnsafeCell::new(data);
   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ value moved from here
```
instead of
```
LL |     let cell = std::cell::UnsafeCell::new(data);
   |                                           ^^^^ value moved from here
```
raising my suspicion that maybe I got the wrong source scope.
@jogru0
Copy link
Contributor

jogru0 commented Apr 10, 2025

#139551 made progress on this issue, it now shows

LL |     let cell = std::cell::UnsafeCell::new(data);
   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ value moved from here

but still not the expected

LL |     let cell = std::cell::UnsafeCell::new(data);
   |                                           ^^^^ value moved from here

@oli-obk You mentioned here that we might want to adjust something so we don't loose the argument span when inlining happens. If that's something that might make sense for me to look into and you could give me some directions/mentoring for that, I'm happy to try it. However, that's certainly not something I know how to do on my own, so if this topic would be too involved for that, I can also just unassign this issue from me and let someone more experienced take over.

@oli-obk
Copy link
Contributor

oli-obk commented Apr 10, 2025

In https://github.com/rust-lang/rust/blob/master/compiler/rustc_mir_transform/src/inline.rs#L1081 we are ignoring the a.span and not passing it to create_temp_if_necessary. I do not believe this is the cause of the issue here, but it is related, as it would be the same issue if the call would not just use a variable, but something like UnsafeCell::new(foo.data), where it would first create a let _tmp15 = foo.data;, but with the call site span instead of the foo.data span.

You could try this on its own to get your hands dirty with the mir-opt test suite, which any changes here will have to touch. It should be as simple as running x t mir-opt --bless to update that test suite, and should likely not require manual changes.

To fix the actual issue you were encountering we'll have to go to where the args from make_call_args are processed. We'd first need to return the Spans somehow, too, and I'm not sure what the best approach for this is. Most likely just turning the Box<[Local]> into a Box<[(Local, Span)]>

But looking at that now, I don't think this is actually resolvable here. The spans and locals should all already be correct, but the later mir-optimizations remove those locals without adjusting debug information, so the local with the right span is erased and only the locals that were inlined are left.

I do not know where this happens, but if you want to do some exploration, you can use -Zdump-mir=all on your test (with all the inlining flags and other opt flags that cause the issues with diagnostics), and go through the optimizations after the inlining pass and see if something obvious shows up

@jogru0
Copy link
Contributor

jogru0 commented Apr 19, 2025

Thanks for the detailed explanation, really appreciated it. I tried to look into it a bit, but unfortunately, I think this is a bit too advanced for me. So I'll unassign myself for now so someone else can take over who is able to work on this more effectively.

@rustbot release-assignment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. A-mir-opt-inlining Area: MIR inlining C-bug Category: This is a bug. D-confusing Diagnostics: Confusing error or lint that should be reworked. L-large_assignments Lint: large_assignments requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants