diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index ef475630d4943..c5a7f119118c9 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1596,8 +1596,11 @@ supported_targets! { ("armebv7r-none-eabi", armebv7r_none_eabi), ("armebv7r-none-eabihf", armebv7r_none_eabihf), ("armv7r-none-eabi", armv7r_none_eabi), + ("thumbv7r-none-eabi", thumbv7r_none_eabi), ("armv7r-none-eabihf", armv7r_none_eabihf), + ("thumbv7r-none-eabihf", thumbv7r_none_eabihf), ("armv8r-none-eabihf", armv8r_none_eabihf), + ("thumbv8r-none-eabihf", thumbv8r_none_eabihf), ("armv7-rtems-eabihf", armv7_rtems_eabihf), @@ -1649,7 +1652,9 @@ supported_targets! { ("thumbv8m.main-none-eabihf", thumbv8m_main_none_eabihf), ("armv7a-none-eabi", armv7a_none_eabi), + ("thumbv7a-none-eabi", thumbv7a_none_eabi), ("armv7a-none-eabihf", armv7a_none_eabihf), + ("thumbv7a-none-eabihf", thumbv7a_none_eabihf), ("armv7a-nuttx-eabi", armv7a_nuttx_eabi), ("armv7a-nuttx-eabihf", armv7a_nuttx_eabihf), ("armv7a-vex-v5", armv7a_vex_v5), diff --git a/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs index 6b7707a47390a..e8c5c16d8eb5e 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_none_eabi.rs @@ -1,40 +1,8 @@ -// Generic ARMv7-A target for bare-metal code - floating point disabled -// -// This is basically the `armv7-unknown-linux-gnueabi` target with some changes -// (listed below) to bring it closer to the bare-metal `thumb` & `aarch64` -// targets: -// -// - `TargetOptions.features`: added `+strict-align`. rationale: unaligned -// memory access is disabled on boot on these cores -// - linker changed to LLD. rationale: C is not strictly needed to build -// bare-metal binaries (the `gcc` linker has the advantage that it knows where C -// libraries and crt*.o are but it's not much of an advantage here); LLD is also -// faster -// - `panic_strategy` set to `abort`. rationale: matches `thumb` targets -// - `relocation-model` set to `static`; also no PIE, no relro and no dynamic -// linking. rationale: matches `thumb` targets +// Targets the Little-endian Cortex-A8 (and similar) processors (ARMv7-A) -use crate::spec::{ - Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, -}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { - let opts = TargetOptions { - abi: Abi::Eabi, - llvm_floatabi: Some(FloatAbi::Soft), - linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), - linker: Some("rust-lld".into()), - features: "+v7,+thumb2,+soft-float,-neon,+strict-align".into(), - relocation_model: RelocModel::Static, - disable_redzone: true, - max_atomic_width: Some(64), - panic_strategy: PanicStrategy::Abort, - emit_debug_gdb_scripts: false, - c_enum_min_bits: Some(8), - has_thumb_interworking: true, - ..Default::default() - }; Target { llvm_target: "armv7a-none-eabi".into(), metadata: TargetMetadata { @@ -46,6 +14,13 @@ pub(crate) fn target() -> Target { pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, - options: opts, + options: TargetOptions { + abi: Abi::Eabi, + llvm_floatabi: Some(FloatAbi::Soft), + features: "+soft-float,-neon,+strict-align".into(), + max_atomic_width: Some(64), + has_thumb_interworking: true, + ..base::arm_none::opts() + }, } } diff --git a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs index 993390543b96d..32a79e346adcf 100644 --- a/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7a_none_eabihf.rs @@ -1,32 +1,8 @@ -// Generic ARMv7-A target for bare-metal code - floating point enabled (assumes -// FPU is present and emits FPU instructions) -// -// This is basically the `armv7-unknown-linux-gnueabihf` target with some -// changes (list in `armv7a_none_eabi.rs`) to bring it closer to the bare-metal -// `thumb` & `aarch64` targets. +// Targets the Little-endian Cortex-A8 (and similar) processors (ARMv7-A) -use crate::spec::{ - Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, -}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { - let opts = TargetOptions { - abi: Abi::EabiHf, - llvm_floatabi: Some(FloatAbi::Hard), - linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), - linker: Some("rust-lld".into()), - features: "+v7,+vfp3d16,+thumb2,-neon,+strict-align".into(), - relocation_model: RelocModel::Static, - disable_redzone: true, - max_atomic_width: Some(64), - panic_strategy: PanicStrategy::Abort, - emit_debug_gdb_scripts: false, - // GCC defaults to 8 for arm-none here. - c_enum_min_bits: Some(8), - has_thumb_interworking: true, - ..Default::default() - }; Target { llvm_target: "armv7a-none-eabihf".into(), metadata: TargetMetadata { @@ -38,6 +14,13 @@ pub(crate) fn target() -> Target { pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, - options: opts, + options: TargetOptions { + abi: Abi::EabiHf, + llvm_floatabi: Some(FloatAbi::Hard), + features: "+vfp3d16,-neon,+strict-align".into(), + max_atomic_width: Some(64), + has_thumb_interworking: true, + ..base::arm_none::opts() + }, } } diff --git a/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs b/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs index 551cbf4a589fa..114b079f360b7 100644 --- a/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7r_none_eabi.rs @@ -1,15 +1,12 @@ // Targets the Little-endian Cortex-R4/R5 processor (ARMv7-R) -use crate::spec::{ - Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, -}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { llvm_target: "armv7r-none-eabi".into(), metadata: TargetMetadata { - description: Some("Armv7-R".into()), + description: Some("Bare Armv7-R".into()), tier: Some(2), host_tools: Some(false), std: Some(false), @@ -17,20 +14,12 @@ pub(crate) fn target() -> Target { pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, - options: TargetOptions { abi: Abi::Eabi, llvm_floatabi: Some(FloatAbi::Soft), - linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), - linker: Some("rust-lld".into()), - relocation_model: RelocModel::Static, - panic_strategy: PanicStrategy::Abort, max_atomic_width: Some(64), - emit_debug_gdb_scripts: false, - // GCC defaults to 8 for arm-none here. - c_enum_min_bits: Some(8), has_thumb_interworking: true, - ..Default::default() + ..base::arm_none::opts() }, } } diff --git a/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs index 97c911ec80909..1c6114f9fc83a 100644 --- a/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs @@ -1,15 +1,12 @@ // Targets the Little-endian Cortex-R4F/R5F processor (ARMv7-R) -use crate::spec::{ - Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, -}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { llvm_target: "armv7r-none-eabihf".into(), metadata: TargetMetadata { - description: Some("Armv7-R, hardfloat".into()), + description: Some("Bare Armv7-R, hardfloat".into()), tier: Some(2), host_tools: Some(false), std: Some(false), @@ -17,21 +14,13 @@ pub(crate) fn target() -> Target { pointer_width: 32, data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), arch: Arch::Arm, - options: TargetOptions { abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), - linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), - linker: Some("rust-lld".into()), - relocation_model: RelocModel::Static, - panic_strategy: PanicStrategy::Abort, features: "+vfp3d16".into(), max_atomic_width: Some(64), - emit_debug_gdb_scripts: false, - // GCC defaults to 8 for arm-none here. - c_enum_min_bits: Some(8), has_thumb_interworking: true, - ..Default::default() + ..base::arm_none::opts() }, } } diff --git a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs index e36240b9c2234..16006e4c52cfb 100644 --- a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs @@ -1,9 +1,6 @@ // Targets the Little-endian Cortex-R52 processor (ARMv8-R) -use crate::spec::{ - Abi, Arch, Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetMetadata, - TargetOptions, -}; +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; pub(crate) fn target() -> Target { Target { @@ -21,10 +18,6 @@ pub(crate) fn target() -> Target { options: TargetOptions { abi: Abi::EabiHf, llvm_floatabi: Some(FloatAbi::Hard), - linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), - linker: Some("rust-lld".into()), - relocation_model: RelocModel::Static, - panic_strategy: PanicStrategy::Abort, // Armv8-R requires a minimum set of floating-point features equivalent to: // fp-armv8, SP-only, with 16 DP (32 SP) registers // LLVM defines Armv8-R to include these features automatically. @@ -36,11 +29,8 @@ pub(crate) fn target() -> Target { // Arm Cortex-R52 Processor Technical Reference Manual // - Chapter 15 Advanced SIMD and floating-point support max_atomic_width: Some(64), - emit_debug_gdb_scripts: false, - // GCC defaults to 8 for arm-none here. - c_enum_min_bits: Some(8), has_thumb_interworking: true, - ..Default::default() + ..base::arm_none::opts() }, } } diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabi.rs new file mode 100644 index 0000000000000..ce11e3f0875c9 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabi.rs @@ -0,0 +1,26 @@ +// Targets the Little-endian Cortex-A8 (and similar) processors (ARMv7-A) + +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; + +pub(crate) fn target() -> Target { + Target { + llvm_target: "thumbv7a-none-eabi".into(), + metadata: TargetMetadata { + description: Some("Thumb-mode Bare Armv7-A".into()), + tier: Some(2), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), + arch: Arch::Arm, + options: TargetOptions { + abi: Abi::Eabi, + llvm_floatabi: Some(FloatAbi::Soft), + features: "+soft-float,-neon,+strict-align".into(), + max_atomic_width: Some(64), + has_thumb_interworking: true, + ..base::arm_none::opts() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabihf.rs new file mode 100644 index 0000000000000..12210e9c2b014 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_none_eabihf.rs @@ -0,0 +1,26 @@ +// Targets the Little-endian Cortex-A8 (and similar) processors (ARMv7-A) + +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; + +pub(crate) fn target() -> Target { + Target { + llvm_target: "thumbv7a-none-eabihf".into(), + metadata: TargetMetadata { + description: Some("Thumb-mode Bare Armv7-A, hardfloat".into()), + tier: Some(2), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), + arch: Arch::Arm, + options: TargetOptions { + abi: Abi::EabiHf, + llvm_floatabi: Some(FloatAbi::Hard), + features: "+vfp3d16,-neon,+strict-align".into(), + max_atomic_width: Some(64), + has_thumb_interworking: true, + ..base::arm_none::opts() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabi.rs new file mode 100644 index 0000000000000..bf71d31a06ecf --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabi.rs @@ -0,0 +1,25 @@ +// Targets the Little-endian Cortex-R4/R5 processor (ARMv7-R) + +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; + +pub(crate) fn target() -> Target { + Target { + llvm_target: "thumbv7r-none-eabi".into(), + metadata: TargetMetadata { + description: Some("Thumb-mode Bare Armv7-R".into()), + tier: Some(2), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), + arch: Arch::Arm, + options: TargetOptions { + abi: Abi::Eabi, + llvm_floatabi: Some(FloatAbi::Soft), + max_atomic_width: Some(64), + has_thumb_interworking: true, + ..base::arm_none::opts() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabihf.rs new file mode 100644 index 0000000000000..88b5e67644035 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/thumbv7r_none_eabihf.rs @@ -0,0 +1,26 @@ +// Targets the Little-endian Cortex-R4F/R5F processor (ARMv7-R) + +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; + +pub(crate) fn target() -> Target { + Target { + llvm_target: "thumbv7r-none-eabihf".into(), + metadata: TargetMetadata { + description: Some("Thumb-mode Bare Armv7-R, hardfloat".into()), + tier: Some(2), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), + arch: Arch::Arm, + options: TargetOptions { + abi: Abi::EabiHf, + llvm_floatabi: Some(FloatAbi::Hard), + features: "+vfp3d16".into(), + max_atomic_width: Some(64), + has_thumb_interworking: true, + ..base::arm_none::opts() + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/thumbv8r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv8r_none_eabihf.rs new file mode 100644 index 0000000000000..87434cd7353c0 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/thumbv8r_none_eabihf.rs @@ -0,0 +1,36 @@ +// Targets the Little-endian Cortex-R52 processor (ARMv8-R) + +use crate::spec::{Abi, Arch, FloatAbi, Target, TargetMetadata, TargetOptions, base}; + +pub(crate) fn target() -> Target { + Target { + llvm_target: "thumbv8r-none-eabihf".into(), + metadata: TargetMetadata { + description: Some("Thumb-mode Bare Armv8-R, hardfloat".into()), + tier: Some(2), + host_tools: Some(false), + std: Some(false), + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), + arch: Arch::Arm, + + options: TargetOptions { + abi: Abi::EabiHf, + llvm_floatabi: Some(FloatAbi::Hard), + // Armv8-R requires a minimum set of floating-point features equivalent to: + // fp-armv8, SP-only, with 16 DP (32 SP) registers + // LLVM defines Armv8-R to include these features automatically. + // + // The Cortex-R52 supports these default features and optionally includes: + // neon-fp-armv8, SP+DP, with 32 DP registers + // + // Reference: + // Arm Cortex-R52 Processor Technical Reference Manual + // - Chapter 15 Advanced SIMD and floating-point support + max_atomic_width: Some(64), + has_thumb_interworking: true, + ..base::arm_none::opts() + }, + } +} diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 4eba426dda59f..fde7dfcabb701 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -492,7 +492,22 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ const HEXAGON_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ // tidy-alphabetical-start ("hvx", Unstable(sym::hexagon_target_feature), &[]), + ("hvx-ieee-fp", Unstable(sym::hexagon_target_feature), &["hvx"]), + ("hvx-length64b", Unstable(sym::hexagon_target_feature), &["hvx"]), ("hvx-length128b", Unstable(sym::hexagon_target_feature), &["hvx"]), + ("hvx-qfloat", Unstable(sym::hexagon_target_feature), &["hvx"]), + ("hvxv60", Unstable(sym::hexagon_target_feature), &["hvx"]), + ("hvxv62", Unstable(sym::hexagon_target_feature), &["hvxv60"]), + ("hvxv65", Unstable(sym::hexagon_target_feature), &["hvxv62"]), + ("hvxv66", Unstable(sym::hexagon_target_feature), &["hvxv65", "zreg"]), + ("hvxv67", Unstable(sym::hexagon_target_feature), &["hvxv66"]), + ("hvxv68", Unstable(sym::hexagon_target_feature), &["hvxv67"]), + ("hvxv69", Unstable(sym::hexagon_target_feature), &["hvxv68"]), + ("hvxv71", Unstable(sym::hexagon_target_feature), &["hvxv69"]), + ("hvxv73", Unstable(sym::hexagon_target_feature), &["hvxv71"]), + ("hvxv75", Unstable(sym::hexagon_target_feature), &["hvxv73"]), + ("hvxv79", Unstable(sym::hexagon_target_feature), &["hvxv75"]), + ("zreg", Unstable(sym::hexagon_target_feature), &[]), // tidy-alphabetical-end ]; @@ -949,7 +964,7 @@ const SPARC_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'stat &[/*(64, "vis")*/]; const HEXAGON_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = - &[/*(512, "hvx-length64b"),*/ (1024, "hvx-length128b")]; + &[(512, "hvx-length64b"), (1024, "hvx-length128b")]; const MIPS_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = &[(128, "msa")]; const CSKY_FEATURES_FOR_CORRECT_FIXED_LENGTH_VECTOR_ABI: &'static [(u64, &'static str)] = diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs index 99268d6182f6c..9b9d2f02550bd 100644 --- a/library/core/src/bool.rs +++ b/library/core/src/bool.rs @@ -1,5 +1,7 @@ //! impl bool {} +use crate::marker::Destruct; + impl bool { /// Returns `Some(t)` if the `bool` is [`true`](../std/keyword.true.html), /// or `None` otherwise. @@ -29,8 +31,9 @@ impl bool { /// assert_eq!(a, 2); /// ``` #[stable(feature = "bool_to_option", since = "1.62.0")] + #[rustc_const_unstable(feature = "const_bool", issue = "151531")] #[inline] - pub fn then_some(self, t: T) -> Option { + pub const fn then_some(self, t: T) -> Option { if self { Some(t) } else { None } } @@ -57,8 +60,9 @@ impl bool { #[doc(alias = "then_with")] #[stable(feature = "lazy_bool_to_option", since = "1.50.0")] #[rustc_diagnostic_item = "bool_then"] + #[rustc_const_unstable(feature = "const_bool", issue = "151531")] #[inline] - pub fn then T>(self, f: F) -> Option { + pub const fn then T + [const] Destruct>(self, f: F) -> Option { if self { Some(f()) } else { None } } @@ -94,8 +98,9 @@ impl bool { /// assert_eq!(a, 2); /// ``` #[unstable(feature = "bool_to_result", issue = "142748")] + #[rustc_const_unstable(feature = "const_bool", issue = "151531")] #[inline] - pub fn ok_or(self, err: E) -> Result<(), E> { + pub const fn ok_or(self, err: E) -> Result<(), E> { if self { Ok(()) } else { Err(err) } } @@ -124,8 +129,12 @@ impl bool { /// assert_eq!(a, 1); /// ``` #[unstable(feature = "bool_to_result", issue = "142748")] + #[rustc_const_unstable(feature = "const_bool", issue = "151531")] #[inline] - pub fn ok_or_else E>(self, f: F) -> Result<(), E> { + pub const fn ok_or_else E + [const] Destruct>( + self, + f: F, + ) -> Result<(), E> { if self { Ok(()) } else { Err(f()) } } } diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 3e8c553f9f159..459c826f40646 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -3,10 +3,7 @@ use core::ascii::EscapeDefault; use crate::fmt::{self, Write}; -#[cfg(not(any( - all(target_arch = "x86_64", target_feature = "sse2"), - all(target_arch = "loongarch64", target_feature = "lsx") -)))] +#[cfg(not(all(target_arch = "loongarch64", target_feature = "lsx")))] use crate::intrinsics::const_eval_select; use crate::{ascii, iter, ops}; @@ -463,19 +460,101 @@ const fn is_ascii(s: &[u8]) -> bool { ) } -/// ASCII test optimized to use the `pmovmskb` instruction on `x86-64` and the -/// `vmskltz.b` instruction on `loongarch64`. +/// Chunk size for vectorized ASCII checking (two 16-byte SSE registers). +#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] +const CHUNK_SIZE: usize = 32; + +/// SSE2 implementation using `_mm_movemask_epi8` (compiles to `pmovmskb`) to +/// avoid LLVM's broken AVX-512 auto-vectorization of counting loops. +/// +/// FIXME(llvm#176906): Remove this workaround once LLVM generates efficient code. +#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] +fn is_ascii_sse2(bytes: &[u8]) -> bool { + use crate::arch::x86_64::{__m128i, _mm_loadu_si128, _mm_movemask_epi8, _mm_or_si128}; + + let mut i = 0; + + while i + CHUNK_SIZE <= bytes.len() { + // SAFETY: We have verified that `i + CHUNK_SIZE <= bytes.len()`. + let ptr = unsafe { bytes.as_ptr().add(i) }; + + // Load two 16-byte chunks and combine them. + // SAFETY: We verified `i + 32 <= len`, so ptr is valid for 32 bytes. + // `_mm_loadu_si128` allows unaligned loads. + let chunk1 = unsafe { _mm_loadu_si128(ptr as *const __m128i) }; + // SAFETY: Same as above - ptr.add(16) is within the valid 32-byte range. + let chunk2 = unsafe { _mm_loadu_si128(ptr.add(16) as *const __m128i) }; + + // OR them together - if any byte has the high bit set, the result will too. + // SAFETY: SSE2 is guaranteed by the cfg predicate. + let combined = unsafe { _mm_or_si128(chunk1, chunk2) }; + + // Create a mask from the MSBs of each byte. + // If any byte is >= 128, its MSB is 1, so the mask will be non-zero. + // SAFETY: SSE2 is guaranteed by the cfg predicate. + let mask = unsafe { _mm_movemask_epi8(combined) }; + + if mask != 0 { + return false; + } + + i += CHUNK_SIZE; + } + + // Handle remaining bytes with simple loop + while i < bytes.len() { + if !bytes[i].is_ascii() { + return false; + } + i += 1; + } + + true +} + +/// ASCII test optimized to use the `pmovmskb` instruction on `x86-64`. +/// +/// Uses explicit SSE2 intrinsics to prevent LLVM from auto-vectorizing with +/// broken AVX-512 code that extracts mask bits one-by-one. +#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))] +#[inline] +#[rustc_allow_const_fn_unstable(const_eval_select)] +const fn is_ascii(bytes: &[u8]) -> bool { + const USIZE_SIZE: usize = size_of::(); + const NONASCII_MASK: usize = usize::MAX / 255 * 0x80; + + const_eval_select!( + @capture { bytes: &[u8] } -> bool: + if const { + is_ascii_simple(bytes) + } else { + // For small inputs, use usize-at-a-time processing to avoid SSE2 call overhead. + if bytes.len() < CHUNK_SIZE { + let chunks = bytes.chunks_exact(USIZE_SIZE); + let remainder = chunks.remainder(); + for chunk in chunks { + let word = usize::from_ne_bytes(chunk.try_into().unwrap()); + if (word & NONASCII_MASK) != 0 { + return false; + } + } + return remainder.iter().all(|b| b.is_ascii()); + } + + is_ascii_sse2(bytes) + } + ) +} + +/// ASCII test optimized to use the `vmskltz.b` instruction on `loongarch64`. /// /// Other platforms are not likely to benefit from this code structure, so they /// use SWAR techniques to test for ASCII in `usize`-sized chunks. -#[cfg(any( - all(target_arch = "x86_64", target_feature = "sse2"), - all(target_arch = "loongarch64", target_feature = "lsx") -))] +#[cfg(all(target_arch = "loongarch64", target_feature = "lsx"))] #[inline] const fn is_ascii(bytes: &[u8]) -> bool { // Process chunks of 32 bytes at a time in the fast path to enable - // auto-vectorization and use of `pmovmskb`. Two 128-bit vector registers + // auto-vectorization and use of `vmskltz.b`. Two 128-bit vector registers // can be OR'd together and then the resulting vector can be tested for // non-ASCII bytes. const CHUNK_SIZE: usize = 32; @@ -485,7 +564,7 @@ const fn is_ascii(bytes: &[u8]) -> bool { while i + CHUNK_SIZE <= bytes.len() { let chunk_end = i + CHUNK_SIZE; - // Get LLVM to produce a `pmovmskb` instruction on x86-64 which + // Get LLVM to produce a `vmskltz.b` instruction on loongarch64 which // creates a mask from the most significant bit of each byte. // ASCII bytes are less than 128 (0x80), so their most significant // bit is unset. diff --git a/library/coretests/tests/bool.rs b/library/coretests/tests/bool.rs index eb5f0f50663e1..802e43045b6e6 100644 --- a/library/coretests/tests/bool.rs +++ b/library/coretests/tests/bool.rs @@ -82,6 +82,10 @@ pub fn test_bool_not() { } } +const fn zero() -> i32 { + 0 +} + #[test] fn test_bool_to_option() { assert_eq!(false.then_some(0), None); @@ -89,11 +93,6 @@ fn test_bool_to_option() { assert_eq!(false.then(|| 0), None); assert_eq!(true.then(|| 0), Some(0)); - /* FIXME(#110395) - const fn zero() -> i32 { - 0 - } - const A: Option = false.then_some(0); const B: Option = true.then_some(0); const C: Option = false.then(zero); @@ -103,7 +102,6 @@ fn test_bool_to_option() { assert_eq!(B, Some(0)); assert_eq!(C, None); assert_eq!(D, Some(0)); - */ } #[test] @@ -112,4 +110,14 @@ fn test_bool_to_result() { assert_eq!(true.ok_or(0), Ok(())); assert_eq!(false.ok_or_else(|| 0), Err(0)); assert_eq!(true.ok_or_else(|| 0), Ok(())); + + const A: Result<(), i32> = false.ok_or(0); + const B: Result<(), i32> = true.ok_or(0); + const C: Result<(), i32> = false.ok_or_else(zero); + const D: Result<(), i32> = true.ok_or_else(zero); + + assert_eq!(A, Err(0)); + assert_eq!(B, Ok(())); + assert_eq!(C, Err(0)); + assert_eq!(D, Ok(())); } diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 8c91567fc94a0..8cca714b73933 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -17,6 +17,7 @@ #![feature(clamp_magnitude)] #![feature(clone_to_uninit)] #![feature(const_array)] +#![feature(const_bool)] #![feature(const_cell_traits)] #![feature(const_clone)] #![feature(const_cmp)] diff --git a/library/std/src/sys/pal/uefi/tests.rs b/library/std/src/sys/pal/uefi/tests.rs index df3344e2df346..9f16ef07a4bde 100644 --- a/library/std/src/sys/pal/uefi/tests.rs +++ b/library/std/src/sys/pal/uefi/tests.rs @@ -1,14 +1,14 @@ //! These tests are not run automatically right now. Please run these tests manually by copying them //! to a separate project when modifying any related code. -use super::alloc::*; use super::time::system_time_internal::{from_uefi, to_uefi}; use crate::io::{IoSlice, IoSliceMut}; +use crate::ops::{Deref, DerefMut}; use crate::time::Duration; const SECS_IN_MINUTE: u64 = 60; -const MAX_UEFI_TIME: Duration = from_uefi(r_efi::efi::Time { +const MAX_UEFI_TIME: Duration = from_uefi(&r_efi::efi::Time { year: 9999, month: 12, day: 31, @@ -20,27 +20,8 @@ const MAX_UEFI_TIME: Duration = from_uefi(r_efi::efi::Time { daylight: 0, pad1: 0, pad2: 0, -}); - -#[test] -fn align() { - // UEFI ABI specifies that allocation alignment minimum is always 8. So this can be - // statically verified. - assert_eq!(POOL_ALIGNMENT, 8); - - // Loop over allocation-request sizes from 0-256 and alignments from 1-128, and verify - // that in case of overalignment there is at least space for one additional pointer to - // store in the allocation. - for i in 0..256 { - for j in &[1, 2, 4, 8, 16, 32, 64, 128] { - if *j <= 8 { - assert_eq!(align_size(i, *j), i); - } else { - assert!(align_size(i, *j) > i + size_of::<*mut ()>()); - } - } - } -} +}) +.unwrap(); // UEFI Time cannot implement Eq due to uninitilaized pad1 and pad2 fn uefi_time_cmp(t1: r_efi::efi::Time, t2: r_efi::efi::Time) -> bool { @@ -70,9 +51,9 @@ fn systemtime_start() { daylight: 0, pad2: 0, }; - assert_eq!(from_uefi(&t), Duration::new(0, 0)); - assert!(uefi_time_cmp(t, to_uefi(&from_uefi(&t), -1440, 0).unwrap())); - assert!(to_uefi(&from_uefi(&t), 0, 0).is_err()); + assert_eq!(from_uefi(&t).unwrap(), Duration::new(0, 0)); + assert!(uefi_time_cmp(t, to_uefi(&from_uefi(&t).unwrap(), -1440, 0).unwrap())); + assert!(to_uefi(&from_uefi(&t).unwrap(), 0, 0).is_err()); } #[test] @@ -90,9 +71,9 @@ fn systemtime_utc_start() { daylight: 0, pad2: 0, }; - assert_eq!(from_uefi(&t), Duration::new(1440 * SECS_IN_MINUTE, 0)); - assert!(uefi_time_cmp(t, to_uefi(&from_uefi(&t), 0, 0).unwrap())); - assert!(to_uefi(&from_uefi(&t), -1440, 0).is_ok()); + assert_eq!(from_uefi(&t).unwrap(), Duration::new(1440 * SECS_IN_MINUTE, 0)); + assert!(uefi_time_cmp(t, to_uefi(&from_uefi(&t).unwrap(), 0, 0).unwrap())); + assert!(to_uefi(&from_uefi(&t).unwrap(), -1440, 0).is_ok()); } #[test] @@ -110,8 +91,8 @@ fn systemtime_end() { daylight: 0, pad2: 0, }; - assert!(to_uefi(&from_uefi(&t), 1440, 0).is_ok()); - assert!(to_uefi(&from_uefi(&t), 1439, 0).is_err()); + assert!(to_uefi(&from_uefi(&t).unwrap(), 1440, 0).is_ok()); + assert!(to_uefi(&from_uefi(&t).unwrap(), 1439, 0).is_err()); } #[test] @@ -139,17 +120,17 @@ fn min_time() { #[test] fn max_time() { - let inp = MAX_UEFI_TIME.0; + let inp = MAX_UEFI_TIME; let new_tz = to_uefi(&inp, -1440, 0).err().unwrap(); assert_eq!(new_tz, 1440); assert!(to_uefi(&inp, new_tz, 0).is_ok()); - let inp = MAX_UEFI_TIME.0 - Duration::from_secs(1440 * SECS_IN_MINUTE); + let inp = MAX_UEFI_TIME - Duration::from_secs(1440 * SECS_IN_MINUTE); let new_tz = to_uefi(&inp, -1440, 0).err().unwrap(); assert_eq!(new_tz, 0); assert!(to_uefi(&inp, new_tz, 0).is_ok()); - let inp = MAX_UEFI_TIME.0 - Duration::from_secs(1440 * SECS_IN_MINUTE + 10); + let inp = MAX_UEFI_TIME - Duration::from_secs(1440 * SECS_IN_MINUTE + 10); let new_tz = to_uefi(&inp, -1440, 0).err().unwrap(); assert_eq!(new_tz, 0); assert!(to_uefi(&inp, new_tz, 0).is_ok()); @@ -266,8 +247,8 @@ fn io_slice_mut_basic() { let mut data_clone = [0, 1, 2, 3, 4]; let mut io_slice_mut = IoSliceMut::new(&mut data_clone); - assert_eq!(data, io_slice_mut.as_slice()); - assert_eq!(data, io_slice_mut.as_mut_slice()); + assert_eq!(data, io_slice_mut.deref()); + assert_eq!(data, io_slice_mut.deref_mut()); io_slice_mut.advance(2); assert_eq!(&data[2..], io_slice_mut.into_slice()); diff --git a/library/test/build.rs b/library/test/build.rs index a2bc8936b5195..8e31adbf2ca74 100644 --- a/library/test/build.rs +++ b/library/test/build.rs @@ -1,4 +1,5 @@ fn main() { + println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rustc-check-cfg=cfg(enable_unstable_features)"); let rustc = std::env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 607b9a384d196..235bbf8ddb783 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -38,6 +38,11 @@ pub struct Finder { const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined "x86_64-unknown-linux-gnuasan", + "thumbv7a-none-eabi", + "thumbv7a-none-eabihf", + "thumbv7r-none-eabi", + "thumbv7r-none-eabihf", + "thumbv8r-none-eabihf", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 8ceeff2c9685e..5d000c900aaaf 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -56,15 +56,15 @@ - [arm-none-eabi](platform-support/arm-none-eabi.md) - [{arm,thumb}v4t-none-eabi](platform-support/armv4t-none-eabi.md) - [{arm,thumb}v5te-none-eabi](platform-support/armv5te-none-eabi.md) - - [armv7a-none-eabi{,hf}](platform-support/armv7a-none-eabi.md) - - [armv7r-none-eabi{,hf}](platform-support/armv7r-none-eabi.md) - - [armebv7r-none-eabi{,hf}](platform-support/armebv7r-none-eabi.md) - - [armv8r-none-eabihf](platform-support/armv8r-none-eabihf.md) + - [{arm,thumb}v7a-none-eabi{,hf}](platform-support/armv7a-none-eabi.md) + - [{arm,thumb}v7r-none-eabi{,hf}](platform-support/armv7r-none-eabi.md) + - [{arm,thumb}v8r-none-eabihf](platform-support/armv8r-none-eabihf.md) - [thumbv6m-none-eabi](./platform-support/thumbv6m-none-eabi.md) - [thumbv7em-none-eabi\*](./platform-support/thumbv7em-none-eabi.md) - [thumbv7m-none-eabi](./platform-support/thumbv7m-none-eabi.md) - [thumbv8m.base-none-eabi](./platform-support/thumbv8m.base-none-eabi.md) - [thumbv8m.main-none-eabi\*](./platform-support/thumbv8m.main-none-eabi.md) + - [armebv7r-none-eabi{,hf}](platform-support/armebv7r-none-eabi.md) - [arm\*-unknown-linux-\*](./platform-support/arm-linux.md) - [armeb-unknown-linux-gnueabi](platform-support/armeb-unknown-linux-gnueabi.md) - [armv5te-unknown-linux-gnueabi](platform-support/armv5te-unknown-linux-gnueabi.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 889f96f5fefab..9362c8b98fe3d 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -411,17 +411,22 @@ target | std | host | notes [`thumbv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Thumb-mode Bare Armv4T [`thumbv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * | | Thumb-mode Bare Armv5TE [`thumbv6m-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv6M with NuttX -`thumbv7a-pc-windows-msvc` | | | -[`thumbv7a-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | | | +[`thumbv7a-none-eabi`](platform-support/armv7a-none-eabi.md) | * | | Thumb-mode Bare Armv7-A +[`thumbv7a-none-eabihf`](platform-support/armv7a-none-eabi.md) | * | | Thumb-mode Bare Armv7-A, hardfloat [`thumbv7a-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX [`thumbv7a-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX, hardfloat +`thumbv7a-pc-windows-msvc` | | | +[`thumbv7a-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | | | [`thumbv7em-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7EM with NuttX [`thumbv7em-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv7EM with NuttX, hardfloat [`thumbv7m-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7M with NuttX `thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode Armv7-A Linux with NEON, musl 1.2.5 +[`thumbv7r-none-eabi`](platform-support/armv7r-none-eabi.md) | * | | Thumb-mode Bare Armv7-R +[`thumbv7r-none-eabihf`](platform-support/armv7r-none-eabi.md) | * | | Thumb-mode Bare Armv7-R, hardfloat [`thumbv8m.base-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv8M Baseline with NuttX [`thumbv8m.main-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv8M Mainline with NuttX [`thumbv8m.main-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv8M Mainline with NuttX, hardfloat +[`thumbv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * | | Thumb-mode Bare Armv8-R, hardfloat [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly [`wasm32-wali-linux-musl`](platform-support/wasm32-wali-linux.md) | ? | | WebAssembly with [WALI](https://github.com/arjunr2/WALI) [`wasm32-wasip3`](platform-support/wasm32-wasip3.md) | ✓ | | WebAssembly with WASIp3 diff --git a/src/doc/rustc/src/platform-support/armv7a-none-eabi.md b/src/doc/rustc/src/platform-support/armv7a-none-eabi.md index 05afb4f4321be..555f69e81a02f 100644 --- a/src/doc/rustc/src/platform-support/armv7a-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv7a-none-eabi.md @@ -1,10 +1,14 @@ -# `armv7a-none-eabi` and `armv7a-none-eabihf` +# `armv7a-none-eabi*` and `thumbv7a-none-eabi*` -* **Tier: 2** +* **Tier: 2** (`armv7a-none-eabi` and `armv7a-none-eabihf`) +* **Tier: 3** (`thumbv7a-none-eabi` and `thumbv7a-none-eabihf`) * **Library Support:** core and alloc (bare-metal, `#![no_std]`) -Bare-metal target for CPUs in the Armv7-A architecture family, supporting -dual ARM/Thumb mode, with ARM mode as the default. +Bare-metal target for CPUs in the Armv7-A architecture family, supporting dual +ARM/Thumb mode. The `armv7a-none-eabi*` targets use Arm mode by default and the +`thumbv7a-none-eabi` targets use Thumb mode by default. The `-eabi` targets use +a soft-float ABI and do not require an FPU, while the `-eabihf` targets use a +hard-float ABI and do require an FPU. Note, this is for processors running in AArch32 mode. For the AArch64 mode added in Armv8-A, see [`aarch64-unknown-none`](aarch64-unknown-none.md) instead. diff --git a/src/doc/rustc/src/platform-support/armv7r-none-eabi.md b/src/doc/rustc/src/platform-support/armv7r-none-eabi.md index 7f22a29f2ee68..20fd55c6abd68 100644 --- a/src/doc/rustc/src/platform-support/armv7r-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv7r-none-eabi.md @@ -1,10 +1,14 @@ -# `armv7r-none-eabi` and `armv7r-none-eabihf` +# `armv7r-none-eabi*` and `thumbv7r-none-eabi*` -* **Tier: 2** +* **Tier: 2** (`armv7r-none-eabi` and `armv7r-none-eabihf`) +* **Tier: 3** (`thumbv7r-none-eabi` and `thumbv7r-none-eabihf`) * **Library Support:** core and alloc (bare-metal, `#![no_std]`) -Bare-metal target for CPUs in the Armv7-R architecture family, supporting -dual ARM/Thumb mode, with ARM mode as the default. +Bare-metal target for CPUs in the Armv7-R architecture family, supporting dual +ARM/Thumb mode. The `armv7r-none-eabi*` targets use Arm mode by default and the +`thumbv7r-none-eabi*` targets use Thumb mode by default. The `-eabi` targets use +a soft-float ABI and do not require an FPU, while the `-eabihf` targets use a +hard-float ABI and do require an FPU. Processors in this family include the [Arm Cortex-R4, 5, 7, and 8][cortex-r]. @@ -25,11 +29,11 @@ See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all ## Requirements -When using the hardfloat targets, the minimum floating-point features assumed -are those of the `vfpv3-d16`, which includes single- and double-precision, with -16 double-precision registers. This floating-point unit appears in Cortex-R4F -and Cortex-R5F processors. See [VFP in the Cortex-R processors][vfp] -for more details on the possible FPU variants. +When using the hardfloat (`-eabibf`) targets, the minimum floating-point +features assumed are those of the `vfpv3-d16`, which includes single- and +double-precision, with 16 double-precision registers. This floating-point unit +appears in Cortex-R4F and Cortex-R5F processors. See [VFP in the Cortex-R +processors][vfp] for more details on the possible FPU variants. If your processor supports a different set of floating-point features than the default expectations of `vfpv3-d16`, then these should also be enabled or diff --git a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md index 369e86dbfc7e8..85abac3d7eb89 100644 --- a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md +++ b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md @@ -1,10 +1,13 @@ -# `armv8r-none-eabihf` +# `armv8r-none-eabihf` and `thumbv8r-none-eabihf` -* **Tier: 2** +* **Tier: 2**: `armv8r-none-eabihf` +* **Tier: 3**: `thumbv8r-none-eabihf` * **Library Support:** core and alloc (bare-metal, `#![no_std]`) -Bare-metal target for CPUs in the Armv8-R architecture family, supporting -dual ARM/Thumb mode, with ARM mode as the default. +Bare-metal target for CPUs in the Armv8-R architecture family, supporting dual +ARM/Thumb mode. The `armv8r-none-eabihf` target uses Arm mode by default and +the `thumbv8r-none-eabihf` target uses Thumb mode by default. Both targets +use a hard-float ABI and require an FPU. Processors in this family include the Arm [Cortex-R52][cortex-r52] and [Cortex-R52+][cortex-r52-plus]. diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 486ca9b22539c..6c34d31cc918c 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -210,6 +210,24 @@ body { color: var(--main-color); } +/* Skip navigation link for keyboard users (WCAG 2.4.1) */ +.skip-main-content { + position: absolute; + left: 0; + top: -100%; + z-index: 1000; + padding: 0.5rem 1rem; + background-color: var(--main-background-color); + color: var(--main-color); + text-decoration: none; + font-weight: 500; + border-bottom-right-radius: 4px; + outline: 2px solid var(--search-input-focused-border-color); +} +.skip-main-content:focus { + top: 0; +} + h1 { font-size: 1.5rem; /* 24px */ } @@ -1114,6 +1132,7 @@ pre, .rustdoc.src .example-wrap, .example-wrap .src-line-numbers { #main-content { position: relative; + outline: none; } .docblock table { diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index 1f8ec9f30c53c..427e7b4071a1e 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -66,6 +66,7 @@ {{ layout.external_html.in_header|safe }} {# #} {# #} + Skip to main content {# #}