Почему компиляция не сбой, когда назначен член перемещенного значения?

Я работаю над примерами в Rust by Example.

fn main() {
    let mut point: Point = Point { x: 0.3, y: 0.4 };
    println!("point coordinates: ({}, {})", point.x, point.y);

    let rectangle = Rectangle {
        p1: Point { x: 1.0, y: 1.0 },
        p2: point,
    };

    point.x = 0.5;     // Why does the compiler not break here?
    println!(" x is {}", point.x); // breaks here

    println!("rectangle is {:?} ", rectangle);
}

Я получаю эту ошибку (Rust 1.7):

использование перемещенного значения: point.x
println! ( "x is {}", point.x);

Теперь я понимаю, что я дал point объекту Rectangle, и именно поэтому я больше не могу его получить, но , почему компиляция завершилась неудачей в println!, а не назначением предыдущей линия

Ответ 1

Что действительно происходит

fn main() {
    let mut point: Point = Point { x: 0.3, y: 0.4 };
    println!("point coordinates: ({}, {})", point.x, point.y);

    drop(point);

    {
        let mut point: Point;
        point.x = 0.5;
    }

    println!(" x is {}", point.x);
}

Оказывается, это хорошо известная проблема.

https://github.com/rust-lang/rust/issues/21232

Ответ 2

Проблема заключается в том, что компилятор допускает частичную повторную инициализацию структуры, но после этого вся структура становится непригодной. Это происходит, даже если структура содержит только одно поле, и даже если вы только пытаетесь прочитать поле, которое вы просто повторно инициализировали.

struct Test { f: u32, }

fn main() {
    let mut t = Test { f: 0, };
    let t1 = t;
    t.f = 1;
    println!("{}", t.f);
}

Это обсуждается в https://github.com/rust-lang/rust/issues/21232