about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-04-12 13:06:49 +0000
committerbors <bors@rust-lang.org>2022-04-12 13:06:49 +0000
commit327caac4d01aef74d6577b87c295270608be09fa (patch)
treecb289ff5f0ef2a5cf45e4da8c4ae6f058350521d
parent2a83fbc42a9bb6bfdb8d3fb4ecce83fb410d7642 (diff)
parent1d76dd9ee7fd33585f69d8ca799283724725430e (diff)
Auto merge of #95974 - fee1-dead:rollup-2fr55cs, r=fee1-dead
Rollup of 5 pull requests

Successful merges:

 - #95671 (feat: Allow usage of sudo [while not accessing root] in x.py)
 - #95716 (sess: warn w/out fluent bundle w/ user sysroot)
 - #95820 (simplify const params diagnostic on stable)
 - #95900 (Fix documentation for wasm32-unknown-unknown)
 - #95947 (`impl const Default for Box<[T]>` and `Box<str>`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_ast/src/lib.rs2
-rw-r--r--compiler/rustc_ast/src/ptr.rs9
-rw-r--r--compiler/rustc_error_messages/src/lib.rs69
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_interface/src/util.rs14
-rw-r--r--compiler/rustc_session/src/session.rs24
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs152
-rw-r--r--library/alloc/src/boxed.rs16
-rw-r--r--library/alloc/tests/const_fns.rs6
-rw-r--r--library/std/src/os/fd/owned.rs6
-rw-r--r--library/std/src/os/fd/raw.rs2
-rw-r--r--src/bootstrap/bootstrap.py4
-rw-r--r--src/test/run-make/translation/Makefile28
-rw-r--r--src/test/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr9
-rw-r--r--src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs2
-rw-r--r--src/test/ui/const-generics/nested-type.min.stderr11
-rw-r--r--src/test/ui/const-generics/nested-type.rs2
17 files changed, 207 insertions, 150 deletions
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index 538bfc21290..a7c23dbb79c 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 70dbda82224..89a0857992e 100644
--- a/compiler/rustc_ast/src/ptr.rs
+++ b/compiler/rustc_ast/src/ptr.rs
@@ -128,14 +128,7 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for P<T> {
 
 impl<T> 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)]
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index 88f3b547605..b33e6b66117 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<Vec<FluentError>> for TranslationBundleError {
 /// (overriding any conflicting messages).
 #[instrument(level = "trace")]
 pub fn fluent_bundle(
-    sysroot: &Path,
+    mut user_provided_sysroot: Option<PathBuf>,
+    mut sysroot_candidates: Vec<PathBuf>,
     requested_locale: Option<LanguageIdentifier>,
     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 a3570320767..fe75ee8b37b 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 592cf60e6c3..3fa8017dc93 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 9881046ddfa..d70f89760a1 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<PathBuf>,
+    bundle: Option<Lrc<rustc_errors::FluentBundle>>,
     registry: rustc_errors::registry::Registry,
     diagnostics_output: DiagnosticOutput,
     driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
@@ -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/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index b2be70e707d..f9664a9b991 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/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index e6faf1df3a8..639e7f213ea 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -1192,17 +1192,25 @@ impl<T: Default> Default for Box<T> {
 
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> Default for Box<[T]> {
+#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+impl<T> 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<str> {
+#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
+impl const Default for Box<str> {
     fn default() -> Self {
-        unsafe { from_boxed_utf8_unchecked(Default::default()) }
+        // SAFETY: This is the same as `Unique::cast<U>` but with an unsized `U = str`.
+        let ptr: Unique<str> = 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 f448b3eb7c3..49b837becbc 100644
--- a/library/alloc/tests/const_fns.rs
+++ b/library/alloc/tests/const_fns.rs
@@ -6,6 +6,9 @@ pub const MY_VEC2: Vec<usize> = 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<str> = Default::default();
+
 use std::collections::{BTreeMap, BTreeSet};
 
 pub const MY_BTREEMAP: BTreeMap<usize, usize> = 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);
diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs
index 807b057234a..e6013c7c051 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<Self> {
         // 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<Self> {
         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 f9c883dd6bf..47ee88d97fb 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;
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 54b6750cc4d..9af0657caff 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -1173,9 +1173,9 @@ class RustBuild(object):
         """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):
diff --git a/src/test/run-make/translation/Makefile b/src/test/run-make/translation/Makefile
index 22a3bf57ecf..bfff75e7acb 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"
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 b1141cf3bdf..9f6c7ccf3fe 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<const T: &'static dyn A>() {
    = 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<const T: &'static dyn A>() {
-   |                  ^^^^^^^^^^^^^^ `&'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 01a6caa130f..116c3fcfb21 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<const T: &'static dyn A>() {
-    //~^ 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 0e3c988ae4d..276ebf31ff8 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 5240f5c3b0b..742340f430e 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<const N: [u8; { //[min]~ ERROR `[u8; _]` is forbidden
     }
 
     Foo::<17>::value()
-    //~^ ERROR cannot call non-const fn
+    //[full]~^ ERROR cannot call non-const fn
 }]>;
 
 fn main() {}