From d1fcf611175e695c35c6cc0537d710277c1a5c6f Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 13 Oct 2022 10:13:02 +0100 Subject: errors: generate typed identifiers in each crate Instead of loading the Fluent resources for every crate in `rustc_error_messages`, each crate generates typed identifiers for its own diagnostics and creates a static which are pulled together in the `rustc_driver` crate and provided to the diagnostic emitter. Signed-off-by: David Wood --- compiler/rustc_driver_impl/src/lib.rs | 48 ++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) (limited to 'compiler/rustc_driver_impl/src') diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index d7e9e00f3b6..f696cc20e23 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -23,11 +23,14 @@ use rustc_codegen_ssa::{traits::CodegenBackend, CodegenErrors, CodegenResults}; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; use rustc_data_structures::sync::SeqCst; use rustc_errors::registry::{InvalidErrorCode, Registry}; -use rustc_errors::{ErrorGuaranteed, PResult, TerminalUrl}; +use rustc_errors::{ + DiagnosticMessage, ErrorGuaranteed, PResult, SubdiagnosticMessage, TerminalUrl, +}; use rustc_feature::find_gated_cfg; use rustc_interface::util::{self, collect_crate_types, get_codegen_backend}; use rustc_interface::{interface, Queries}; use rustc_lint::LintStore; +use rustc_macros::fluent_messages; use rustc_metadata::locator; use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS}; use rustc_session::config::{ErrorOutputType, Input, OutputType, PrintRequest, TrimmedDefPaths}; @@ -61,6 +64,44 @@ use crate::session_diagnostics::{ RLinkWrongFileType, RlinkNotAFile, RlinkUnableToRead, }; +fluent_messages! { "../locales/en-US.ftl" } + +pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ + // tidy-alphabetical-start + crate::DEFAULT_LOCALE_RESOURCE, + rustc_ast_lowering::DEFAULT_LOCALE_RESOURCE, + rustc_ast_passes::DEFAULT_LOCALE_RESOURCE, + rustc_attr::DEFAULT_LOCALE_RESOURCE, + rustc_borrowck::DEFAULT_LOCALE_RESOURCE, + rustc_builtin_macros::DEFAULT_LOCALE_RESOURCE, + rustc_codegen_ssa::DEFAULT_LOCALE_RESOURCE, + rustc_const_eval::DEFAULT_LOCALE_RESOURCE, + rustc_error_messages::DEFAULT_LOCALE_RESOURCE, + rustc_expand::DEFAULT_LOCALE_RESOURCE, + rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE, + rustc_hir_typeck::DEFAULT_LOCALE_RESOURCE, + rustc_incremental::DEFAULT_LOCALE_RESOURCE, + rustc_infer::DEFAULT_LOCALE_RESOURCE, + rustc_interface::DEFAULT_LOCALE_RESOURCE, + rustc_lint::DEFAULT_LOCALE_RESOURCE, + rustc_metadata::DEFAULT_LOCALE_RESOURCE, + rustc_middle::DEFAULT_LOCALE_RESOURCE, + rustc_mir_build::DEFAULT_LOCALE_RESOURCE, + rustc_mir_dataflow::DEFAULT_LOCALE_RESOURCE, + rustc_monomorphize::DEFAULT_LOCALE_RESOURCE, + rustc_parse::DEFAULT_LOCALE_RESOURCE, + rustc_passes::DEFAULT_LOCALE_RESOURCE, + rustc_plugin_impl::DEFAULT_LOCALE_RESOURCE, + rustc_privacy::DEFAULT_LOCALE_RESOURCE, + rustc_query_system::DEFAULT_LOCALE_RESOURCE, + rustc_resolve::DEFAULT_LOCALE_RESOURCE, + rustc_session::DEFAULT_LOCALE_RESOURCE, + rustc_symbol_mangling::DEFAULT_LOCALE_RESOURCE, + rustc_trait_selection::DEFAULT_LOCALE_RESOURCE, + rustc_ty_utils::DEFAULT_LOCALE_RESOURCE, + // tidy-alphabetical-end +]; + /// Exit status code used for successful compilation and help output. pub const EXIT_SUCCESS: i32 = 0; @@ -218,6 +259,7 @@ fn run_compiler( output_file: ofile, output_dir: odir, file_loader, + locale_resources: DEFAULT_LOCALE_RESOURCES, lint_caps: Default::default(), parse_sess_created: None, register_lints: None, @@ -320,7 +362,7 @@ fn run_compiler( } // Make sure name resolution and macro expansion is run. - queries.global_ctxt()?.enter(|tcx| tcx.resolver_for_lowering(())); + queries.global_ctxt()?; if callbacks.after_expansion(compiler, queries) == Compilation::Stop { return early_exit(); @@ -1162,7 +1204,7 @@ static DEFAULT_HOOK: LazyLock) + Sync + Send + /// hook. pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES, false); let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr( rustc_errors::ColorConfig::Auto, None, -- cgit 1.4.1-3-g733a5 From 26255186e2e94e0fe62cfd0965662494b6aab27c Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 17 Oct 2022 14:11:26 +0100 Subject: various: translation resources from cg backend Extend `CodegenBackend` trait with a function returning the translation resources from the codegen backend, which can be added to the complete list of resources provided to the emitter. Signed-off-by: David Wood --- compiler/rustc_codegen_cranelift/src/lib.rs | 5 +++++ compiler/rustc_codegen_gcc/src/lib.rs | 4 ++++ compiler/rustc_codegen_llvm/src/lib.rs | 4 ++++ compiler/rustc_codegen_ssa/src/traits/backend.rs | 4 ++++ compiler/rustc_driver_impl/src/lib.rs | 4 ++-- compiler/rustc_error_messages/src/lib.rs | 2 +- compiler/rustc_errors/src/json/tests.rs | 4 ++-- compiler/rustc_expand/src/parse/tests.rs | 8 ++++---- compiler/rustc_expand/src/tests.rs | 18 ++++++++++++------ compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_interface/src/util.rs | 3 +++ compiler/rustc_session/src/parse.rs | 7 ++----- compiler/rustc_session/src/session.rs | 12 +++++------- src/librustdoc/clean/render_macro_matchers.rs | 3 ++- src/librustdoc/core.rs | 6 ++++-- src/librustdoc/doctest.rs | 12 ++++++++---- src/librustdoc/passes/lint/check_code_block_syntax.rs | 6 ++++-- src/tools/clippy/clippy_lints/src/doc.rs | 6 ++++-- src/tools/clippy/src/driver.rs | 5 ++++- src/tools/rustfmt/src/parse/session.rs | 6 ++++-- .../hotplug_codegen_backend/the_backend.rs | 2 ++ tests/ui-fulldeps/mod_dir_path_canonicalized.rs | 7 ++++--- tests/ui-fulldeps/pprust-expr-roundtrip.rs | 4 +--- 23 files changed, 86 insertions(+), 48 deletions(-) (limited to 'compiler/rustc_driver_impl/src') diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index c7fe382bac4..5ba568bfd6e 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -172,6 +172,11 @@ pub struct CraneliftCodegenBackend { } impl CodegenBackend for CraneliftCodegenBackend { + fn locale_resource(&self) -> &'static str { + // FIXME(rust-lang/rust#100717) - cranelift codegen backend is not yet translated + "" + } + fn init(&self, sess: &Session) { use rustc_session::config::Lto; match sess.lto() { diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 546c892aae5..44538b41528 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -103,6 +103,10 @@ pub struct GccCodegenBackend { } impl CodegenBackend for GccCodegenBackend { + fn locale_resource(&self) -> &'static str { + crate::DEFAULT_LOCALE_RESOURCE + } + fn init(&self, sess: &Session) { if sess.lto() != Lto::No { sess.emit_warning(LTONotSupported {}); diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index de886c881a5..c41e74c51a0 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -249,6 +249,10 @@ impl LlvmCodegenBackend { } impl CodegenBackend for LlvmCodegenBackend { + fn locale_resource(&self) -> &'static str { + crate::DEFAULT_LOCALE_RESOURCE + } + fn init(&self, sess: &Session) { llvm_util::init(sess); // Make sure llvm is inited } diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 5c35070ea66..64bebe50ddb 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -57,6 +57,10 @@ impl<'tcx, T> Backend<'tcx> for T where } pub trait CodegenBackend { + /// Locale resources for diagnostic messages - a string the content of the Fluent resource. + /// Called before `init` so that all other functions are able to emit translatable diagnostics. + fn locale_resource(&self) -> &'static str; + fn init(&self, _sess: &Session) {} fn print(&self, _req: PrintRequest, _sess: &Session) {} fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec { diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index f696cc20e23..54bcb154da2 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -362,7 +362,7 @@ fn run_compiler( } // Make sure name resolution and macro expansion is run. - queries.global_ctxt()?; + queries.global_ctxt()?.enter(|tcx| tcx.resolver_for_lowering(())); if callbacks.after_expansion(compiler, queries) == Compilation::Stop { return early_exit(); @@ -1204,7 +1204,7 @@ static DEFAULT_HOOK: LazyLock) + Sync + Send + /// hook. pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { let fallback_bundle = - rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES, false); + rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES.to_vec(), false); let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr( rustc_errors::ColorConfig::Auto, None, diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 13952f8456e..40ed10e7165 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -223,7 +223,7 @@ pub type LazyFallbackBundle = Lrc FluentBund /// Return the default `FluentBundle` with standard "en-US" diagnostic messages. #[instrument(level = "trace")] pub fn fallback_fluent_bundle( - resources: &'static [&'static str], + resources: Vec<&'static str>, with_directionality_markers: bool, ) -> LazyFallbackBundle { Lrc::new(Lazy::new(move || { diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index bbfad26c6f0..671dc449eaa 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -42,11 +42,11 @@ impl Write for Shared { /// Test the span yields correct positions in JSON. fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { - static TEST_LOCALE_RESOURCES: &[&str] = &[crate::DEFAULT_LOCALE_RESOURCE]; rustc_span::create_default_session_globals_then(|| { let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); sm.new_source_file(Path::new("test.rs").to_owned().into(), code.to_owned()); - let fallback_bundle = crate::fallback_fluent_bundle(TEST_LOCALE_RESOURCES, false); + let fallback_bundle = + crate::fallback_fluent_bundle(vec![crate::DEFAULT_LOCALE_RESOURCE], false); let output = Arc::new(Mutex::new(Vec::new())); let je = JsonEmitter::new( diff --git a/compiler/rustc_expand/src/parse/tests.rs b/compiler/rustc_expand/src/parse/tests.rs index a416300ba7e..8b37728b60f 100644 --- a/compiler/rustc_expand/src/parse/tests.rs +++ b/compiler/rustc_expand/src/parse/tests.rs @@ -17,11 +17,11 @@ use rustc_span::{BytePos, FileName, Pos, Span}; use std::path::PathBuf; -static TEST_LOCALE_RESOURCES: &[&str] = - &[crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE]; - fn sess() -> ParseSess { - ParseSess::new(TEST_LOCALE_RESOURCES, FilePathMapping::empty()) + ParseSess::new( + vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE], + FilePathMapping::empty(), + ) } /// Parses an item. diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs index bd1b3ff28b7..14918d3c190 100644 --- a/compiler/rustc_expand/src/tests.rs +++ b/compiler/rustc_expand/src/tests.rs @@ -34,7 +34,10 @@ where /// Maps a string to tts, using a made-up filename. pub(crate) fn string_to_stream(source_str: String) -> TokenStream { - let ps = ParseSess::new(TEST_LOCALE_RESOURCES, FilePathMapping::empty()); + let ps = ParseSess::new( + vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE], + FilePathMapping::empty(), + ); source_file_to_stream( &ps, ps.source_map().new_source_file(PathBuf::from("bogofile").into(), source_str), @@ -45,7 +48,10 @@ pub(crate) fn string_to_stream(source_str: String) -> TokenStream { /// Parses a string, returns a crate. pub(crate) fn string_to_crate(source_str: String) -> ast::Crate { - let ps = ParseSess::new(TEST_LOCALE_RESOURCES, FilePathMapping::empty()); + let ps = ParseSess::new( + vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE], + FilePathMapping::empty(), + ); with_error_checking_parse(source_str, &ps, |p| p.parse_crate_mod()) } @@ -123,14 +129,14 @@ impl Write for Shared { } } -static TEST_LOCALE_RESOURCES: &[&str] = - &[crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE]; - fn test_harness(file_text: &str, span_labels: Vec, expected_output: &str) { create_default_session_if_not_set_then(|_| { let output = Arc::new(Mutex::new(Vec::new())); - let fallback_bundle = rustc_errors::fallback_fluent_bundle(TEST_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE], + false, + ); let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); source_map.new_source_file(Path::new("test.rs").to_owned().into(), file_text.to_owned()); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 8ef1df39933..71a72036994 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -50,7 +50,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) { output_file: None, temps_dir, }; - let sess = build_session(sessopts, io, None, registry, &[], Default::default(), None, None); + let sess = build_session(sessopts, io, None, registry, vec![], Default::default(), None, None); (sess, cfg) } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 20ba5c6eb2d..e5d2fb2ea28 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -90,6 +90,9 @@ pub fn create_session( } }; + let mut locale_resources = Vec::from(locale_resources); + locale_resources.push(codegen_backend.locale_resource()); + let mut sess = session::build_session( sopts, io, diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 9d0ef9f2f12..4e8c3f73e29 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -226,10 +226,7 @@ pub struct ParseSess { impl ParseSess { /// Used for testing. - pub fn new( - locale_resources: &'static [&'static str], - file_path_mapping: FilePathMapping, - ) -> Self { + pub fn new(locale_resources: Vec<&'static str>, file_path_mapping: FilePathMapping) -> Self { let fallback_bundle = fallback_fluent_bundle(locale_resources, false); let sm = Lrc::new(SourceMap::new(file_path_mapping)); let handler = Handler::with_tty_emitter( @@ -268,7 +265,7 @@ impl ParseSess { } pub fn with_silent_emitter(fatal_note: Option) -> Self { - let fallback_bundle = fallback_fluent_bundle(&[], false); + let fallback_bundle = fallback_fluent_bundle(Vec::new(), false); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let fatal_handler = Handler::with_tty_emitter(ColorConfig::Auto, false, None, None, None, fallback_bundle); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 0be057de6d7..446ba63ed1c 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1341,7 +1341,7 @@ pub fn build_session( io: CompilerIO, bundle: Option>, registry: rustc_errors::registry::Registry, - fluent_resources: &'static [&'static str], + fluent_resources: Vec<&'static str>, driver_lint_caps: FxHashMap, file_loader: Option>, target_override: Option, @@ -1630,13 +1630,11 @@ pub enum IncrCompSession { InvalidBecauseOfErrors { session_directory: PathBuf }, } -// FIXME(#100717): early errors aren't translated at the moment, so this is fine, but it will need -// to reference every crate that might emit an early error for translation to work. -static EARLY_ERROR_LOCALE_RESOURCE: &'static [&'static str] = - &[rustc_errors::DEFAULT_LOCALE_RESOURCE]; - fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler { - let fallback_bundle = fallback_fluent_bundle(EARLY_ERROR_LOCALE_RESOURCE, false); + // FIXME(#100717): early errors aren't translated at the moment, so this is fine, but it will + // need to reference every crate that might emit an early error for translation to work. + let fallback_bundle = + fallback_fluent_bundle(vec![rustc_errors::DEFAULT_LOCALE_RESOURCE], false); let emitter: Box = match output { config::ErrorOutputType::HumanReadable(kind) => { let (short, color_config) = kind.unzip(); diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs index 068d596f52f..ef38ca3c16c 100644 --- a/src/librustdoc/clean/render_macro_matchers.rs +++ b/src/librustdoc/clean/render_macro_matchers.rs @@ -63,7 +63,8 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option, unstable_opts: &UnstableOptions, ) -> rustc_errors::Handler { - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); let emitter: Box = match error_format { ErrorOutputType::HumanReadable(kind) => { let (short, color_config) = kind.unzip(); diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 509240a5194..8a73d25d3f0 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -546,8 +546,10 @@ pub(crate) fn make_test( // Any errors in parsing should also appear when the doctest is compiled for real, so just // send all the errors that librustc_ast emits directly into a `Sink` instead of stderr. let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); supports_color = EmitterWriter::stderr( ColorConfig::Auto, None, @@ -742,8 +744,10 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool { // Any errors in parsing should also appear when the doctest is compiled for real, so just // send all the errors that librustc_ast emits directly into a `Sink` instead of stderr. let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); let emitter = EmitterWriter::new( Box::new(io::sink()), diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs index 71f922662da..26fbb03a43e 100644 --- a/src/librustdoc/passes/lint/check_code_block_syntax.rs +++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs @@ -33,8 +33,10 @@ fn check_rust_syntax( code_block: RustCodeBlock, ) { let buffer = Lrc::new(Lock::new(Buffer::default())); - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); let emitter = BufferEmitter { buffer: Lrc::clone(&buffer), fallback_bundle }; let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs index 660dd8391a3..6fdb7de25cc 100644 --- a/src/tools/clippy/clippy_lints/src/doc.rs +++ b/src/tools/clippy/clippy_lints/src/doc.rs @@ -704,8 +704,10 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) { let filename = FileName::anon_source_code(&code); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false + ); let emitter = EmitterWriter::new( Box::new(io::sink()), None, diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index 45209fb8519..9ac849aecf1 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -209,7 +209,10 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { // Separate the output with an empty line eprintln!(); - let fallback_bundle = rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false + ); let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr( rustc_errors::ColorConfig::Auto, None, diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs index a7a363d47ba..a64963db6a7 100644 --- a/src/tools/rustfmt/src/parse/session.rs +++ b/src/tools/rustfmt/src/parse/session.rs @@ -123,8 +123,10 @@ fn default_handler( let emitter = if hide_parse_errors { silent_emitter() } else { - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); Box::new(EmitterWriter::stderr( color_cfg, Some(source_map.clone()), diff --git a/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs index 3aa57d58908..8dac53c2a62 100644 --- a/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs +++ b/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs @@ -27,6 +27,8 @@ use std::any::Any; struct TheBackend; impl CodegenBackend for TheBackend { + fn locale_resource(&self) -> &'static str { "" } + fn codegen_crate<'a, 'tcx>( &self, tcx: TyCtxt<'tcx>, diff --git a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs index f9d6fc8bae1..ddc86c1dc31 100644 --- a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs +++ b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs @@ -30,10 +30,11 @@ pub fn main() { assert_eq!(gravy::foo(), 10); } -static TEST_LOCALE_RESOURCES: &[&str] = &[rustc_parse::DEFAULT_LOCALE_RESOURCE]; - fn parse() { - let parse_session = ParseSess::new(TEST_LOCALE_RESOURCES, FilePathMapping::empty()); + let parse_session = ParseSess::new( + vec![rustc_parse::DEFAULT_LOCALE_RESOURCE], + FilePathMapping::empty() + ); let path = Path::new(file!()); let path = path.canonicalize().unwrap(); diff --git a/tests/ui-fulldeps/pprust-expr-roundtrip.rs b/tests/ui-fulldeps/pprust-expr-roundtrip.rs index 5c8aa865163..e417a6a833b 100644 --- a/tests/ui-fulldeps/pprust-expr-roundtrip.rs +++ b/tests/ui-fulldeps/pprust-expr-roundtrip.rs @@ -219,10 +219,8 @@ fn main() { rustc_span::create_default_session_globals_then(|| run()); } -static TEST_LOCALE_RESOURCES: &[&str] = &[rustc_parse::DEFAULT_LOCALE_RESOURCE]; - fn run() { - let ps = ParseSess::new(TEST_LOCALE_RESOURCES, FilePathMapping::empty()); + let ps = ParseSess::new(vec![rustc_parse::DEFAULT_LOCALE_RESOURCE], FilePathMapping::empty()); iter_exprs(2, &mut |mut e| { // If the pretty printer is correct, then `parse(print(e))` should be identical to `e`, -- cgit 1.4.1-3-g733a5 From 90677edcba063ee83316ef109e0fe54116015575 Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Sat, 25 Feb 2023 20:14:10 +1300 Subject: refactor: statically guarantee that current error codes are documented --- compiler/rustc_driver_impl/src/lib.rs | 5 +--- compiler/rustc_error_codes/src/error_codes.rs | 11 ++++---- compiler/rustc_error_codes/src/lib.rs | 7 +++-- compiler/rustc_errors/src/json.rs | 2 +- compiler/rustc_errors/src/lib.rs | 4 +-- compiler/rustc_errors/src/registry.rs | 12 +++------ src/tools/error_index_generator/main.rs | 37 +++++++++++---------------- src/tools/tidy/src/error_codes.rs | 24 +++-------------- 8 files changed, 34 insertions(+), 68 deletions(-) (limited to 'compiler/rustc_driver_impl/src') diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 54bcb154da2..464ddae476a 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -485,7 +485,7 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { let normalised = if upper_cased_code.starts_with('E') { upper_cased_code } else { format!("E{code:0>4}") }; match registry.try_find_description(&normalised) { - Ok(Some(description)) => { + Ok(description) => { let mut is_in_code_block = false; let mut text = String::new(); // Slice off the leading newline and print. @@ -509,9 +509,6 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { print!("{text}"); } } - Ok(None) => { - early_error(output, &format!("no extended information for {code}")); - } Err(InvalidErrorCode) => { early_error(output, &format!("{code} is not a valid error code")); } diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 97201219cdf..df857be85ad 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -513,7 +513,9 @@ E0790: include_str!("./error_codes/E0790.md"), E0791: include_str!("./error_codes/E0791.md"), E0792: include_str!("./error_codes/E0792.md"), E0793: include_str!("./error_codes/E0793.md"), -; +} + +// Undocumented removed error codes. Note that many removed error codes are documented. // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard // E0019, // merged into E0015 @@ -570,7 +572,7 @@ E0793: include_str!("./error_codes/E0793.md"), // E0246, // invalid recursive type // E0247, // E0248, // value used as a type, now reported earlier during resolution - // as E0412 +// // as E0412 // E0249, // E0257, // E0258, @@ -631,14 +633,14 @@ E0793: include_str!("./error_codes/E0793.md"), // E0558, // replaced with a generic attribute input check // E0563, // cannot determine a type for this `impl Trait` removed in 6383de15 // E0564, // only named lifetimes are allowed in `impl Trait`, - // but `{}` was found in the type `{}` +// // but `{}` was found in the type `{}` // E0598, // lifetime of {} is too short to guarantee its contents can be... // E0611, // merged into E0616 // E0612, // merged into E0609 // E0613, // Removed (merged with E0609) // E0629, // missing 'feature' (rustc_const_unstable) // E0630, // rustc_const_unstable attribute must be paired with stable/unstable - // attribute +// // attribute // E0645, // trait aliases not finished // E0694, // an unknown tool name found in scoped attributes // E0702, // replaced with a generic attribute input check @@ -647,4 +649,3 @@ E0793: include_str!("./error_codes/E0793.md"), // E0721, // `await` keyword // E0723, // unstable feature in `const` context // E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`. -} diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index bd424dd9d06..d6b120e4dfc 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -5,10 +5,9 @@ //! the goal being to make their maintenance easier. macro_rules! register_diagnostics { - ($($ecode:ident: $message:expr,)* ; $($code:ident,)*) => ( - pub static DIAGNOSTICS: &[(&str, Option<&str>)] = &[ - $( (stringify!($ecode), Some($message)), )* - $( (stringify!($code), None), )* + ($($ecode:ident: $message:expr,)*) => ( + pub static DIAGNOSTICS: &[(&str, &str)] = &[ + $( (stringify!($ecode), $message), )* ]; ) } diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index e475fc725c3..f32d6b96b9b 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -580,7 +580,7 @@ impl DiagnosticCode { let je_result = je.registry.as_ref().map(|registry| registry.try_find_description(&s)).unwrap(); - DiagnosticCode { code: s, explanation: je_result.unwrap_or(None) } + DiagnosticCode { code: s, explanation: je_result.ok() } }) } } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index edec8cce92f..c71668657f7 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1477,9 +1477,7 @@ impl HandlerInner { .emitted_diagnostic_codes .iter() .filter_map(|x| match &x { - DiagnosticId::Error(s) - if registry.try_find_description(s).map_or(false, |o| o.is_some()) => - { + DiagnosticId::Error(s) if registry.try_find_description(s).is_ok() => { Some(s.clone()) } _ => None, diff --git a/compiler/rustc_errors/src/registry.rs b/compiler/rustc_errors/src/registry.rs index da764d993bb..f26d8e7ebdc 100644 --- a/compiler/rustc_errors/src/registry.rs +++ b/compiler/rustc_errors/src/registry.rs @@ -5,21 +5,17 @@ pub struct InvalidErrorCode; #[derive(Clone)] pub struct Registry { - long_descriptions: FxHashMap<&'static str, Option<&'static str>>, + long_descriptions: FxHashMap<&'static str, &'static str>, } impl Registry { - pub fn new(long_descriptions: &[(&'static str, Option<&'static str>)]) -> Registry { + pub fn new(long_descriptions: &[(&'static str, &'static str)]) -> Registry { Registry { long_descriptions: long_descriptions.iter().copied().collect() } } /// 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, InvalidErrorCode> { + /// registry. + pub fn try_find_description(&self, code: &str) -> Result<&'static str, InvalidErrorCode> { self.long_descriptions.get(code).copied().ok_or(InvalidErrorCode) } } diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index 373196b6642..7f5f70e0bea 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -55,11 +55,8 @@ fn render_markdown(output_path: &Path) -> Result<(), Box> { write!(output_file, "# Rust Compiler Error Index\n")?; - for (err_code, description) in error_codes().iter() { - match description { - Some(ref desc) => write!(output_file, "## {}\n{}\n", err_code, desc)?, - None => {} - } + for (err_code, description) in rustc_error_codes::DIAGNOSTICS.iter() { + write!(output_file, "## {}\n{}\n", err_code, description)? } Ok(()) @@ -109,23 +106,19 @@ This page lists all the error codes emitted by the Rust compiler. let mut chapters = Vec::with_capacity(err_codes.len()); for (err_code, explanation) in err_codes.iter() { - if let Some(explanation) = explanation { - introduction.push_str(&format!(" * [{0}](./{0}.html)\n", err_code)); - - let content = add_rust_attribute_on_codeblock(explanation); - chapters.push(BookItem::Chapter(Chapter { - name: err_code.to_string(), - content: format!("# Error code {}\n\n{}\n", err_code, content), - number: None, - sub_items: Vec::new(), - // We generate it into the `error_codes` folder. - path: Some(PathBuf::from(&format!("{}.html", err_code))), - source_path: None, - parent_names: Vec::new(), - })); - } else { - introduction.push_str(&format!(" * {}\n", err_code)); - } + introduction.push_str(&format!(" * [{0}](./{0}.html)\n", err_code)); + + let content = add_rust_attribute_on_codeblock(explanation); + chapters.push(BookItem::Chapter(Chapter { + name: err_code.to_string(), + content: format!("# Error code {}\n\n{}\n", err_code, content), + number: None, + sub_items: Vec::new(), + // We generate it into the `error_codes` folder. + path: Some(PathBuf::from(&format!("{}.html", err_code))), + source_path: None, + parent_names: Vec::new(), + })); } let mut config = Config::from_str(include_str!("book_config.toml"))?; diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index 8c904e8d712..c60caa0d49c 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -45,7 +45,7 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut let mut errors = Vec::new(); // Stage 1: create list - let error_codes = extract_error_codes(root_path, &mut errors, verbose); + let error_codes = extract_error_codes(root_path, &mut errors); println!("Found {} error codes", error_codes.len()); println!("Highest error code: `{}`", error_codes.iter().max().unwrap()); @@ -65,18 +65,17 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut } /// Stage 1: Parses a list of error codes from `error_codes.rs`. -fn extract_error_codes(root_path: &Path, errors: &mut Vec, verbose: bool) -> Vec { +fn extract_error_codes(root_path: &Path, errors: &mut Vec) -> Vec { let path = root_path.join(Path::new(ERROR_CODES_PATH)); let file = fs::read_to_string(&path).unwrap_or_else(|e| panic!("failed to read `{path:?}`: {e}")); let mut error_codes = Vec::new(); - let mut reached_undocumented_codes = false; for line in file.lines() { let line = line.trim(); - if !reached_undocumented_codes && line.starts_with('E') { + if line.starts_with('E') { let split_line = line.split_once(':'); // Extract the error code from the line, emitting a fatal error if it is not in a correct format. @@ -111,23 +110,6 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec, verbose: bool } error_codes.push(err_code); - } else if reached_undocumented_codes && line.starts_with('E') { - let err_code = match line.split_once(',') { - None => line, - Some((err_code, _)) => err_code, - } - .to_string(); - - verbose_print!(verbose, "warning: Error code `{}` is undocumented.", err_code); - - if error_codes.contains(&err_code) { - errors.push(format!("Found duplicate error code: `{}`", err_code)); - } - - error_codes.push(err_code); - } else if line == ";" { - // Once we reach the undocumented error codes, adapt to different syntax. - reached_undocumented_codes = true; } } -- cgit 1.4.1-3-g733a5