diff --git a/Cargo.lock b/Cargo.lock index c83763be3d893..d261948a2dfe0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1235,40 +1235,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "fluent-bundle" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e242c601dec9711505f6d5bbff5bedd4b61b2469f2e8bb8e57ee7c9747a87ffd" -dependencies = [ - "fluent-langneg", - "fluent-syntax", - "intl-memoizer", - "intl_pluralrules", - "rustc-hash", - "self_cell", - "smallvec", - "unic-langid", -] - -[[package]] -name = "fluent-langneg" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94" -dependencies = [ - "unic-langid", -] - -[[package]] -name = "fluent-syntax" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0abed97648395c902868fee9026de96483933faa54ea3b40d652f7dfe61ca78" -dependencies = [ - "thiserror", -] - [[package]] name = "fnv" version = "1.0.7" @@ -1813,26 +1779,6 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "intl-memoizer" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c310433e4a310918d6ed9243542a6b83ec1183df95dff8f23f87bb88a264a66f" -dependencies = [ - "type-map", - "unic-langid", -] - -[[package]] -name = "intl_pluralrules" -version = "7.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b18f988384267d7066cc2be425e6faf352900652c046b6971d2e228d3b1c5ecf" -dependencies = [ - "tinystr", - "unic-langid", -] - [[package]] name = "itertools" version = "0.10.1" @@ -2863,12 +2809,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - [[package]] name = "proc-macro2" version = "1.0.30" @@ -3702,21 +3642,6 @@ dependencies = [ name = "rustc_error_codes" version = "0.0.0" -[[package]] -name = "rustc_error_messages" -version = "0.0.0" -dependencies = [ - "fluent-bundle", - "fluent-syntax", - "intl-memoizer", - "rustc_data_structures", - "rustc_macros", - "rustc_serialize", - "rustc_span", - "tracing", - "unic-langid", -] - [[package]] name = "rustc_errors" version = "0.0.0" @@ -3724,7 +3649,6 @@ dependencies = [ "annotate-snippets", "atty", "rustc_data_structures", - "rustc_error_messages", "rustc_lint_defs", "rustc_macros", "rustc_serialize", @@ -3781,7 +3705,6 @@ dependencies = [ "odht", "rustc_ast", "rustc_data_structures", - "rustc_error_messages", "rustc_feature", "rustc_index", "rustc_macros", @@ -3938,7 +3861,6 @@ version = "0.0.0" dependencies = [ "rustc_ast", "rustc_data_structures", - "rustc_error_messages", "rustc_hir", "rustc_macros", "rustc_serialize", @@ -4648,12 +4570,6 @@ dependencies = [ "libc", ] -[[package]] -name = "self_cell" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af" - [[package]] name = "semver" version = "1.0.3" @@ -5185,12 +5101,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "tinystr" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29738eedb4388d9ea620eeab9384884fc3f06f586a2eddb56bedc5885126c7c1" - [[package]] name = "tinyvec" version = "0.3.4" @@ -5349,15 +5259,6 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "type-map" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d3364c5e96cb2ad1603037ab253ddd34d7fb72a58bdddf4b7350760fc69a46" -dependencies = [ - "rustc-hash", -] - [[package]] name = "typenum" version = "1.12.0" @@ -5412,49 +5313,6 @@ dependencies = [ "unic-ucd-version", ] -[[package]] -name = "unic-langid" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73328fcd730a030bdb19ddf23e192187a6b01cd98be6d3140622a89129459ce5" -dependencies = [ - "unic-langid-impl", - "unic-langid-macros", -] - -[[package]] -name = "unic-langid-impl" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a4a8eeaf0494862c1404c95ec2f4c33a2acff5076f64314b465e3ddae1b934d" -dependencies = [ - "tinystr", -] - -[[package]] -name = "unic-langid-macros" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18f980d6d87e8805f2836d64b4138cc95aa7986fa63b1f51f67d5fbff64dd6e5" -dependencies = [ - "proc-macro-hack", - "tinystr", - "unic-langid-impl", - "unic-langid-macros-impl", -] - -[[package]] -name = "unic-langid-macros-impl" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29396ffd97e27574c3e01368b1a64267d3064969e4848e2e130ff668be9daa9f" -dependencies = [ - "proc-macro-hack", - "quote", - "syn", - "unic-langid-impl", -] - [[package]] name = "unic-ucd-version" version = "0.9.0" diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 70f7f1e493e07..21b582ef3345b 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -1,6 +1,6 @@ -use rustc_errors::{struct_span_err, DiagnosticBuilder, DiagnosticId, ErrorGuaranteed, MultiSpan}; +use rustc_errors::{struct_span_err, DiagnosticBuilder, DiagnosticId, ErrorGuaranteed}; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_span::Span; +use rustc_span::{MultiSpan, Span}; impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { crate fn cannot_move_when_borrowed( diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index b945d687043b4..7045ef517156b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1,7 +1,7 @@ use either::Either; use rustc_const_eval::util::CallKind; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; +use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::{AsyncGeneratorKind, GeneratorKind}; @@ -15,7 +15,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::{self, subst::Subst, suggest_constraining_type_params, PredicateKind, Ty}; use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex}; use rustc_span::symbol::sym; -use rustc_span::{BytePos, Span}; +use rustc_span::{BytePos, MultiSpan, Span}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::TraitEngineExt as _; diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 723adb8da1b17..c9395492c9e06 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -109,7 +109,7 @@ impl RegionName { *span, format!("lifetime `{}` represents this closure's body", self), ); - diag.note(note); + diag.note(¬e); } RegionNameSource::AnonRegionFromArgument(RegionNameHighlight::CannotMatchHirTy( span, diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 138e1fa017603..31213412d45f2 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -7,11 +7,11 @@ use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{self, Visitor}; use rustc_ast::{token, BlockCheckMode, UnsafeSource}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{pluralize, Applicability, MultiSpan, PResult}; +use rustc_errors::{pluralize, Applicability, PResult}; use rustc_expand::base::{self, *}; use rustc_parse_format as parse; use rustc_span::symbol::{sym, Ident, Symbol}; -use rustc_span::{InnerSpan, Span}; +use rustc_span::{InnerSpan, MultiSpan, Span}; use smallvec::SmallVec; use std::borrow::Cow; @@ -446,9 +446,7 @@ impl<'a, 'b> Context<'a, 'b> { .iter() .filter(|fmt| fmt.precision_span.is_some()) .count(); - e.span_label( - span, - &format!( + e.span_label(span, &format!( "this precision flag adds an extra required argument at position {}, \ which is why there {} expected", pos, @@ -457,8 +455,7 @@ impl<'a, 'b> Context<'a, 'b> { } else { format!("are {} arguments", count) }, - ), - ); + )); if let Some(arg) = self.args.get(pos) { e.span_label( arg.span, diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 92c4ab7eb8627..9417874ffb40b 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1707,33 +1707,23 @@ impl SharedEmitter { impl Emitter for SharedEmitter { fn emit_diagnostic(&mut self, diag: &rustc_errors::Diagnostic) { - let fluent_args = self.to_fluent_args(diag.args()); drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic { - msg: self.translate_messages(&diag.message, &fluent_args).to_string(), + msg: diag.message(), code: diag.code.clone(), lvl: diag.level(), }))); for child in &diag.children { drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic { - msg: self.translate_messages(&child.message, &fluent_args).to_string(), + msg: child.message(), code: None, lvl: child.level, }))); } drop(self.sender.send(SharedEmitterMessage::AbortIfErrors)); } - fn source_map(&self) -> Option<&Lrc> { None } - - fn fluent_bundle(&self) -> Option<&Lrc> { - None - } - - fn fallback_fluent_bundle(&self) -> &Lrc { - panic!("shared emitter attempted to translate a diagnostic"); - } } impl SharedEmitterMain { @@ -1764,9 +1754,9 @@ impl SharedEmitterMain { let msg = msg.strip_prefix("error: ").unwrap_or(&msg); let mut err = match level { - Level::Error { lint: false } => sess.struct_err(msg).forget_guarantee(), - Level::Warning => sess.struct_warn(msg), - Level::Note => sess.struct_note_without_error(msg), + Level::Error { lint: false } => sess.struct_err(&msg).forget_guarantee(), + Level::Warning => sess.struct_warn(&msg), + Level::Note => sess.struct_note_without_error(&msg), _ => bug!("Invalid inline asm diagnostic level"), }; diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index febdd0ed74675..69f96d07f905d 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1172,13 +1172,9 @@ static DEFAULT_HOOK: SyncLazy) + Sync + Send + /// When `install_ice_hook` is called, this function will be called as the panic /// hook. pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(false).expect("failed to load fallback fluent bundle"); let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr( rustc_errors::ColorConfig::Auto, None, - None, - fallback_bundle, false, false, None, @@ -1213,7 +1209,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { } for note in &xs { - handler.note_without_error(note.as_ref()); + handler.note_without_error(note); } // If backtraces are enabled, also print the query stack diff --git a/compiler/rustc_error_messages/Cargo.toml b/compiler/rustc_error_messages/Cargo.toml deleted file mode 100644 index fc84c7c8665b4..0000000000000 --- a/compiler/rustc_error_messages/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "rustc_error_messages" -version = "0.0.0" -edition = "2021" - -[lib] -doctest = false - -[dependencies] -fluent-bundle = "0.15.2" -fluent-syntax = "0.11" -intl-memoizer = "0.5.1" -rustc_data_structures = { path = "../rustc_data_structures" } -rustc_serialize = { path = "../rustc_serialize" } -rustc_span = { path = "../rustc_span" } -rustc_macros = { path = "../rustc_macros" } -tracing = "0.1" -unic-langid = { version = "0.9.0", features = ["macros"] } diff --git a/compiler/rustc_error_messages/locales/en-US/diagnostics.ftl b/compiler/rustc_error_messages/locales/en-US/diagnostics.ftl deleted file mode 100644 index 336e7a6685708..0000000000000 --- a/compiler/rustc_error_messages/locales/en-US/diagnostics.ftl +++ /dev/null @@ -1,87 +0,0 @@ -parser-struct-literal-body-without-path = - struct literal body without path - .suggestion = you might have forgotten to add the struct literal inside the block - -typeck-field-multiply-specified-in-initializer = - field `{$ident}` specified more than once - .label = used more than once - .previous-use-label = first use of `{$ident}` - -typeck-unrecognized-atomic-operation = - unrecognized atomic operation function: `{$op}` - .label = unrecognized atomic operation - -typeck-wrong-number-of-generic-arguments-to-intrinsic = - intrinsic has wrong number of {$descr} parameters: found {$found}, expected {$expected} - .label = expected {$expected} {$descr} {$expected -> - [one] parameter - *[other] parameters - } - -typeck-unrecognized-intrinsic-function = - unrecognized intrinsic function: `{$name}` - .label = unrecognized intrinsic - -typeck-lifetimes-or-bounds-mismatch-on-trait = - lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration - .label = lifetimes do not match {$item_kind} in trait - .generics-label = lifetimes in impl do not match this {$item_kind} in trait - -typeck-drop-impl-on-wrong-item = - the `Drop` trait may only be implemented for structs, enums, and unions - .label = must be a struct, enum, or union - -typeck-field-already-declared = - field `{$field_name}` is already declared - .label = field already declared - .previous-decl-label = `{$field_name}` first declared here - -typeck-copy-impl-on-type-with-dtor = - the trait `Copy` may not be implemented for this type; the type has a destructor - .label = `Copy` not allowed on types with destructors - -typeck-multiple-relaxed-default-bounds = - type parameter has more than one relaxed default bound, only one is supported - -typeck-copy-impl-on-non-adt = - the trait `Copy` may not be implemented for this type - .label = type is not a structure or enumeration - -typeck-trait-object-declared-with-no-traits = - at least one trait is required for an object type - -typeck-ambiguous-lifetime-bound = - ambiguous lifetime bound, explicit lifetime bound required - -typeck-assoc-type-binding-not-allowed = - associated type bindings are not allowed here - .label = associated type not allowed here - -typeck-functional-record-update-on-non-struct = - functional record update syntax requires a struct - -typeck-typeof-reserved-keyword-used = - `typeof` is a reserved keyword but unimplemented - .label = reserved keyword - -typeck-return-stmt-outside-of-fn-body = - return statement outside of function body - .encl-body-label = the return is part of this body... - .encl-fn-label = ...not the enclosing function body - -typeck-yield-expr-outside-of-generator = - yield expression outside of generator literal - -typeck-struct-expr-non-exhaustive = - cannot create non-exhaustive {$what} using struct expression - -typeck-method-call-on-unknown-type = - the type of this value must be known to call a method on a raw pointer on it - -typeck-value-of-associated-struct-already-specified = - the value of the associated type `{$item_name}` (from trait `{$def_path}`) is already specified - .label = re-bound here - .previous-bound-label = `{$item_name}` bound here first - -typeck-address-of-temporary-taken = cannot take address of a temporary - .label = temporary value diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs deleted file mode 100644 index 88f3b547605a2..0000000000000 --- a/compiler/rustc_error_messages/src/lib.rs +++ /dev/null @@ -1,390 +0,0 @@ -#![feature(let_chains)] -#![feature(path_try_exists)] - -use fluent_bundle::FluentResource; -use fluent_syntax::parser::ParserError; -use rustc_data_structures::sync::Lrc; -use rustc_macros::{Decodable, Encodable}; -use rustc_span::Span; -use std::borrow::Cow; -use std::error::Error; -use std::fmt; -use std::fs; -use std::io; -use std::path::Path; -use tracing::{instrument, trace}; - -#[cfg(parallel_compiler)] -use intl_memoizer::concurrent::IntlLangMemoizer; -#[cfg(not(parallel_compiler))] -use intl_memoizer::IntlLangMemoizer; - -pub use fluent_bundle::{FluentArgs, FluentError, FluentValue}; -pub use unic_langid::{langid, LanguageIdentifier}; - -static FALLBACK_FLUENT_RESOURCE: &'static str = include_str!("../locales/en-US/diagnostics.ftl"); - -pub type FluentBundle = fluent_bundle::bundle::FluentBundle; - -#[cfg(parallel_compiler)] -fn new_bundle(locales: Vec) -> FluentBundle { - FluentBundle::new_concurrent(locales) -} - -#[cfg(not(parallel_compiler))] -fn new_bundle(locales: Vec) -> FluentBundle { - FluentBundle::new(locales) -} - -#[derive(Debug)] -pub enum TranslationBundleError { - /// Failed to read from `.ftl` file. - ReadFtl(io::Error), - /// Failed to parse contents of `.ftl` file. - ParseFtl(ParserError), - /// Failed to add `FluentResource` to `FluentBundle`. - AddResource(FluentError), - /// `$sysroot/share/locale/$locale` does not exist. - MissingLocale(io::Error), - /// Cannot read directory entries of `$sysroot/share/locale/$locale`. - ReadLocalesDir(io::Error), - /// Cannot read directory entry of `$sysroot/share/locale/$locale`. - ReadLocalesDirEntry(io::Error), - /// `$sysroot/share/locale/$locale` is not a directory. - LocaleIsNotDir, -} - -impl fmt::Display for TranslationBundleError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - TranslationBundleError::ReadFtl(e) => write!(f, "could not read ftl file: {}", e), - TranslationBundleError::ParseFtl(e) => { - write!(f, "could not parse ftl file: {}", e) - } - TranslationBundleError::AddResource(e) => write!(f, "failed to add resource: {}", e), - TranslationBundleError::MissingLocale(e) => { - write!(f, "missing locale directory: {}", e) - } - TranslationBundleError::ReadLocalesDir(e) => { - write!(f, "could not read locales dir: {}", e) - } - TranslationBundleError::ReadLocalesDirEntry(e) => { - write!(f, "could not read locales dir entry: {}", e) - } - TranslationBundleError::LocaleIsNotDir => { - write!(f, "`$sysroot/share/locales/$locale` is not a directory") - } - } - } -} - -impl Error for TranslationBundleError { - fn source(&self) -> Option<&(dyn Error + 'static)> { - match self { - TranslationBundleError::ReadFtl(e) => Some(e), - TranslationBundleError::ParseFtl(e) => Some(e), - TranslationBundleError::AddResource(e) => Some(e), - TranslationBundleError::MissingLocale(e) => Some(e), - TranslationBundleError::ReadLocalesDir(e) => Some(e), - TranslationBundleError::ReadLocalesDirEntry(e) => Some(e), - TranslationBundleError::LocaleIsNotDir => None, - } - } -} - -impl From<(FluentResource, Vec)> for TranslationBundleError { - fn from((_, mut errs): (FluentResource, Vec)) -> Self { - TranslationBundleError::ParseFtl(errs.pop().expect("failed ftl parse with no errors")) - } -} - -impl From> for TranslationBundleError { - fn from(mut errs: Vec) -> Self { - TranslationBundleError::AddResource( - errs.pop().expect("failed adding resource to bundle with no errors"), - ) - } -} - -/// Returns Fluent bundle with the user's locale resources from -/// `$sysroot/share/locale/$requested_locale/*.ftl`. -/// -/// If `-Z additional-ftl-path` was provided, load that resource and add it to the bundle -/// (overriding any conflicting messages). -#[instrument(level = "trace")] -pub fn fluent_bundle( - sysroot: &Path, - requested_locale: Option, - additional_ftl_path: Option<&Path>, - with_directionality_markers: bool, -) -> Result>, TranslationBundleError> { - if requested_locale.is_none() && additional_ftl_path.is_none() { - return Ok(None); - } - - let fallback_locale = langid!("en-US"); - let requested_fallback_locale = requested_locale.as_ref() == Some(&fallback_locale); - - // If there is only `-Z additional-ftl-path`, assume locale is "en-US", otherwise use user - // provided locale. - let locale = requested_locale.clone().unwrap_or(fallback_locale); - trace!(?locale); - let mut bundle = new_bundle(vec![locale]); - - // Fluent diagnostics can insert directionality isolation markers around interpolated variables - // indicating that there may be a shift from right-to-left to left-to-right text (or - // vice-versa). These are disabled because they are sometimes visible in the error output, but - // may be worth investigating in future (for example: if type names are left-to-right and the - // surrounding diagnostic messages are right-to-left, then these might be helpful). - bundle.set_use_isolating(with_directionality_markers); - - // If the user requests the default locale then don't try to load anything. - if !requested_fallback_locale && let Some(requested_locale) = requested_locale { - let mut sysroot = sysroot.to_path_buf(); - sysroot.push("share"); - sysroot.push("locale"); - sysroot.push(requested_locale.to_string()); - trace!(?sysroot); - - let _ = sysroot.try_exists().map_err(TranslationBundleError::MissingLocale)?; - - if !sysroot.is_dir() { - return Err(TranslationBundleError::LocaleIsNotDir); - } - - for entry in sysroot.read_dir().map_err(TranslationBundleError::ReadLocalesDir)? { - let entry = entry.map_err(TranslationBundleError::ReadLocalesDirEntry)?; - let path = entry.path(); - trace!(?path); - if path.extension().and_then(|s| s.to_str()) != Some("ftl") { - trace!("skipping"); - continue; - } - - let resource_str = - fs::read_to_string(path).map_err(TranslationBundleError::ReadFtl)?; - let resource = - FluentResource::try_new(resource_str).map_err(TranslationBundleError::from)?; - trace!(?resource); - bundle.add_resource(resource).map_err(TranslationBundleError::from)?; - } - } - - if let Some(additional_ftl_path) = additional_ftl_path { - let resource_str = - fs::read_to_string(additional_ftl_path).map_err(TranslationBundleError::ReadFtl)?; - let resource = - FluentResource::try_new(resource_str).map_err(TranslationBundleError::from)?; - trace!(?resource); - bundle.add_resource_overriding(resource); - } - - let bundle = Lrc::new(bundle); - Ok(Some(bundle)) -} - -/// Return the default `FluentBundle` with standard "en-US" diagnostic messages. -#[instrument(level = "trace")] -pub fn fallback_fluent_bundle( - with_directionality_markers: bool, -) -> Result, TranslationBundleError> { - let fallback_resource = FluentResource::try_new(FALLBACK_FLUENT_RESOURCE.to_string()) - .map_err(TranslationBundleError::from)?; - trace!(?fallback_resource); - let mut fallback_bundle = new_bundle(vec![langid!("en-US")]); - // See comment in `fluent_bundle`. - fallback_bundle.set_use_isolating(with_directionality_markers); - fallback_bundle.add_resource(fallback_resource).map_err(TranslationBundleError::from)?; - let fallback_bundle = Lrc::new(fallback_bundle); - Ok(fallback_bundle) -} - -/// Identifier for the Fluent message/attribute corresponding to a diagnostic message. -type FluentId = Cow<'static, str>; - -/// Abstraction over a message in a diagnostic to support both translatable and non-translatable -/// diagnostic messages. -/// -/// Intended to be removed once diagnostics are entirely translatable. -#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] -pub enum DiagnosticMessage { - /// Non-translatable diagnostic message. - // FIXME(davidtwco): can a `Cow<'static, str>` be used here? - Str(String), - /// Identifier for a Fluent message (with optional attribute) corresponding to the diagnostic - /// message. - /// - /// - /// - FluentIdentifier(FluentId, Option), -} - -impl DiagnosticMessage { - /// Returns the `String` contained within the `DiagnosticMessage::Str` variant, assuming that - /// this diagnostic message is of the legacy, non-translatable variety. Panics if this - /// assumption does not hold. - /// - /// Don't use this - it exists to support some places that do comparison with diagnostic - /// strings. - pub fn expect_str(&self) -> &str { - match self { - DiagnosticMessage::Str(s) => s, - _ => panic!("expected non-translatable diagnostic message"), - } - } - - /// Create a `DiagnosticMessage` for the provided Fluent identifier. - pub fn fluent(id: impl Into) -> Self { - DiagnosticMessage::FluentIdentifier(id.into(), None) - } - - /// Create a `DiagnosticMessage` for the provided Fluent identifier and attribute. - pub fn fluent_attr(id: impl Into, attr: impl Into) -> Self { - DiagnosticMessage::FluentIdentifier(id.into(), Some(attr.into())) - } -} - -/// `From` impl that enables existing diagnostic calls to functions which now take -/// `impl Into` to continue to work as before. -impl> From for DiagnosticMessage { - fn from(s: S) -> Self { - DiagnosticMessage::Str(s.into()) - } -} - -/// A span together with some additional data. -#[derive(Clone, Debug)] -pub struct SpanLabel { - /// The span we are going to include in the final snippet. - pub span: Span, - - /// Is this a primary span? This is the "locus" of the message, - /// and is indicated with a `^^^^` underline, versus `----`. - pub is_primary: bool, - - /// What label should we attach to this span (if any)? - pub label: Option, -} - -/// A collection of `Span`s. -/// -/// Spans have two orthogonal attributes: -/// -/// - They can be *primary spans*. In this case they are the locus of -/// the error, and would be rendered with `^^^`. -/// - They can have a *label*. In this case, the label is written next -/// to the mark in the snippet when we render. -#[derive(Clone, Debug, Hash, PartialEq, Eq, Encodable, Decodable)] -pub struct MultiSpan { - primary_spans: Vec, - span_labels: Vec<(Span, DiagnosticMessage)>, -} - -impl MultiSpan { - #[inline] - pub fn new() -> MultiSpan { - MultiSpan { primary_spans: vec![], span_labels: vec![] } - } - - pub fn from_span(primary_span: Span) -> MultiSpan { - MultiSpan { primary_spans: vec![primary_span], span_labels: vec![] } - } - - pub fn from_spans(mut vec: Vec) -> MultiSpan { - vec.sort(); - MultiSpan { primary_spans: vec, span_labels: vec![] } - } - - pub fn push_span_label(&mut self, span: Span, label: impl Into) { - self.span_labels.push((span, label.into())); - } - - /// Selects the first primary span (if any). - pub fn primary_span(&self) -> Option { - self.primary_spans.first().cloned() - } - - /// Returns all primary spans. - pub fn primary_spans(&self) -> &[Span] { - &self.primary_spans - } - - /// Returns `true` if any of the primary spans are displayable. - pub fn has_primary_spans(&self) -> bool { - self.primary_spans.iter().any(|sp| !sp.is_dummy()) - } - - /// Returns `true` if this contains only a dummy primary span with any hygienic context. - pub fn is_dummy(&self) -> bool { - let mut is_dummy = true; - for span in &self.primary_spans { - if !span.is_dummy() { - is_dummy = false; - } - } - is_dummy - } - - /// Replaces all occurrences of one Span with another. Used to move `Span`s in areas that don't - /// display well (like std macros). Returns whether replacements occurred. - pub fn replace(&mut self, before: Span, after: Span) -> bool { - let mut replacements_occurred = false; - for primary_span in &mut self.primary_spans { - if *primary_span == before { - *primary_span = after; - replacements_occurred = true; - } - } - for span_label in &mut self.span_labels { - if span_label.0 == before { - span_label.0 = after; - replacements_occurred = true; - } - } - replacements_occurred - } - - /// Returns the strings to highlight. We always ensure that there - /// is an entry for each of the primary spans -- for each primary - /// span `P`, if there is at least one label with span `P`, we return - /// those labels (marked as primary). But otherwise we return - /// `SpanLabel` instances with empty labels. - pub fn span_labels(&self) -> Vec { - let is_primary = |span| self.primary_spans.contains(&span); - - let mut span_labels = self - .span_labels - .iter() - .map(|&(span, ref label)| SpanLabel { - span, - is_primary: is_primary(span), - label: Some(label.clone()), - }) - .collect::>(); - - for &span in &self.primary_spans { - if !span_labels.iter().any(|sl| sl.span == span) { - span_labels.push(SpanLabel { span, is_primary: true, label: None }); - } - } - - span_labels - } - - /// Returns `true` if any of the span labels is displayable. - pub fn has_span_labels(&self) -> bool { - self.span_labels.iter().any(|(sp, _)| !sp.is_dummy()) - } -} - -impl From for MultiSpan { - fn from(span: Span) -> MultiSpan { - MultiSpan::from_span(span) - } -} - -impl From> for MultiSpan { - fn from(spans: Vec) -> MultiSpan { - MultiSpan::from_spans(spans) - } -} diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index 5f919982890e0..4846dc43605f8 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -8,7 +8,6 @@ doctest = false [dependencies] tracing = "0.1" -rustc_error_messages = { path = "../rustc_error_messages" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 003fd1eea3ace..5f59eba23f8e9 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -7,23 +7,16 @@ use crate::emitter::FileWithAnnotatedLines; use crate::snippet::Line; -use crate::{ - CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage, Emitter, FluentBundle, Level, - MultiSpan, Style, SubDiagnostic, -}; +use crate::{CodeSuggestion, Diagnostic, DiagnosticId, Emitter, Level, SubDiagnostic}; use annotate_snippets::display_list::{DisplayList, FormatOptions}; use annotate_snippets::snippet::*; use rustc_data_structures::sync::Lrc; -use rustc_error_messages::FluentArgs; use rustc_span::source_map::SourceMap; -use rustc_span::SourceFile; +use rustc_span::{MultiSpan, SourceFile}; /// Generates diagnostics using annotate-snippet pub struct AnnotateSnippetEmitterWriter { source_map: Option>, - fluent_bundle: Option>, - fallback_bundle: Lrc, - /// If true, hides the longer explanation text short_message: bool, /// If true, will normalize line numbers with `LL` to prevent noise in UI test diffs. @@ -35,10 +28,8 @@ pub struct AnnotateSnippetEmitterWriter { impl Emitter for AnnotateSnippetEmitterWriter { /// The entry point for the diagnostics generation fn emit_diagnostic(&mut self, diag: &Diagnostic) { - let fluent_args = self.to_fluent_args(diag.args()); - let mut children = diag.children.clone(); - let (mut primary_span, suggestions) = self.primary_span_formatted(&diag, &fluent_args); + let (mut primary_span, suggestions) = self.primary_span_formatted(&diag); self.fix_multispans_in_extern_macros_and_render_macro_backtrace( &self.source_map, @@ -50,8 +41,7 @@ impl Emitter for AnnotateSnippetEmitterWriter { self.emit_messages_default( &diag.level, - &diag.message, - &fluent_args, + diag.message(), &diag.code, &primary_span, &children, @@ -63,14 +53,6 @@ impl Emitter for AnnotateSnippetEmitterWriter { self.source_map.as_ref() } - fn fluent_bundle(&self) -> Option<&Lrc> { - self.fluent_bundle.as_ref() - } - - fn fallback_fluent_bundle(&self) -> &Lrc { - &self.fallback_bundle - } - fn should_show_explain(&self) -> bool { !self.short_message } @@ -100,19 +82,10 @@ fn annotation_type_for_level(level: Level) -> AnnotationType { impl AnnotateSnippetEmitterWriter { pub fn new( source_map: Option>, - fluent_bundle: Option>, - fallback_bundle: Lrc, short_message: bool, macro_backtrace: bool, ) -> Self { - Self { - source_map, - fluent_bundle, - fallback_bundle, - short_message, - ui_testing: false, - macro_backtrace, - } + Self { source_map, short_message, ui_testing: false, macro_backtrace } } /// Allows to modify `Self` to enable or disable the `ui_testing` flag. @@ -126,14 +99,12 @@ impl AnnotateSnippetEmitterWriter { fn emit_messages_default( &mut self, level: &Level, - messages: &[(DiagnosticMessage, Style)], - args: &FluentArgs<'_>, + message: String, code: &Option, msp: &MultiSpan, _children: &[SubDiagnostic], _suggestions: &[CodeSuggestion], ) { - let message = self.translate_messages(messages, args); if let Some(source_map) = &self.source_map { // Make sure our primary file comes first let primary_lo = if let Some(ref primary_span) = msp.primary_span().as_ref() { @@ -149,7 +120,8 @@ impl AnnotateSnippetEmitterWriter { // should be done if it happens return; }; - let mut annotated_files = FileWithAnnotatedLines::collect_annotations(self, args, msp); + let mut annotated_files = + FileWithAnnotatedLines::collect_annotations(msp, &self.source_map); if let Ok(pos) = annotated_files.binary_search_by(|x| x.file.name.cmp(&primary_lo.file.name)) { diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index ecb3cdd627cec..32c52a6a8a6d9 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -1,16 +1,15 @@ use crate::snippet::Style; -use crate::{ - CodeSuggestion, DiagnosticMessage, Level, MultiSpan, Substitution, SubstitutionPart, - SuggestionStyle, ToolMetadata, -}; +use crate::CodeSuggestion; +use crate::Level; +use crate::Substitution; +use crate::SubstitutionPart; +use crate::SuggestionStyle; +use crate::ToolMetadata; use rustc_data_structures::stable_map::FxHashMap; -use rustc_error_messages::FluentValue; use rustc_lint_defs::{Applicability, LintExpectationId}; use rustc_serialize::json::Json; use rustc_span::edition::LATEST_STABLE_EDITION; -use rustc_span::symbol::{Ident, Symbol}; -use rustc_span::{Span, DUMMY_SP}; -use std::borrow::Cow; +use rustc_span::{MultiSpan, Span, DUMMY_SP}; use std::fmt; use std::hash::{Hash, Hasher}; @@ -19,66 +18,6 @@ use std::hash::{Hash, Hasher}; #[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] pub struct SuggestionsDisabled; -/// Simplified version of `FluentArg` that can implement `Encodable` and `Decodable`. Collection of -/// `DiagnosticArg` are converted to `FluentArgs` (consuming the collection) at the start of -/// diagnostic emission. -pub type DiagnosticArg<'source> = (Cow<'source, str>, DiagnosticArgValue<'source>); - -/// Simplified version of `FluentValue` that can implement `Encodable` and `Decodable`. Converted -/// to a `FluentValue` by the emitter to be used in diagnostic translation. -#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] -pub enum DiagnosticArgValue<'source> { - Str(Cow<'source, str>), - Number(usize), -} - -/// Converts a value of a type into a `DiagnosticArg` (typically a field of a `SessionDiagnostic` -/// struct). Implemented as a custom trait rather than `From` so that it is implemented on the type -/// being converted rather than on `DiagnosticArgValue`, which enables types from other `rustc_*` -/// crates to implement this. -pub trait IntoDiagnosticArg { - fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static>; -} - -impl IntoDiagnosticArg for String { - fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { - DiagnosticArgValue::Str(Cow::Owned(self)) - } -} - -impl IntoDiagnosticArg for Symbol { - fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { - self.to_ident_string().into_diagnostic_arg() - } -} - -impl IntoDiagnosticArg for Ident { - fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { - self.to_string().into_diagnostic_arg() - } -} - -impl<'a> IntoDiagnosticArg for &'a str { - fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { - self.to_string().into_diagnostic_arg() - } -} - -impl IntoDiagnosticArg for usize { - fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { - DiagnosticArgValue::Number(self) - } -} - -impl<'source> Into> for DiagnosticArgValue<'source> { - fn into(self) -> FluentValue<'source> { - match self { - DiagnosticArgValue::Str(s) => From::from(s), - DiagnosticArgValue::Number(n) => From::from(n), - } - } -} - #[must_use] #[derive(Clone, Debug, Encodable, Decodable)] pub struct Diagnostic { @@ -86,12 +25,11 @@ pub struct Diagnostic { // outside of what methods in this crate themselves allow. crate level: Level, - pub message: Vec<(DiagnosticMessage, Style)>, + pub message: Vec<(String, Style)>, pub code: Option, pub span: MultiSpan, pub children: Vec, pub suggestions: Result, SuggestionsDisabled>, - args: Vec>, /// This is not used for highlighting or rendering any error message. Rather, it can be used /// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of @@ -114,7 +52,7 @@ pub enum DiagnosticId { #[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)] pub struct SubDiagnostic { pub level: Level, - pub message: Vec<(DiagnosticMessage, Style)>, + pub message: Vec<(String, Style)>, pub span: MultiSpan, pub render_span: Option, } @@ -167,23 +105,18 @@ impl StringPart { } impl Diagnostic { - pub fn new>(level: Level, message: M) -> Self { + pub fn new(level: Level, message: &str) -> Self { Diagnostic::new_with_code(level, None, message) } - pub fn new_with_code>( - level: Level, - code: Option, - message: M, - ) -> Self { + pub fn new_with_code(level: Level, code: Option, message: &str) -> Self { Diagnostic { level, - message: vec![(message.into(), Style::NoStyle)], + message: vec![(message.to_owned(), Style::NoStyle)], code, span: MultiSpan::new(), children: vec![], suggestions: Ok(vec![]), - args: vec![], sort_span: DUMMY_SP, is_lint: false, } @@ -277,7 +210,7 @@ impl Diagnostic { /// /// This span is *not* considered a ["primary span"][`MultiSpan`]; only /// the `Span` supplied when creating the diagnostic is primary. - pub fn span_label(&mut self, span: Span, label: impl Into) -> &mut Self { + pub fn span_label>(&mut self, span: Span, label: T) -> &mut Self { self.span.push_span_label(span, label.into()); self } @@ -301,7 +234,7 @@ impl Diagnostic { self.set_span(after); for span_label in before.span_labels() { if let Some(label) = span_label.label { - self.span.push_span_label(after, label); + self.span_label(after, label); } } self @@ -395,67 +328,52 @@ impl Diagnostic { } /// Add a note attached to this diagnostic. - pub fn note(&mut self, msg: impl Into) -> &mut Self { + pub fn note(&mut self, msg: &str) -> &mut Self { self.sub(Level::Note, msg, MultiSpan::new(), None); self } - pub fn highlighted_note>( - &mut self, - msg: Vec<(M, Style)>, - ) -> &mut Self { + pub fn highlighted_note(&mut self, msg: Vec<(String, Style)>) -> &mut Self { self.sub_with_highlights(Level::Note, msg, MultiSpan::new(), None); self } /// Prints the span with a note above it. /// This is like [`Diagnostic::note()`], but it gets its own span. - pub fn note_once(&mut self, msg: impl Into) -> &mut Self { + pub fn note_once(&mut self, msg: &str) -> &mut Self { self.sub(Level::OnceNote, msg, MultiSpan::new(), None); self } /// Prints the span with a note above it. /// This is like [`Diagnostic::note()`], but it gets its own span. - pub fn span_note>( - &mut self, - sp: S, - msg: impl Into, - ) -> &mut Self { + pub fn span_note>(&mut self, sp: S, msg: &str) -> &mut Self { self.sub(Level::Note, msg, sp.into(), None); self } /// Prints the span with a note above it. /// This is like [`Diagnostic::note()`], but it gets its own span. - pub fn span_note_once>( - &mut self, - sp: S, - msg: impl Into, - ) -> &mut Self { + pub fn span_note_once>(&mut self, sp: S, msg: &str) -> &mut Self { self.sub(Level::OnceNote, msg, sp.into(), None); self } /// Add a warning attached to this diagnostic. - pub fn warn(&mut self, msg: impl Into) -> &mut Self { + pub fn warn(&mut self, msg: &str) -> &mut Self { self.sub(Level::Warning, msg, MultiSpan::new(), None); self } /// Prints the span with a warning above it. /// This is like [`Diagnostic::warn()`], but it gets its own span. - pub fn span_warn>( - &mut self, - sp: S, - msg: impl Into, - ) -> &mut Self { + pub fn span_warn>(&mut self, sp: S, msg: &str) -> &mut Self { self.sub(Level::Warning, msg, sp.into(), None); self } /// Add a help message attached to this diagnostic. - pub fn help(&mut self, msg: impl Into) -> &mut Self { + pub fn help(&mut self, msg: &str) -> &mut Self { self.sub(Level::Help, msg, MultiSpan::new(), None); self } @@ -468,11 +386,7 @@ impl Diagnostic { /// Prints the span with some help above it. /// This is like [`Diagnostic::help()`], but it gets its own span. - pub fn span_help>( - &mut self, - sp: S, - msg: impl Into, - ) -> &mut Self { + pub fn span_help>(&mut self, sp: S, msg: &str) -> &mut Self { self.sub(Level::Help, msg, sp.into(), None); self } @@ -508,7 +422,7 @@ impl Diagnostic { /// In other words, multiple changes need to be applied as part of this suggestion. pub fn multipart_suggestion( &mut self, - msg: impl Into, + msg: &str, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self { @@ -524,7 +438,7 @@ impl Diagnostic { /// In other words, multiple changes need to be applied as part of this suggestion. pub fn multipart_suggestion_verbose( &mut self, - msg: impl Into, + msg: &str, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self { @@ -538,7 +452,7 @@ impl Diagnostic { /// [`Diagnostic::multipart_suggestion()`] but you can set the [`SuggestionStyle`]. pub fn multipart_suggestion_with_style( &mut self, - msg: impl Into, + msg: &str, suggestion: Vec<(Span, String)>, applicability: Applicability, style: SuggestionStyle, @@ -551,7 +465,7 @@ impl Diagnostic { .map(|(span, snippet)| SubstitutionPart { snippet, span }) .collect(), }], - msg: msg.into(), + msg: msg.to_owned(), style, applicability, tool_metadata: Default::default(), @@ -567,7 +481,7 @@ impl Diagnostic { /// improve understandability. pub fn tool_only_multipart_suggestion( &mut self, - msg: impl Into, + msg: &str, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self { @@ -579,7 +493,7 @@ impl Diagnostic { .map(|(span, snippet)| SubstitutionPart { snippet, span }) .collect(), }], - msg: msg.into(), + msg: msg.to_owned(), style: SuggestionStyle::CompletelyHidden, applicability, tool_metadata: Default::default(), @@ -607,7 +521,7 @@ impl Diagnostic { pub fn span_suggestion( &mut self, sp: Span, - msg: impl Into, + msg: &str, suggestion: String, applicability: Applicability, ) -> &mut Self { @@ -625,7 +539,7 @@ impl Diagnostic { pub fn span_suggestion_with_style( &mut self, sp: Span, - msg: impl Into, + msg: &str, suggestion: String, applicability: Applicability, style: SuggestionStyle, @@ -634,7 +548,7 @@ impl Diagnostic { substitutions: vec![Substitution { parts: vec![SubstitutionPart { snippet: suggestion, span: sp }], }], - msg: msg.into(), + msg: msg.to_owned(), style, applicability, tool_metadata: Default::default(), @@ -646,7 +560,7 @@ impl Diagnostic { pub fn span_suggestion_verbose( &mut self, sp: Span, - msg: impl Into, + msg: &str, suggestion: String, applicability: Applicability, ) -> &mut Self { @@ -665,7 +579,7 @@ impl Diagnostic { pub fn span_suggestions( &mut self, sp: Span, - msg: impl Into, + msg: &str, suggestions: impl Iterator, applicability: Applicability, ) -> &mut Self { @@ -677,7 +591,7 @@ impl Diagnostic { .collect(); self.push_suggestion(CodeSuggestion { substitutions, - msg: msg.into(), + msg: msg.to_owned(), style: SuggestionStyle::ShowCode, applicability, tool_metadata: Default::default(), @@ -689,7 +603,7 @@ impl Diagnostic { /// See also [`Diagnostic::span_suggestion()`]. pub fn multipart_suggestions( &mut self, - msg: impl Into, + msg: &str, suggestions: impl Iterator>, applicability: Applicability, ) -> &mut Self { @@ -702,7 +616,7 @@ impl Diagnostic { .collect(), }) .collect(), - msg: msg.into(), + msg: msg.to_owned(), style: SuggestionStyle::ShowCode, applicability, tool_metadata: Default::default(), @@ -716,7 +630,7 @@ impl Diagnostic { pub fn span_suggestion_short( &mut self, sp: Span, - msg: impl Into, + msg: &str, suggestion: String, applicability: Applicability, ) -> &mut Self { @@ -739,7 +653,7 @@ impl Diagnostic { pub fn span_suggestion_hidden( &mut self, sp: Span, - msg: impl Into, + msg: &str, suggestion: String, applicability: Applicability, ) -> &mut Self { @@ -760,7 +674,7 @@ impl Diagnostic { pub fn tool_only_span_suggestion( &mut self, sp: Span, - msg: impl Into, + msg: &str, suggestion: String, applicability: Applicability, ) -> &mut Self { @@ -778,13 +692,13 @@ impl Diagnostic { /// the suggestion in a tool-specific way, as it may not even directly involve Rust code. pub fn tool_only_suggestion_with_metadata( &mut self, - msg: impl Into, + msg: &str, applicability: Applicability, tool_metadata: Json, ) { self.push_suggestion(CodeSuggestion { substitutions: vec![], - msg: msg.into(), + msg: msg.to_owned(), style: SuggestionStyle::CompletelyHidden, applicability, tool_metadata: ToolMetadata::new(tool_metadata), @@ -818,25 +732,16 @@ impl Diagnostic { self.code.clone() } - pub fn set_primary_message(&mut self, msg: impl Into) -> &mut Self { + pub fn set_primary_message>(&mut self, msg: M) -> &mut Self { self.message[0] = (msg.into(), Style::NoStyle); self } - pub fn args(&self) -> &[DiagnosticArg<'static>] { - &self.args - } - - pub fn set_arg( - &mut self, - name: impl Into>, - arg: DiagnosticArgValue<'static>, - ) -> &mut Self { - self.args.push((name.into(), arg.into())); - self + pub fn message(&self) -> String { + self.message.iter().map(|i| i.0.as_str()).collect::() } - pub fn styled_message(&self) -> &Vec<(DiagnosticMessage, Style)> { + pub fn styled_message(&self) -> &Vec<(String, Style)> { &self.message } @@ -847,13 +752,13 @@ impl Diagnostic { pub fn sub( &mut self, level: Level, - message: impl Into, + message: &str, span: MultiSpan, render_span: Option, ) { let sub = SubDiagnostic { level, - message: vec![(message.into(), Style::NoStyle)], + message: vec![(message.to_owned(), Style::NoStyle)], span, render_span, }; @@ -862,14 +767,13 @@ impl Diagnostic { /// Convenience function for internal use, clients should use one of the /// public methods above. - fn sub_with_highlights>( + fn sub_with_highlights( &mut self, level: Level, - mut message: Vec<(M, Style)>, + message: Vec<(String, Style)>, span: MultiSpan, render_span: Option, ) { - let message = message.drain(..).map(|m| (m.0.into(), m.1)).collect(); let sub = SubDiagnostic { level, message, span, render_span }; self.children.push(sub); } @@ -879,7 +783,7 @@ impl Diagnostic { &self, ) -> ( &Level, - &Vec<(DiagnosticMessage, Style)>, + &Vec<(String, Style)>, &Option, &MultiSpan, &Result, SuggestionsDisabled>, @@ -910,3 +814,13 @@ impl PartialEq for Diagnostic { self.keys() == other.keys() } } + +impl SubDiagnostic { + pub fn message(&self) -> String { + self.message.iter().map(|i| i.0.as_str()).collect::() + } + + pub fn styled_message(&self) -> &Vec<(String, Style)> { + &self.message + } +} diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 74e0f74294613..853243ef3f06d 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -1,10 +1,8 @@ -use crate::diagnostic::DiagnosticArgValue; -use crate::{Diagnostic, DiagnosticId, DiagnosticMessage, DiagnosticStyledString, ErrorGuaranteed}; -use crate::{Handler, Level, MultiSpan, StashKey}; +use crate::{Diagnostic, DiagnosticId, DiagnosticStyledString, ErrorGuaranteed}; +use crate::{Handler, Level, StashKey}; use rustc_lint_defs::Applicability; -use rustc_span::Span; -use std::borrow::Cow; +use rustc_span::{MultiSpan, Span}; use std::fmt::{self, Debug}; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; @@ -101,10 +99,7 @@ mod sealed_level_is_error { impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> { /// Convenience function for internal use, clients should use one of the /// `struct_*` methods on [`Handler`]. - crate fn new_guaranteeing_error, const L: Level>( - handler: &'a Handler, - message: M, - ) -> Self + crate fn new_guaranteeing_error(handler: &'a Handler, message: &str) -> Self where (): sealed_level_is_error::IsError, { @@ -168,11 +163,7 @@ impl EmissionGuarantee for ErrorGuaranteed { impl<'a> DiagnosticBuilder<'a, ()> { /// Convenience function for internal use, clients should use one of the /// `struct_*` methods on [`Handler`]. - crate fn new>( - handler: &'a Handler, - level: Level, - message: M, - ) -> Self { + crate fn new(handler: &'a Handler, level: Level, message: &str) -> Self { let diagnostic = Diagnostic::new_with_code(level, None, message); Self::new_diagnostic(handler, diagnostic) } @@ -210,7 +201,7 @@ impl EmissionGuarantee for () { impl<'a> DiagnosticBuilder<'a, !> { /// Convenience function for internal use, clients should use one of the /// `struct_*` methods on [`Handler`]. - crate fn new_fatal(handler: &'a Handler, message: impl Into) -> Self { + crate fn new_fatal(handler: &'a Handler, message: &str) -> Self { let diagnostic = Diagnostic::new_with_code(Level::Fatal, None, message); Self::new_diagnostic_fatal(handler, diagnostic) } @@ -355,7 +346,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { } // Take the `Diagnostic` by replacing it with a dummy. - let dummy = Diagnostic::new(Level::Allow, DiagnosticMessage::Str("".to_string())); + let dummy = Diagnostic::new(Level::Allow, ""); let diagnostic = std::mem::replace(&mut *self.inner.diagnostic, dummy); // Disable the ICE on `Drop`. @@ -408,7 +399,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { /// the diagnostic was constructed. However, the label span is *not* considered a /// ["primary span"][`MultiSpan`]; only the `Span` supplied when creating the diagnostic is /// primary. - pub fn span_label(&mut self, span: Span, label: impl Into) -> &mut Self); + pub fn span_label(&mut self, span: Span, label: impl Into) -> &mut Self); forward!( /// Labels all the given spans with the provided label. @@ -443,25 +434,25 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { found: DiagnosticStyledString, ) -> &mut Self); - forward!(pub fn note(&mut self, msg: impl Into) -> &mut Self); - forward!(pub fn note_once(&mut self, msg: impl Into) -> &mut Self); + forward!(pub fn note(&mut self, msg: &str) -> &mut Self); + forward!(pub fn note_once(&mut self, msg: &str) -> &mut Self); forward!(pub fn span_note( &mut self, sp: impl Into, - msg: impl Into, + msg: &str, ) -> &mut Self); forward!(pub fn span_note_once( &mut self, sp: impl Into, - msg: impl Into, + msg: &str, ) -> &mut Self); - forward!(pub fn warn(&mut self, msg: impl Into) -> &mut Self); + forward!(pub fn warn(&mut self, msg: &str) -> &mut Self); forward!(pub fn span_warn(&mut self, sp: impl Into, msg: &str) -> &mut Self); - forward!(pub fn help(&mut self, msg: impl Into) -> &mut Self); + forward!(pub fn help(&mut self, msg: &str) -> &mut Self); forward!(pub fn span_help( &mut self, sp: impl Into, - msg: impl Into, + msg: &str, ) -> &mut Self); forward!(pub fn help_use_latest_edition(&mut self,) -> &mut Self); forward!(pub fn set_is_lint(&mut self,) -> &mut Self); @@ -470,67 +461,67 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { forward!(pub fn multipart_suggestion( &mut self, - msg: impl Into, + msg: &str, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self); forward!(pub fn multipart_suggestion_verbose( &mut self, - msg: impl Into, + msg: &str, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self); forward!(pub fn tool_only_multipart_suggestion( &mut self, - msg: impl Into, + msg: &str, suggestion: Vec<(Span, String)>, applicability: Applicability, ) -> &mut Self); forward!(pub fn span_suggestion( &mut self, sp: Span, - msg: impl Into, + msg: &str, suggestion: String, applicability: Applicability, ) -> &mut Self); forward!(pub fn span_suggestions( &mut self, sp: Span, - msg: impl Into, + msg: &str, suggestions: impl Iterator, applicability: Applicability, ) -> &mut Self); forward!(pub fn multipart_suggestions( &mut self, - msg: impl Into, + msg: &str, suggestions: impl Iterator>, applicability: Applicability, ) -> &mut Self); forward!(pub fn span_suggestion_short( &mut self, sp: Span, - msg: impl Into, + msg: &str, suggestion: String, applicability: Applicability, ) -> &mut Self); forward!(pub fn span_suggestion_verbose( &mut self, sp: Span, - msg: impl Into, + msg: &str, suggestion: String, applicability: Applicability, ) -> &mut Self); forward!(pub fn span_suggestion_hidden( &mut self, sp: Span, - msg: impl Into, + msg: &str, suggestion: String, applicability: Applicability, ) -> &mut Self); forward!(pub fn tool_only_span_suggestion( &mut self, sp: Span, - msg: impl Into, + msg: &str, suggestion: String, applicability: Applicability, ) -> &mut Self); @@ -538,11 +529,6 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { forward!(pub fn set_primary_message(&mut self, msg: impl Into) -> &mut Self); forward!(pub fn set_span(&mut self, sp: impl Into) -> &mut Self); forward!(pub fn code(&mut self, s: DiagnosticId) -> &mut Self); - forward!(pub fn set_arg( - &mut self, - name: impl Into>, - arg: DiagnosticArgValue<'static>, - ) -> &mut Self); } impl Debug for DiagnosticBuilder<'_, G> { @@ -561,9 +547,7 @@ impl Drop for DiagnosticBuilderInner<'_> { if !panicking() { handler.emit_diagnostic(&mut Diagnostic::new( Level::Bug, - DiagnosticMessage::Str( - "the following error was constructed but not emitted".to_string(), - ), + "the following error was constructed but not emitted", )); handler.emit_diagnostic(&mut self.diagnostic); panic!(); diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 6a763d4d1404b..93b7201023a49 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -10,20 +10,19 @@ use Destination::*; use rustc_span::source_map::SourceMap; -use rustc_span::{SourceFile, Span}; +use rustc_span::{MultiSpan, SourceFile, Span}; use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, Style, StyledString}; use crate::styled_buffer::StyledBuffer; use crate::{ - CodeSuggestion, Diagnostic, DiagnosticArg, DiagnosticId, DiagnosticMessage, FluentBundle, - Handler, Level, MultiSpan, SubDiagnostic, SubstitutionHighlight, SuggestionStyle, + CodeSuggestion, Diagnostic, DiagnosticId, Handler, Level, SubDiagnostic, SubstitutionHighlight, + SuggestionStyle, }; use rustc_lint_defs::pluralize; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; -use rustc_error_messages::FluentArgs; use rustc_span::hygiene::{ExpnKind, MacroKind}; use std::borrow::Cow; use std::cmp::{max, min, Reverse}; @@ -59,25 +58,13 @@ impl HumanReadableErrorType { self, dst: Box, source_map: Option>, - bundle: Option>, - fallback_bundle: Lrc, teach: bool, terminal_width: Option, macro_backtrace: bool, ) -> EmitterWriter { let (short, color_config) = self.unzip(); let color = color_config.suggests_using_colors(); - EmitterWriter::new( - dst, - source_map, - bundle, - fallback_bundle, - short, - teach, - color, - terminal_width, - macro_backtrace, - ) + EmitterWriter::new(dst, source_map, short, teach, color, terminal_width, macro_backtrace) } } @@ -225,74 +212,6 @@ pub trait Emitter { fn source_map(&self) -> Option<&Lrc>; - /// Return `FluentBundle` with localized diagnostics for the locale requested by the user. If no - /// language was requested by the user then this will be `None` and `fallback_fluent_bundle` - /// should be used. - fn fluent_bundle(&self) -> Option<&Lrc>; - - /// Return `FluentBundle` with localized diagnostics for the default locale of the compiler. - /// Used when the user has not requested a specific language or when a localized diagnostic is - /// unavailable for the requested locale. - fn fallback_fluent_bundle(&self) -> &Lrc; - - /// Convert diagnostic arguments (a rustc internal type that exists to implement - /// `Encodable`/`Decodable`) into `FluentArgs` which is necessary to perform translation. - /// - /// Typically performed once for each diagnostic at the start of `emit_diagnostic` and then - /// passed around as a reference thereafter. - fn to_fluent_args<'arg>(&self, args: &[DiagnosticArg<'arg>]) -> FluentArgs<'arg> { - FromIterator::from_iter(args.to_vec().drain(..)) - } - - /// Convert `DiagnosticMessage`s to a string, performing translation if necessary. - fn translate_messages( - &self, - messages: &[(DiagnosticMessage, Style)], - args: &FluentArgs<'_>, - ) -> Cow<'_, str> { - Cow::Owned( - messages.iter().map(|(m, _)| self.translate_message(m, args)).collect::(), - ) - } - - /// Convert a `DiagnosticMessage` to a string, performing translation if necessary. - fn translate_message<'a>( - &'a self, - message: &'a DiagnosticMessage, - args: &'a FluentArgs<'_>, - ) -> Cow<'_, str> { - trace!(?message, ?args); - let (identifier, attr) = match message { - DiagnosticMessage::Str(msg) => return Cow::Borrowed(&msg), - DiagnosticMessage::FluentIdentifier(identifier, attr) => (identifier, attr), - }; - - let bundle = match self.fluent_bundle() { - Some(bundle) if bundle.has_message(&identifier) => bundle, - _ => self.fallback_fluent_bundle(), - }; - - let message = bundle.get_message(&identifier).expect("missing diagnostic in fluent bundle"); - let value = match attr { - Some(attr) => { - message.get_attribute(attr).expect("missing attribute in fluent message").value() - } - None => message.value().expect("missing value in fluent message"), - }; - - let mut err = vec![]; - let translated = bundle.format_pattern(value, Some(&args), &mut err); - trace!(?translated, ?err); - debug_assert!( - err.is_empty(), - "identifier: {:?}, args: {:?}, errors: {:?}", - identifier, - args, - err - ); - translated - } - /// Formats the substitutions of the primary_span /// /// There are a lot of conditions to this method, but in short: @@ -306,12 +225,10 @@ pub trait Emitter { fn primary_span_formatted<'a>( &mut self, diag: &'a Diagnostic, - fluent_args: &FluentArgs<'_>, ) -> (MultiSpan, &'a [CodeSuggestion]) { let mut primary_span = diag.span.clone(); let suggestions = diag.suggestions.as_ref().map_or(&[][..], |suggestions| &suggestions[..]); if let Some((sugg, rest)) = suggestions.split_first() { - let msg = self.translate_message(&sugg.msg, fluent_args); if rest.is_empty() && // ^ if there is only one suggestion // don't display multi-suggestions as labels @@ -319,7 +236,7 @@ pub trait Emitter { // don't display multipart suggestions as labels sugg.substitutions[0].parts.len() == 1 && // don't display long messages as labels - msg.split_whitespace().count() < 10 && + sugg.msg.split_whitespace().count() < 10 && // don't display multiline suggestions as labels !sugg.substitutions[0].parts[0].snippet.contains('\n') && ![ @@ -335,12 +252,12 @@ pub trait Emitter { let msg = if substitution.is_empty() || sugg.style.hide_inline() { // This substitution is only removal OR we explicitly don't want to show the // code inline (`hide_inline`). Therefore, we don't show the substitution. - format!("help: {}", &msg) + format!("help: {}", sugg.msg) } else { // Show the default suggestion text with the substitution format!( "help: {}{}: `{}`", - &msg, + sugg.msg, if self .source_map() .map(|sm| is_case_difference( @@ -416,7 +333,7 @@ pub trait Emitter { children.push(SubDiagnostic { level: Level::Note, - message: vec![(DiagnosticMessage::Str(msg), Style::NoStyle)], + message: vec![(msg, Style::NoStyle)], span: MultiSpan::new(), render_span: None, }); @@ -575,19 +492,9 @@ impl Emitter for EmitterWriter { self.sm.as_ref() } - fn fluent_bundle(&self) -> Option<&Lrc> { - self.fluent_bundle.as_ref() - } - - fn fallback_fluent_bundle(&self) -> &Lrc { - &self.fallback_bundle - } - fn emit_diagnostic(&mut self, diag: &Diagnostic) { - let fluent_args = self.to_fluent_args(diag.args()); - let mut children = diag.children.clone(); - let (mut primary_span, suggestions) = self.primary_span_formatted(&diag, &fluent_args); + let (mut primary_span, suggestions) = self.primary_span_formatted(&diag); debug!("emit_diagnostic: suggestions={:?}", suggestions); self.fix_multispans_in_extern_macros_and_render_macro_backtrace( @@ -600,8 +507,7 @@ impl Emitter for EmitterWriter { self.emit_messages_default( &diag.level, - &diag.message, - &fluent_args, + &diag.styled_message(), &diag.code, &primary_span, &children, @@ -630,15 +536,6 @@ impl Emitter for SilentEmitter { fn source_map(&self) -> Option<&Lrc> { None } - - fn fluent_bundle(&self) -> Option<&Lrc> { - None - } - - fn fallback_fluent_bundle(&self) -> &Lrc { - panic!("silent emitter attempted to translate message") - } - fn emit_diagnostic(&mut self, d: &Diagnostic) { if d.level == Level::Fatal { let mut d = d.clone(); @@ -694,8 +591,6 @@ impl ColorConfig { pub struct EmitterWriter { dst: Destination, sm: Option>, - fluent_bundle: Option>, - fallback_bundle: Lrc, short_message: bool, teach: bool, ui_testing: bool, @@ -715,8 +610,6 @@ impl EmitterWriter { pub fn stderr( color_config: ColorConfig, source_map: Option>, - fluent_bundle: Option>, - fallback_bundle: Lrc, short_message: bool, teach: bool, terminal_width: Option, @@ -726,8 +619,6 @@ impl EmitterWriter { EmitterWriter { dst, sm: source_map, - fluent_bundle, - fallback_bundle, short_message, teach, ui_testing: false, @@ -739,8 +630,6 @@ impl EmitterWriter { pub fn new( dst: Box, source_map: Option>, - fluent_bundle: Option>, - fallback_bundle: Lrc, short_message: bool, teach: bool, colored: bool, @@ -750,8 +639,6 @@ impl EmitterWriter { EmitterWriter { dst: Raw(dst, colored), sm: source_map, - fluent_bundle, - fallback_bundle, short_message, teach, ui_testing: false, @@ -1289,8 +1176,7 @@ impl EmitterWriter { fn msg_to_buffer( &self, buffer: &mut StyledBuffer, - msg: &[(DiagnosticMessage, Style)], - args: &FluentArgs<'_>, + msg: &[(String, Style)], padding: usize, label: &str, override_style: Option