-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Allow MIR borrowck to catch unused mutable locals #48605
Conversation
This looks about right. There may be some complications around closures: let mut x = &mut vec![];
// ^^^ not needed
let closure = || {
x.push(22);
};
closure(); Also, we have to disable the other lint, from old AST borrowck |
4c57b73
to
0c547e1
Compare
☔ The latest upstream changes (presumably #48208) made this pull request unmergeable. Please resolve the merge conflicts. |
9833513
to
29347ae
Compare
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 great! My main concern is the tests, left some suggestions below.
@@ -8,6 +8,8 @@ | |||
// option. This file may not be copied, modified, or distributed | |||
// except according to those terms. | |||
|
|||
//compile-flags: -Z borrowck=compare -Z emit-end-regions |
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 don't think that this will necessarily test the way you want it. How about this instead?
// revisions: lexical nll
#![cfg_attr(nll, feature(nll))]
This will run the test twice, once in normal mode and once in nll mode.
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, can we add another test case for nested closures? I see this one:
let mut a = Vec::new();
callback(|| {
a.push(3);
});
but I think I want:
let mut a = Vec::new();
callback(|| {
callback(|| a.push(3)); // nested call
});
});
as well
29347ae
to
a275eda
Compare
@@ -8,6 +8,9 @@ | |||
// option. This file may not be copied, modified, or distributed | |||
// except according to those terms. | |||
|
|||
// revisions: lexical nll | |||
#![cfg_attr(nll, feature(nll))] |
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.
We're getting travis errors. The problem is that we have to update the //~ ERROR
declarations in this file to account for the revisions.
For each line:
foo //~ ERROR bar
we have to change it to
foo //[lexical]~ ERROR bar
//[nll]~^ ERROR bar
8679570
to
49b51c7
Compare
Ok, so I figured out why Travis CI is complaining. Given the following code: fn main() {
let mut a = 3;
} The current implementation sees an assignment to |
49b51c7
to
b221e0b
Compare
Ok, so the latest commit still doesn't fix everything yet. It's quite over-eager in its job and flags too much fn args as being unnecessarily mutable. It also doesn't catch the following case: fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
&mut arg[..] //[lexical]~^ ERROR: variable does not need to be mutable
//[nll]~^ ERROR: variable does not need to be mutable
} ... which tells me that we need additional logic in |
☔ The latest upstream changes (presumably #48770) made this pull request unmergeable. Please resolve the merge conflicts. |
b221e0b
to
403e49a
Compare
We should be able to use the initialization state for this. Presumably we are doing a similar analysis already to report errors in the case that the variable is not Ah, indeed we do, right here: rust/src/librustc_mir/borrow_check/mod.rs Lines 1279 to 1303 in 8c4ff22
|
src/librustc_mir/borrow_check/mod.rs
Outdated
@@ -1547,6 +1614,23 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { | |||
err.emit(); | |||
}, | |||
Reservation(WriteKind::Mutate) | Write(WriteKind::Mutate) => { | |||
match place { |
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 think logic is too simplistic. For example, consider this case:
let mut x = (1, 2);
x.0 = 22;
Here, the mutated place will be a field projection, but we still need to record x
as a "used mut". We want to integrate more with the is_mutable
code, I think -- in particular, maybe it should return the "root reason" that a path was mutable, even on success (right now it does that only on error). Then, if that root reason is a Local, we can add it to the used_mut
set? etc
e697cb7
to
d37b1df
Compare
d37b1df
to
0a1cb9b
Compare
@bors r=nikomatsakis |
📌 Commit 0a1cb9b has been approved by |
⌛ Testing commit 0a1cb9b with merge 4073a87ff295c3262735383970366c4f2d12d6ec... |
💔 Test failed - status-travis |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
1 similar comment
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
@bors retry Assuming the 30-minute timeout is spurious. |
Allow MIR borrowck to catch unused mutable locals Fixes #47279. r? @nikomatsakis
☀️ Test successful - status-appveyor, status-travis |
Fixes #47279.
r? @nikomatsakis