about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs2
-rw-r--r--compiler/rustc_driver/src/lib.rs2
-rw-r--r--compiler/rustc_error_messages/locales/en-US/parser.ftl3
-rw-r--r--compiler/rustc_error_messages/locales/en-US/typeck.ftl (renamed from compiler/rustc_error_messages/locales/en-US/diagnostics.ftl)4
-rw-r--r--compiler/rustc_error_messages/src/lib.rs40
-rw-r--r--compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs12
-rw-r--r--compiler/rustc_errors/src/emitter.rs19
-rw-r--r--compiler/rustc_errors/src/json.rs16
-rw-r--r--compiler/rustc_errors/src/json/tests.rs2
-rw-r--r--compiler/rustc_errors/src/lib.rs6
-rw-r--r--compiler/rustc_expand/src/tests.rs4
-rw-r--r--compiler/rustc_session/src/parse.rs6
-rw-r--r--compiler/rustc_session/src/session.rs22
-rw-r--r--src/librustdoc/core.rs2
-rw-r--r--src/librustdoc/doctest.rs4
-rw-r--r--src/librustdoc/passes/check_code_block_syntax.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/doc.rs6
-rw-r--r--src/tools/clippy/src/driver.rs3
-rw-r--r--src/tools/rustfmt/src/parse/session.rs10
19 files changed, 94 insertions, 81 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 92c4ab7eb86..d5d21775f0a 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -1731,7 +1731,7 @@ impl Emitter for SharedEmitter {
         None
     }
 
-    fn fallback_fluent_bundle(&self) -> &Lrc<rustc_errors::FluentBundle> {
+    fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
         panic!("shared emitter attempted to translate a diagnostic");
     }
 }
diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs
index febdd0ed746..904d6f8cfd8 100644
--- a/compiler/rustc_driver/src/lib.rs
+++ b/compiler/rustc_driver/src/lib.rs
@@ -1173,7 +1173,7 @@ static DEFAULT_HOOK: SyncLazy<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send +
 /// 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");
+        rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
     let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
         rustc_errors::ColorConfig::Auto,
         None,
diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl
new file mode 100644
index 00000000000..24e59a93cea
--- /dev/null
+++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl
@@ -0,0 +1,3 @@
+parser-struct-literal-body-without-path =
+    struct literal body without path
+    .suggestion = you might have forgotten to add the struct literal inside the block
diff --git a/compiler/rustc_error_messages/locales/en-US/diagnostics.ftl b/compiler/rustc_error_messages/locales/en-US/typeck.ftl
index 2b1deb34304..721201d9312 100644
--- a/compiler/rustc_error_messages/locales/en-US/diagnostics.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/typeck.ftl
@@ -1,7 +1,3 @@
-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
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index b33e6b66117..de0dd18cc6e 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -1,5 +1,7 @@
 #![feature(let_chains)]
+#![feature(once_cell)]
 #![feature(path_try_exists)]
+#![feature(type_alias_impl_trait)]
 
 use fluent_bundle::FluentResource;
 use fluent_syntax::parser::ParserError;
@@ -14,6 +16,11 @@ use std::io;
 use std::path::{Path, PathBuf};
 use tracing::{instrument, trace};
 
+#[cfg(not(parallel_compiler))]
+use std::lazy::Lazy;
+#[cfg(parallel_compiler)]
+use std::lazy::SyncLazy as Lazy;
+
 #[cfg(parallel_compiler)]
 use intl_memoizer::concurrent::IntlLangMemoizer;
 #[cfg(not(parallel_compiler))]
@@ -22,7 +29,8 @@ 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 static DEFAULT_LOCALE_RESOURCES: &'static [&'static str] =
+    &[include_str!("../locales/en-US/typeck.ftl"), include_str!("../locales/en-US/parser.ftl")];
 
 pub type FluentBundle = fluent_bundle::bundle::FluentBundle<FluentResource, IntlLangMemoizer>;
 
@@ -192,20 +200,30 @@ pub fn fluent_bundle(
     Ok(Some(bundle))
 }
 
