unwrap()は変数の所有権を移動させることがある

所有権をわかったつもりだったが、わかってなかった。*1

Rust By ExapmpleのPipesの章で、以下のコメントにあるstdinがdropされると記述が信じられなかった。

match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) {
    Err(why) => panic!("couldn't write to wc stdin: {}", why),
    Ok(_) => println!("sent pangram to wc"),
}

// Because `stdin` does not live after the above calls, it is `drop`ed,
// and the pipe is closed.
//
// This is very important, otherwise `wc` wouldn't start processing the
// input we just sent.

drop()されていない筈だと、Rustでビルドすると確かにビルドエラーになる。コンパイラのエラーメッセージが賢くて、馬鹿にも理解できるように教えてくれた。

Copyトレイトが実装されていないことで unrap()を呼ぶと所有権が移動してしまい、dropしていたのだ。

928 |     pub const fn unwrap(self) -> T {
    |                         ^^^^
    = note: move occurs because `process.stdin` has type `Option<ChildStdin>`, which does not implement the `Copy` trait
help: you could `clone` the value and consume it, if the `ChildStdin: Clone` trait bound could be satisfied
    |
27  |     match process.stdin.clone().unwrap().write_all(PANGRAM.as_bytes()) {
    |                        ++++++++

*1:「完全に理解した」ですね。