Change:
} } <del> let mut err = struct_span_err!( tcx.sess, span, E0599, "no {} named `{}` found for {} `{}` in the current scope", item_kind, item_name, rcvr_ty.prefix_string(self.tcx), ty_str_reported, ); </del> <ins> 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, "no {} named `{}` found for {} `{}` in the current scope", item_kind, item_name, rcvr_ty.prefix_string(self.tcx), ty_str_reported, ) }; </ins> if tcx.sess.source_map().is_multiline(sugg_span) { err.span_label(sugg_span.with_hi(span.lo()), ""); }

Discussion:
No response No response It could also recommend using <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
This seems like a good first issue am I missing something? I am happy to claim it. The write! docs say that write! should accept a writer, a format string, and a list of arguments, so the error output should probably remind that
claim
That's great, let us know if you're having any trouble
Ok! So this is where I am with it: the macro for write! is the following: The issue being that if a writer is forgotten, the macro gets expanded with .writefmt() being called on the formatting string, and the rest of the arguments get passed into formatargs!, which then returns an error that the formatting string maybe was forgotten. In most other erroneous cases, .writefmt() will get called on something that is not a writer and will return a more helpful error that whatever first argument was passed to write! does not have a method writefmt. I had two ideas, the first being to modify the error from , which is where the missing string literal to format with error originates. My idea is that if a string literal is missing AND the formatargs was called from a write! then there probably is a missing writer. My second idea is to add another pattern match to the write! macro itself like: I am not sure which approach is more appropriate, or how exactly to determine the macro that called formatargs! to clarify the error. Do either of these approaches seem worthwhile? I think the write! macro should be the parent of format_args in AST and that is how I would access it? Thanks :) James
You will have to determine whether you are in an expansion of the macro. See for an example of how you could do that and check that it's write/writeln/etc. Most likely you can use and/or to do that. I think this is not a good idea that arm will show up in the documentation, and probably confuse people it also isn't helpful when it's used on something other than a literal.

I think I would have the following approach: If the method is named and if we're in a write macro expansion don't emit the "no method named x found for ..." error at , but instead emit an error like... being more specific if it's a string literal...
Got it, thank you so much for pointing me in the right direction As far as the writefmt, this is where I am so far: Which gives the following output: Where I am checking to see if the function is writefmt and the macro is write! and then creating the relevant error message. I still need to create the recommended substitution from your example, I think that would be from rustcerrors::CodeSuggestions, is that correct? Then for the error about the missing format string, using ecx.expansioncause() gives me the whole line of the write! macro , I can think of some hacky ways to pull write! out of the outer span, is there a better way to extract the outer macro or should I just focus on improving the portion of the diagnostic? Thanks again! James
I suggest posting on https://rust- so more people see your message and can help you.
first of all, I would suggest using the fact that the macro has so you can match on the def id like this for example: This will be more reliable than matching on the name, as it won't fire on user provided macros with the same name, for example. Secondly I wouldn't suggest using , currently it is seen more as an anti-pattern. Instead you could probably use to highlight the argument and say (there are other alternatives like printing the type instead, but using is a good idea anyway, I think). Thirdly about your question about suggestions: the easiest way is to use to get the span just before the literal, to add there. However, I'm not sure if such suggestion is a good idea, after all may not be present, or may be named differently, etc; a suggestion that is almost always wrong seems awkward (this reminds me that suggestions should be more powerful than they are currently in rustc…).
Thanks for the tip , I've been lurking on Zulip for a little bit but wasn't sure if it was the right place for questions once there was already an issue on github Amazing thank you so much!

I get what you're saying about the suggestion being unclear since the writer name will almost always be different... I also was thinking it might be a little awkward. Anyway I implemented the changes as you suggested and now I think the error message makes it pretty clear that a writer is missing: Otherwise is there anything that could be improved with the message? I am not sure if E0599 is still the correct error code but I think that it is because the error is still technically no method found?
looks good :) I think at this point you can open a PR, if any tweaks are needed we'll tell you in the review process. Feel free to , if you want me to review it.
Ok awesome thanks, just submitted PR