Changes using mutable reference of a field are not reflected after move of the original instance

I was trying to manipulate the field x of the struct Foo by borrowing a mutable reference from its instance foo.

If I try to print the field x using the moved binding y of the instance foo after the move of the original instance, it keeps printing the value that haven't changed.

Simplified example below:

struct Foo {
    x: i32,
}

fn main() {
    let mut foo = Foo { x: 42 };
    let x = &mut foo.x;
    *x = 13;
    let y = foo;
    println!("{}", y.x); // -> 42; expected result: 13
}

Instead, if I print the moved binding y itself, it prints the changed value.

println!("{:?}", y); // -> Foo { x: 13 }

Or, if I print something else like x or foo.x before the move, it prints the thing as expected.

println!("{}", x); // -> 13
let y = foo;
println!("{}", y.x); // -> 13

Is this an intended behavior?


This is a known bug in the compiler which only affects rustc 1.45. rustc 1.44 is not affected and the issue has already been fixed on Beta which means it will be fixed on rustc 1.46.

An issue has been opened to track it.

While this issue seem critical, it is very unlikely to be found in real code according to oli-obk, one of the main contributor to rustc, and in particular on const expressions:

The bug is almost impossible to trigger on real world code. You need all values that are going into the bug to be constant values and there can't be any control flow or function calls in between.

Version 1.45.1 has been released and contains a backport of the fix from beta, among other things. Later version 1.45.2 was released with more (unrelated) fixes.