From 8156e062ee12f091e128db23f09d196cd028edc1 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 31 Jan 2025 17:29:45 +0100 Subject: [PATCH 1/8] doc all differences of ptr:copy(_nonoverlapping) with memcpy and memmove --- library/core/src/intrinsics/mod.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index c0d435f99c0..5683377774c 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -4250,7 +4250,8 @@ pub const fn ptr_metadata + ?Sized, M>(_ptr: *cons /// 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. @@ -4377,8 +4378,10 @@ pub const unsafe fn copy_nonoverlapping(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 From db7e61cfa53f72f1be9179180272b836bf781a40 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Thu, 30 Jan 2025 12:51:22 +0100 Subject: [PATCH 2/8] document capacity for ZST as example and prose --- library/alloc/src/vec/mod.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 48afcf6e064..0aacdd2fc5b 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1240,6 +1240,19 @@ impl Vec { /// 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::(), 0); + /// let v = vec![ZeroSized; 0]; + /// assert_eq!(v.capacity(), usize::MAX); + /// } + /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")] From 9d9bac0e968362ff3da4788cc04c65d5f0b6898f Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Mon, 10 Feb 2025 12:18:23 +0000 Subject: [PATCH 3/8] refactor `notable_traits_button` to use iterator combinators instead of for loop --- src/librustdoc/html/render/mod.rs | 32 +++++++++++-------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index b2ad2fa773a..8dfde1679fe 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1465,8 +1465,6 @@ pub(crate) fn notable_traits_button( ty: &clean::Type, cx: &Context<'_>, ) -> Option { - 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()); From ab7fb0d483027632f22e22ecd7d2c7bfc1f3ac10 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sun, 16 Mar 2025 13:01:11 +0800 Subject: [PATCH 4/8] Add a centralized test for print request stability gating I can't find any dedicated tests that actually exercises the stability gating (via `-Z unstable-options`) of print requests, so here's a dedicated one. I coalesced `tests/ui/feature-gates/feature-gate-print-check-cfg.rs` into this test, because AFAICT that print request is not feature gated, but only `-Z unstable-options`-gated just like other unstable print requests. --- .../feature-gate-print-check-cfg.rs | 3 - .../feature-gate-print-check-cfg.stderr | 2 - tests/ui/print-request/stability.rs | 103 ++++++++++++++++++ 3 files changed, 103 insertions(+), 5 deletions(-) delete mode 100644 tests/ui/feature-gates/feature-gate-print-check-cfg.rs delete mode 100644 tests/ui/feature-gates/feature-gate-print-check-cfg.stderr create mode 100644 tests/ui/print-request/stability.rs diff --git a/tests/ui/feature-gates/feature-gate-print-check-cfg.rs b/tests/ui/feature-gates/feature-gate-print-check-cfg.rs deleted file mode 100644 index 304e0c132e5..00000000000 --- a/tests/ui/feature-gates/feature-gate-print-check-cfg.rs +++ /dev/null @@ -1,3 +0,0 @@ -//@ compile-flags: --print=check-cfg - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-print-check-cfg.stderr b/tests/ui/feature-gates/feature-gate-print-check-cfg.stderr deleted file mode 100644 index 62ee44b94a4..00000000000 --- a/tests/ui/feature-gates/feature-gate-print-check-cfg.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: the `-Z unstable-options` flag must also be passed to enable the check-cfg print option - diff --git a/tests/ui/print-request/stability.rs b/tests/ui/print-request/stability.rs new file mode 100644 index 00000000000..b205b055569 --- /dev/null +++ b/tests/ui/print-request/stability.rs @@ -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() {} From 5f8e0920f9911d7919d087295543ac3432cf1326 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sun, 16 Mar 2025 11:46:09 +0800 Subject: [PATCH 5/8] Alphabetically sort `PrintKind` and enforce with tidy --- compiler/rustc_session/src/config.rs | 34 +++++++++++++++------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 34755249b60..96006433b60 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -873,27 +873,29 @@ pub struct PrintRequest { #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum PrintKind { - FileNames, - HostTuple, - Sysroot, - TargetLibdir, - CrateName, + // tidy-alphabetical-start + AllTargetSpecs, + CallingConventions, Cfg, CheckCfg, - CallingConventions, - TargetList, + CodeModels, + CrateName, + DeploymentTarget, + FileNames, + HostTuple, + LinkArgs, + NativeStaticLibs, + RelocationModels, + SplitDebuginfo, + StackProtectorStrategies, + Sysroot, TargetCPUs, TargetFeatures, - RelocationModels, - CodeModels, - TlsModels, + TargetLibdir, + TargetList, TargetSpec, - AllTargetSpecs, - NativeStaticLibs, - StackProtectorStrategies, - LinkArgs, - SplitDebuginfo, - DeploymentTarget, + TlsModels, + // tidy-alphabetical-end } #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Default)] From f9eabc28d94aec376f7649ba785c86e922702a37 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sun, 16 Mar 2025 12:19:16 +0800 Subject: [PATCH 6/8] Extract print request stability gating and unknown print request help into helpers To avoid duplicating stability check logic and make the print request collection logic more straightforward. --- compiler/rustc_session/src/config.rs | 78 +++++++++++++--------------- 1 file changed, 35 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 96006433b60..bc20d970968 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2032,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::>(); - 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); @@ -2093,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::AllTargetSpecs | PrintKind::CheckCfg | PrintKind::TargetSpec + 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::>(); + 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") => { From 24edbfbc2433be60207daefbdf1d59ed3b1cbf7d Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sun, 16 Mar 2025 12:58:53 +0800 Subject: [PATCH 7/8] Rename `PrintKind::{AllTargetSpecs,TargetSpec}` to `{AllTargetSpecsJson,TargetSpecJson}` To correspond to their actual print request names, `target-spec-json` and `all-target-specs-json`, and for consistency with other print name <-> print kind mappings. --- compiler/rustc_driver_impl/src/lib.rs | 4 ++-- compiler/rustc_session/src/config.rs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index ed5662da16d..2d636da4a12 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -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); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index bc20d970968..701d06e4fd4 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -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 ]; @@ -874,7 +874,7 @@ pub struct PrintRequest { #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum PrintKind { // tidy-alphabetical-start - AllTargetSpecs, + AllTargetSpecsJson, CallingConventions, Cfg, CheckCfg, @@ -893,7 +893,7 @@ pub enum PrintKind { TargetFeatures, TargetLibdir, TargetList, - TargetSpec, + TargetSpecJson, TlsModels, // tidy-alphabetical-end } @@ -2063,7 +2063,7 @@ fn check_print_request_stability( (print_name, print_kind): (&str, PrintKind), ) { match print_kind { - PrintKind::AllTargetSpecs | PrintKind::CheckCfg | PrintKind::TargetSpec + PrintKind::AllTargetSpecsJson | PrintKind::CheckCfg | PrintKind::TargetSpecJson if !unstable_opts.unstable_options => { early_dcx.early_fatal(format!( From f20a6c70fb7a1b9bf1b855e6d1e711c1afd6bb48 Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Sun, 16 Mar 2025 21:32:41 +0100 Subject: [PATCH 8/8] make `_Unwind_Action` a type alias, not enum It's bitflags in practice, so an enum is unsound, as an enum must only have the described values. The x86_64 psABI declares it as a `typedef int _Unwind_Action`, which seems reasonable. I made a newtype first but that was more annoying than just a typedef. We don't really use this value for much other than a short check. --- library/std/src/sys/personality/gcc.rs | 4 ++-- library/unwind/src/libunwind.rs | 17 +++++++---------- library/unwind/src/unwinding.rs | 17 +++++++---------- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs index cd2c7899f4b..9a5b3b2fd19 100644 --- a/library/std/src/sys/personality/gcc.rs +++ b/library/std/src/sys/personality/gcc.rs @@ -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, diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index 1a640bbde71..1283c8e3a01 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -125,16 +125,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")), diff --git a/library/unwind/src/unwinding.rs b/library/unwind/src/unwinding.rs index 1b94005ab6c..ba425803303 100644 --- a/library/unwind/src/unwinding.rs +++ b/library/unwind/src/unwinding.rs @@ -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)]