+/// Type alias for the result of `fallback_fluent_bundle` - a reference-counted pointer to a lazily
+/// evaluated fluent bundle.
+pub type LazyFallbackBundle = Lrc<Lazy<FluentBundle, impl FnOnce() -> FluentBundle>>;
+
 /// Return the default `FluentBundle` with standard "en-US" diagnostic messages.
 #[instrument(level = "trace")]
 pub fn fallback_fluent_bundle(
+    resources: &'static [&'static str],
     with_directionality_markers: bool,
-) -> Result<Lrc<FluentBundle>, 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)
+) -> LazyFallbackBundle {
+    Lrc::new(Lazy::new(move || {
+        let mut fallback_bundle = new_bundle(vec![langid!("en-US")]);
+        // See comment in `fluent_bundle`.
+        fallback_bundle.set_use_isolating(with_directionality_markers);
+
+        for resource in resources {
+            let resource = FluentResource::try_new(resource.to_string())
+                .expect("failed to parse fallback fluent resource");
+            trace!(?resource);
+            fallback_bundle.add_resource_overriding(resource);
+        }
+
+        fallback_bundle
+    }))
 }
 
 /// Identifier for the Fluent message/attribute corresponding to a diagnostic message.
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
index 003fd1eea3a..1f270fcf56b 100644
--- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
+++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
@@ -8,8 +8,8 @@
 use crate::emitter::FileWithAnnotatedLines;
 use crate::snippet::Line;
 use crate::{
-    CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage, Emitter, FluentBundle, Level,
-    MultiSpan, Style, SubDiagnostic,
+    CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage, Emitter, FluentBundle,
+    LazyFallbackBundle, Level, MultiSpan, Style, SubDiagnostic,
 };
 use annotate_snippets::display_list::{DisplayList, FormatOptions};
 use annotate_snippets::snippet::*;
