From 386ca6acc358fc81028680a45c8f3695c2988fef Mon Sep 17 00:00:00 2001 From: gimbles Date: Sun, 10 Apr 2022 20:51:11 +0530 Subject: [PATCH 1/6] Allow usage of sudo while not accessing root --- src/bootstrap/bootstrap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 71b8f3c4553bc..927e686070f29 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -1161,9 +1161,9 @@ def check_vendored_status(self): """Check that vendoring is configured properly""" vendor_dir = os.path.join(self.rust_root, 'vendor') if 'SUDO_USER' in os.environ and not self.use_vendored_sources: - if os.environ.get('USER') != os.environ['SUDO_USER']: + if os.getuid() == 0: self.use_vendored_sources = True - print('info: looks like you are running this command under `sudo`') + print('info: looks like you\'re trying to run this command as root') print(' and so in order to preserve your $HOME this will now') print(' use vendored sources by default.') if not os.path.exists(vendor_dir): From 3f4bbd50fda2be3ccf31031003bce19645afa99a Mon Sep 17 00:00:00 2001 From: O01eg Date: Mon, 11 Apr 2022 19:16:10 +0300 Subject: [PATCH 2/6] Fix documentation for wasm32-unknown-unknown --- library/std/src/os/fd/owned.rs | 6 +++--- library/std/src/os/fd/raw.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 807b057234ac1..e6013c7c051e5 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -8,7 +8,7 @@ use crate::fmt; use crate::fs; use crate::marker::PhantomData; use crate::mem::forget; -#[cfg(not(any(target_os = "wasi", target_env = "sgx")))] +#[cfg(not(any(target_arch = "wasm32", target_env = "sgx")))] use crate::sys::cvt; use crate::sys_common::{AsInner, FromInner, IntoInner}; @@ -76,7 +76,7 @@ impl BorrowedFd<'_> { impl OwnedFd { /// Creates a new `OwnedFd` instance that shares the same underlying file handle /// as the existing `OwnedFd` instance. - #[cfg(not(target_os = "wasi"))] + #[cfg(not(target_arch = "wasm32"))] pub fn try_clone(&self) -> crate::io::Result { // We want to atomically duplicate this file descriptor and set the // CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This @@ -95,7 +95,7 @@ impl OwnedFd { Ok(unsafe { Self::from_raw_fd(fd) }) } - #[cfg(target_os = "wasi")] + #[cfg(target_arch = "wasm32")] pub fn try_clone(&self) -> crate::io::Result { Err(crate::io::const_io_error!( crate::io::ErrorKind::Unsupported, diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs index f9c883dd6bf08..47ee88d97fb93 100644 --- a/library/std/src/os/fd/raw.rs +++ b/library/std/src/os/fd/raw.rs @@ -5,7 +5,7 @@ use crate::fs; use crate::io; use crate::os::raw; -#[cfg(doc)] +#[cfg(all(doc, not(target_arch = "wasm32")))] use crate::os::unix::io::AsFd; #[cfg(unix)] use crate::os::unix::io::OwnedFd; From a2902ebe578c2b116d74b946f53ddfc6c1416cae Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 11 Apr 2022 11:43:21 -0700 Subject: [PATCH 3/6] impl const Default for Box<[T]> and Box --- library/alloc/src/boxed.rs | 16 ++++++++++++---- library/alloc/tests/const_fns.rs | 6 ++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index e6faf1df3a810..639e7f213eaae 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1192,17 +1192,25 @@ impl Default for Box { #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] -impl Default for Box<[T]> { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for Box<[T]> { fn default() -> Self { - Box::<[T; 0]>::new([]) + let ptr: Unique<[T]> = Unique::<[T; 0]>::dangling(); + Box(ptr, Global) } } #[cfg(not(no_global_oom_handling))] #[stable(feature = "default_box_extra", since = "1.17.0")] -impl Default for Box { +#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] +impl const Default for Box { fn default() -> Self { - unsafe { from_boxed_utf8_unchecked(Default::default()) } + // SAFETY: This is the same as `Unique::cast` but with an unsized `U = str`. + let ptr: Unique = unsafe { + let bytes: Unique<[u8]> = Unique::<[u8; 0]>::dangling(); + Unique::new_unchecked(bytes.as_ptr() as *mut str) + }; + Box(ptr, Global) } } diff --git a/library/alloc/tests/const_fns.rs b/library/alloc/tests/const_fns.rs index f448b3eb7c300..49b837becbcd8 100644 --- a/library/alloc/tests/const_fns.rs +++ b/library/alloc/tests/const_fns.rs @@ -6,6 +6,9 @@ pub const MY_VEC2: Vec = Default::default(); pub const MY_STRING: String = String::new(); pub const MY_STRING2: String = Default::default(); +pub const MY_BOXED_SLICE: Box<[usize]> = Default::default(); +pub const MY_BOXED_STR: Box = Default::default(); + use std::collections::{BTreeMap, BTreeSet}; pub const MY_BTREEMAP: BTreeMap = BTreeMap::new(); @@ -23,6 +26,9 @@ fn test_const() { assert_eq!(MY_VEC, MY_VEC2); assert_eq!(MY_STRING, MY_STRING2); + assert_eq!(MY_VEC, *MY_BOXED_SLICE); + assert_eq!(MY_STRING, *MY_BOXED_STR); + assert_eq!(MAP_LEN, 0); assert_eq!(SET_LEN, 0); assert!(MAP_IS_EMPTY && SET_IS_EMPTY); From 2d5eda8fb0392f469e599a6ac3fb23461161dff6 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 11 Apr 2022 11:44:13 -0700 Subject: [PATCH 4/6] Use const Box::default in P::<[T]>::new --- compiler/rustc_ast/src/lib.rs | 2 ++ compiler/rustc_ast/src/ptr.rs | 9 +-------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 538bfc2129017..a7c23dbb79ca5 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -9,6 +9,8 @@ test(attr(deny(warnings))) )] #![feature(box_patterns)] +#![feature(const_default_impls)] +#![feature(const_trait_impl)] #![feature(crate_visibility_modifier)] #![feature(if_let_guard)] #![feature(label_break_value)] diff --git a/compiler/rustc_ast/src/ptr.rs b/compiler/rustc_ast/src/ptr.rs index 70dbda8222445..89a0857992e49 100644 --- a/compiler/rustc_ast/src/ptr.rs +++ b/compiler/rustc_ast/src/ptr.rs @@ -128,14 +128,7 @@ impl> Encodable for P { impl P<[T]> { pub const fn new() -> P<[T]> { - // HACK(eddyb) bypass the lack of a `const fn` to create an empty `Box<[T]>` - // (as trait methods, `default` in this case, can't be `const fn` yet). - P { - ptr: unsafe { - use std::ptr::NonNull; - std::mem::transmute(NonNull::<[T; 0]>::dangling() as NonNull<[T]>) - }, - } + P { ptr: Box::default() } } #[inline(never)] From 3b4589a30914fbaf9bc0f1115dc7437523b1465b Mon Sep 17 00:00:00 2001 From: Oliver Downard Date: Fri, 8 Apr 2022 19:10:07 +0100 Subject: [PATCH 5/6] simplify const params diagnostic on stable --- compiler/rustc_typeck/src/check/wfcheck.rs | 152 ++++++++++-------- .../issues/issue-63322-forbid-dyn.min.stderr | 9 +- .../issues/issue-63322-forbid-dyn.rs | 2 +- .../ui/const-generics/nested-type.min.stderr | 11 +- src/test/ui/const-generics/nested-type.rs | 2 +- 5 files changed, 86 insertions(+), 90 deletions(-) diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index b2be70e707dab..f9664a9b99155 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -816,16 +816,69 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { hir::GenericParamKind::Const { ty: hir_ty, default: _ } => { let ty = tcx.type_of(tcx.hir().local_def_id(param.hir_id)); - let err_ty_str; - let mut is_ptr = true; - let err = if tcx.features().adt_const_params { - match ty.peel_refs().kind() { + if tcx.features().adt_const_params { + let err = match ty.peel_refs().kind() { ty::FnPtr(_) => Some("function pointers"), ty::RawPtr(_) => Some("raw pointers"), _ => None, + }; + + if let Some(unsupported_type) = err { + tcx.sess.span_err( + hir_ty.span, + &format!( + "using {} as const generic parameters is forbidden", + unsupported_type + ), + ); + } + + if traits::search_for_structural_match_violation(param.span, tcx, ty).is_some() { + // We use the same error code in both branches, because this is really the same + // issue: we just special-case the message for type parameters to make it + // clearer. + if let ty::Param(_) = ty.peel_refs().kind() { + // Const parameters may not have type parameters as their types, + // because we cannot be sure that the type parameter derives `PartialEq` + // and `Eq` (just implementing them is not enough for `structural_match`). + struct_span_err!( + tcx.sess, + hir_ty.span, + E0741, + "`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \ + used as the type of a const parameter", + ty, + ) + .span_label( + hir_ty.span, + format!("`{}` may not derive both `PartialEq` and `Eq`", ty), + ) + .note( + "it is not currently possible to use a type parameter as the type of a \ + const parameter", + ) + .emit(); + } else { + struct_span_err!( + tcx.sess, + hir_ty.span, + E0741, + "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \ + the type of a const parameter", + ty, + ) + .span_label( + hir_ty.span, + format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty), + ) + .emit(); + } } } else { - match ty.kind() { + let err_ty_str; + let mut is_ptr = true; + + let err = match ty.kind() { ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None, ty::FnPtr(_) => Some("function pointers"), ty::RawPtr(_) => Some("raw pointers"), @@ -834,74 +887,33 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { err_ty_str = format!("`{}`", ty); Some(err_ty_str.as_str()) } - } - }; - if let Some(unsupported_type) = err { - if is_ptr { - tcx.sess.span_err( - hir_ty.span, - &format!( - "using {} as const generic parameters is forbidden", - unsupported_type - ), - ); - } else { - let mut err = tcx.sess.struct_span_err( - hir_ty.span, - &format!( - "{} is forbidden as the type of a const generic parameter", - unsupported_type - ), - ); - err.note("the only supported types are integers, `bool` and `char`"); - if tcx.sess.is_nightly_build() { - err.help( + }; + + if let Some(unsupported_type) = err { + if is_ptr { + tcx.sess.span_err( + hir_ty.span, + &format!( + "using {} as const generic parameters is forbidden", + unsupported_type + ), + ); + } else { + let mut err = tcx.sess.struct_span_err( + hir_ty.span, + &format!( + "{} is forbidden as the type of a const generic parameter", + unsupported_type + ), + ); + err.note("the only supported types are integers, `bool` and `char`"); + if tcx.sess.is_nightly_build() { + err.help( "more complex types are supported with `#![feature(adt_const_params)]`", ); + } + err.emit(); } - err.emit(); - } - }; - - if traits::search_for_structural_match_violation(param.span, tcx, ty).is_some() { - // We use the same error code in both branches, because this is really the same - // issue: we just special-case the message for type parameters to make it - // clearer. - if let ty::Param(_) = ty.peel_refs().kind() { - // Const parameters may not have type parameters as their types, - // because we cannot be sure that the type parameter derives `PartialEq` - // and `Eq` (just implementing them is not enough for `structural_match`). - struct_span_err!( - tcx.sess, - hir_ty.span, - E0741, - "`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \ - used as the type of a const parameter", - ty, - ) - .span_label( - hir_ty.span, - format!("`{}` may not derive both `PartialEq` and `Eq`", ty), - ) - .note( - "it is not currently possible to use a type parameter as the type of a \ - const parameter", - ) - .emit(); - } else { - struct_span_err!( - tcx.sess, - hir_ty.span, - E0741, - "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \ - the type of a const parameter", - ty, - ) - .span_label( - hir_ty.span, - format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty), - ) - .emit(); } } } diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr index b1141cf3bdfbf..9f6c7ccf3fe74 100644 --- a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr +++ b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr @@ -7,12 +7,5 @@ LL | fn test() { = note: the only supported types are integers, `bool` and `char` = help: more complex types are supported with `#![feature(adt_const_params)]` -error[E0741]: `&'static (dyn A + 'static)` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter - --> $DIR/issue-63322-forbid-dyn.rs:9:18 - | -LL | fn test() { - | ^^^^^^^^^^^^^^ `&'static (dyn A + 'static)` doesn't derive both `PartialEq` and `Eq` - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0741`. diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs index 01a6caa130f38..116c3fcfb2170 100644 --- a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs +++ b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs @@ -7,7 +7,7 @@ struct B; impl A for B {} fn test() { - //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` to be used + //[full]~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` to be used //[min]~^^ ERROR `&'static (dyn A + 'static)` is forbidden unimplemented!() } diff --git a/src/test/ui/const-generics/nested-type.min.stderr b/src/test/ui/const-generics/nested-type.min.stderr index 0e3c988ae4d8c..276ebf31ff8b8 100644 --- a/src/test/ui/const-generics/nested-type.min.stderr +++ b/src/test/ui/const-generics/nested-type.min.stderr @@ -14,14 +14,5 @@ LL | | }]>; = note: the only supported types are integers, `bool` and `char` = help: more complex types are supported with `#![feature(adt_const_params)]` -error[E0015]: cannot call non-const fn `Foo::{constant#0}::Foo::<17_usize>::value` in constants - --> $DIR/nested-type.rs:15:5 - | -LL | Foo::<17>::value() - | ^^^^^^^^^^^^^^^^^^ - | - = note: calls in constants are limited to constant functions, tuple structs and tuple variants - -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0015`. diff --git a/src/test/ui/const-generics/nested-type.rs b/src/test/ui/const-generics/nested-type.rs index 5240f5c3b0b64..742340f430e2b 100644 --- a/src/test/ui/const-generics/nested-type.rs +++ b/src/test/ui/const-generics/nested-type.rs @@ -13,7 +13,7 @@ struct Foo::value() - //~^ ERROR cannot call non-const fn + //[full]~^ ERROR cannot call non-const fn }]>; fn main() {} From fc3cca24f1230bb308e83168a3260abf36359f85 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 6 Apr 2022 04:16:07 +0100 Subject: [PATCH 6/6] sess: try sysroot candidates for fluent bundle Instead of checking only the user provided sysroot or the default (when no sysroot is provided), search user provided sysroot and then check default sysroots for locale requested by the user. Signed-off-by: David Wood --- compiler/rustc_error_messages/src/lib.rs | 69 +++++++++++++----------- compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_interface/src/util.rs | 14 +++++ compiler/rustc_session/src/session.rs | 24 +++++---- src/test/run-make/translation/Makefile | 28 +++++++++- 5 files changed, 94 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 88f3b547605a2..b33e6b6611706 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -11,7 +11,7 @@ use std::error::Error; use std::fmt; use std::fs; use std::io; -use std::path::Path; +use std::path::{Path, PathBuf}; use tracing::{instrument, trace}; #[cfg(parallel_compiler)] @@ -45,7 +45,7 @@ pub enum TranslationBundleError { /// Failed to add `FluentResource` to `FluentBundle`. AddResource(FluentError), /// `$sysroot/share/locale/$locale` does not exist. - MissingLocale(io::Error), + MissingLocale, /// Cannot read directory entries of `$sysroot/share/locale/$locale`. ReadLocalesDir(io::Error), /// Cannot read directory entry of `$sysroot/share/locale/$locale`. @@ -62,9 +62,7 @@ impl fmt::Display for TranslationBundleError { 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::MissingLocale => write!(f, "missing locale directory"), TranslationBundleError::ReadLocalesDir(e) => { write!(f, "could not read locales dir: {}", e) } @@ -84,7 +82,7 @@ impl Error for TranslationBundleError { TranslationBundleError::ReadFtl(e) => Some(e), TranslationBundleError::ParseFtl(e) => Some(e), TranslationBundleError::AddResource(e) => Some(e), - TranslationBundleError::MissingLocale(e) => Some(e), + TranslationBundleError::MissingLocale => None, TranslationBundleError::ReadLocalesDir(e) => Some(e), TranslationBundleError::ReadLocalesDirEntry(e) => Some(e), TranslationBundleError::LocaleIsNotDir => None, @@ -113,7 +111,8 @@ impl From> for TranslationBundleError { /// (overriding any conflicting messages). #[instrument(level = "trace")] pub fn fluent_bundle( - sysroot: &Path, + mut user_provided_sysroot: Option, + mut sysroot_candidates: Vec, requested_locale: Option, additional_ftl_path: Option<&Path>, with_directionality_markers: bool, @@ -140,33 +139,43 @@ pub fn fluent_bundle( // 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") { + let mut found_resources = false; + for sysroot in user_provided_sysroot.iter_mut().chain(sysroot_candidates.iter_mut()) { + sysroot.push("share"); + sysroot.push("locale"); + sysroot.push(requested_locale.to_string()); + trace!(?sysroot); + + if !sysroot.exists() { 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 !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)?; + found_resources = true; + } + } + + if !found_resources { + return Err(TranslationBundleError::MissingLocale); } } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index a357032076772..fe75ee8b37b8d 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -44,6 +44,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) { let sess = build_session( sessopts, None, + None, registry, DiagnosticOutput::Default, Default::default(), diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 592cf60e6c3bb..3fa8017dc93c3 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -83,9 +83,23 @@ pub fn create_session( // target_override is documented to be called before init(), so this is okay let target_override = codegen_backend.target_override(&sopts); + let bundle = match rustc_errors::fluent_bundle( + sopts.maybe_sysroot.clone(), + sysroot_candidates(), + sopts.debugging_opts.translate_lang.clone(), + sopts.debugging_opts.translate_additional_ftl.as_deref(), + sopts.debugging_opts.translate_directionality_markers, + ) { + Ok(bundle) => bundle, + Err(e) => { + early_error(sopts.error_format, &format!("failed to load fluent bundle: {e}")); + } + }; + let mut sess = session::build_session( sopts, input_path, + bundle, descriptions, diagnostic_output, lint_caps, diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 9881046ddfa29..d70f89760a1ff 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -20,8 +20,8 @@ use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType}; use rustc_errors::json::JsonEmitter; use rustc_errors::registry::Registry; use rustc_errors::{ - fallback_fluent_bundle, fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, - EmissionGuarantee, ErrorGuaranteed, FluentBundle, MultiSpan, + fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, EmissionGuarantee, + ErrorGuaranteed, FluentBundle, MultiSpan, }; use rustc_macros::HashStable_Generic; pub use rustc_span::def_id::StableCrateId; @@ -1162,6 +1162,7 @@ pub enum DiagnosticOutput { pub fn build_session( sopts: config::Options, local_crate_source_file: Option, + bundle: Option>, registry: rustc_errors::registry::Registry, diagnostics_output: DiagnosticOutput, driver_lint_caps: FxHashMap, @@ -1214,16 +1215,17 @@ pub fn build_session( hash_kind, )); - let bundle = fluent_bundle( - &sysroot, - sopts.debugging_opts.translate_lang.clone(), - sopts.debugging_opts.translate_additional_ftl.as_deref(), - sopts.debugging_opts.translate_directionality_markers, - ) - .expect("failed to load fluent bundle"); let fallback_bundle = - fallback_fluent_bundle(sopts.debugging_opts.translate_directionality_markers) - .expect("failed to load fallback fluent 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 emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle, write_dest); diff --git a/src/test/run-make/translation/Makefile b/src/test/run-make/translation/Makefile index 22a3bf57ecf96..bfff75e7acb08 100644 --- a/src/test/run-make/translation/Makefile +++ b/src/test/run-make/translation/Makefile @@ -15,7 +15,9 @@ normal: basic-translation.rs custom: basic-translation.rs basic-translation.ftl $(RUSTC) $< -Ztranslate-additional-ftl=$(CURDIR)/basic-translation.ftl 2>&1 | grep "this is a test message" -# Make a local copy of the sysroot and add the custom locale to it. +# Check that a locale can be loaded from the sysroot given a language +# identifier by making a local copy of the sysroot and adding the custom locale +# to it. sysroot: basic-translation.rs basic-translation.ftl mkdir $(FAKEROOT) ln -s $(SYSROOT)/* $(FAKEROOT) @@ -31,3 +33,27 @@ sysroot: basic-translation.rs basic-translation.ftl mkdir -p $(FAKEROOT)/share/locale/zh-CN/ ln -s $(CURDIR)/basic-translation.ftl $(FAKEROOT)/share/locale/zh-CN/basic-translation.ftl $(RUSTC) $< --sysroot $(FAKEROOT) -Ztranslate-lang=zh-CN 2>&1 | grep "this is a test message" + +# Check that the compiler errors out when the sysroot requested cannot be +# found. This test might start failing if there actually exists a Klingon +# translation of rustc's error messages. +sysroot-missing: + $(RUSTC) $< -Ztranslate-lang=tlh 2>&1 || grep "missing locale directory" + +# Check that the compiler errors out when the sysroot requested cannot be +# found. This test might start failing if there actually exists a Klingon +# translation of rustc's error messages. +sysroot-invalid: basic-translation.rs basic-translation.ftl + mkdir $(FAKEROOT) + ln -s $(SYSROOT)/* $(FAKEROOT) + rm -f $(FAKEROOT)/lib + mkdir $(FAKEROOT)/lib + ln -s $(SYSROOT)/lib/* $(FAKEROOT)/lib + rm -f $(FAKEROOT)/lib/rustlib + mkdir $(FAKEROOT)/lib/rustlib + ln -s $(SYSROOT)/lib/rustlib/* $(FAKEROOT)/lib/rustlib + rm -f $(FAKEROOT)/lib/rustlib/src + mkdir $(FAKEROOT)/lib/rustlib/src + ln -s $(SYSROOT)/lib/rustlib/src/* $(FAKEROOT)/lib/rustlib/src + touch $(FAKEROOT)/share/locale/zh-CN/ + $(RUSTC) $< --sysroot $(FAKEROOT) -Ztranslate-lang=zh-CN 2>&1 || grep "`\$sysroot/share/locales/\$locale` is not a directory"