Auto merge of #138583 - jhpratt:rollup-h699hty, r=jhpratt

Rollup of 5 pull requests

Successful merges:

 - #136293 (document capacity for ZST as example)
 - #136359 (doc all differences of ptr:copy(_nonoverlapping) with memcpy and memmove)
 - #136816 (refactor `notable_traits_button` to use iterator combinators  instead of for loop)
 - #138552 (Misc print request handling cleanups + a centralized test for print request stability gating)
 - #138573 (Make `_Unwind_Action` a type alias, not enum)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-03-17 03:45:06 +00:00
commit 10bcdad7df
11 changed files with 206 additions and 114 deletions

View file

@ -649,10 +649,10 @@ fn print_crate_info(
HostTuple => println_info!("{}", rustc_session::config::host_tuple()),
Sysroot => println_info!("{}", sess.sysroot.display()),
TargetLibdir => println_info!("{}", sess.target_tlib_path.dir.display()),
TargetSpec => {
TargetSpecJson => {
println_info!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap());
}
AllTargetSpecs => {
AllTargetSpecsJson => {
let mut targets = BTreeMap::new();
for name in rustc_target::spec::TARGETS {
let triple = TargetTuple::from_tuple(name);

View file

@ -44,7 +44,7 @@ pub mod sigpipe;
pub const PRINT_KINDS: &[(&str, PrintKind)] = &[
// tidy-alphabetical-start
("all-target-specs-json", PrintKind::AllTargetSpecs),
("all-target-specs-json", PrintKind::AllTargetSpecsJson),
("calling-conventions", PrintKind::CallingConventions),
("cfg", PrintKind::Cfg),
("check-cfg", PrintKind::CheckCfg),
@ -63,7 +63,7 @@ pub const PRINT_KINDS: &[(&str, PrintKind)] = &[
("target-features", PrintKind::TargetFeatures),
("target-libdir", PrintKind::TargetLibdir),
("target-list", PrintKind::TargetList),
("target-spec-json", PrintKind::TargetSpec),
("target-spec-json", PrintKind::TargetSpecJson),
("tls-models", PrintKind::TlsModels),
// tidy-alphabetical-end
];
@ -873,27 +873,29 @@ pub struct PrintRequest {
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum PrintKind {
FileNames,
HostTuple,
Sysroot,
TargetLibdir,
CrateName,
// tidy-alphabetical-start
AllTargetSpecsJson,
CallingConventions,
Cfg,
CheckCfg,
CallingConventions,
TargetList,
CodeModels,
CrateName,
DeploymentTarget,
FileNames,
HostTuple,
LinkArgs,
NativeStaticLibs,
RelocationModels,
SplitDebuginfo,
StackProtectorStrategies,
Sysroot,
TargetCPUs,
TargetFeatures,
RelocationModels,
CodeModels,
TargetLibdir,
TargetList,
TargetSpecJson,
TlsModels,
TargetSpec,
AllTargetSpecs,
NativeStaticLibs,
StackProtectorStrategies,
LinkArgs,
SplitDebuginfo,
DeploymentTarget,
// tidy-alphabetical-end
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Default)]
@ -2030,49 +2032,13 @@ fn collect_print_requests(
prints.extend(matches.opt_strs("print").into_iter().map(|req| {
let (req, out) = split_out_file_name(&req);
let kind = match PRINT_KINDS.iter().find(|&&(name, _)| name == req) {
Some((_, PrintKind::TargetSpec)) => {
if unstable_opts.unstable_options {
PrintKind::TargetSpec
} else {
early_dcx.early_fatal(
"the `-Z unstable-options` flag must also be passed to \
enable the target-spec-json print option",
);
}
}
Some((_, PrintKind::AllTargetSpecs)) => {
if unstable_opts.unstable_options {
PrintKind::AllTargetSpecs
} else {
early_dcx.early_fatal(
"the `-Z unstable-options` flag must also be passed to \
enable the all-target-specs-json print option",
);
}
}
Some((_, PrintKind::CheckCfg)) => {
if unstable_opts.unstable_options {
PrintKind::CheckCfg
} else {
early_dcx.early_fatal(
"the `-Z unstable-options` flag must also be passed to \
enable the check-cfg print option",
);
}
}
Some(&(_, print_kind)) => print_kind,
None => {
let prints =
PRINT_KINDS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>();
let prints = prints.join(", ");
let mut diag =
early_dcx.early_struct_fatal(format!("unknown print request: `{req}`"));
#[allow(rustc::diagnostic_outside_of_impl)]
diag.help(format!("valid print requests are: {prints}"));
diag.emit()
}
let kind = if let Some((print_name, print_kind)) =
PRINT_KINDS.iter().find(|&&(name, _)| name == req)
{
check_print_request_stability(early_dcx, unstable_opts, (print_name, *print_kind));
*print_kind
} else {
emit_unknown_print_request_help(early_dcx, req)
};
let out = out.unwrap_or(OutFileName::Stdout);
@ -2091,6 +2057,34 @@ fn collect_print_requests(
prints
}
fn check_print_request_stability(
early_dcx: &EarlyDiagCtxt,
unstable_opts: &UnstableOptions,
(print_name, print_kind): (&str, PrintKind),
) {
match print_kind {
PrintKind::AllTargetSpecsJson | PrintKind::CheckCfg | PrintKind::TargetSpecJson
if !unstable_opts.unstable_options =>
{
early_dcx.early_fatal(format!(
"the `-Z unstable-options` flag must also be passed to enable the `{print_name}` \
print option"
));
}
_ => {}
}
}
fn emit_unknown_print_request_help(early_dcx: &EarlyDiagCtxt, req: &str) -> ! {
let prints = PRINT_KINDS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>();
let prints = prints.join(", ");
let mut diag = early_dcx.early_struct_fatal(format!("unknown print request: `{req}`"));
#[allow(rustc::diagnostic_outside_of_impl)]
diag.help(format!("valid print requests are: {prints}"));
diag.emit()
}
pub fn parse_target_triple(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> TargetTuple {
match matches.opt_str("target") {
Some(target) if target.ends_with(".json") => {

View file

@ -1252,6 +1252,19 @@ impl<T, A: Allocator> Vec<T, A> {
/// vec.push(42);
/// assert!(vec.capacity() >= 10);
/// ```
///
/// A vector with zero-sized elements will always have a capacity of usize::MAX:
///
/// ```
/// #[derive(Clone)]
/// struct ZeroSized;
///
/// fn main() {
/// assert_eq!(std::mem::size_of::<ZeroSized>(), 0);
/// let v = vec![ZeroSized; 0];
/// assert_eq!(v.capacity(), usize::MAX);
/// }
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_vec_string_slice", since = "CURRENT_RUSTC_VERSION")]

View file

@ -3641,7 +3641,8 @@ pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + ?Sized, M>(ptr: *const
/// For regions of memory which might overlap, use [`copy`] instead.
///
/// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
/// with the argument order swapped.
/// with the source and destination arguments swapped,
/// and `count` counting the number of `T`s instead of bytes.
///
/// The copy is "untyped" in the sense that data may be uninitialized or otherwise violate the
/// requirements of `T`. The initialization state is preserved exactly.
@ -3761,8 +3762,10 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
/// If the source and destination will *never* overlap,
/// [`copy_nonoverlapping`] can be used instead.
///
/// `copy` is semantically equivalent to C's [`memmove`], but with the argument
/// order swapped. Copying takes place as if the bytes were copied from `src`
/// `copy` is semantically equivalent to C's [`memmove`], but
/// with the source and destination arguments swapped,
/// and `count` counting the number of `T`s instead of bytes.
/// Copying takes place as if the bytes were copied from `src`
/// to a temporary array and then copied from the array to `dst`.
///
/// The copy is "untyped" in the sense that data may be uninitialized or otherwise violate the

View file

@ -220,7 +220,7 @@ cfg_if::cfg_if! {
Ok(action) => action,
Err(_) => return uw::_URC_FATAL_PHASE1_ERROR,
};
if actions as i32 & uw::_UA_SEARCH_PHASE as i32 != 0 {
if actions & uw::_UA_SEARCH_PHASE != 0 {
match eh_action {
EHAction::None | EHAction::Cleanup(_) => uw::_URC_CONTINUE_UNWIND,
EHAction::Catch(_) | EHAction::Filter(_) => uw::_URC_HANDLER_FOUND,
@ -230,7 +230,7 @@ cfg_if::cfg_if! {
match eh_action {
EHAction::None => uw::_URC_CONTINUE_UNWIND,
// Forced unwinding hits a terminate action.
EHAction::Filter(_) if actions as i32 & uw::_UA_FORCE_UNWIND as i32 != 0 => uw::_URC_CONTINUE_UNWIND,
EHAction::Filter(_) if actions & uw::_UA_FORCE_UNWIND != 0 => uw::_URC_CONTINUE_UNWIND,
EHAction::Cleanup(lpad) | EHAction::Catch(lpad) | EHAction::Filter(lpad) => {
uw::_Unwind_SetGR(
context,

View file

@ -128,16 +128,13 @@ if #[cfg(any(target_vendor = "apple", target_os = "netbsd", not(target_arch = "a
//
// 32-bit ARM on iOS/tvOS/watchOS use either DWARF/Compact unwinding or
// "setjmp-longjmp" / SjLj unwinding.
#[repr(C)]
#[derive(Copy, Clone, PartialEq)]
pub enum _Unwind_Action {
_UA_SEARCH_PHASE = 1,
_UA_CLEANUP_PHASE = 2,
_UA_HANDLER_FRAME = 4,
_UA_FORCE_UNWIND = 8,
_UA_END_OF_STACK = 16,
}
pub use _Unwind_Action::*;
pub type _Unwind_Action = c_int;
pub const _UA_SEARCH_PHASE: c_int = 1;
pub const _UA_CLEANUP_PHASE: c_int = 2;
pub const _UA_HANDLER_FRAME: c_int = 4;
pub const _UA_FORCE_UNWIND: c_int = 8;
pub const _UA_END_OF_STACK: c_int = 16;
#[cfg_attr(
all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux", target_os = "xous")),

View file

@ -2,16 +2,13 @@
use core::ffi::{c_int, c_void};
#[repr(C)]
#[derive(Copy, Clone, PartialEq)]
pub enum _Unwind_Action {
_UA_SEARCH_PHASE = 1,
_UA_CLEANUP_PHASE = 2,
_UA_HANDLER_FRAME = 4,
_UA_FORCE_UNWIND = 8,
_UA_END_OF_STACK = 16,
}
pub use _Unwind_Action::*;
pub type _Unwind_Action = c_int;
pub const _UA_SEARCH_PHASE: c_int = 1;
pub const _UA_CLEANUP_PHASE: c_int = 2;
pub const _UA_HANDLER_FRAME: c_int = 4;
pub const _UA_FORCE_UNWIND: c_int = 8;
pub const _UA_END_OF_STACK: c_int = 16;
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq)]

View file

@ -1465,8 +1465,6 @@ pub(crate) fn notable_traits_button(
ty: &clean::Type,
cx: &Context<'_>,
) -> Option<impl fmt::Display> {
let mut has_notable_trait = false;
if ty.is_unit() {
// Very common fast path.
return None;
@ -1484,27 +1482,19 @@ pub(crate) fn notable_traits_button(
return None;
}
if let Some(impls) = cx.cache().impls.get(&did) {
for i in impls {
let impl_ = i.inner_impl();
if impl_.polarity != ty::ImplPolarity::Positive {
continue;
}
if !ty.is_doc_subtype_of(&impl_.for_, cx.cache()) {
let impls = cx.cache().impls.get(&did)?;
let has_notable_trait = impls
.iter()
.map(Impl::inner_impl)
.filter(|impl_| {
impl_.polarity == ty::ImplPolarity::Positive
// Two different types might have the same did,
// without actually being the same.
continue;
}
if let Some(trait_) = &impl_.trait_ {
let trait_did = trait_.def_id();
if cx.cache().traits.get(&trait_did).is_some_and(|t| t.is_notable_trait(cx.tcx())) {
has_notable_trait = true;
}
}
}
}
&& ty.is_doc_subtype_of(&impl_.for_, cx.cache())
})
.filter_map(|impl_| impl_.trait_.as_ref())
.filter_map(|trait_| cx.cache().traits.get(&trait_.def_id()))
.any(|t| t.is_notable_trait(cx.tcx()));
has_notable_trait.then(|| {
cx.types_with_notable_traits.borrow_mut().insert(ty.clone());

View file

@ -1,3 +0,0 @@
//@ compile-flags: --print=check-cfg
fn main() {}

View file

@ -1,2 +0,0 @@
error: the `-Z unstable-options` flag must also be passed to enable the check-cfg print option

View file

@ -0,0 +1,103 @@
//! Check that we properly gate unstable print requests (`--print=KIND`) and require the user to
//! specify `-Z unstable-options` to use unstable print requests.
// We don't care about the exact *stdout* output (i.e. what the print requests actually give back)
// for the purposes of this test.
//@ dont-check-compiler-stdout
// We want to check for the core error message of the unstable print requests being `-Z
// unstable-options`-gated and not the help because the help can change with addition of a new print
// request, which is not important for the purposes of this test.
//@ dont-check-compiler-stderr
// =======================
// Unstable print requests
// =======================
//@ revisions: all_target_specs_json
//@[all_target_specs_json] compile-flags: --print=all-target-specs-json
//@[all_target_specs_json] error-pattern: the `-Z unstable-options` flag must also be passed
//@ revisions: check_cfg
//@[check_cfg] compile-flags: --print=check-cfg
//@[check_cfg] error-pattern: the `-Z unstable-options` flag must also be passed
//@ revisions: target_spec_json
//@[target_spec_json] compile-flags: --print=target-spec-json
//@[target_spec_json] error-pattern: the `-Z unstable-options` flag must also be passed
// =======================
// Stable print requests
// =======================
//@ revisions: calling_conventions
//@[calling_conventions] compile-flags: --print=calling-conventions
//@[calling_conventions] check-pass
//@ revisions: cfg
//@[cfg] compile-flags: --print=cfg
//@[cfg] check-pass
//@ revisions: code_models
//@[code_models] compile-flags: --print=code-models
//@[code_models] check-pass
//@ revisions: crate_name
//@[crate_name] compile-flags: --print=crate-name
//@[crate_name] check-pass
// Note: `--print=deployment_target` is only accepted on Apple targets.
//@ revisions: deployment_target
//@[deployment_target] only-apple
//@[deployment_target] compile-flags: --print=deployment-target
//@[deployment_target] check-pass
//@ revisions: file_names
//@[file_names] compile-flags: --print=file-names
//@[file_names] check-pass
//@ revisions: host_tuple
//@[host_tuple] compile-flags: --print=host-tuple
//@[host_tuple] check-pass
//@ revisions: link_args
//@[link_args] compile-flags: --print=link-args
//@[link_args] check-pass
//@ revisions: native_static_libs
//@[native_static_libs] compile-flags: --print=native-static-libs
//@[native_static_libs] check-pass
//@ revisions: relocation_models
//@[relocation_models] compile-flags: --print=relocation-models
//@[relocation_models] check-pass
//@ revisions: split_debuginfo
//@[split_debuginfo] compile-flags: --print=split-debuginfo
//@[split_debuginfo] check-pass
//@ revisions: stack_protector_strategies
//@[stack_protector_strategies] compile-flags: --print=stack-protector-strategies
//@[stack_protector_strategies] check-pass
//@ revisions: target_cpus
//@[target_cpus] compile-flags: --print=target-cpus
//@[target_cpus] check-pass
//@ revisions: target_features
//@[target_features] compile-flags: --print=target-features
//@[target_features] check-pass
//@ revisions: target_libdir
//@[target_libdir] compile-flags: --print=target-libdir
//@[target_libdir] check-pass
//@ revisions: target_list
//@[target_list] compile-flags: --print=target-list
//@[target_list] check-pass
//@ revisions: tls_models
//@[tls_models] compile-flags: --print=tls-models
//@[tls_models] check-pass
fn main() {}