135

I saw this code in the wild:

fields.sort_by_key(|&(_, ref field)| field.tags().into_iter().min().unwrap());
let fields = fields;

What does the let fields = fields; line do? Why is it there?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
timthelion
  • 2,636
  • 2
  • 21
  • 30

2 Answers2

172

It makes fields immutable again.

fields was previously defined as mutable (let mut fields = …;), to be used with sort_by_key which sorts in-place and requires the target to be mutable. The author has chosen here to explicitly prevent further mutability.

"Downgrading" a mutable binding to immutable is quite common in Rust.

Another common way to do this is to use a block expression:

let fields = {
    let mut fields = …;
    fields.sort_by_key(…);
    fields
};
mcarton
  • 27,633
  • 5
  • 85
  • 95
  • 51
    Or "upgrading", depending upon your perspective. – Synesso Feb 09 '19 at 03:06
  • 10
    IMO your another way to write that is the way to go: the mutable variable is scoped the time we need to use it, and then it is moved. It is better semantically. – Boiethios Feb 13 '19 at 08:48
  • @DarthBoiethios Does one or the other changes anything to compiled code? Like adding an additional, useless instruction? Or enabling more aggressive optimisations by the compiler based on immutability assumptions? – iago-lito Feb 27 '19 at 19:22
  • 1
    @iago-lito Honestly, I'm not sure, but my uneducated guess is that is does not change anything. – Boiethios Feb 27 '19 at 19:47
  • 1
    @iago-lito [Right now it actually does!](https://github.com/rust-lang/rust/issues/58622) However this is considered a bug and is likely to be fixed at some point. – mcarton Feb 27 '19 at 20:13
  • Oh, and a quite recent bug it seems. Cristal clear. Thanks :) – iago-lito Feb 27 '19 at 20:30
  • 1
    @iago-lito [A recent comment on the issue](https://github.com/rust-lang/rust/issues/58622#issuecomment-1180324150) suggests that nowadays both examples generate the same code. – mcarton Oct 02 '22 at 20:34
20

The statement let var = var; makes var immutable and bound to its current value. fields was declared as mut earlier.

Govind Parmar
  • 20,656
  • 7
  • 53
  • 85