-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
Mir Borrowck: Parity with Ast for E0384 (Cannot assign twice to immutable) #46022
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
Mir Borrowck: Parity with Ast for E0384 (Cannot assign twice to immutable) #46022
Conversation
|
r? @pnkfelix |
|
I don't think loop {
let x = String::new();
drop(x);
}You probably want to create a separate dataflow for "propagating initializations" (basically the opposite of the |
838def0 to
8347043
Compare
|
Nice PR. However, I think we are getting quite a bit of separate move-in implementation sprawl - there are already 2, and now we're getting another one. I think we can merge them - that would imply changing the For that, you'll need to have some sort of flag on the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only initializes the destination on the non-panic-path, so you'll probably want some label on the Init you create to indicate that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks wrong - you don't want to "christmas tree" every initialization for this lvalue, you want just the initialization for the call.
e.g. in a code like
let x;
if true {
x = 2;
} else {
x = get();
x = 3;
}You want to highlight just the get, not the other assignment to x.
If you want to do this correctly, you could just do
let call_loc = Location { // why doesn't MIR have a terminator_loc method?
block: call_bb, // feel free to add one
statement_index: self.mir[call_bb].statements.len()
};
for init_index in &init_loc_map[call_loc] {
zero_to_one(sets.gen_set.words_mut(), *init_index);
}|
r=me with the initialization sprawl bought under control. |
|
@matthewjasper the title of this PR still says "[WIP]", but it looks like your review is close to finished. Please make sure to remove that if you feel this PR should be merged. |
|
How are you doing with this PR? Could you address the nits so we can move forward? |
8347043 to
d895346
Compare
|
Comments addressed. |
src/librustc_mir/borrow_check.rs
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: opening brace for ifs is in the same line as the if:
if flow_state.ever_inits.curr_state.contains(ii) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: no newline at end of file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to use a in_out.add rather than a zero_to_one here - I'm not sure of a good reason for this to always be for an uninitialized variable (it could be that right now we only assign to temporaries, but that might not remain so in the future).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, even if it doesn't matter for borrow-check (because you can't have assignments in the panic path) you should not mark call destinations as uninitialized if the call unwinds (i.e. if the init loc map entry is a NonPanicPathOnly).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean as initialized?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea my bad
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want to have arguments assigned before the first statement, to avoid edge cases such as my wrong.
|
This is cool. r=me modulo nits |
356316b to
88776fd
Compare
|
Nits addressed |
* Used for new dataflow to track if a variable has every been initialized * Used for other dataflows that need to be updated for initializations
Matches current ast-borrowck behavior.
88776fd to
d64a318
Compare
|
@bors r+ |
|
📌 Commit d64a318 has been approved by |
…rror, r=arielb1 Mir Borrowck: Parity with Ast for E0384 (Cannot assign twice to immutable) - Closes rust-lang#45199 - Don't allow assigning to dropped immutable variables - Show the "first assignment" note on the first assignment that can actually come before the second assignment. - Make "first assignment" notes point to function parameters if needed. - Don't show a "first assignment" note if the first and second assignment have the same span (in a loop). This matches ast borrowck for now, but maybe this we should add "in previous loop iteration" as with some other borrowck errors. (Commit 2) - Use revisions to check mir borrowck for the existing tests for this error. (Commit 3) ~~Still working on a less ad-hoc way to get 'first assignment' notes to show on the correct assignment. Also need to check mutating function arguments.~~ Now using a new dataflow pass.
…elb1 Mir Borrowck: Parity with Ast for E0384 (Cannot assign twice to immutable) - Closes #45199 - Don't allow assigning to dropped immutable variables - Show the "first assignment" note on the first assignment that can actually come before the second assignment. - Make "first assignment" notes point to function parameters if needed. - Don't show a "first assignment" note if the first and second assignment have the same span (in a loop). This matches ast borrowck for now, but maybe this we should add "in previous loop iteration" as with some other borrowck errors. (Commit 2) - Use revisions to check mir borrowck for the existing tests for this error. (Commit 3) ~~Still working on a less ad-hoc way to get 'first assignment' notes to show on the correct assignment. Also need to check mutating function arguments.~~ Now using a new dataflow pass.
|
☀️ Test successful - status-appveyor, status-travis |
Still working on a less ad-hoc way to get 'first assignment' notes to show on the correct assignment. Also need to check mutating function arguments.Now using a new dataflow pass.