Skip to content

Commit 327caac

Browse files
committed
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
2 parents 2a83fbc + 1d76dd9 commit 327caac

File tree

17 files changed

+207
-150
lines changed

17 files changed

+207
-150
lines changed

compiler/rustc_ast/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
test(attr(deny(warnings)))
1010
)]
1111
#![feature(box_patterns)]
12+
#![feature(const_default_impls)]
13+
#![feature(const_trait_impl)]
1214
#![feature(crate_visibility_modifier)]
1315
#![feature(if_let_guard)]
1416
#![feature(label_break_value)]

compiler/rustc_ast/src/ptr.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,7 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for P<T> {
128128

129129
impl<T> P<[T]> {
130130
pub const fn new() -> P<[T]> {
131-
// HACK(eddyb) bypass the lack of a `const fn` to create an empty `Box<[T]>`
132-
// (as trait methods, `default` in this case, can't be `const fn` yet).
133-
P {
134-
ptr: unsafe {
135-
use std::ptr::NonNull;
136-
std::mem::transmute(NonNull::<[T; 0]>::dangling() as NonNull<[T]>)
137-
},
138-
}
131+
P { ptr: Box::default() }
139132
}
140133

141134
#[inline(never)]

compiler/rustc_error_messages/src/lib.rs

+39-30
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::error::Error;
1111
use std::fmt;
1212
use std::fs;
1313
use std::io;
14-
use std::path::Path;
14+
use std::path::{Path, PathBuf};
1515
use tracing::{instrument, trace};
1616

1717
#[cfg(parallel_compiler)]
@@ -45,7 +45,7 @@ pub enum TranslationBundleError {
4545
/// Failed to add `FluentResource` to `FluentBundle`.
4646
AddResource(FluentError),
4747
/// `$sysroot/share/locale/$locale` does not exist.
48-
MissingLocale(io::Error),
48+
MissingLocale,
4949
/// Cannot read directory entries of `$sysroot/share/locale/$locale`.
5050
ReadLocalesDir(io::Error),
5151
/// Cannot read directory entry of `$sysroot/share/locale/$locale`.
@@ -62,9 +62,7 @@ impl fmt::Display for TranslationBundleError {
6262
write!(f, "could not parse ftl file: {}", e)
6363
}
6464
TranslationBundleError::AddResource(e) => write!(f, "failed to add resource: {}", e),
65-
TranslationBundleError::MissingLocale(e) => {
66-
write!(f, "missing locale directory: {}", e)
67-
}
65+
TranslationBundleError::MissingLocale => write!(f, "missing locale directory"),
6866
TranslationBundleError::ReadLocalesDir(e) => {
6967
write!(f, "could not read locales dir: {}", e)
7068
}
@@ -84,7 +82,7 @@ impl Error for TranslationBundleError {
8482
TranslationBundleError::ReadFtl(e) => Some(e),
8583
TranslationBundleError::ParseFtl(e) => Some(e),
8684
TranslationBundleError::AddResource(e) => Some(e),
87-
TranslationBundleError::MissingLocale(e) => Some(e),
85+
TranslationBundleError::MissingLocale => None,
8886
TranslationBundleError::ReadLocalesDir(e) => Some(e),
8987
TranslationBundleError::ReadLocalesDirEntry(e) => Some(e),
9088
TranslationBundleError::LocaleIsNotDir => None,
@@ -113,7 +111,8 @@ impl From<Vec<FluentError>> for TranslationBundleError {
113111
/// (overriding any conflicting messages).
114112
#[instrument(level = "trace")]
115113
pub fn fluent_bundle(
116-
sysroot: &Path,
114+
mut user_provided_sysroot: Option<PathBuf>,
115+
mut sysroot_candidates: Vec<PathBuf>,
117116
requested_locale: Option<LanguageIdentifier>,
118117
additional_ftl_path: Option<&Path>,
119118
with_directionality_markers: bool,
@@ -140,33 +139,43 @@ pub fn fluent_bundle(
140139

141140
// If the user requests the default locale then don't try to load anything.
142141
if !requested_fallback_locale && let Some(requested_locale) = requested_locale {
143-
let mut sysroot = sysroot.to_path_buf();
144-
sysroot.push("share");
145-
sysroot.push("locale");
146-
sysroot.push(requested_locale.to_string());
147-
trace!(?sysroot);
148-
149-
let _ = sysroot.try_exists().map_err(TranslationBundleError::MissingLocale)?;
150-
151-
if !sysroot.is_dir() {
152-
return Err(TranslationBundleError::LocaleIsNotDir);
153-
}
154-
155-
for entry in sysroot.read_dir().map_err(TranslationBundleError::ReadLocalesDir)? {
156-
let entry = entry.map_err(TranslationBundleError::ReadLocalesDirEntry)?;
157-
let path = entry.path();
158-
trace!(?path);
159-
if path.extension().and_then(|s| s.to_str()) != Some("ftl") {
142+
let mut found_resources = false;
143+
for sysroot in user_provided_sysroot.iter_mut().chain(sysroot_candidates.iter_mut()) {
144+
sysroot.push("share");
145+
sysroot.push("locale");
146+
sysroot.push(requested_locale.to_string());
147+
trace!(?sysroot);
148+
149+
if !sysroot.exists() {
160150
trace!("skipping");
161151
continue;
162152
}
163153

164-
let resource_str =
165-
fs::read_to_string(path).map_err(TranslationBundleError::ReadFtl)?;
166-
let resource =
167-
FluentResource::try_new(resource_str).map_err(TranslationBundleError::from)?;
168-
trace!(?resource);
169-
bundle.add_resource(resource).map_err(TranslationBundleError::from)?;
154+
if !sysroot.is_dir() {
155+
return Err(TranslationBundleError::LocaleIsNotDir);
156+
}
157+
158+
for entry in sysroot.read_dir().map_err(TranslationBundleError::ReadLocalesDir)? {
159+
let entry = entry.map_err(TranslationBundleError::ReadLocalesDirEntry)?;
160+
let path = entry.path();
161+
trace!(?path);
162+
if path.extension().and_then(|s| s.to_str()) != Some("ftl") {
163+
trace!("skipping");
164+
continue;
165+
}
166+
167+
let resource_str =
168+
fs::read_to_string(path).map_err(TranslationBundleError::ReadFtl)?;
169+
let resource =
170+
FluentResource::try_new(resource_str).map_err(TranslationBundleError::from)?;
171+
trace!(?resource);
172+
bundle.add_resource(resource).map_err(TranslationBundleError::from)?;
173+
found_resources = true;
174+
}
175+
}
176+
177+
if !found_resources {
178+
return Err(TranslationBundleError::MissingLocale);
170179
}
171180
}
172181

compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
4444
let sess = build_session(
4545
sessopts,
4646
None,
47+
None,
4748
registry,
4849
DiagnosticOutput::Default,
4950
Default::default(),

compiler/rustc_interface/src/util.rs

+14
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,23 @@ pub fn create_session(
8383
// target_override is documented to be called before init(), so this is okay
8484
let target_override = codegen_backend.target_override(&sopts);
8585

86+
let bundle = match rustc_errors::fluent_bundle(
87+
sopts.maybe_sysroot.clone(),
88+
sysroot_candidates(),
89+
sopts.debugging_opts.translate_lang.clone(),
90+
sopts.debugging_opts.translate_additional_ftl.as_deref(),
91+
sopts.debugging_opts.translate_directionality_markers,
92+
) {
93+
Ok(bundle) => bundle,
94+
Err(e) => {
95+
early_error(sopts.error_format, &format!("failed to load fluent bundle: {e}"));
96+
}
97+
};
98+
8699
let mut sess = session::build_session(
87100
sopts,
88101
input_path,
102+
bundle,
89103
descriptions,
90104
diagnostic_output,
91105
lint_caps,

compiler/rustc_session/src/session.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType};
2020
use rustc_errors::json::JsonEmitter;
2121
use rustc_errors::registry::Registry;
2222
use rustc_errors::{
23-
fallback_fluent_bundle, fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
24-
EmissionGuarantee, ErrorGuaranteed, FluentBundle, MultiSpan,
23+
fallback_fluent_bundle, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, EmissionGuarantee,
24+
ErrorGuaranteed, FluentBundle, MultiSpan,
2525
};
2626
use rustc_macros::HashStable_Generic;
2727
pub use rustc_span::def_id::StableCrateId;
@@ -1162,6 +1162,7 @@ pub enum DiagnosticOutput {
11621162
pub fn build_session(
11631163
sopts: config::Options,
11641164
local_crate_source_file: Option<PathBuf>,
1165+
bundle: Option<Lrc<rustc_errors::FluentBundle>>,
11651166
registry: rustc_errors::registry::Registry,
11661167
diagnostics_output: DiagnosticOutput,
11671168
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
@@ -1214,16 +1215,17 @@ pub fn build_session(
12141215
hash_kind,
12151216
));
12161217

1217-
let bundle = fluent_bundle(
1218-
&sysroot,
1219-
sopts.debugging_opts.translate_lang.clone(),
1220-
sopts.debugging_opts.translate_additional_ftl.as_deref(),
1221-
sopts.debugging_opts.translate_directionality_markers,
1222-
)
1223-
.expect("failed to load fluent bundle");
12241218
let fallback_bundle =
1225-
fallback_fluent_bundle(sopts.debugging_opts.translate_directionality_markers)
1226-
.expect("failed to load fallback fluent bundle");
1219+
match fallback_fluent_bundle(sopts.debugging_opts.translate_directionality_markers) {
1220+
Ok(bundle) => bundle,
1221+
Err(e) => {
1222+
early_error(
1223+
sopts.error_format,
1224+
&format!("failed to load fallback fluent bundle: {e}"),
1225+
);
1226+
}
1227+
};
1228+
12271229
let emitter =
12281230
default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle, write_dest);
12291231

compiler/rustc_typeck/src/check/wfcheck.rs

+82-70
Original file line numberDiff line numberDiff line change
@@ -816,16 +816,69 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
816816
hir::GenericParamKind::Const { ty: hir_ty, default: _ } => {
817817
let ty = tcx.type_of(tcx.hir().local_def_id(param.hir_id));
818818

819-
let err_ty_str;
820-
let mut is_ptr = true;
821-
let err = if tcx.features().adt_const_params {
822-
match ty.peel_refs().kind() {
819+
if tcx.features().adt_const_params {
820+
let err = match ty.peel_refs().kind() {
823821
ty::FnPtr(_) => Some("function pointers"),
824822
ty::RawPtr(_) => Some("raw pointers"),
825823
_ => None,
824+
};
825+
826+
if let Some(unsupported_type) = err {
827+
tcx.sess.span_err(
828+
hir_ty.span,
829+
&format!(
830+
"using {} as const generic parameters is forbidden",
831+
unsupported_type
832+
),
833+
);
834+
}
835+
836+
if traits::search_for_structural_match_violation(param.span, tcx, ty).is_some() {
837+
// We use the same error code in both branches, because this is really the same
838+
// issue: we just special-case the message for type parameters to make it
839+
// clearer.
840+
if let ty::Param(_) = ty.peel_refs().kind() {
841+
// Const parameters may not have type parameters as their types,
842+
// because we cannot be sure that the type parameter derives `PartialEq`
843+
// and `Eq` (just implementing them is not enough for `structural_match`).
844+
struct_span_err!(
845+
tcx.sess,
846+
hir_ty.span,
847+
E0741,
848+
"`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
849+
used as the type of a const parameter",
850+
ty,
851+
)
852+
.span_label(
853+
hir_ty.span,
854+
format!("`{}` may not derive both `PartialEq` and `Eq`", ty),
855+
)
856+
.note(
857+
"it is not currently possible to use a type parameter as the type of a \
858+
const parameter",
859+
)
860+
.emit();
861+
} else {
862+
struct_span_err!(
863+
tcx.sess,
864+
hir_ty.span,
865+
E0741,
866+
"`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
867+
the type of a const parameter",
868+
ty,
869+
)
870+
.span_label(
871+
hir_ty.span,
872+
format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty),
873+
)
874+
.emit();
875+
}
826876
}
827877
} else {
828-
match ty.kind() {
878+
let err_ty_str;
879+
let mut is_ptr = true;
880+
881+
let err = match ty.kind() {
829882
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None,
830883
ty::FnPtr(_) => Some("function pointers"),
831884
ty::RawPtr(_) => Some("raw pointers"),
@@ -834,74 +887,33 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
834887
err_ty_str = format!("`{}`", ty);
835888
Some(err_ty_str.as_str())
836889
}
837-
}
838-
};
839-
if let Some(unsupported_type) = err {
840-
if is_ptr {
841-
tcx.sess.span_err(
842-
hir_ty.span,
843-
&format!(
844-
"using {} as const generic parameters is forbidden",
845-
unsupported_type
846-
),
847-
);
848-
} else {
849-
let mut err = tcx.sess.struct_span_err(
850-
hir_ty.span,
851-
&format!(
852-
"{} is forbidden as the type of a const generic parameter",
853-
unsupported_type
854-
),
855-
);
856-
err.note("the only supported types are integers, `bool` and `char`");
857-
if tcx.sess.is_nightly_build() {
858-
err.help(
890+
};
891+
892+
if let Some(unsupported_type) = err {
893+
if is_ptr {
894+
tcx.sess.span_err(
895+
hir_ty.span,
896+
&format!(
897+
"using {} as const generic parameters is forbidden",
898+
unsupported_type
899+
),
900+
);
901+
} else {
902+
let mut err = tcx.sess.struct_span_err(
903+
hir_ty.span,
904+
&format!(
905+
"{} is forbidden as the type of a const generic parameter",
906+
unsupported_type
907+
),
908+
);
909+
err.note("the only supported types are integers, `bool` and `char`");
910+
if tcx.sess.is_nightly_build() {
911+
err.help(
859912
"more complex types are supported with `#![feature(adt_const_params)]`",
860913
);
914+
}
915+
err.emit();
861916
}
862-
err.emit();
863-
}
864-
};
865-
866-
if traits::search_for_structural_match_violation(param.span, tcx, ty).is_some() {
867-
// We use the same error code in both branches, because this is really the same
868-
// issue: we just special-case the message for type parameters to make it
869-
// clearer.
870-
if let ty::Param(_) = ty.peel_refs().kind() {
871-
// Const parameters may not have type parameters as their types,
872-
// because we cannot be sure that the type parameter derives `PartialEq`
873-
// and `Eq` (just implementing them is not enough for `structural_match`).
874-
struct_span_err!(
875-
tcx.sess,
876-
hir_ty.span,
877-
E0741,
878-
"`{}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
879-
used as the type of a const parameter",
880-
ty,
881-
)
882-
.span_label(
883-
hir_ty.span,
884-
format!("`{}` may not derive both `PartialEq` and `Eq`", ty),
885-
)
886-
.note(
887-
"it is not currently possible to use a type parameter as the type of a \
888-
const parameter",
889-
)
890-
.emit();
891-
} else {
892-
struct_span_err!(
893-
tcx.sess,
894-
hir_ty.span,
895-
E0741,
896-
"`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
897-
the type of a const parameter",
898-
ty,
899-
)
900-
.span_label(
901-
hir_ty.span,
902-
format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty),
903-
)
904-
.emit();
905917
}
906918
}
907919
}

0 commit comments

Comments
 (0)