In this code, fp should have been declared as a mutable reference, and the compiler gives you a nice clear error message saying so:
use std::env::args;
use std::fs::File;
use std::io::{stdout, Write};
fn main() {
let mut args = args();
let _ = args.next();
let dest = args.next();
let h1; let h2; let h3;
let fp: &dyn Write = match dest {
Some(path) => { h1 = File::create(path).unwrap(); &h1 },
None => { h2 = stdout(); h3 = h2.lock(); &h3 }
};
writeln!(fp, "hello world").unwrap();
}
⟶
error[E0596]: cannot borrow `*fp` as mutable, as it is behind a `&` reference
--> test.rs:17:14
|
12 | let fp: &dyn Write = match dest {
| -- help: consider changing this to be a mutable reference:
| `&mut dyn std::io::Write`
...
17 | writeln!(fp, "hello world").unwrap();
| ^^ `fp` is a `&` reference, so the data it refers to
| cannot be borrowed as mutable
But you have a BufWriter in between writeln! and the match, you get a different and very confusing error message:
use std::env::args;
use std::fs::File;
use std::io::{stdout, Write, BufWriter};
fn main() {
let mut args = args();
let _ = args.next();
let dest = args.next();
let h1; let h2; let h3;
let fp: &dyn Write = match dest {
Some(path) => { h1 = File::create(path).unwrap(); &h1 },
None => { h2 = stdout(); h3 = h2.lock(); &h3 }
};
let fp = BufWriter::new(fp);
writeln!(fp, "hello world").unwrap();
}
⟶
error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write`
is not satisfied
--> test.rs:17:14
|
17 | let fp = BufWriter::new(fp);
| ^^^^^^^^^^^^^^ the trait `std::io::Write`
| is not implemented for `&dyn std::io::Write`
|
= note: required by `std::io::BufWriter::<W>::new`
How can it possibly be that "the trait std::io::Write is not implemented for &dyn std::io::Write" ?! Well, in fact, it's the exact same problem as the first sample code, and the error message is literally true. &dyn std::io::Write doesn't implement std::io::Write, but &mut dyn std::io::Write does.
Could the compiler perhaps print an additional note when &T doesn't satisfy a trait bound, but &mut T would have, explaining that this might be the problem? Or vice versa, of course.
In this code,
fpshould have been declared as a mutable reference, and the compiler gives you a nice clear error message saying so:⟶
But you have a BufWriter in between
writeln!and the match, you get a different and very confusing error message:⟶
How can it possibly be that "the trait
std::io::Writeis not implemented for&dyn std::io::Write" ?! Well, in fact, it's the exact same problem as the first sample code, and the error message is literally true.&dyn std::io::Writedoesn't implementstd::io::Write, but&mut dyn std::io::Writedoes.Could the compiler perhaps print an additional note when
&Tdoesn't satisfy a trait bound, but&mut Twould have, explaining that this might be the problem? Or vice versa, of course.