Skip to content

Commit

Permalink
Auto merge of rust-lang#95974 - fee1-dead:rollup-2fr55cs, r=fee1-dead
Browse files Browse the repository at this point in the history
Rollup of 5 pull requests

Successful merges:

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

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Apr 12, 2022
2 parents 2a83fbc + 1d76dd9 commit 327caac
Show file tree
Hide file tree
Showing 17 changed files with 207 additions and 150 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_ast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
9 changes: 1 addition & 8 deletions compiler/rustc_ast/src/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
69 changes: 39 additions & 30 deletions compiler/rustc_error_messages/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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`.
Expand All @@ -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)
}
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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);
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
let sess = build_session(
sessopts,
None,
None,
registry,
DiagnosticOutput::Default,
Default::default(),
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
24 changes: 13 additions & 11 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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>,
Expand Down Expand Up @@ -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);

Expand Down
152 changes: 82 additions & 70 deletions compiler/rustc_typeck/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand All @@ -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();
}
}
}
Expand Down
Loading

0 comments on commit 327caac

Please sign in to comment.