1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
|
//@ edition:2018
// Exercise the unused_mut attribute in some positive and negative cases
#![warn(unused_mut)]
async fn baz_async(
mut a: i32,
//~^ WARN: variable does not need to be mutable
#[allow(unused_mut)] mut b: i32,
) {}
fn baz(
mut a: i32,
//~^ WARN: variable does not need to be mutable
#[allow(unused_mut)] mut b: i32,
#[allow(unused_mut)] (mut c, d): (i32, i32)
) {}
struct RefStruct {}
impl RefStruct {
async fn baz_async(
mut a: i32,
//~^ WARN: variable does not need to be mutable
#[allow(unused_mut)] mut b: i32,
) {}
fn baz(
&self,
mut a: i32,
//~^ WARN: variable does not need to be mutable
#[allow(unused_mut)] mut b: i32,
#[allow(unused_mut)] (mut c, d): (i32, i32)
) {}
}
trait RefTrait {
fn baz(
&self,
mut a: i32,
//~^ WARN: variable does not need to be mutable
#[allow(unused_mut)] mut b: i32,
#[allow(unused_mut)] (mut c, d): (i32, i32)
) {}
}
impl RefTrait for () {
fn baz(
&self,
mut a: i32,
//~^ WARN: variable does not need to be mutable
#[allow(unused_mut)] mut b: i32,
#[allow(unused_mut)] (mut c, d): (i32, i32)
) {}
}
fn main() {
let _ = async move |
mut a: i32,
//~^ WARN: variable does not need to be mutable
#[allow(unused_mut)] mut b: i32,
| {};
let _ = |
mut a: i32,
//~^ WARN: variable does not need to be mutable
#[allow(unused_mut)] mut b: i32,
#[allow(unused_mut)] (mut c, d): (i32, i32)
| {};
// negative cases
let mut a = 3; //~ WARN: variable does not need to be mutable
let mut a = 2; //~ WARN: variable does not need to be mutable
let mut b = 3; //~ WARN: variable does not need to be mutable
let mut a = vec![3]; //~ WARN: variable does not need to be mutable
let (mut a, b) = (1, 2); //~ WARN: variable does not need to be mutable
let mut a; //~ WARN: variable does not need to be mutable
a = 3;
let mut b; //~ WARN: variable does not need to be mutable
if true {
b = 3;
} else {
b = 4;
}
match 30 {
mut x => {} //~ WARN: variable does not need to be mutable
}
match (30, 2) {
// FIXME: Here's a false positive,
// shouldn't be removed `mut` not to be bound with a different way.
(mut x, 1) | //~ WARN: variable does not need to be mutable
(mut x, 2) |
(mut x, 3) => {
}
_ => {}
}
let x = |mut y: isize| 10; //~ WARN: variable does not need to be mutable
fn what(mut foo: isize) {} //~ WARN: variable does not need to be mutable
let mut a = &mut 5; //~ WARN: variable does not need to be mutable
*a = 4;
let mut a = 5;
let mut b = (&mut a,); //~ WARN: variable does not need to be mutable
*b.0 = 4;
let mut x = &mut 1; //~ WARN: variable does not need to be mutable
let mut f = || {
*x += 1;
};
f();
fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
&mut arg[..] //~^ WARN: variable does not need to be mutable
}
let mut v : &mut Vec<()> = &mut vec![]; //~ WARN: variable does not need to be mutable
v.push(());
// positive cases
let mut a = 2;
a = 3;
let mut a = Vec::new();
a.push(3);
let mut a = Vec::new();
callback(|| {
a.push(3);
});
let mut a = Vec::new();
callback(|| {
callback(|| {
a.push(3);
});
});
let (mut a, b) = (1, 2);
a = 34;
match 30 {
mut x => {
x = 21;
}
}
match (30, 2) {
(mut x, 1) |
(mut x, 2) |
(mut x, 3) => {
x = 21
}
_ => {}
}
// Attribute should be respected on match arms
match 0 {
#[allow(unused_mut)]
mut x => {
let mut y = 1;
},
}
let x = |mut y: isize| y = 32;
fn nothing(mut foo: isize) { foo = 37; }
// leading underscore should avoid the warning, just like the
// unused variable lint.
let mut _allowed = 1;
let mut raw_address_of_mut = 1; // OK
let mut_ptr = &raw mut raw_address_of_mut;
let mut raw_address_of_const = 1; //~ WARN: variable does not need to be mutable
let const_ptr = &raw const raw_address_of_const;
}
fn callback<F>(f: F) where F: FnOnce() {}
// make sure the lint attribute can be turned off
#[allow(unused_mut)]
fn foo(mut a: isize) {
let mut a = 3;
let mut b = vec![2];
}
// make sure the lint attribute can be turned off on let statements
#[deny(unused_mut)]
fn bar() {
#[allow(unused_mut)]
let mut a = 3;
let mut b = vec![2]; //~ ERROR: variable does not need to be mutable
}
struct Arg(i32);
// Regression test for https://github.com/rust-lang/rust/issues/110849
fn write_through_reference(mut arg: &mut Arg) {
//~^ WARN: variable does not need to be mutable
arg.0 = 1
}
|