Auto merge of #51964 - matthewjasper:unused-mut-mir-generation, r=nikomatsakis
[NLL] Fix various unused mut errors Closes #51801 Closes #50897 Closes #51830 Closes #51904 cc #51918 - keeping this one open in case there are any more issues This PR contains multiple changes. List of changes with examples of what they fix: * Change mir generation so that the parameter variable doesn't get a name when a `ref` pattern is used as an argument ```rust fn f(ref y: i32) {} // doesn't trigger lint ``` * Change mir generation so that by-move closure captures don't get first moved into a temporary. ```rust let mut x = 0; // doesn't trigger lint move || { x = 1; }; ``` * Treat generator upvars the same as closure upvars ```rust let mut x = 0; // This mut is now necessary and is not linted against. move || { x = 1; yield; }; ``` r? @nikomatsakis
This commit is contained in:
commit
b51ca20ce5
10 changed files with 212 additions and 48 deletions
|
|
@ -34,38 +34,31 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
|
|||
// ...
|
||||
// let mut _2: ();
|
||||
// let mut _3: [closure@NodeId(22) d:D];
|
||||
// let mut _4: D;
|
||||
// bb0: {
|
||||
// StorageLive(_1);
|
||||
// _1 = D::{{constructor}}(const 0i32,);
|
||||
// StorageLive(_3);
|
||||
// StorageLive(_4);
|
||||
// _4 = move _1;
|
||||
// _3 = [closure@NodeId(22)] { d: move _4 };
|
||||
// drop(_4) -> [return: bb4, unwind: bb3];
|
||||
// _3 = [closure@NodeId(22)] { d: move _1 };
|
||||
// _2 = const foo(move _3) -> [return: bb2, unwind: bb4];
|
||||
// }
|
||||
// bb1: {
|
||||
// resume;
|
||||
// }
|
||||
// bb2: {
|
||||
// drop(_1) -> bb1;
|
||||
// drop(_3) -> [return: bb5, unwind: bb3];
|
||||
// }
|
||||
// bb3: {
|
||||
// drop(_3) -> bb2;
|
||||
// drop(_1) -> bb1;
|
||||
// }
|
||||
// bb4: {
|
||||
// StorageDead(_4);
|
||||
// _2 = const foo(move _3) -> [return: bb5, unwind: bb3];
|
||||
// drop(_3) -> bb3;
|
||||
// }
|
||||
// bb5: {
|
||||
// drop(_3) -> [return: bb6, unwind: bb2];
|
||||
// }
|
||||
// bb6: {
|
||||
// StorageDead(_3);
|
||||
// _0 = ();
|
||||
// drop(_1) -> [return: bb7, unwind: bb1];
|
||||
// drop(_1) -> [return: bb6, unwind: bb1];
|
||||
// }
|
||||
// bb7: {
|
||||
// bb6: {
|
||||
// StorageDead(_1);
|
||||
// return;
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -37,17 +37,13 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 {
|
|||
// ...
|
||||
// let mut _3: ();
|
||||
// let mut _4: [closure@NodeId(22) r:&'19s D];
|
||||
// let mut _5: &'21_1rs D;
|
||||
// bb0: {
|
||||
// StorageLive(_1);
|
||||
// _1 = D::{{constructor}}(const 0i32,);
|
||||
// StorageLive(_2);
|
||||
// _2 = &'21_1rs _1;
|
||||
// StorageLive(_4);
|
||||
// StorageLive(_5);
|
||||
// _5 = _2;
|
||||
// _4 = [closure@NodeId(22)] { r: move _5 };
|
||||
// StorageDead(_5);
|
||||
// _4 = [closure@NodeId(22)] { r: _2 };
|
||||
// _3 = const foo(move _4) -> [return: bb2, unwind: bb3];
|
||||
// }
|
||||
// bb1: {
|
||||
|
|
|
|||
25
src/test/ui/nll/capture-mut-ref.rs
Normal file
25
src/test/ui/nll/capture-mut-ref.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Check that capturing a mutable reference by move and assigning to its
|
||||
// referent doesn't make the unused mut lint think that it is mutable.
|
||||
|
||||
#![feature(nll)]
|
||||
#![deny(unused_mut)]
|
||||
|
||||
fn mutable_upvar() {
|
||||
let mut x = &mut 0;
|
||||
//~^ ERROR
|
||||
move || {
|
||||
*x = 1;
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
16
src/test/ui/nll/capture-mut-ref.stderr
Normal file
16
src/test/ui/nll/capture-mut-ref.stderr
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
error: variable does not need to be mutable
|
||||
--> $DIR/capture-mut-ref.rs:18:9
|
||||
|
|
||||
LL | let mut x = &mut 0;
|
||||
| ----^
|
||||
| |
|
||||
| help: remove this `mut`
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/capture-mut-ref.rs:15:9
|
||||
|
|
||||
LL | #![deny(unused_mut)]
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
64
src/test/ui/nll/extra-unused-mut.rs
Normal file
64
src/test/ui/nll/extra-unused-mut.rs
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// extra unused mut lint tests for #51918
|
||||
|
||||
// run-pass
|
||||
|
||||
#![feature(generators, nll)]
|
||||
#![deny(unused_mut)]
|
||||
|
||||
fn ref_argument(ref _y: i32) {}
|
||||
|
||||
// #51801
|
||||
fn mutable_upvar() {
|
||||
let mut x = 0;
|
||||
move || {
|
||||
x = 1;
|
||||
};
|
||||
}
|
||||
|
||||
// #50897
|
||||
fn generator_mutable_upvar() {
|
||||
let mut x = 0;
|
||||
move || {
|
||||
x = 1;
|
||||
yield;
|
||||
};
|
||||
}
|
||||
|
||||
// #51830
|
||||
fn ref_closure_argument() {
|
||||
let _ = Some(0).as_ref().map(|ref _a| true);
|
||||
}
|
||||
|
||||
struct Expr {
|
||||
attrs: Vec<u32>,
|
||||
}
|
||||
|
||||
// #51904
|
||||
fn parse_dot_or_call_expr_with(mut attrs: Vec<u32>) {
|
||||
let x = Expr { attrs: vec![] };
|
||||
Some(Some(x)).map(|expr|
|
||||
expr.map(|mut expr| {
|
||||
attrs.push(666);
|
||||
expr.attrs = attrs;
|
||||
expr
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
ref_argument(0);
|
||||
mutable_upvar();
|
||||
generator_mutable_upvar();
|
||||
ref_closure_argument();
|
||||
parse_dot_or_call_expr_with(Vec::new());
|
||||
}
|
||||
24
src/test/ui/nll/generator-upvar-mutability.rs
Normal file
24
src/test/ui/nll/generator-upvar-mutability.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Check that generators respect the muatability of their upvars.
|
||||
|
||||
#![feature(generators, nll)]
|
||||
|
||||
fn mutate_upvar() {
|
||||
let x = 0;
|
||||
move || {
|
||||
x = 1;
|
||||
//~^ ERROR
|
||||
yield;
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
9
src/test/ui/nll/generator-upvar-mutability.stderr
Normal file
9
src/test/ui/nll/generator-upvar-mutability.stderr
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
error[E0594]: cannot assign to immutable item `x`
|
||||
--> $DIR/generator-upvar-mutability.rs:18:9
|
||||
|
|
||||
LL | x = 1;
|
||||
| ^^^^^ cannot assign
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0594`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue