Closed
Description
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.