移动原始实例后,不会反映使用字段可变引用的更改

Ohj*_*won 61 reference move rust

我试图通过从它的实例借用一个可变引用来操纵x结构的字段。Foofoo

如果我尝试在原始实例移动x使用y实例的移动绑定打印字段,它会继续打印未更改的值。foo

下面的简化示例:

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
}
Run Code Online (Sandbox Code Playgroud)

相反,如果我打印移动的绑定y本身,它会打印更改后的值。

println!("{:?}", y); // -> Foo { x: 13 }
Run Code Online (Sandbox Code Playgroud)

或者,如果我在移动之前xfoo.x 之前打印其他内容,它会按预期打印内容。

println!("{}", x); // -> 13
let y = foo;
println!("{}", y.x); // -> 13
Run Code Online (Sandbox Code Playgroud)

这是预期的行为吗?

mca*_*ton 52

这是编译器中的一个已知错误,仅影响 rustc 1.45。rustc 1.44 不受影响,该问题已在 Beta 版上修复,这意味着它将在 rustc 1.46 上修复。

已打开一个问题来跟踪它。

虽然这个问题看起来很关键,但根据oli-obk(rustc的主要贡献者之一)的说法,它不太可能在实际代码中发现,尤其是在const表达式中:

该错误几乎不可能在现实世界的代码上触发。您需要所有进入 bug 的值都是常量值,并且中间不能有任何控制流或函数调用。

版本 1.45.1已发布,其中包含beta 修复程序向后移植等。更高版本1.45.2发布了更多(不相关)修复。

  • 我将在一段时间内将这个答案与 GitHub 问题保持同步。 (9认同)