@@ -22,7 +22,7 @@ use rustc_span::SourceFile;
 pub struct AnnotateSnippetEmitterWriter {
     source_map: Option<Lrc<SourceMap>>,
     fluent_bundle: Option<Lrc<FluentBundle>>,
-    fallback_bundle: Lrc<FluentBundle>,
+    fallback_bundle: LazyFallbackBundle,
 
     /// If true, hides the longer explanation text
     short_message: bool,
@@ -67,8 +67,8 @@ impl Emitter for AnnotateSnippetEmitterWriter {
         self.fluent_bundle.as_ref()
     }
 
-    fn fallback_fluent_bundle(&self) -> &Lrc<FluentBundle> {
-        &self.fallback_bundle
+    fn fallback_fluent_bundle(&self) -> &FluentBundle {
+        &**self.fallback_bundle
     }
 
     fn should_show_explain(&self) -> bool {
@@ -101,7 +101,7 @@ impl AnnotateSnippetEmitterWriter {
     pub fn new(
         source_map: Option<Lrc<SourceMap>>,
         fluent_bundle: Option<Lrc<FluentBundle>>,
-        fallback_bundle: Lrc<FluentBundle>,
+        fallback_bundle: LazyFallbackBundle,
         short_message: bool,
         macro_backtrace: bool,
     ) -> Self {
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 6a763d4d140..47cdf39cd52 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -16,7 +16,8 @@ use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, Styl
 use crate::styled_buffer::StyledBuffer;
 use crate::{
     CodeSuggestion, Diagnostic, DiagnosticArg, DiagnosticId, DiagnosticMessage, FluentBundle,
-    Handler, Level, MultiSpan, SubDiagnostic, SubstitutionHighlight, SuggestionStyle,
+    Handler, LazyFallbackBundle, Level, MultiSpan, SubDiagnostic, SubstitutionHighlight,
+    SuggestionStyle,
 };
 
 use rustc_lint_defs::pluralize;
@@ -60,7 +61,7 @@ impl HumanReadableErrorType {
         dst: Box<dyn Write + Send>,
         source_map: Option<Lrc<SourceMap>>,
         bundle: Option<Lrc<FluentBundle>>,
-        fallback_bundle: Lrc<FluentBundle>,
+        fallback_bundle: LazyFallbackBundle,
         teach: bool,
         terminal_width: Option<usize>,
         macro_backtrace: bool,
@@ -233,7 +234,7 @@ pub trait Emitter {
     /// 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<FluentBundle>;
+    fn fallback_fluent_bundle(&self) -> &FluentBundle;
 
     /// Convert diagnostic arguments (a rustc internal type that exists to implement
     /// `Encodable`/`Decodable`) into `FluentArgs` which is necessary to perform translation.
@@ -579,8 +580,8 @@ impl Emitter for EmitterWriter {
         self.fluent_bundle.as_ref()
     }
 
-    fn fallback_fluent_bundle(&self) -> &Lrc<FluentBundle> {
-        &self.fallback_bundle
+    fn fallback_fluent_bundle(&self) -> &FluentBundle {
+        &**self.fallback_bundle
     }
 
     fn emit_diagnostic(&mut self, diag: &Diagnostic) {
@@ -635,7 +636,7 @@ impl Emitter for SilentEmitter {
         None
     }
 
-    fn fallback_fluent_bundle(&self) -> &Lrc<FluentBundle> {
+    fn fallback_fluent_bundle(&self) -> &FluentBundle {
         panic!("silent emitter attempted to translate message")
     }
 
@@ -695,7 +696,7 @@ pub struct EmitterWriter {
     dst: Destination,
     sm: Option<Lrc<SourceMap>>,
     fluent_bundle: Option<Lrc<FluentBundle>>,
-    fallback_bundle: Lrc<FluentBundle>,
+    fallback_bundle: LazyFallbackBundle,
     short_message: bool,
     teach: bool,
     ui_testing: bool,
@@ -716,7 +717,7 @@ impl EmitterWriter {
         color_config: ColorConfig,
         source_map: Option<Lrc<SourceMap>>,
         fluent_bundle: Option<Lrc<FluentBundle>>,
-        fallback_bundle: Lrc<FluentBundle>,
+        fallback_bundle: LazyFallbackBundle,
         short_message: bool,
         teach: bool,
         terminal_width: Option<usize>,
@@ -740,7 +741,7 @@ impl EmitterWriter {
         dst: Box<dyn Write + Send>,
         source_map: Option<Lrc<SourceMap>>,
         fluent_bundle: Option<Lrc<FluentBundle>>,
-        fallback_bundle: Lrc<FluentBundle>,
+        fallback_bundle: LazyFallbackBundle,
         short_message: bool,
         teach: bool,
         colored: bool,
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index f78490da245..0139007da42 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -15,7 +15,9 @@ use crate::emitter::{Emitter, HumanReadableErrorType};
 use crate::registry::Registry;
 use crate::DiagnosticId;
 use crate::ToolMetadata;
-use crate::{CodeSuggestion, FluentBundle, MultiSpan, SpanLabel, SubDiagnostic};
+use crate::{
+    CodeSuggestion, FluentBundle, LazyFallbackBundle, MultiSpan, SpanLabel, SubDiagnostic,
+};
 use rustc_lint_defs::Applicability;
 
 use rustc_data_structures::sync::Lrc;
@@ -38,7 +40,7 @@ pub struct JsonEmitter {
     registry: Option<Registry>,
     sm: Lrc<SourceMap>,
     fluent_bundle: Option<Lrc<FluentBundle>>,
-    fallback_bundle: Lrc<FluentBundle>,
+    fallback_bundle: LazyFallbackBundle,
     pretty: bool,
     ui_testing: bool,
     json_rendered: HumanReadableErrorType,
@@ -51,7 +53,7 @@ impl JsonEmitter {
         registry: Option<Registry>,
         source_map: Lrc<SourceMap>,
         fluent_bundle: Option<Lrc<FluentBundle>>,
-        fallback_bundle: Lrc<FluentBundle>,
+        fallback_bundle: LazyFallbackBundle,
         pretty: bool,
         json_rendered: HumanReadableErrorType,
         terminal_width: Option<usize>,
@@ -75,7 +77,7 @@ impl JsonEmitter {
         pretty: bool,
         json_rendered: HumanReadableErrorType,
         fluent_bundle: Option<Lrc<FluentBundle>>,
-        fallback_bundle: Lrc<FluentBundle>,
+        fallback_bundle: LazyFallbackBundle,
         terminal_width: Option<usize>,
         macro_backtrace: bool,
     ) -> JsonEmitter {
@@ -97,7 +99,7 @@ impl JsonEmitter {
         registry: Option<Registry>,
         source_map: Lrc<SourceMap>,
         fluent_bundle: Option<Lrc<FluentBundle>>,
-        fallback_bundle: Lrc<FluentBundle>,
+        fallback_bundle: LazyFallbackBundle,
         pretty: bool,
         json_rendered: HumanReadableErrorType,
         terminal_width: Option<usize>,
@@ -192,8 +194,8 @@ impl Emitter for JsonEmitter {
         self.fluent_bundle.as_ref()
     }
 
-    fn fallback_fluent_bundle(&self) -> &Lrc<FluentBundle> {
-        &self.fallback_bundle
+    fn fallback_fluent_bundle(&self) -> &FluentBundle {
+        &**self.fallback_bundle
     }
 
     fn should_show_explain(&self) -> bool {
diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs
index 0f175c732c1..7eb6a4975fe 100644
--- a/compiler/rustc_errors/src/json/tests.rs
+++ b/compiler/rustc_errors/src/json/tests.rs
@@ -40,7 +40,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         sm.new_source_file(Path::new("test.rs").to_owned().into(), code.to_owned());
         let fallback_bundle =
-            crate::fallback_fluent_bundle(false).expect("failed to load fallback fluent bundle");
+            crate::fallback_fluent_bundle(rustc_error_messages::DEFAULT_LOCALE_RESOURCES, false);
 
         let output = Arc::new(Mutex::new(Vec::new()));
         let je = JsonEmitter::new(
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index c927fcb2109..cfad1fc01ab 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -33,7 +33,7 @@ use rustc_data_structures::sync::{self, Lock, Lrc};
 use rustc_data_structures::AtomicRef;
 pub use rustc_error_messages::{
     fallback_fluent_bundle, fluent_bundle, DiagnosticMessage, FluentBundle, LanguageIdentifier,
-    MultiSpan, SpanLabel,
+    LazyFallbackBundle, MultiSpan, SpanLabel, DEFAULT_LOCALE_RESOURCES,
 };
 pub use rustc_lint_defs::{pluralize, Applicability};
 use rustc_serialize::json::Json;
@@ -547,7 +547,7 @@ impl Handler {
         treat_err_as_bug: Option<NonZeroUsize>,
         sm: Option<Lrc<SourceMap>>,
         fluent_bundle: Option<Lrc<FluentBundle>>,
-        fallback_bundle: Lrc<FluentBundle>,
+        fallback_bundle: LazyFallbackBundle,
     ) -> Self {
         Self::with_tty_emitter_and_flags(
             color_config,
@@ -562,7 +562,7 @@ impl Handler {
         color_config: ColorConfig,
         sm: Option<Lrc<SourceMap>>,
         fluent_bundle: Option<Lrc<FluentBundle>>,
-        fallback_bundle: Lrc<FluentBundle>,
+        fallback_bundle: LazyFallbackBundle,
         flags: HandlerFlags,
     ) -> Self {
         let emitter = Box::new(EmitterWriter::stderr(
diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs
index 88f3cf9d722..693159f9aec 100644
--- a/compiler/rustc_expand/src/tests.rs
+++ b/compiler/rustc_expand/src/tests.rs
@@ -127,8 +127,8 @@ fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &
     create_default_session_if_not_set_then(|_| {
         let output = Arc::new(Mutex::new(Vec::new()));
 
-        let fallback_bundle = rustc_errors::fallback_fluent_bundle(false)
-            .expect("failed to load fallback fluent bundle");
+        let fallback_bundle =
+            rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
         let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         source_map.new_source_file(Path::new("test.rs").to_owned().into(), file_text.to_owned());
 
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index 1fa180b320c..6a36ae63c68 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -173,8 +173,7 @@ pub struct ParseSess {
 impl ParseSess {
     /// Used for testing.
     pub fn new(file_path_mapping: FilePathMapping) -> Self {
-        let fallback_bundle =
-            fallback_fluent_bundle(false).expect("failed to load fallback fluent bundle");
+        let fallback_bundle = fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
         let sm = Lrc::new(SourceMap::new(file_path_mapping));
         let handler = Handler::with_tty_emitter(
             ColorConfig::Auto,
@@ -211,8 +210,7 @@ impl ParseSess {
     }
 
     pub fn with_silent_emitter(fatal_note: Option<String>) -> Self {
-        let fallback_bundle =
-            fallback_fluent_bundle(false).expect("failed to load fallback fluent bundle");
+        let fallback_bundle = fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let fatal_handler =
             Handler::with_tty_emitter(ColorConfig::Auto, false, None, None, None, fallback_bundle);
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index d70f89760a1..c461b26788a 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -21,7 +21,7 @@ use rustc_errors::json::JsonEmitter;
 use rustc_errors::registry::Registry;
 use rustc_errors::{
     fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, EmissionGuarantee,
-    ErrorGuaranteed, FluentBundle, MultiSpan,
+    ErrorGuaranteed, FluentBundle, LazyFallbackBundle, MultiSpan,
 };
 use rustc_macros::HashStable_Generic;
 pub use rustc_span::def_id::StableCrateId;
@@ -1080,7 +1080,7 @@ fn default_emitter(
     registry: rustc_errors::registry::Registry,
     source_map: Lrc<SourceMap>,
     bundle: Option<Lrc<FluentBundle>>,
-    fallback_bundle: Lrc<FluentBundle>,
+    fallback_bundle: LazyFallbackBundle,
     emitter_dest: Option<Box<dyn Write + Send>>,
 ) -> Box<dyn Emitter + sync::Send> {
     let macro_backtrace = sopts.debugging_opts.macro_backtrace;
@@ -1215,17 +1215,10 @@ pub fn build_session(
         hash_kind,
     ));
 
-    let fallback_bundle =
-        match fallback_fluent_bundle(sopts.debugging_opts.translate_directionality_markers) {
-            Ok(bundle) => bundle,
-            Err(e) => {
-                early_error(
-                    sopts.error_format,
-                    &format!("failed to load fallback fluent bundle: {e}"),
-                );
-            }
-        };
-
+    let fallback_bundle = fallback_fluent_bundle(
+        rustc_errors::DEFAULT_LOCALE_RESOURCES,
+        sopts.debugging_opts.translate_directionality_markers,
+    );
     let emitter =
         default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle, write_dest);
 
@@ -1460,8 +1453,7 @@ pub enum IncrCompSession {
 }
 
 fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler {
-    let fallback_bundle =
-        fallback_fluent_bundle(false).expect("failed to load fallback fluent bundle");
+    let fallback_bundle = fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
     let emitter: Box<dyn Emitter + sync::Send> = match output {
         config::ErrorOutputType::HumanReadable(kind) => {
             let (short, color_config) = kind.unzip();
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 9d5ae68b3e4..81c11dc30cb 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -146,7 +146,7 @@ crate fn new_handler(
     debugging_opts: &DebuggingOptions,
 ) -> rustc_errors::Handler {
     let fallback_bundle =
-        rustc_errors::fallback_fluent_bundle(false).expect("failed to load fallback fluent bundle");
+        rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
     let emitter: Box<dyn Emitter + sync::Send> = match error_format {
         ErrorOutputType::HumanReadable(kind) => {
             let (short, color_config) = kind.unzip();
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index eabe0803b49..61826844574 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -537,8 +537,8 @@ crate fn make_test(
             // Any errors in parsing should also appear when the doctest is compiled for real, so just
             // send all the errors that librustc_ast emits directly into a `Sink` instead of stderr.
             let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-            let fallback_bundle = rustc_errors::fallback_fluent_bundle(false)
-                .expect("failed to load fallback fluent bundle");
+            let fallback_bundle =
+                rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
             supports_color = EmitterWriter::stderr(
                 ColorConfig::Auto,
                 None,
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index 465dd523ff4..d66dfca07f1 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -1,6 +1,6 @@
 //! Validates syntax inside Rust code blocks (\`\`\`rust).
 use rustc_data_structures::sync::{Lock, Lrc};
-use rustc_errors::{emitter::Emitter, Applicability, Diagnostic, Handler};
+use rustc_errors::{emitter::Emitter, Applicability, Diagnostic, Handler, LazyFallbackBundle};
 use rustc_middle::lint::LintDiagnosticBuilder;
 use rustc_parse::parse_stream_from_source_str;
 use rustc_session::parse::ParseSess;
@@ -32,8 +32,8 @@ struct SyntaxChecker<'a, 'tcx> {
 impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
     fn check_rust_syntax(&self, item: &clean::Item, dox: &str, code_block: RustCodeBlock) {
         let buffer = Lrc::new(Lock::new(Buffer::default()));
-        let fallback_bundle = rustc_errors::fallback_fluent_bundle(false)
-            .expect("failed to load fallback fluent bundle");
+        let fallback_bundle =
+            rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
         let emitter = BufferEmitter { buffer: Lrc::clone(&buffer), fallback_bundle };
 
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
@@ -173,7 +173,7 @@ struct Buffer {
 
 struct BufferEmitter {
     buffer: Lrc<Lock<Buffer>>,
-    fallback_bundle: Lrc<rustc_errors::FluentBundle>,
+    fallback_bundle: LazyFallbackBundle,
 }
 
 impl Emitter for BufferEmitter {
@@ -194,7 +194,7 @@ impl Emitter for BufferEmitter {
         None
     }
 
-    fn fallback_fluent_bundle(&self) -> &Lrc<rustc_errors::FluentBundle> {
-        &self.fallback_bundle
+    fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
+        &**self.fallback_bundle
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs
index 28d0c75fde6..503cef76775 100644
--- a/src/tools/clippy/clippy_lints/src/doc.rs
+++ b/src/tools/clippy/clippy_lints/src/doc.rs
@@ -621,8 +621,10 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) {
                 let filename = FileName::anon_source_code(&code);
 
                 let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-                let fallback_bundle =
-                    rustc_errors::fallback_fluent_bundle(false).expect("failed to load fallback fluent bundle");
+                let fallback_bundle = rustc_errors::fallback_fluent_bundle(
+                    rustc_errors::DEFAULT_LOCALE_RESOURCES,
+                    false
+                );
                 let emitter = EmitterWriter::new(
                     Box::new(io::sink()),
                     None,
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index 00dc916b217..32a09fdb9d9 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -165,7 +165,8 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
     // Separate the output with an empty line
     eprintln!();
 
-    let fallback_bundle = rustc_errors::fallback_fluent_bundle(false).expect("failed to load fallback fluent bundle");
+    let fallback_bundle =
+        rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
     let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
         rustc_errors::ColorConfig::Auto,
         None,
diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs
index 7125b2ee685..4408e20747a 100644
--- a/src/tools/rustfmt/src/parse/session.rs
+++ b/src/tools/rustfmt/src/parse/session.rs
@@ -36,7 +36,7 @@ impl Emitter for SilentEmitter {
     fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
         None
     }
-    fn fallback_fluent_bundle(&self) -> &Lrc<rustc_errors::FluentBundle> {
+    fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
         panic!("silent emitter attempted to translate a diagnostic");
     }
 }
@@ -93,7 +93,7 @@ impl Emitter for SilentOnIgnoredFilesEmitter {
         self.emitter.fluent_bundle()
     }
 
-    fn fallback_fluent_bundle(&self) -> &Lrc<rustc_errors::FluentBundle> {
+    fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
         self.emitter.fallback_fluent_bundle()
     }
 }
@@ -114,8 +114,8 @@ fn default_handler(
     let emitter = if hide_parse_errors {
         silent_emitter()
     } else {
-        let fallback_bundle = rustc_errors::fallback_fluent_bundle(false)
-            .expect("failed to load fallback fluent bundle");
+        let fallback_bundle =
+            rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
         Box::new(EmitterWriter::stderr(
             color_cfg,
             Some(source_map.clone()),
@@ -350,7 +350,7 @@ mod tests {
             fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
                 None
             }
-            fn fallback_fluent_bundle(&self) -> &Lrc<rustc_errors::FluentBundle> {
+            fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
                 panic!("test emitter attempted to translate a diagnostic");
             }
         }