1
Fork 0

check for write macro and write_fmt with err msg

added ui test
blessed stderrs
fixed typo
reblessed
This commit is contained in:
James Dietz 2023-03-14 18:01:14 -04:00
parent 2036fdd24f
commit ff88787ff0
4 changed files with 125 additions and 13 deletions

View file

@ -245,6 +245,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None
}
fn suggest_missing_writer(
&self,
rcvr_ty: Ty<'tcx>,
args: (&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>]),
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
let (ty_str, _ty_file) = self.tcx.short_ty_string(rcvr_ty);
let mut err =
struct_span_err!(self.tcx.sess, args.0.span, E0599, "cannot write into `{}`", ty_str);
err.span_note(
args.0.span,
"must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method",
);
if let ExprKind::Lit(_) = args.0.kind {
err.span_help(
args.0.span.shrink_to_lo(),
"a writer is needed before this format string",
);
};
err
}
pub fn report_no_match_method_error(
&self,
mut span: Span,
@ -323,7 +345,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
let mut err = struct_span_err!(
let is_write = sugg_span.ctxt().outer_expn_data().macro_def_id.map_or(false, |def_id| {
tcx.is_diagnostic_item(sym::write_macro, def_id)
|| tcx.is_diagnostic_item(sym::writeln_macro, def_id)
}) && item_name.name == Symbol::intern("write_fmt");
let mut err = if is_write
&& let Some(args) = args
{
self.suggest_missing_writer(rcvr_ty, args)
} else {
struct_span_err!(
tcx.sess,
span,
E0599,
@ -332,7 +363,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
item_name,
rcvr_ty.prefix_string(self.tcx),
ty_str_reported,
);
)
};
if tcx.sess.source_map().is_multiline(sugg_span) {
err.span_label(sugg_span.with_hi(span.lo()), "");
}

View file

@ -0,0 +1,17 @@
// Check error for missing writer in writeln! and write! macro
fn main() {
let x = 1;
let y = 2;
write!("{}_{}", x, y);
//~^ ERROR format argument must be a string literal
//~| HELP you might be missing a string literal to format with
//~| ERROR cannot write into `&'static str`
//~| NOTE must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method
//~| HELP a writer is needed before this format string
writeln!("{}_{}", x, y);
//~^ ERROR format argument must be a string literal
//~| HELP you might be missing a string literal to format with
//~| ERROR cannot write into `&'static str`
//~| NOTE must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method
//~| HELP a writer is needed before this format string
}

View file

@ -0,0 +1,59 @@
error: format argument must be a string literal
--> $DIR/missing-writer.rs:5:21
|
LL | write!("{}_{}", x, y);
| ^
|
help: you might be missing a string literal to format with
|
LL | write!("{}_{}", "{} {}", x, y);
| ++++++++
error: format argument must be a string literal
--> $DIR/missing-writer.rs:11:23
|
LL | writeln!("{}_{}", x, y);
| ^
|
help: you might be missing a string literal to format with
|
LL | writeln!("{}_{}", "{} {}", x, y);
| ++++++++
error[E0599]: cannot write into `&'static str`
--> $DIR/missing-writer.rs:5:12
|
LL | write!("{}_{}", x, y);
| -------^^^^^^^------- method not found in `&str`
|
note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method
--> $DIR/missing-writer.rs:5:12
|
LL | write!("{}_{}", x, y);
| ^^^^^^^
help: a writer is needed before this format string
--> $DIR/missing-writer.rs:5:12
|
LL | write!("{}_{}", x, y);
| ^
error[E0599]: cannot write into `&'static str`
--> $DIR/missing-writer.rs:11:14
|
LL | writeln!("{}_{}", x, y);
| ---------^^^^^^^------- method not found in `&str`
|
note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method
--> $DIR/missing-writer.rs:11:14
|
LL | writeln!("{}_{}", x, y);
| ^^^^^^^
help: a writer is needed before this format string
--> $DIR/missing-writer.rs:11:14
|
LL | writeln!("{}_{}", x, y);
| ^
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0599`.

View file

@ -21,18 +21,22 @@ note: required by a bound in `BufWriter`
--> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
error[E0599]: the method `write_fmt` exists for struct `BufWriter<&dyn Write>`, but its trait bounds were not satisfied
--> $DIR/mut-borrow-needed-by-trait.rs:21:5
--> $DIR/mut-borrow-needed-by-trait.rs:21:14
|
LL | writeln!(fp, "hello world").unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `BufWriter<&dyn Write>` due to unsatisfied trait bounds
| ---------^^---------------- method cannot be called on `BufWriter<&dyn Write>` due to unsatisfied trait bounds
--> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
|
= note: doesn't satisfy `BufWriter<&dyn std::io::Write>: std::io::Write`
|
note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method
--> $DIR/mut-borrow-needed-by-trait.rs:21:14
|
LL | writeln!(fp, "hello world").unwrap();
| ^^
= note: the following trait bounds were not satisfied:
`&dyn std::io::Write: std::io::Write`
which is required by `BufWriter<&dyn std::io::Write>: std::io::Write`
= note: this error originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 3 previous errors