126

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
  • 326,504
  • 69
  • 892
  • 1,159
timthelion
  • 2,452
  • 2
  • 19
  • 29

2 Answers2

162

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
  • 24,420
  • 5
  • 70
  • 79
  • 48
    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
20

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

Govind Parmar
  • 19,325
  • 7
  • 50
  • 80