Change:
The functionality (does anyone still uses this now that it's ?) gives the same "no extended information" message for real error codes that don't have a "long" explanation written, and nonexistent codes. These messages should be disambiguated (as "no extended information for E0XXX" vs. "E0XXX does not exist" or similar). I thought this would be straightforward to implement: we (which get successfully , although the ), only to when macroexpanding the arrays . So this should, you would think, just be a matter of editing reflect that, and making the care. But when I actually do this (zackmdavis/rust ... my changes to seem to have absolutely no effect (!?!); we still get a even though I thought my code pretty clearly said otherwise, on more than one day that I've looked at this. I hereby give up in despair, bafflement, and tears. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
The diagnostic registration is "just" a macrorules macro now so I suspect this is pretty simple to implement per the suggested path in the issue description; I'm going to mark as E-easy and E-mentor with myself as the mentor. You'll want to edit the array definitions to have the type or so and add in the short diagnostics. Once that's done, if you run you'll likely hit an error in the use site of from . Fixing that'll mostly involve fixing up the diagnostics registry in ; I would store the long diagnostics and short diagnostics separately, adding a field like . Once this is done, there might be a few more type errors to clean up but that should mostly be a matter of making types match up I would hope. Let me know if you have any questions; here on this issue or feel free to open up a PR with some initial work and I can try and provide feedback there.
One additional thing that we should probably add as part of this work is an error if the same diagnostic code is registered twice (cc ). I imagine this would mostly be a matter of inserting all the codes into an FxHashSet and panicking if there's one inserted twice; an ICE here is fine since it'll definitely be caught in CI.
Hey, If this still needs fixed, I would love to work on this. I will probably be reaching out before to long for some guidance. claim
Shoot not sure if I read what was happening in this thread all the way. are you working on this already?
I'm not; go for it! (Although ... I thought I remembered seeing an issue recently where people were discussing moving away from the numeric error codes, but I can't find it. was that a real thing?)
Maybe you are referring to this conversation on Zulip? https://rust-

Discussion:
use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_data_structures::profiling::print_time_passes_entry; use rustc_data_structures::sync::SeqCst; <del> use rustc_errors::{registry::Registry, PResult}; </del> <ins> use rustc_errors::{ registry::{InvalidErrorCode, Registry}, PResult, }; </ins> use rustc_feature::{find_gated_cfg, UnstableFeatures}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_interface::util::{collect_crate_types, get_builtin_codegen_backend};

fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { let normalised = if code.starts_with('E') { code.to_string() } else { format!("E{0:0>4}", code) }; <del> match registry.find_description(&normalised) { Some(ref description) => { </del> <ins> match registry.try_find_description(&normalised) { Ok(Some(description)) => { </ins> let mut is_in_code_block = false; let mut text = String::new(); // Slice off the leading newline and print. for line in description.lines() { let indent_level =

} text.push('n'); } if stdout_isatty() { show_content_with_pager(&text); } else { print!("{}", text); } } <del> None => { </del> <ins> Ok(None) => { </ins> early_error(output, &format!("no extended information for {}", code)); } <ins> Err(InvalidErrorCode) => { early_error(output, &format!("{} is not a valid error code", code)); } </ins> } }

macro_rules! register_diagnostics { ($($ecode:ident: $message:expr,)* ; $($code:ident,)*) => ( <del> pub static DIAGNOSTICS: &[(&str, &str)] = &[ $( (stringify!($ecode), $message), )* </del> <ins> pub static DIAGNOSTICS: &[(&str, Option<&str>)] = &[ $( (stringify!($ecode), Some($message)), )* $( (stringify!($code), None), )* </ins> ]; ) }

DiagnosticId::Error(s) => s, DiagnosticId::Lint(s) => s, }; <del> let explanation = je.registry.as_ref().and_then(|registry| registry.find_description(&s)); </del> <ins> let je_result = je.registry.as_ref().map(|registry| registry.try_find_description(&s)).unwrap(); </ins> <del> DiagnosticCode { code: s, explanation } </del> <ins> DiagnosticCode { code: s, explanation: je_result.unwrap_or(None) } </ins> }) } }

.emitted_diagnostic_codes .iter() .filter_map(|x| match &x { <del> DiagnosticId::Error(s) if registry.find_description(s).is_some() => { Some(s.clone()) </del> <ins> DiagnosticId::Error(s) => { if let Ok(Some(_explanation)) = registry.try_find_description(s) { Some(s.clone()) } else { None } </ins> } _ => None, })

use rustc_data_structures::fx::FxHashMap; <ins> #[derive(Debug)] pub struct InvalidErrorCode; </ins> #[derive(Clone)] pub struct Registry { <del> descriptions: FxHashMap<&'static str, &'static str>, </del> <ins> long_descriptions: FxHashMap<&'static str, Option<&'static str>>, </ins> } impl Registry { <del> pub fn new(descriptions: &[(&'static str, &'static str)]) -> Registry { Registry { descriptions: descriptions.iter().cloned().collect() } </del> <ins> pub fn new(long_descriptions: &[(&'static str, Option<&'static str>)]) -> Registry { Registry { long_descriptions: long_descriptions.iter().cloned().collect() } </ins> } <ins> /// This will panic if an invalid error code is passed in </ins> pub fn find_description(&self, code: &str) -> Option<&'static str> { <del> self.descriptions.get(code).cloned() </del> <ins> self.try_find_description(code).unwrap() } /// Returns `InvalidErrorCode` if the code requested does not exist in the /// registry. Otherwise, returns an `Option` where `None` means the error /// code is valid but has no extended information. pub fn try_find_description( &self, code: &str, ) -> Result<Option<&'static str>, InvalidErrorCode> { if !self.long_descriptions.contains_key(code) { return Err(InvalidErrorCode); } Ok(self.long_descriptions.get(code).unwrap().clone()) </ins> } }