From 9a4ead9bc6664708fd83981e2b0e3960c798acc0 Mon Sep 17 00:00:00 2001 From: Nicky Lim Date: Tue, 20 Jun 2023 02:45:40 +0800 Subject: [PATCH 1/4] Migrate diagnostics on `lib.rs` --- src/librustdoc/errors.rs | 34 ++++++++++++++++++++++++++++++++++ src/librustdoc/lib.rs | 31 ++++++++++++++++--------------- src/librustdoc/messages.ftl | 7 +++++++ 3 files changed, 57 insertions(+), 15 deletions(-) create mode 100644 src/librustdoc/errors.rs create mode 100644 src/librustdoc/messages.ftl diff --git a/src/librustdoc/errors.rs b/src/librustdoc/errors.rs new file mode 100644 index 0000000000000..41ff638c1fb7e --- /dev/null +++ b/src/librustdoc/errors.rs @@ -0,0 +1,34 @@ +use crate::fluent_generated as fluent; +use rustc_errors::IntoDiagnostic; +use rustc_macros::Diagnostic; +use rustc_span::ErrorGuaranteed; + +#[derive(Diagnostic)] +#[diag(rustdoc_main_error)] +pub(crate) struct MainError { + pub(crate) error: String, +} + +pub(crate) struct CouldntGenerateDocumentation { + pub(crate) error: String, + pub(crate) file: String, +} + +impl IntoDiagnostic<'_> for CouldntGenerateDocumentation { + fn into_diagnostic( + self, + handler: &'_ rustc_errors::Handler, + ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { + let mut diag = handler.struct_err(fluent::rustdoc_couldnt_generate_documentation); + diag.set_arg("error", self.error); + if !self.file.is_empty() { + diag.note(fluent::_subdiag::note); + } + + diag + } +} + +#[derive(Diagnostic)] +#[diag(rustdoc_compilation_failed)] +pub(crate) struct CompilationFailed; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index a8cd0ec453ed7..eec230a14f187 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -19,6 +19,8 @@ #![warn(rustc::internal)] #![allow(clippy::collapsible_if, clippy::collapsible_else_if)] #![allow(rustc::potential_query_instability)] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] extern crate thin_vec; #[macro_use] @@ -43,6 +45,7 @@ extern crate rustc_driver; extern crate rustc_errors; extern crate rustc_expand; extern crate rustc_feature; +extern crate rustc_fluent_macro; extern crate rustc_hir; extern crate rustc_hir_analysis; extern crate rustc_hir_pretty; @@ -74,8 +77,10 @@ use std::env::{self, VarError}; use std::io::{self, IsTerminal}; use std::process; +use errors::{CouldntGenerateDocumentation, MainError}; use rustc_driver::abort_on_err; -use rustc_errors::ErrorGuaranteed; +use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_interface::interface; use rustc_middle::ty::TyCtxt; use rustc_session::config::{make_crate_type_option, ErrorOutputType, RustcOptGroup}; @@ -83,6 +88,7 @@ use rustc_session::getopts; use rustc_session::{early_error, early_warn}; use crate::clean::utils::DOC_RUST_LANG_ORG_CHANNEL; +use crate::errors::CompilationFailed; /// A macro to create a FxHashMap. /// @@ -108,6 +114,7 @@ mod core; mod docfs; mod doctest; mod error; +mod errors; mod externalfiles; mod fold; mod formats; @@ -123,6 +130,8 @@ mod visit; mod visit_ast; mod visit_lib; +fluent_messages! { "./messages.ftl" } + pub fn main() { // See docs in https://github.com/rust-lang/rust/blob/master/compiler/rustc/src/main.rs // about jemalloc. @@ -683,10 +692,7 @@ type MainResult = Result<(), ErrorGuaranteed>; fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainResult { match res { Ok(()) => diag.has_errors().map_or(Ok(()), Err), - Err(err) => { - let reported = diag.struct_err(err).emit(); - Err(reported) - } + Err(error) => Err(diag.emit_err(MainError { error })), } } @@ -698,15 +704,10 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>( ) -> MainResult { match formats::run_format::(krate, renderopts, cache, tcx) { Ok(_) => tcx.sess.has_errors().map_or(Ok(()), Err), - Err(e) => { - let mut msg = - tcx.sess.struct_err(format!("couldn't generate documentation: {}", e.error)); - let file = e.file.display().to_string(); - if !file.is_empty() { - msg.note(format!("failed to create or modify \"{}\"", file)); - } - Err(msg.emit()) - } + Err(e) => Err(tcx.sess.emit_err(CouldntGenerateDocumentation { + error: e.error, + file: e.file.display().to_string(), + })), } } @@ -817,7 +818,7 @@ fn main_args(at_args: &[String]) -> MainResult { compiler.enter(|queries| { let mut gcx = abort_on_err(queries.global_ctxt(), sess); if sess.diagnostic().has_errors_or_lint_errors().is_some() { - sess.fatal("Compilation failed, aborting rustdoc"); + sess.emit_fatal(CompilationFailed); } gcx.enter(|tcx| { diff --git a/src/librustdoc/messages.ftl b/src/librustdoc/messages.ftl new file mode 100644 index 0000000000000..f1a244b615858 --- /dev/null +++ b/src/librustdoc/messages.ftl @@ -0,0 +1,7 @@ +rustdoc_main_error = {$error} + +rustdoc_couldnt_generate_documentation = + couldn't generate documentation: {$error} + .note = failed to create or modify "{$file}" + +rustdoc_compilation_failed = Compilation failed, aborting rustdoc From f1763afafcf8bca9f8c53d5d5bc2f5ad4cdfc64b Mon Sep 17 00:00:00 2001 From: Nicky Lim Date: Fri, 23 Jun 2023 00:20:09 +0800 Subject: [PATCH 2/4] Convert error messages to lowercase --- src/librustdoc/messages.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/messages.ftl b/src/librustdoc/messages.ftl index f1a244b615858..7e41b2cbf2fd7 100644 --- a/src/librustdoc/messages.ftl +++ b/src/librustdoc/messages.ftl @@ -4,4 +4,4 @@ rustdoc_couldnt_generate_documentation = couldn't generate documentation: {$error} .note = failed to create or modify "{$file}" -rustdoc_compilation_failed = Compilation failed, aborting rustdoc +rustdoc_compilation_failed = compilation failed, aborting rustdoc From b5be644c047992eee4df25008543457ad369311f Mon Sep 17 00:00:00 2001 From: Nicky Lim Date: Mon, 26 Jun 2023 23:53:52 +0800 Subject: [PATCH 3/4] Address comments, migrate more diagnostics --- src/librustdoc/clean/cfg.rs | 4 +- src/librustdoc/config.rs | 87 ++++++--------- src/librustdoc/core.rs | 2 + src/librustdoc/errors.rs | 173 ++++++++++++++++++++++++++---- src/librustdoc/externalfiles.rs | 5 +- src/librustdoc/lib.rs | 19 ++-- src/librustdoc/messages.ftl | 63 ++++++++++- src/librustdoc/scrape_examples.rs | 11 +- src/librustdoc/theme.rs | 2 + src/librustdoc/visit_ast.rs | 4 +- 10 files changed, 278 insertions(+), 92 deletions(-) diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 5177cffe6bae4..49418bb408e76 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -439,7 +439,7 @@ impl<'a> fmt::Display for Display<'a> { write!(fmt, "`{}`", feat)?; } } else { - write_with_opt_paren(fmt, !sub_cfg.is_all(), Display(sub_cfg, self.1))?; + write_with_opt_paren(fmt, !sub_cfg.is_all(), Display(&sub_cfg, self.1))?; } } Ok(()) @@ -476,7 +476,7 @@ impl<'a> fmt::Display for Display<'a> { write!(fmt, "`{}`", feat)?; } } else { - write_with_opt_paren(fmt, !sub_cfg.is_simple(), Display(sub_cfg, self.1))?; + write_with_opt_paren(fmt, !sub_cfg.is_simple(), Display(&sub_cfg, self.1))?; } } Ok(()) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 9f08609a6d1a6..3dd9b5e0e3ddd 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -19,6 +19,15 @@ use rustc_span::edition::Edition; use rustc_target::spec::TargetTriple; use crate::core::new_handler; +use crate::errors::{ + ArgumentsToThemeMustBeFiles, ArgumentsToThemeMustHaveACssExtension, + CannotUseBothOutDirAndOutputAtOnce, ErrorLoadingThemeFile, ExtendCssArgMustBeAFile, + FlagIsDeprecated, FlagNoLongerFunctions, + GenerateLinkToDefinitionOptionCanOnlyBeUsedWithHtmlOutputFormat, + HtmlOutputFormatUnsupportedForShowCoverageOption, IndexPageArgMustBeAFile, MissingFileOperand, + TestFlagMustBePassedToEnableNoRun, ThemeFileMissingCssRulesFromDefaultTheme, + TooManyFileOperands, UnknownCrateType, UnknownInputFormat, UnrecognizedEmissionType, +}; use crate::externalfiles::ExternalHtml; use crate::html; use crate::html::markdown::IdMap; @@ -381,7 +390,7 @@ impl Options { match kind.parse() { Ok(kind) => emit.push(kind), Err(()) => { - diag.err(format!("unrecognized emission type: {}", kind)); + diag.emit_err(UnrecognizedEmissionType { kind }); return Err(1); } } @@ -406,6 +415,8 @@ impl Options { ) { Ok(p) => p, Err(e) => { + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] diag.struct_err(e).emit(); return Err(1); } @@ -437,10 +448,10 @@ impl Options { let input = PathBuf::from(if describe_lints { "" // dummy, this won't be used } else if matches.free.is_empty() { - diag.struct_err("missing file operand").emit(); + diag.emit_err(MissingFileOperand); return Err(1); } else if matches.free.len() > 1 { - diag.struct_err("too many file operands").emit(); + diag.emit_err(TooManyFileOperands); return Err(1); } else { &matches.free[0] @@ -455,6 +466,8 @@ impl Options { let extern_html_root_urls = match parse_extern_html_roots(matches) { Ok(ex) => ex, Err(err) => { + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] diag.struct_err(err).emit(); return Err(1); } @@ -514,7 +527,7 @@ impl Options { let no_run = matches.opt_present("no-run"); if !should_test && no_run { - diag.err("the `--test` flag must be passed to enable `--no-run`"); + diag.emit_err(TestFlagMustBePassedToEnableNoRun); return Err(1); } @@ -522,7 +535,7 @@ impl Options { let output = matches.opt_str("output").map(|s| PathBuf::from(&s)); let output = match (out_dir, output) { (Some(_), Some(_)) => { - diag.struct_err("cannot use both 'out-dir' and 'output' at once").emit(); + diag.emit_err(CannotUseBothOutDirAndOutputAtOnce); return Err(1); } (Some(out_dir), None) => out_dir, @@ -537,7 +550,7 @@ impl Options { if let Some(ref p) = extension_css { if !p.is_file() { - diag.struct_err("option --extend-css argument must be a file").emit(); + diag.emit_err(ExtendCssArgMustBeAFile); return Err(1); } } @@ -549,6 +562,8 @@ impl Options { ) { Ok(p) => p, Err(e) => { + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] diag.struct_err(e).emit(); return Err(1); } @@ -558,32 +573,19 @@ impl Options { matches.opt_strs("theme").iter().map(|s| (PathBuf::from(&s), s.to_owned())) { if !theme_file.is_file() { - diag.struct_err(format!("invalid argument: \"{}\"", theme_s)) - .help("arguments to --theme must be files") - .emit(); + diag.emit_err(ArgumentsToThemeMustBeFiles { theme: theme_s }); return Err(1); } if theme_file.extension() != Some(OsStr::new("css")) { - diag.struct_err(format!("invalid argument: \"{}\"", theme_s)) - .help("arguments to --theme must have a .css extension") - .emit(); + diag.emit_err(ArgumentsToThemeMustHaveACssExtension { theme: theme_s }); return Err(1); } let (success, ret) = theme::test_theme_against(&theme_file, &paths, &diag); if !success { - diag.struct_err(format!("error loading theme file: \"{}\"", theme_s)).emit(); + diag.emit_err(ErrorLoadingThemeFile { theme: theme_s }); return Err(1); } else if !ret.is_empty() { - diag.struct_warn(format!( - "theme file \"{}\" is missing CSS rules from the default theme", - theme_s - )) - .warn("the theme may appear incorrect when loaded") - .help(format!( - "to see what rules are missing, call `rustdoc --check-theme \"{}\"`", - theme_s - )) - .emit(); + diag.emit_warning(ThemeFileMissingCssRulesFromDefaultTheme { theme: theme_s }); } themes.push(StylePath { path: theme_file }); } @@ -610,7 +612,7 @@ impl Options { match matches.opt_str("r").as_deref() { Some("rust") | None => {} Some(s) => { - diag.struct_err(format!("unknown input format: {}", s)).emit(); + diag.emit_err(UnknownInputFormat { format: s }); return Err(1); } } @@ -618,7 +620,7 @@ impl Options { let index_page = matches.opt_str("index-page").map(|s| PathBuf::from(&s)); if let Some(ref index_page) = index_page { if !index_page.is_file() { - diag.struct_err("option `--index-page` argument must be a file").emit(); + diag.emit_err(IndexPageArgMustBeAFile); return Err(1); } } @@ -630,7 +632,7 @@ impl Options { let crate_types = match parse_crate_types_from_list(matches.opt_strs("crate-type")) { Ok(types) => types, Err(e) => { - diag.struct_err(format!("unknown crate type: {}", e)).emit(); + diag.emit_err(UnknownCrateType { err: e }); return Err(1); } }; @@ -639,15 +641,14 @@ impl Options { Some(s) => match OutputFormat::try_from(s.as_str()) { Ok(out_fmt) => { if !out_fmt.is_json() && show_coverage { - diag.struct_err( - "html output format isn't supported for the --show-coverage option", - ) - .emit(); + diag.emit_err(HtmlOutputFormatUnsupportedForShowCoverageOption); return Err(1); } out_fmt } Err(e) => { + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] diag.struct_err(e).emit(); return Err(1); } @@ -692,10 +693,7 @@ impl Options { matches.opt_present("extern-html-root-takes-precedence"); if generate_link_to_definition && (show_coverage || output_format != OutputFormat::Html) { - diag.struct_err( - "--generate-link-to-definition option can only be used with HTML output format", - ) - .emit(); + diag.emit_err(GenerateLinkToDefinitionOptionCanOnlyBeUsedWithHtmlOutputFormat); return Err(1); } @@ -789,12 +787,7 @@ fn check_deprecated_options(matches: &getopts::Matches, diag: &rustc_errors::Han for &flag in deprecated_flags.iter() { if matches.opt_present(flag) { - diag.struct_warn(format!("the `{}` flag is deprecated", flag)) - .note( - "see issue #44136 \ - for more information", - ) - .emit(); + diag.emit_warning(FlagIsDeprecated { flag }); } } @@ -802,19 +795,7 @@ fn check_deprecated_options(matches: &getopts::Matches, diag: &rustc_errors::Han for &flag in removed_flags.iter() { if matches.opt_present(flag) { - let mut err = diag.struct_warn(format!("the `{}` flag no longer functions", flag)); - err.note( - "see issue #44136 \ - for more information", - ); - - if flag == "no-defaults" || flag == "passes" { - err.help("you may want to use --document-private-items"); - } else if flag == "plugins" || flag == "plugin-path" { - err.warn("see CVE-2018-1000622"); - } - - err.emit(); + diag.emit_warning(FlagNoLongerFunctions::new(flag)); } } } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index e10a629777526..58dbd908b3454 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -298,6 +298,8 @@ pub(crate) fn create_config( } } +#[allow(rustc::untranslatable_diagnostic)] +#[allow(rustc::diagnostic_outside_of_impl)] pub(crate) fn run_global_ctxt( tcx: TyCtxt<'_>, show_coverage: bool, diff --git a/src/librustdoc/errors.rs b/src/librustdoc/errors.rs index 41ff638c1fb7e..9a2b90b9f4629 100644 --- a/src/librustdoc/errors.rs +++ b/src/librustdoc/errors.rs @@ -1,34 +1,163 @@ -use crate::fluent_generated as fluent; -use rustc_errors::IntoDiagnostic; -use rustc_macros::Diagnostic; -use rustc_span::ErrorGuaranteed; +use std::{io, path::Path}; + +use rustc_macros::{Diagnostic, Subdiagnostic}; #[derive(Diagnostic)] -#[diag(rustdoc_main_error)] -pub(crate) struct MainError { +#[diag(rustdoc_couldnt_generate_documentation)] +pub(crate) struct CouldntGenerateDocumentation { pub(crate) error: String, + #[subdiagnostic] + pub(crate) file: Option, } -pub(crate) struct CouldntGenerateDocumentation { - pub(crate) error: String, +#[derive(Subdiagnostic)] +#[note(rustdoc_failed_to_create_or_modify_file)] +pub(crate) struct FailedToCreateOrModifyFile { pub(crate) file: String, } -impl IntoDiagnostic<'_> for CouldntGenerateDocumentation { - fn into_diagnostic( - self, - handler: &'_ rustc_errors::Handler, - ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = handler.struct_err(fluent::rustdoc_couldnt_generate_documentation); - diag.set_arg("error", self.error); - if !self.file.is_empty() { - diag.note(fluent::_subdiag::note); - } +#[derive(Diagnostic)] +#[diag(rustdoc_compilation_failed)] +pub(crate) struct CompilationFailed; - diag - } +#[derive(Diagnostic)] +#[diag(rustdoc_load_string_error_read_fail)] +pub(crate) struct LoadStringErrorReadFail<'a> { + pub(crate) file_path: &'a Path, + pub(crate) err: io::Error, } #[derive(Diagnostic)] -#[diag(rustdoc_compilation_failed)] -pub(crate) struct CompilationFailed; +#[diag(rustdoc_load_string_error_bad_utf8)] +pub(crate) struct LoadStringErrorBadUtf8<'a> { + pub(crate) file_path: &'a Path, +} + +#[derive(Diagnostic)] +#[diag(rustdoc_scrape_examples_must_use_output_path_and_target_crate_together)] +pub(crate) struct ScrapeExamplesMustUseOutputPathAndTargetCrateTogether; + +#[derive(Diagnostic)] +#[diag(rustdoc_scrape_examples_must_use_output_path_and_target_crate_with_scrape_tests)] +pub(crate) struct ScrapeExamplesMustUseOutputPathAndTargetCrateWithScrapeTests; + +#[derive(Diagnostic)] +#[diag(rustdoc_load_examples_failed)] +pub(crate) struct LoadExamplesFailed { + pub(crate) err: String, +} + +#[derive(Diagnostic)] +#[diag(rustdoc_arguments_to_theme_must_be_files)] +#[help] +pub(crate) struct ArgumentsToThemeMustBeFiles { + pub(crate) theme: String, +} + +#[derive(Diagnostic)] +#[diag(rustdoc_arguments_to_theme_must_have_a_css_extension)] +#[help] +pub(crate) struct ArgumentsToThemeMustHaveACssExtension { + pub(crate) theme: String, +} + +#[derive(Diagnostic)] +#[diag(rustdoc_error_loading_theme_file)] +pub(crate) struct ErrorLoadingThemeFile { + pub(crate) theme: String, +} + +#[derive(Diagnostic)] +#[diag(rustdoc_theme_file_missing_css_rules_from_default_theme)] +#[warning] +#[help] +pub(crate) struct ThemeFileMissingCssRulesFromDefaultTheme { + pub(crate) theme: String, +} + +#[derive(Diagnostic)] +#[diag(rustdoc_unrecognized_emission_type)] +pub(crate) struct UnrecognizedEmissionType<'a> { + pub(crate) kind: &'a str, +} + +#[derive(Diagnostic)] +#[diag(rustdoc_missing_file_operand)] +pub(crate) struct MissingFileOperand; + +#[derive(Diagnostic)] +#[diag(rustdoc_too_many_file_operands)] +pub(crate) struct TooManyFileOperands; + +#[derive(Diagnostic)] +#[diag(rustdoc_test_flag_must_be_passed_to_enable_no_run)] +pub(crate) struct TestFlagMustBePassedToEnableNoRun; + +#[derive(Diagnostic)] +#[diag(rustdoc_extend_css_arg_must_be_a_file)] +pub(crate) struct ExtendCssArgMustBeAFile; + +#[derive(Diagnostic)] +#[diag(rustdoc_cannot_use_both_out_dir_and_output_at_once)] +pub(crate) struct CannotUseBothOutDirAndOutputAtOnce; + +#[derive(Diagnostic)] +#[diag(rustdoc_unknown_input_format)] +pub(crate) struct UnknownInputFormat<'a> { + pub(crate) format: &'a str, +} + +#[derive(Diagnostic)] +#[diag(rustdoc_index_page_arg_must_be_a_file)] +pub(crate) struct IndexPageArgMustBeAFile; + +#[derive(Diagnostic)] +#[diag(rustdoc_unknown_crate_type)] +pub(crate) struct UnknownCrateType { + pub(crate) err: String, +} + +#[derive(Diagnostic)] +#[diag(rustdoc_html_output_format_unsupported_for_show_coverage_option)] +pub(crate) struct HtmlOutputFormatUnsupportedForShowCoverageOption; + +#[derive(Diagnostic)] +#[diag(rustdoc_generate_link_to_definition_option_can_only_be_used_with_html_output_format)] +pub(crate) struct GenerateLinkToDefinitionOptionCanOnlyBeUsedWithHtmlOutputFormat; + +#[derive(Diagnostic)] +#[diag(rustdoc_flag_is_deprecated)] +#[note] +pub(crate) struct FlagIsDeprecated<'a> { + pub(crate) flag: &'a str, +} + +#[derive(Diagnostic)] +#[diag(rustdoc_flag_no_longer_functions)] +#[note] +pub(crate) struct FlagNoLongerFunctions<'a> { + flag: &'a str, + #[subdiagnostic] + help: Option, + #[subdiagnostic] + warning: Option, +} + +#[derive(Subdiagnostic)] +#[help(rustdoc_may_want_to_use_document_private_items)] +pub(crate) struct MayWantToUseDocumentPrivateItems; + +#[derive(Subdiagnostic)] +#[warning(rustdoc_see_cve_2018_1000622)] +pub(crate) struct SeeCve20181000622; + +impl<'a> FlagNoLongerFunctions<'a> { + pub(crate) fn new(flag: &'a str) -> Self { + let (help, warning) = match flag { + "no-defaults" | "passes" => (Some(MayWantToUseDocumentPrivateItems), None), + "plugins" | "plugin-path" => (None, Some(SeeCve20181000622)), + _ => (None, None), + }; + Self { flag, help, warning } + } +} diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs index 88049c4ca0051..875d302d35d28 100644 --- a/src/librustdoc/externalfiles.rs +++ b/src/librustdoc/externalfiles.rs @@ -1,3 +1,4 @@ +use crate::errors::{LoadStringErrorBadUtf8, LoadStringErrorReadFail}; use crate::html::markdown::{ErrorCodes, HeadingOffset, IdMap, Markdown, Playground}; use crate::rustc_span::edition::Edition; use std::fs; @@ -83,14 +84,14 @@ pub(crate) fn load_string>( let contents = match fs::read(file_path) { Ok(bytes) => bytes, Err(e) => { - diag.struct_err(format!("error reading `{}`: {}", file_path.display(), e)).emit(); + diag.emit_err(LoadStringErrorReadFail { file_path, err: e }); return Err(LoadStringError::ReadFail); } }; match str::from_utf8(&contents) { Ok(s) => Ok(s.to_string()), Err(_) => { - diag.struct_err(format!("error reading `{}`: not UTF-8", file_path.display())).emit(); + diag.emit_err(LoadStringErrorBadUtf8 { file_path }); Err(LoadStringError::BadUtf8) } } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index eec230a14f187..8f8e3d110ffab 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -77,7 +77,7 @@ use std::env::{self, VarError}; use std::io::{self, IsTerminal}; use std::process; -use errors::{CouldntGenerateDocumentation, MainError}; +use errors::{CouldntGenerateDocumentation, FailedToCreateOrModifyFile}; use rustc_driver::abort_on_err; use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, SubdiagnosticMessage}; use rustc_fluent_macro::fluent_messages; @@ -689,10 +689,15 @@ fn usage(argv0: &str) { /// A result type used by several functions under `main()`. type MainResult = Result<(), ErrorGuaranteed>; +#[allow(rustc::untranslatable_diagnostic)] +#[allow(rustc::diagnostic_outside_of_impl)] fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainResult { match res { Ok(()) => diag.has_errors().map_or(Ok(()), Err), - Err(error) => Err(diag.emit_err(MainError { error })), + Err(err) => { + let reported = diag.struct_err(err).emit(); + Err(reported) + } } } @@ -704,10 +709,12 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>( ) -> MainResult { match formats::run_format::(krate, renderopts, cache, tcx) { Ok(_) => tcx.sess.has_errors().map_or(Ok(()), Err), - Err(e) => Err(tcx.sess.emit_err(CouldntGenerateDocumentation { - error: e.error, - file: e.file.display().to_string(), - })), + Err(e) => { + let file = e.file.display().to_string(); + let file = + if file.is_empty() { None } else { Some(FailedToCreateOrModifyFile { file }) }; + Err(tcx.sess.emit_err(CouldntGenerateDocumentation { error: e.error, file })) + } } } diff --git a/src/librustdoc/messages.ftl b/src/librustdoc/messages.ftl index 7e41b2cbf2fd7..46cbafc58f705 100644 --- a/src/librustdoc/messages.ftl +++ b/src/librustdoc/messages.ftl @@ -1,7 +1,64 @@ -rustdoc_main_error = {$error} - rustdoc_couldnt_generate_documentation = couldn't generate documentation: {$error} - .note = failed to create or modify "{$file}" + +rustdoc_failed_to_create_or_modify_file = failed to create or modify "{$file}" rustdoc_compilation_failed = compilation failed, aborting rustdoc + +rustdoc_load_string_error_read_fail = error reading `{$file_path}`: {$err} + +rustdoc_load_string_error_bad_utf8 = error reading `{$file_path}`: not UTF-8 + +rustdoc_arguments_to_theme_must_be_files = invalid argument: "{$theme}" + .help = arguments to --theme must be files + +rustdoc_arguments_to_theme_must_have_a_css_extension = invalid argument: "{$theme}" + .help = arguments to --theme must have a .css extension + +rustdoc_error_loading_theme_file = error loading theme file: "{$theme}" + +rustdoc_theme_file_missing_css_rules_from_default_theme = theme file "{$theme}" is missing CSS rules from the default theme + .warn = the theme may appear incorrect when loaded + .help = to see what rules are missing, call `rustdoc --check-theme "{$theme}"` + +rustdoc_scrape_examples_must_use_output_path_and_target_crate_together = must use --scrape-examples-output-path and --scrape-examples-target-crate together + +rustdoc_scrape_examples_must_use_output_path_and_target_crate_with_scrape_tests = must use --scrape-examples-output-path and --scrape-examples-target-crate with --scrape-tests + +rustdoc_load_examples_failed = failed to load examples: {$err} + +rustdoc_unrecognized_emission_type = unrecognized emission type: {$kind} + +rustdoc_missing_file_operand = missing file operand + +rustdoc_too_many_file_operands = too many file operands + +rustdoc_test_flag_must_be_passed_to_enable_no_run = the `--test` flag must be passed to enable `--no-run` + +rustdoc_cannot_use_both_out_dir_and_output_at_once = cannot use both 'out-dir' and 'output' at once + +rustdoc_extend_css_arg_must_be_a_file = option --extend-css argument must be a file + +rustdoc_unknown_input_format = unknown input format: {$format} + +rustdoc_index_page_arg_must_be_a_file = option `--index-page` argument must be a file + +rustdoc_unknown_crate_type = unknown crate type: {$err} + +rustdoc_html_output_format_unsupported_for_show_coverage_option = html output format isn't supported for the --show-coverage option + +rustdoc_generate_link_to_definition_option_can_only_be_used_with_html_output_format = --generate-link-to-definition option can only be used with HTML output format + +rustdoc_flag_is_deprecated = the `{$flag}` flag is deprecated + .note = + see issue #44136 + for more information, + +rustdoc_flag_no_longer_functions = the `{$flag}` flag no longer functions + .note = + see issue #44136 + for more information, + +rustdoc_may_want_to_use_document_private_items = you may want to use --document-private-items + +rustdoc_see_cve_2018_1000622 = see CVE-2018-1000622 diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index d2fa7769bbd2f..5a57fa44291b9 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -2,6 +2,9 @@ use crate::clean; use crate::config; +use crate::errors::LoadExamplesFailed; +use crate::errors::ScrapeExamplesMustUseOutputPathAndTargetCrateTogether; +use crate::errors::ScrapeExamplesMustUseOutputPathAndTargetCrateWithScrapeTests; use crate::formats; use crate::formats::renderer::FormatRenderer; use crate::html::render::Context; @@ -52,11 +55,11 @@ impl ScrapeExamplesOptions { scrape_tests, })), (Some(_), false, _) | (None, true, _) => { - diag.err("must use --scrape-examples-output-path and --scrape-examples-target-crate together"); + diag.emit_err(ScrapeExamplesMustUseOutputPathAndTargetCrateTogether); Err(1) } (None, false, true) => { - diag.err("must use --scrape-examples-output-path and --scrape-examples-target-crate with --scrape-tests"); + diag.emit_err(ScrapeExamplesMustUseOutputPathAndTargetCrateWithScrapeTests); Err(1) } (None, false, false) => Ok(None), @@ -272,6 +275,8 @@ where } } +#[allow(rustc::untranslatable_diagnostic)] +#[allow(rustc::diagnostic_outside_of_impl)] pub(crate) fn run( krate: clean::Crate, mut renderopts: config::RenderOptions, @@ -358,7 +363,7 @@ pub(crate) fn load_call_locations( }; inner().map_err(|e: String| { - diag.err(format!("failed to load examples: {}", e)); + diag.emit_err(LoadExamplesFailed { err: e }); 1 }) } diff --git a/src/librustdoc/theme.rs b/src/librustdoc/theme.rs index 722e01cd1fc72..523bf1ae89a3a 100644 --- a/src/librustdoc/theme.rs +++ b/src/librustdoc/theme.rs @@ -230,6 +230,8 @@ pub(crate) fn get_differences( } } +#[allow(rustc::untranslatable_diagnostic)] +#[allow(rustc::diagnostic_outside_of_impl)] pub(crate) fn test_theme_against>( f: &P, origin: &FxHashMap, diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 22c8cc092438c..0431fcdb47e65 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -183,8 +183,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { .unwrap_or(&[]) .iter() .filter_map(|attr| { + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] Cfg::parse(attr.meta_item()?) - .map_err(|e| self.cx.sess().diagnostic().span_err(e.span, e.msg)) + .map_err(|e| self.cx.sess().span_err(e.span, e.msg)) .ok() }) .collect::>() From cf544bd2b6305666df81aa856d3f67c99cda2c80 Mon Sep 17 00:00:00 2001 From: Nicky Lim Date: Mon, 7 Aug 2023 20:39:17 +0800 Subject: [PATCH 4/4] Temp commit --- tests/ui/issues/issue-21763.stderr | 3 --- tests/ui/mismatched_types/issue-36053-2.stderr | 1 + tests/ui/recursion/issue-83150.stderr | 3 ++- tests/ui/typeck/issue-31173.stderr | 1 + 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/ui/issues/issue-21763.stderr b/tests/ui/issues/issue-21763.stderr index df50118ac4774..a887635d35466 100644 --- a/tests/ui/issues/issue-21763.stderr +++ b/tests/ui/issues/issue-21763.stderr @@ -9,9 +9,6 @@ LL | foo::, Rc<()>>>(); = note: required for `hashbrown::raw::RawTable<(Rc<()>, Rc<()>)>` to implement `Send` note: required because it appears within the type `HashMap, Rc<()>, RandomState>` --> $HASHBROWN_SRC_LOCATION - | -LL | pub struct HashMap { - | ^^^^^^^ note: required because it appears within the type `HashMap, Rc<()>>` --> $SRC_DIR/std/src/collections/hash/map.rs:LL:COL note: required by a bound in `foo` diff --git a/tests/ui/mismatched_types/issue-36053-2.stderr b/tests/ui/mismatched_types/issue-36053-2.stderr index a6764a1dc6d31..e79826c058ab0 100644 --- a/tests/ui/mismatched_types/issue-36053-2.stderr +++ b/tests/ui/mismatched_types/issue-36053-2.stderr @@ -27,6 +27,7 @@ LL | once::<&str>("str").fuse().filter(|a: &str| true).count(); | = note: doesn't satisfy `_: Iterator` | + = note: the full type name has been written to '$TEST_BUILD_DIR/mismatched_types/issue-36053-2/issue-36053-2.long-type-15876109348482306250.txt' = note: the following trait bounds were not satisfied: `<[closure@$DIR/issue-36053-2.rs:7:39: 7:48] as FnOnce<(&&str,)>>::Output = bool` which is required by `Filter>, [closure@$DIR/issue-36053-2.rs:7:39: 7:48]>: Iterator` diff --git a/tests/ui/recursion/issue-83150.stderr b/tests/ui/recursion/issue-83150.stderr index eae58771a4169..c6f0f3263a652 100644 --- a/tests/ui/recursion/issue-83150.stderr +++ b/tests/ui/recursion/issue-83150.stderr @@ -12,7 +12,8 @@ LL | func(&mut iter.map(|x| x + 1)) error[E0275]: overflow evaluating the requirement `Map<&mut std::ops::Range, [closure@$DIR/issue-83150.rs:13:24: 13:27]>: Iterator` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`) - = note: required for `&mut Map<&mut std::ops::Range, [closure@$DIR/issue-83150.rs:13:24: 13:27]>` to implement `Iterator` + = note: required for `&mut Map<&mut Range, [closure@issue-83150.rs:13:24]>` to implement `Iterator` + = note: the full type name has been written to '$TEST_BUILD_DIR/recursion/issue-83150/issue-83150.long-type-hash.txt' = note: 65 redundant requirements hidden = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<..., ...>, ...>, ...>, ...>, ...>, ...>, ...>` to implement `Iterator` = note: the full type name has been written to '$TEST_BUILD_DIR/recursion/issue-83150/issue-83150.long-type-hash.txt' diff --git a/tests/ui/typeck/issue-31173.stderr b/tests/ui/typeck/issue-31173.stderr index b622122f33ea7..df42941ff6afd 100644 --- a/tests/ui/typeck/issue-31173.stderr +++ b/tests/ui/typeck/issue-31173.stderr @@ -42,6 +42,7 @@ LL | | .collect(); | = note: doesn't satisfy `_: Iterator` | + = note: the full type name has been written to '$TEST_BUILD_DIR/typeck/issue-31173/issue-31173.long-type-16947039427408058100.txt' = note: the following trait bounds were not satisfied: `, [closure@$DIR/issue-31173.rs:7:21: 7:25]> as Iterator>::Item = &_` which is required by `Cloned, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`