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
This commit is contained in:
bors 2022-04-12 13:06:49 +00:00
commit 327caac4d0
17 changed files with 206 additions and 149 deletions

View File

@ -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)]

View File

@ -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)]

View File

@ -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 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);
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") {
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);
}
}

View File

@ -44,6 +44,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
let sess = build_session(
sessopts,
None,
None,
registry,
DiagnosticOutput::Default,
Default::default(),

View File

@ -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,

View File

@ -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);

View File

@ -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();
}
}
}

View File

@ -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)
}
}

View File

@ -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);

View File

@ -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,

View File

@ -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;

View File

@ -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):

View File

@ -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"

View File

@ -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 previous error
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0741`.

View File

@ -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!()
}

View File

@ -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 previous error
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0015`.

View File

@ -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() {}