Rust: Value assigned is never read

Created on 19 Mar 2018  路  14Comments  路  Source: rust-lang/rust

I have the following simple code:

fn main() {
    let mut foo = String::new();
    foo = "Hi!".to_string();

    println!("{}", foo);
}

The compiler gives me the following warning:

warning: value assigned to `foo` is never read
 --> src\main.rs:2:6
  |
2 |     let mut foo = String::new();
  |         ^^^^^^^
  |
  = note: #[warn(unused_assignments)] on by default

This warning seems to be wrong to me. The assignment foo has been used in the println! macro. So I should not get this error. When I remove the mutable assignment as follows, I get no warning as expected:

fn main() {
    let foo = "Hi!".to_string();
    println!("{}", foo);
}

I am using rustc 1.24.1 (d3ae9a9e0 2018-02-27) on Windows 7.

A-lint A-suggestion-diagnostics C-enhancement T-compiler

Most helpful comment

(I am working on this)

All 14 comments

Hi, I think what it means is that the result of the assignment of "String::new()" is never used, since it is overwritten by "Hi!".to_string(); afterwards.

note that
````rust
fn main() {
let foo;
foo = "Hi!".to_string();

println!("{}", foo);

}
````
doesn't trigger a warning.

Hi, the warning underlines the the part mut foo. So it is telling me that I am not using the left side of the assignment:

2 |     let mut foo = String::new();
  |         ^^^^^^^

Yeah, I agree that's a bit confusing.

Tagging with A-diagnostics due to the mut issue; @matthiaskrgr is correct that fundamentally, this warning is correct.

This is #33536 which was incorrectly closed.

Hello,
Two things in the this and a point from the closed ticket:

  • A message should point out the connecting value to the binding in question:

    • warning: valueString::new()assigned to bindingfoois never read

  • it would be nice to let the developer know that a mut was not needed from analysis

The tuple in the indirect link to the other ticket would not need a pretty print to know how to address the problem with the above advice with both lhs and rhs warnings. Like:

  |
2 |     let (mut a, b) = tup;
  |             ^^^     ^^^
  |

Thank you. Good day.

(I am working on this)

it would be nice to let the developer know that a mut was not needed from analysis

Note that upon removing the unused initializer

fn main() {
    let mut foo;
    foo = "Hi!".to_string();

    println!("{}", foo);
}

one does indeed get another warning that

warning: variable does not need to be mutable
 --> src/main.rs:2:6
  |
2 |     let mut foo;
  |         ---^^^^
  |         |
  |         help: remove this `mut`
  |
  = note: #[warn(unused_mut)] on by default

I assume in the general case getting both at once could be hard or false-positive-y, so the two-step is probably fine for this.

Hello,
I agree with @scottmcm about the benefits of the layered approach staying as implemented.

What @zackmdavis has presented in the merge looks clean and useful. Only one nitpick:

  • The tuple test marks the whole value. That can confuse the developer into thinking x = (3, 4) instead of just 3. Can you either expose that value (in this case 3) in the warning message itself or limit the how much of RHS is marked?
    I am not sure how valid it would always be with other structured literals, but it is a clear win here. Thank you. Good day.

Current output:

warning: value assigned to `foo` is never read
 --> src/main.rs:2:10
  |
2 |     let mut foo = String::new();
  |             ^^^
  |
  = note: #[warn(unused_assignments)] on by default
  = help: maybe it is overwritten before being read?

That help should have a span pointing to the reassignment of foo.

Seems wrong. Unused warning should not show up here?

let mut x: u8;
x=6;
x=7;
println!("The value of x is: {}", x);

Output:

warning: value assigned to `x` is never read
 --> src/main.rs:3:5
  |
3 |     x=6;
  |     ^
  |
  = note: `#[warn(unused_assignments)]` on by default
  = help: maybe it is overwritten before being read?

No, the 6 written on that line is never read (it is overwritten on the next line, by setting to 7). I agree with @estebank that it'd be good to point out where the write occurs, though.

Hello,
Two things in the this and a point from the closed ticket:

  • A message should point out the connecting value to the binding in question:

    • warning: valueString::new()assigned to bindingfoois never read
  • it would be nice to let the developer know that a mut was not needed from analysis

The tuple in the indirect link to the other ticket would not need a pretty print to know how to address the problem with the above advice with both lhs and rhs warnings. Like:

  |
2 |     let (mut a, b) = tup;
  |             ^^^     ^^^
  |

Thank you. Good day.
retry this
let (mut _x, mut _y) = (1, 2); _x = 4; println!("{}-{}", _x, _y);

let (mut _x, mut _y) = (1, 2); _x = 4; println!("{}-{}", _x, _y);
or

let (mut x, mut y) = (1, 2); x = x + 1; y = y + 2; println!("{}-{}", x, y);

Was this page helpful?
0 / 5 - 0 ratings