The first time I found that Rust compiler can be stupid
It’s not me, it’s not me, finally!
I got an error, which has a solution which is verbose and dumb. And I believe it’s a compiler’s fault.
Look at the structure:
struct ThreadCommands {
control_tx: [Option<Sender<ControlCommand>>;8],
draw_rx: [Option<Receiver<DrawCommand>>;8]
}
When I try to initialize it:
let mut control = ThreadCommands {
control_tx: [None;8],
draw_rx: [None;8]
};
It all falls apart:
the trait `std::marker::Copy` is not implemented for `std::option::Option<std::sync::mpsc::Sender<ControlCommand>>`
There is a big reason why there is no Copy
trait for Sender
. It’s explicitly forbidden, as mpsc
channel allows only one Sender
.
But array initialization is requires Copy
. This is stupid thing number one. Can’t we just pretend it’s in the code N times without writing it explicitly?
Second: Even if Some<Sender>
must not be copied, the None
should be trivially copied. I do not agree here with compiler and it forces me to write this:
ThreadCommands {
control_tx: [None,None,None,None, None,None,None,None],
draw_rx: [None,None,None,None, None,None,None,None]
}
Which is less than bright for a compiler.
Forum was nice enough to point me to the Default
trait.
#[derive(Default)]
struct ThreadCommands {
control_tx: [Option<Sender<ControlCommand>>;8],
draw_rx: [Option<Receiver<DrawCommand>>;8]
}...let mut control:ThreadCommands = Default::default();
It worked. But I still disappointed, as Rust wasn’t that smart to see through types.
UPD: No, it’s not stupid, it’s old.
steffahn from Rust forum was very helpful and provided with few workarounds, and, more importantly, s/he said that nightly Rust now can do copy for None
, even Some<Type>
is copy-forbidden. It’s just wasn’t stabilized yet.