From 10fb96c5a338fefed8667854d7c1a152bfb001d1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 27 Jun 2026 14:07:07 +0200 Subject: [PATCH 01/15] signed strict division: just use normal division --- library/core/src/num/imp/overflow_panic.rs | 6 ------ library/core/src/num/int_macros.rs | 18 ++++++++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/library/core/src/num/imp/overflow_panic.rs b/library/core/src/num/imp/overflow_panic.rs index f62d09ea041ab..fd5b88ad324c6 100644 --- a/library/core/src/num/imp/overflow_panic.rs +++ b/library/core/src/num/imp/overflow_panic.rs @@ -20,12 +20,6 @@ pub(in crate::num) const fn mul() -> ! { panic!("attempt to multiply with overflow") } -#[cold] -#[track_caller] -pub(in crate::num) const fn div() -> ! { - panic!("attempt to divide with overflow") -} - #[cold] #[track_caller] pub(in crate::num) const fn rem() -> ! { diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 090fea81891ad..8a374f015a958 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -983,9 +983,12 @@ macro_rules! int_impl { /// This function will always panic on overflow, regardless of whether overflow checks are enabled. /// /// The only case where such an overflow can occur is when one divides `MIN / -1` on a signed type (where - /// [`MIN`](Self::MIN) is the negative minimal value for the type); this is equivalent to `-MIN`, a positive value + /// [`MIN`](Self::MIN) is the negative minimal value for the type); the result of this is `-MIN`, a positive value /// that is too large to represent in the type. /// + /// Note that this is equivalent to normal division: `MIN / -1` will also panic both in + /// debug and release builds. + /// /// # Examples /// /// ``` @@ -1010,8 +1013,8 @@ macro_rules! int_impl { #[inline] #[track_caller] pub const fn strict_div(self, rhs: Self) -> Self { - let (a, b) = self.overflowing_div(rhs); - if b { imp::overflow_panic::div() } else { a } + // Normal division already checks for "div-by-minus-1". + self / rhs } /// Checked Euclidean division. Computes `self.div_euclid(rhs)`, @@ -1050,9 +1053,12 @@ macro_rules! int_impl { /// This function will always panic on overflow, regardless of whether overflow checks are enabled. /// /// The only case where such an overflow can occur is when one divides `MIN / -1` on a signed type (where - /// [`MIN`](Self::MIN) is the negative minimal value for the type); this is equivalent to `-MIN`, a positive value + /// [`MIN`](Self::MIN) is the negative minimal value for the type); the result of this is `-MIN`, a positive value /// that is too large to represent in the type. /// + /// Note that this is equivalent to `div_euclid`: `MIN.div_euclid(-1)` will also panic both + /// in debug and release builds. + /// /// # Examples /// /// ``` @@ -1077,8 +1083,8 @@ macro_rules! int_impl { #[inline] #[track_caller] pub const fn strict_div_euclid(self, rhs: Self) -> Self { - let (a, b) = self.overflowing_div_euclid(rhs); - if b { imp::overflow_panic::div() } else { a } + // Normal `div_euclid` already checks for "div-by-minus-1". + self.div_euclid(rhs) } /// Checked integer division without remainder. Computes `self / rhs`, From 4e50b9061c91bc72b86208644f095b9cccc39f08 Mon Sep 17 00:00:00 2001 From: kn1g78 Date: Sun, 28 Jun 2026 15:50:27 +0800 Subject: [PATCH 02/15] Deduplicate codegen backends in bootstrap config --- src/bootstrap/src/core/config/tests.rs | 22 +++++++++++++++++- src/bootstrap/src/core/config/toml/rust.rs | 26 +++++++++++++--------- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index c281aa94f64e6..9e7216c5796ef 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -11,8 +11,9 @@ use serde::Deserialize; use super::flags::Flags; use super::toml::change_id::ChangeIdWrapper; +use super::toml::rust::parse_codegen_backends; use super::{Config, RUSTC_IF_UNCHANGED_ALLOWED_PATHS}; -use crate::ChangeId; +use crate::{ChangeId, CodegenBackendKind}; use crate::core::build_steps::clippy::{LintConfig, get_clippy_rules_in_order}; use crate::core::build_steps::llvm::LLVM_INVALIDATION_PATHS; use crate::core::build_steps::{llvm, test}; @@ -206,6 +207,25 @@ fn rust_optimize() { assert_eq!(parse("rust.optimize = \"s\"").rust_optimize.get_opt_level(), Some("s".to_string())); } +#[test] +fn deduplicates_codegen_backends() { + assert_eq!( + parse_codegen_backends( + vec!["llvm", "llvm", "cranelift", "llvm"].into_iter().map(str::to_owned).collect(), + "rust", + ), + [CodegenBackendKind::Llvm, CodegenBackendKind::Cranelift] + ); + + assert_eq!( + parse_codegen_backends( + vec!["cranelift", "llvm", "cranelift"].into_iter().map(str::to_owned).collect(), + "target.x86_64-unknown-linux-gnu", + ), + [CodegenBackendKind::Cranelift, CodegenBackendKind::Llvm] + ); +} + #[test] #[should_panic] fn invalid_rust_optimize() { diff --git a/src/bootstrap/src/core/config/toml/rust.rs b/src/bootstrap/src/core/config/toml/rust.rs index a872671343405..3d423e22a01d2 100644 --- a/src/bootstrap/src/core/config/toml/rust.rs +++ b/src/bootstrap/src/core/config/toml/rust.rs @@ -422,23 +422,29 @@ pub(crate) fn parse_codegen_backends( Please, use '{stripped}' instead." ) } - if !BUILTIN_CODEGEN_BACKENDS.contains(&backend.as_str()) { + let backend = match backend.as_str() { + "llvm" => CodegenBackendKind::Llvm, + "cranelift" => CodegenBackendKind::Cranelift, + "gcc" => CodegenBackendKind::Gcc, + backend => CodegenBackendKind::Custom(backend.to_string()), + }; + + if found_backends.contains(&backend) { + continue; + } + + if !BUILTIN_CODEGEN_BACKENDS.contains(&backend.name()) { if CiEnv::is_rust_lang_managed_ci_job() { - eprintln!("Unknown codegen backend {backend}"); + eprintln!("Unknown codegen backend {}", backend.name()); exit!(1); } println!( - "HELP: '{backend}' for '{section}.codegen-backends' might fail. \ - List of known codegen backends: {BUILTIN_CODEGEN_BACKENDS:?}" + "HELP: '{}' for '{section}.codegen-backends' might fail. \ + List of known codegen backends: {BUILTIN_CODEGEN_BACKENDS:?}", + backend.name() ); } - let backend = match backend.as_str() { - "llvm" => CodegenBackendKind::Llvm, - "cranelift" => CodegenBackendKind::Cranelift, - "gcc" => CodegenBackendKind::Gcc, - backend => CodegenBackendKind::Custom(backend.to_string()), - }; found_backends.push(backend); } if found_backends.is_empty() { From 81ec882a2fb7de44de542d121c7b12a691d3cbd4 Mon Sep 17 00:00:00 2001 From: kn1g78 Date: Sun, 28 Jun 2026 17:27:21 +0800 Subject: [PATCH 03/15] Fix bootstrap config test import order --- src/bootstrap/src/core/config/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index 9e7216c5796ef..3f8a7262b8e23 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -13,7 +13,6 @@ use super::flags::Flags; use super::toml::change_id::ChangeIdWrapper; use super::toml::rust::parse_codegen_backends; use super::{Config, RUSTC_IF_UNCHANGED_ALLOWED_PATHS}; -use crate::{ChangeId, CodegenBackendKind}; use crate::core::build_steps::clippy::{LintConfig, get_clippy_rules_in_order}; use crate::core::build_steps::llvm::LLVM_INVALIDATION_PATHS; use crate::core::build_steps::{llvm, test}; @@ -23,6 +22,7 @@ use crate::core::config::{ }; use crate::utils::tests::TestCtx; use crate::utils::tests::git::git_test; +use crate::{ChangeId, CodegenBackendKind}; pub(crate) fn parse(config: &str) -> Config { TestCtx::new().config("check").with_default_toml_config(config).create_config() From f98365f1f3a472e60aa8296504bdefbee65cfc19 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 28 Jun 2026 22:01:18 -0700 Subject: [PATCH 04/15] Rename `align` to `platform_align` on `Scalar` and `Primitive` To emphasize that just because you see a `Scalar(I32)` that doesn't really tell you anything about the alignment it has -- one should be looking at the type (well, the place) for that. No actual layout or behaviour changes in *this* PR. --- compiler/rustc_abi/src/layout.rs | 9 +++-- compiler/rustc_abi/src/layout/simple.rs | 6 +-- compiler/rustc_abi/src/lib.rs | 37 +++++++++++++++---- .../src/value_and_place.rs | 2 +- compiler/rustc_codegen_gcc/src/builder.rs | 2 +- compiler/rustc_codegen_gcc/src/type_of.rs | 3 +- compiler/rustc_codegen_llvm/src/builder.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/operand.rs | 6 +-- .../rustc_const_eval/src/interpret/operand.rs | 4 +- .../rustc_const_eval/src/interpret/place.rs | 2 +- compiler/rustc_mir_transform/src/gvn.rs | 2 +- compiler/rustc_target/src/callconv/mod.rs | 2 +- .../rustc_ty_utils/src/layout/invariant.rs | 10 ++--- src/tools/miri/src/shims/native_lib/mod.rs | 2 +- 14 files changed, 57 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 7b68fbc9e77b0..003e811dc7855 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -477,12 +477,14 @@ impl LayoutCalculator { Ok(Some((repr, _))) => match repr { // Mismatched alignment (e.g. union is #[repr(packed)]): disable opt BackendRepr::Scalar(_) | BackendRepr::ScalarPair(_, _) - if repr.scalar_align(dl).unwrap() != align => + if repr.scalar_platform_align(dl).unwrap() != align => { BackendRepr::Memory { sized: true } } // Vectors require at least element alignment, else disable the opt - BackendRepr::SimdVector { element, count: _ } if element.align(dl).abi > align => { + BackendRepr::SimdVector { element, count: _ } + if element.default_align(dl).abi > align => + { BackendRepr::Memory { sized: true } } // the alignment tests passed and we can use this @@ -986,7 +988,8 @@ impl LayoutCalculator { // roundtripping pointers through ptrtoint/inttoptr. (p @ Primitive::Pointer(_), i @ Primitive::Int(..)) | (i @ Primitive::Int(..), p @ Primitive::Pointer(_)) - if p.size(dl) == i.size(dl) && p.align(dl) == i.align(dl) => + if p.size(dl) == i.size(dl) + && p.default_align(dl) == i.default_align(dl) => { p } diff --git a/compiler/rustc_abi/src/layout/simple.rs b/compiler/rustc_abi/src/layout/simple.rs index b103e1e97bd96..5fd504def384a 100644 --- a/compiler/rustc_abi/src/layout/simple.rs +++ b/compiler/rustc_abi/src/layout/simple.rs @@ -49,7 +49,7 @@ impl LayoutData { pub fn scalar(cx: &C, scalar: Scalar) -> Self { let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar); let size = scalar.size(cx); - let align = scalar.align(cx); + let align = scalar.default_align(cx); let range = scalar.valid_range(cx); @@ -90,8 +90,8 @@ impl LayoutData { pub fn scalar_pair(cx: &C, a: Scalar, b: Scalar) -> Self { let dl = cx.data_layout(); - let b_align = b.align(dl).abi; - let align = a.align(dl).abi.max(b_align).max(dl.aggregate_align); + let b_align = b.default_align(dl).abi; + let align = a.default_align(dl).abi.max(b_align).max(dl.aggregate_align); let b_offset = a.size(dl).align_to(b_align); let size = (b_offset + b.size(dl)).align_to(align); diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index a5a4411146c44..4f5858975b991 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1404,7 +1404,11 @@ impl Primitive { } } - pub fn align(self, cx: &C) -> AbiAlign { + /// The *platform-specific* ABI alignment of this primitive. + /// + /// This is the type alignment for the corresponding built-in. + /// In other contexts it might have different alignment. + pub fn default_align(self, cx: &C) -> AbiAlign { use Primitive::*; let dl = cx.data_layout(); @@ -1579,8 +1583,12 @@ impl Scalar { } } - pub fn align(self, cx: &impl HasDataLayout) -> AbiAlign { - self.primitive().align(cx) + /// The *platform-specific* ABI alignment of this scalar. + /// + /// This is the type alignment for the corresponding built-in. + /// In other contexts it might have different alignment. + pub fn default_align(self, cx: &impl HasDataLayout) -> AbiAlign { + self.primitive().default_align(cx) } pub fn size(self, cx: &impl HasDataLayout) -> Size { @@ -1792,6 +1800,13 @@ impl IntoDiagArg for NumScalableVectors { #[cfg_attr(feature = "nightly", derive(StableHash))] pub enum BackendRepr { Scalar(Scalar), + /// Two scalars listed in *memory* order, so the first is at offset zero + /// and the second at a non-zero offset. + /// These need not be `FieldIdx(0)` and `FieldIdx(1)`. + /// + /// As of June 2026 the offset to the second scalar is the size of the first + /// scalar rounded up to the platform alignment of the second scalar. + /// That may soon change, however; see MCP#1007. ScalarPair(Scalar, Scalar), SimdScalableVector { element: Scalar, @@ -1857,10 +1872,16 @@ impl BackendRepr { /// The psABI alignment for a `Scalar` or `ScalarPair` /// /// `None` for other variants. - pub fn scalar_align(&self, cx: &C) -> Option { + /// + /// It's unclear whether this is a meaningful operation, and MCP#1007 proposes changes. + /// You should generally be using the alignment of the place or the type, + /// not calculating something from the `Scalar`s. + pub fn scalar_platform_align(&self, cx: &C) -> Option { match *self { - BackendRepr::Scalar(s) => Some(s.align(cx).abi), - BackendRepr::ScalarPair(s1, s2) => Some(s1.align(cx).max(s2.align(cx)).abi), + BackendRepr::Scalar(s) => Some(s.default_align(cx).abi), + BackendRepr::ScalarPair(s1, s2) => { + Some(s1.default_align(cx).max(s2.default_align(cx)).abi) + } // The align of a Vector can vary in surprising ways BackendRepr::SimdVector { .. } | BackendRepr::Memory { .. } @@ -1877,9 +1898,9 @@ impl BackendRepr { BackendRepr::Scalar(s) => Some(s.size(cx)), // May have some padding between the pair. BackendRepr::ScalarPair(s1, s2) => { - let field2_offset = s1.size(cx).align_to(s2.align(cx).abi); + let field2_offset = s1.size(cx).align_to(s2.default_align(cx).abi); let size = (field2_offset + s2.size(cx)).align_to( - self.scalar_align(cx) + self.scalar_platform_align(cx) // We absolutely must have an answer here or everything is FUBAR. .unwrap(), ); diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index a2a2cac3faaa8..995a70f24240b 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -56,7 +56,7 @@ fn codegen_field<'tcx>( } fn scalar_pair_calculate_b_offset(tcx: TyCtxt<'_>, a_scalar: Scalar, b_scalar: Scalar) -> Offset32 { - let b_offset = a_scalar.size(&tcx).align_to(b_scalar.align(&tcx).abi); + let b_offset = a_scalar.size(&tcx).align_to(b_scalar.default_align(&tcx).abi); Offset32::new(b_offset.bytes().try_into().unwrap()) } diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 8ae4dedff8f28..bea2b3d483b73 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1064,7 +1064,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { }, ) } else if let abi::BackendRepr::ScalarPair(ref a, ref b) = place.layout.backend_repr { - let b_offset = a.size(self).align_to(b.align(self).abi); + let b_offset = a.size(self).align_to(b.default_align(self).abi); let mut load = |i, scalar: &abi::Scalar, align| { let ptr = if i == 0 { diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index 5b198eeaf0182..9807a84c0788d 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -325,7 +325,8 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { return cx.type_i1(); } - let offset = if index == 0 { Size::ZERO } else { a.size(cx).align_to(b.align(cx).abi) }; + let offset = + if index == 0 { Size::ZERO } else { a.size(cx).align_to(b.default_align(cx).abi) }; self.scalar_gcc_type_at(cx, scalar, offset) } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index afb6985d21a95..f442b483e568e 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -789,7 +789,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { }); OperandValue::Immediate(llval) } else if let abi::BackendRepr::ScalarPair(a, b) = place.layout.backend_repr { - let b_offset = a.size(self).align_to(b.align(self).abi); + let b_offset = a.size(self).align_to(b.default_align(self).abi); let mut load = |i, scalar: abi::Scalar, layout, align, offset| { let llptr = if i == 0 { diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index c87ea83eacf62..a47b3443ea664 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -227,7 +227,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { b @ abi::Scalar::Initialized { .. }, ) => { let (a_size, b_size) = (a.size(bx), b.size(bx)); - let b_offset = (offset + a_size).align_to(b.align(bx).abi); + let b_offset = (offset + a_size).align_to(b.default_align(bx).abi); assert!(b_offset.bytes() > 0); let a_val = read_scalar( offset, @@ -388,7 +388,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { assert_eq!(field.size, a.size(bx.cx())); (Some(a), a_llval) } else { - assert_eq!(offset, a.size(bx.cx()).align_to(b.align(bx.cx()).abi)); + assert_eq!(offset, a.size(bx.cx()).align_to(b.default_align(bx.cx()).abi)); assert_eq!(field.size, b.size(bx.cx())); (Some(b), b_llval) } @@ -962,7 +962,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue { let BackendRepr::ScalarPair(a_scalar, b_scalar) = dest.layout.backend_repr else { bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout); }; - let b_offset = a_scalar.size(bx).align_to(b_scalar.align(bx).abi); + let b_offset = a_scalar.size(bx).align_to(b_scalar.default_align(bx).abi); let val = bx.from_immediate(a); let align = dest.val.align; diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 7b2983620d420..1f67b896fc8ec 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -419,7 +419,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { Immediate::from(if offset.bytes() == 0 { a_val } else { - assert_eq!(offset, a.size(cx).align_to(b.align(cx).abi)); + assert_eq!(offset, a.size(cx).align_to(b.default_align(cx).abi)); b_val }) } @@ -614,7 +614,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // We would anyway check against `ptr_align.restrict_for_offset(b_offset)`, // which `ptr.offset(b_offset)` cannot possibly fail to satisfy. let (a_size, b_size) = (a.size(self), b.size(self)); - let b_offset = a_size.align_to(b.align(self).abi); + let b_offset = a_size.align_to(b.default_align(self).abi); assert!(b_offset.bytes() > 0); // in `operand_field` we use the offset to tell apart the fields let a_val = alloc.read_scalar( alloc_range(Size::ZERO, a_size), diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index b4e6a6b99b7a8..d6d73b2d8da81 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -733,7 +733,7 @@ where ) }; let a_size = a_val.size(); - let b_offset = a_size.align_to(b.align(&tcx).abi); + let b_offset = a_size.align_to(b.default_align(&tcx).abi); assert!(b_offset.bytes() > 0); // in `operand_field` we use the offset to tell apart the fields // It is tempting to verify `b_offset` against `layout.fields.offset(1)`, diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index b30d2bd135546..2db4502ecc6b6 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -742,7 +742,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { a1.size(&self.ecx) == a2.size(&self.ecx) && b1.size(&self.ecx) == b2.size(&self.ecx) // The alignment of the second component determines its offset, so that also needs to match. - && b1.align(&self.ecx) == b2.align(&self.ecx) + && b1.default_align(&self.ecx) == b2.default_align(&self.ecx) // None of the inputs may be a pointer. && !matches!(a1.primitive(), Primitive::Pointer(..)) && !matches!(b1.primitive(), Primitive::Pointer(..)) diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 30d16b5c7b1c9..4bc88cc4f9705 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -399,7 +399,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> { BackendRepr::Scalar(scalar) => PassMode::Direct(scalar_attrs(scalar, Size::ZERO)), BackendRepr::ScalarPair(a, b) => PassMode::Pair( scalar_attrs(a, Size::ZERO), - scalar_attrs(b, a.size(cx).align_to(b.align(cx).abi)), + scalar_attrs(b, a.size(cx).align_to(b.default_align(cx).abi)), ), BackendRepr::SimdVector { .. } => PassMode::Direct(ArgAttributes::new()), BackendRepr::Memory { .. } => Self::indirect_pass_mode(&layout), diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs index 8c07a7ec3d2de..decf1ffb5570d 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -84,7 +84,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou fn check_layout_abi<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayout<'tcx>) { // Verify the ABI-mandated alignment and size for scalars. - let align = layout.backend_repr.scalar_align(cx); + let align = layout.backend_repr.scalar_platform_align(cx); let size = layout.backend_repr.scalar_size(cx); if let Some(align) = align { assert_eq!( @@ -208,9 +208,9 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou }; // The fields should be at the right offset, and match the `scalar` layout. let size1 = scalar1.size(cx); - let align1 = scalar1.align(cx).abi; + let align1 = scalar1.default_align(cx).abi; let size2 = scalar2.size(cx); - let align2 = scalar2.align(cx).abi; + let align2 = scalar2.default_align(cx).abi; assert_eq!( offset1, Size::ZERO, @@ -251,7 +251,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou BackendRepr::SimdVector { element, count } => { let align = layout.align.abi; let size = layout.size; - let element_align = element.align(cx).abi; + let element_align = element.default_align(cx).abi; let element_size = element.size(cx); // Currently, vectors must always be aligned to at least their elements: assert!(align >= element_align); @@ -321,7 +321,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou } // The top-level ABI and the ABI of the variants should be coherent. let scalar_coherent = |s1: Scalar, s2: Scalar| { - s1.size(cx) == s2.size(cx) && s1.align(cx) == s2.align(cx) + s1.size(cx) == s2.size(cx) && s1.default_align(cx) == s2.default_align(cx) }; let abi_coherent = match (layout.backend_repr, variant.backend_repr) { (BackendRepr::Scalar(s1), BackendRepr::Scalar(s2)) => scalar_coherent(s1, s2), diff --git a/src/tools/miri/src/shims/native_lib/mod.rs b/src/tools/miri/src/shims/native_lib/mod.rs index 27571a9eb7c87..5014541faeb01 100644 --- a/src/tools/miri/src/shims/native_lib/mod.rs +++ b/src/tools/miri/src/shims/native_lib/mod.rs @@ -321,7 +321,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { imm.layout ) }; - a.size(this).align_to(b.align(this).abi).bytes_usize() + a.size(this).align_to(b.default_align(this).abi).bytes_usize() }; write_scalar(this, sc_first, 0)?; From e0b512158c1874acdab4f610ee678b4da96fb91d Mon Sep 17 00:00:00 2001 From: scottmcm Date: Mon, 29 Jun 2026 16:52:43 +0000 Subject: [PATCH 05/15] Apply suggestions from code review Co-authored-by: Ralf Jung --- compiler/rustc_abi/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 4f5858975b991..e86c7f15e9679 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1586,7 +1586,7 @@ impl Scalar { /// The *platform-specific* ABI alignment of this scalar. /// /// This is the type alignment for the corresponding built-in. - /// In other contexts it might have different alignment. + /// This is *not* necessarily the correct alignment for a type that has this `BackendRepr::Scalar`! pub fn default_align(self, cx: &impl HasDataLayout) -> AbiAlign { self.primitive().default_align(cx) } @@ -1800,7 +1800,8 @@ impl IntoDiagArg for NumScalableVectors { #[cfg_attr(feature = "nightly", derive(StableHash))] pub enum BackendRepr { Scalar(Scalar), - /// Two scalars listed in *memory* order, so the first is at offset zero + /// The data contained in this type can be entirely represented by two scalars. + /// The two scalars are listed in *memory* order, so the first is at offset zero /// and the second at a non-zero offset. /// These need not be `FieldIdx(0)` and `FieldIdx(1)`. /// From 804de70ca033c1e9ad490c60f6ed7f2bbc96a550 Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Thu, 25 Jun 2026 10:18:08 +0000 Subject: [PATCH 06/15] QNX target renaming - aarch64-unknown-nto-qnx800 becomes simply aarch64-unknown-qnx - x86_64-pc-nto-qnx800 becomes simply x86_64-pc-qnx - references to QNX OS and QNX Neutrino RTOS are replaced with QNX SDP for uniformity - various nto_qnx modules are named to qnx_sdp to match the above The new target names are more consistent with those used by the QNX SDP 8.0 toolchain, and reflect a level on ongoing API stability similar to that for macOS and Linux (which simply have minimum supported versions record for their targets). Once the compiler knows about the new target names, libc and backtrace can be updated to match, and then building libstd for the new targets can be fixed. With these changes I can run: ```console $ ./x build library/std --stage 2 --target x86_64-pc-nto-qnx710,aarch64-unknown-nto-qnx710,x86_64-pc-nto-qnx710_iosock,aarch64-unknown-nto-qnx710_iosock,aarch64-unknown-nto-qnx700 $ ./x build library/core --stage 1 --target x86_64-pc-qnx,aarch64-unknown-qnx ``` --- compiler/rustc_target/src/spec/base/mod.rs | 2 +- .../src/spec/base/{nto_qnx.rs => qnx_sdp.rs} | 0 compiler/rustc_target/src/spec/mod.rs | 6 +- .../targets/aarch64_unknown_nto_qnx700.rs | 9 +- .../targets/aarch64_unknown_nto_qnx710.rs | 10 +- .../aarch64_unknown_nto_qnx710_iosock.rs | 10 +- .../targets/aarch64_unknown_nto_qnx800.rs | 11 -- .../src/spec/targets/aarch64_unknown_qnx.rs | 12 +++ .../src/spec/targets/i686_pc_nto_qnx700.rs | 15 +-- .../src/spec/targets/x86_64_pc_nto_qnx710.rs | 10 +- .../targets/x86_64_pc_nto_qnx710_iosock.rs | 10 +- .../src/spec/targets/x86_64_pc_nto_qnx800.rs | 11 -- .../src/spec/targets/x86_64_pc_qnx.rs | 12 +++ library/std/build.rs | 1 + library/std/src/env.rs | 1 + library/std/src/net/tcp/tests.rs | 8 +- library/std/src/net/udp/tests.rs | 8 +- library/std/src/os/mod.rs | 2 +- library/std/src/os/unix/mod.rs | 2 +- library/std/src/os/unix/net/datagram.rs | 2 + library/std/src/os/unix/net/mod.rs | 2 + library/std/src/os/unix/net/stream.rs | 3 +- library/std/src/os/unix/net/tests.rs | 2 +- library/std/src/os/unix/net/ucred.rs | 4 +- library/std/src/os/unix/process.rs | 2 +- library/std/src/sys/args/unix.rs | 1 + library/std/src/sys/env_consts.rs | 11 ++ library/std/src/sys/fd/unix.rs | 4 + library/std/src/sys/fs/unix.rs | 30 +++++- library/std/src/sys/io/error/unix.rs | 1 + .../std/src/sys/net/connection/socket/mod.rs | 5 +- .../std/src/sys/net/connection/socket/unix.rs | 2 + library/std/src/sys/pal/unix/sync/condvar.rs | 8 +- library/std/src/sys/pal/unix/time.rs | 2 +- library/std/src/sys/paths/unix.rs | 2 +- library/std/src/sys/process/unix/unix.rs | 29 +++-- library/std/src/sys/random/mod.rs | 1 + library/std/src/sys/thread/unix.rs | 7 +- library/unwind/src/lib.rs | 2 +- src/bootstrap/src/core/sanity.rs | 2 + src/doc/rustc/src/platform-support.md | 4 +- src/doc/rustc/src/platform-support/nto-qnx.md | 101 +++++------------- src/librustdoc/clean/cfg.rs | 10 +- src/tools/miri/tests/pass-dep/shims/gettid.rs | 2 +- tests/assembly-llvm/targets/targets-elf.rs | 12 +-- tests/rustdoc-html/doc-cfg/all-targets.rs | 2 +- tests/rustdoc-html/doc-cfg/sort.rs | 2 + .../auxiliary/used_pre_main_constructor.rs | 1 + tests/ui/check-cfg/cfg-crate-features.stderr | 2 +- tests/ui/check-cfg/well-known-values.stderr | 6 +- tests/ui/intrinsics/intrinsic-alignment.rs | 1 + tests/ui/process/process-sigpipe.rs | 4 +- tests/ui/structs/rec-align-u64.rs | 1 + 53 files changed, 229 insertions(+), 181 deletions(-) rename compiler/rustc_target/src/spec/base/{nto_qnx.rs => qnx_sdp.rs} (100%) delete mode 100644 compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx800.rs create mode 100644 compiler/rustc_target/src/spec/targets/aarch64_unknown_qnx.rs delete mode 100644 compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx800.rs create mode 100644 compiler/rustc_target/src/spec/targets/x86_64_pc_qnx.rs diff --git a/compiler/rustc_target/src/spec/base/mod.rs b/compiler/rustc_target/src/spec/base/mod.rs index 9e7ff620fea43..13f364f3d8258 100644 --- a/compiler/rustc_target/src/spec/base/mod.rs +++ b/compiler/rustc_target/src/spec/base/mod.rs @@ -26,8 +26,8 @@ pub(crate) mod managarm_mlibc; pub(crate) mod motor; pub(crate) mod msvc; pub(crate) mod netbsd; -pub(crate) mod nto_qnx; pub(crate) mod openbsd; +pub(crate) mod qnx_sdp; pub(crate) mod redox; pub(crate) mod solaris; pub(crate) mod solid; diff --git a/compiler/rustc_target/src/spec/base/nto_qnx.rs b/compiler/rustc_target/src/spec/base/qnx_sdp.rs similarity index 100% rename from compiler/rustc_target/src/spec/base/nto_qnx.rs rename to compiler/rustc_target/src/spec/base/qnx_sdp.rs diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index f00b6e079c76e..7d2115f81a1ef 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1791,10 +1791,10 @@ supported_targets! { ("aarch64-unknown-nto-qnx700", aarch64_unknown_nto_qnx700), ("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx710), ("aarch64-unknown-nto-qnx710_iosock", aarch64_unknown_nto_qnx710_iosock), - ("aarch64-unknown-nto-qnx800", aarch64_unknown_nto_qnx800), + ("aarch64-unknown-qnx", aarch64_unknown_qnx), ("x86_64-pc-nto-qnx710", x86_64_pc_nto_qnx710), ("x86_64-pc-nto-qnx710_iosock", x86_64_pc_nto_qnx710_iosock), - ("x86_64-pc-nto-qnx800", x86_64_pc_nto_qnx800), + ("x86_64-pc-qnx", x86_64_pc_qnx), ("i686-pc-nto-qnx700", i686_pc_nto_qnx700), ("aarch64-unknown-linux-ohos", aarch64_unknown_linux_ohos), @@ -1995,6 +1995,7 @@ crate::target_spec_enum! { OpenBsd = "openbsd", Psp = "psp", Psx = "psx", + Qnx = "qnx", Qurt = "qurt", Redox = "redox", Rtems = "rtems", @@ -2035,7 +2036,6 @@ crate::target_spec_enum! { Nto70 = "nto70", Nto71 = "nto71", Nto71IoSock = "nto71_iosock", - Nto80 = "nto80", Ohos = "ohos", Relibc = "relibc", Sgx = "sgx", diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs index e1f29f832f0b5..db8905dba6cc3 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx700.rs @@ -1,11 +1,12 @@ -use crate::spec::base::nto_qnx; +use crate::spec::base::qnx_sdp; use crate::spec::{Env, Target}; pub(crate) fn target() -> Target { - let mut target = nto_qnx::aarch64(); - target.metadata.description = Some("ARM64 QNX Neutrino 7.0 RTOS".into()); + let mut target = qnx_sdp::aarch64(); + target.metadata.description = Some("ARM64 QNX SDP 7.0".into()); target.options.pre_link_args = - nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::Aarch64); + qnx_sdp::pre_link_args(qnx_sdp::ApiVariant::Default, qnx_sdp::Arch::Aarch64); + // for QNX SDP 7.x, we keep target_os = "nto" for backwards compatibility, and use target_env to specify which version target.options.env = Env::Nto70; target } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs index 1baa56630d3a9..3a76a0e34d699 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710.rs @@ -1,12 +1,12 @@ -use crate::spec::base::nto_qnx; +use crate::spec::base::qnx_sdp; use crate::spec::{Env, Target}; pub(crate) fn target() -> Target { - let mut target = nto_qnx::aarch64(); - target.metadata.description = - Some("ARM64 QNX Neutrino 7.1 RTOS with io-pkt network stack".into()); + let mut target = qnx_sdp::aarch64(); + target.metadata.description = Some("ARM64 QNX SDP 7.1 with io-pkt network stack".into()); target.options.pre_link_args = - nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::Aarch64); + qnx_sdp::pre_link_args(qnx_sdp::ApiVariant::Default, qnx_sdp::Arch::Aarch64); + // for QNX SDP 7.x, we keep target_os = "nto" for backwards compatibility, and use target_env to specify which version target.options.env = Env::Nto71; target } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710_iosock.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710_iosock.rs index 80ae93247a3f0..e612105201ff0 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710_iosock.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx710_iosock.rs @@ -1,12 +1,12 @@ -use crate::spec::base::nto_qnx; +use crate::spec::base::qnx_sdp; use crate::spec::{Env, Target}; pub(crate) fn target() -> Target { - let mut target = nto_qnx::aarch64(); - target.metadata.description = - Some("ARM64 QNX Neutrino 7.1 RTOS with io-sock network stack".into()); + let mut target = qnx_sdp::aarch64(); + target.metadata.description = Some("ARM64 QNX SDP 7.1 with io-sock network stack".into()); target.options.pre_link_args = - nto_qnx::pre_link_args(nto_qnx::ApiVariant::IoSock, nto_qnx::Arch::Aarch64); + qnx_sdp::pre_link_args(qnx_sdp::ApiVariant::IoSock, qnx_sdp::Arch::Aarch64); + // for QNX SDP 7.x, we keep target_os = "nto" for backwards compatibility, and use target_env to specify which version target.options.env = Env::Nto71IoSock; target } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx800.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx800.rs deleted file mode 100644 index 5d265087c4a21..0000000000000 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_nto_qnx800.rs +++ /dev/null @@ -1,11 +0,0 @@ -use crate::spec::base::nto_qnx; -use crate::spec::{Env, Target}; - -pub(crate) fn target() -> Target { - let mut target = nto_qnx::aarch64(); - target.metadata.description = Some("ARM64 QNX Neutrino 8.0 RTOS".into()); - target.options.pre_link_args = - nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::Aarch64); - target.options.env = Env::Nto80; - target -} diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_qnx.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_qnx.rs new file mode 100644 index 0000000000000..cbd2f4224185d --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_qnx.rs @@ -0,0 +1,12 @@ +use crate::spec::base::qnx_sdp; +use crate::spec::{Os, Target}; + +pub(crate) fn target() -> Target { + let mut target = qnx_sdp::aarch64(); + target.metadata.description = Some("ARM64 QNX SDP 8.0+".into()); + target.options.pre_link_args = + qnx_sdp::pre_link_args(qnx_sdp::ApiVariant::Default, qnx_sdp::Arch::Aarch64); + // for QNX SDP 8.0, we have target_os = "qnx" and no target_env + target.options.os = Os::Qnx; + target +} diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_nto_qnx700.rs b/compiler/rustc_target/src/spec/targets/i686_pc_nto_qnx700.rs index 7184a54961e20..c8def7e5bc423 100644 --- a/compiler/rustc_target/src/spec/targets/i686_pc_nto_qnx700.rs +++ b/compiler/rustc_target/src/spec/targets/i686_pc_nto_qnx700.rs @@ -1,9 +1,9 @@ -use crate::spec::base::nto_qnx; +use crate::spec::base::qnx_sdp; use crate::spec::{Arch, Env, RustcAbi, StackProbeType, Target, TargetOptions, base}; pub(crate) fn target() -> Target { - let mut meta = nto_qnx::meta(); - meta.description = Some("32-bit x86 QNX Neutrino 7.0 RTOS".into()); + let mut meta = qnx_sdp::meta(); + meta.description = Some("32-bit x86 QNX SDP 7.0".into()); meta.std = Some(false); Target { llvm_target: "i586-pc-unknown".into(), @@ -17,14 +17,15 @@ pub(crate) fn target() -> Target { rustc_abi: Some(RustcAbi::X86Sse2), cpu: "pentium4".into(), max_atomic_width: Some(64), - pre_link_args: nto_qnx::pre_link_args( - nto_qnx::ApiVariant::Default, - nto_qnx::Arch::I586, + pre_link_args: qnx_sdp::pre_link_args( + qnx_sdp::ApiVariant::Default, + qnx_sdp::Arch::I586, ), + // for QNX SDP 7.x, we keep target_os = "nto" for backwards compatibility, and use target_env to specify which version env: Env::Nto70, vendor: "pc".into(), stack_probes: StackProbeType::Inline, - ..base::nto_qnx::opts() + ..base::qnx_sdp::opts() }, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs index 9160015485097..6d814725d16ed 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs @@ -1,12 +1,12 @@ -use crate::spec::base::nto_qnx; +use crate::spec::base::qnx_sdp; use crate::spec::{Env, Target}; pub(crate) fn target() -> Target { - let mut target = nto_qnx::x86_64(); - target.metadata.description = - Some("x86 64-bit QNX Neutrino 7.1 RTOS with io-pkt network stack".into()); + let mut target = qnx_sdp::x86_64(); + target.metadata.description = Some("x86 64-bit QNX SDP 7.1 with io-pkt network stack".into()); target.options.pre_link_args = - nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::X86_64); + qnx_sdp::pre_link_args(qnx_sdp::ApiVariant::Default, qnx_sdp::Arch::X86_64); + // for QNX SDP 7.x, we keep target_os = "nto" for backwards compatibility, and use target_env to specify which version target.options.env = Env::Nto71; target } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs index 1e97ae6b7a08e..33789b61a18b1 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710_iosock.rs @@ -1,12 +1,12 @@ -use crate::spec::base::nto_qnx; +use crate::spec::base::qnx_sdp; use crate::spec::{Env, Target}; pub(crate) fn target() -> Target { - let mut target = nto_qnx::x86_64(); - target.metadata.description = - Some("x86 64-bit QNX Neutrino 7.1 RTOS with io-sock network stack".into()); + let mut target = qnx_sdp::x86_64(); + target.metadata.description = Some("x86 64-bit QNX SDP 7.1 with io-sock network stack".into()); target.options.pre_link_args = - nto_qnx::pre_link_args(nto_qnx::ApiVariant::IoSock, nto_qnx::Arch::X86_64); + qnx_sdp::pre_link_args(qnx_sdp::ApiVariant::IoSock, qnx_sdp::Arch::X86_64); + // for QNX SDP 7.x, we keep target_os = "nto" for backwards compatibility, and use target_env to specify which version target.options.env = Env::Nto71IoSock; target } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx800.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx800.rs deleted file mode 100644 index bd98df621db16..0000000000000 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx800.rs +++ /dev/null @@ -1,11 +0,0 @@ -use crate::spec::base::nto_qnx; -use crate::spec::{Env, Target}; - -pub(crate) fn target() -> Target { - let mut target = nto_qnx::x86_64(); - target.metadata.description = Some("x86 64-bit QNX Neutrino 8.0 RTOS".into()); - target.options.pre_link_args = - nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::X86_64); - target.options.env = Env::Nto80; - target -} diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_qnx.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_qnx.rs new file mode 100644 index 0000000000000..59eff3dbeb5d4 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_qnx.rs @@ -0,0 +1,12 @@ +use crate::spec::base::qnx_sdp; +use crate::spec::{Os, Target}; + +pub(crate) fn target() -> Target { + let mut target = qnx_sdp::x86_64(); + target.metadata.description = Some("x86 64-bit QNX SDP 8.0+".into()); + target.options.pre_link_args = + qnx_sdp::pre_link_args(qnx_sdp::ApiVariant::Default, qnx_sdp::Arch::X86_64); + // for QNX SDP 8.0, we have target_os = "qnx" and no target_env + target.options.os = Os::Qnx; + target +} diff --git a/library/std/build.rs b/library/std/build.rs index 5f2e441bf7d83..98856b58d890f 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -48,6 +48,7 @@ fn main() { || target_os == "vita" || target_os == "aix" || target_os == "nto" + || target_os == "qnx" || target_os == "xous" || target_os == "hurd" || target_os == "uefi" diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 1cbabf572367e..fa5dfd8b76ec1 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -1096,6 +1096,7 @@ pub mod consts { /// * `"netbsd"` /// * `"nto"` /// * `"openbsd"` + /// * `"qnx"` /// * `"redox"` /// * `"solaris"` /// * `"solid_asp3"` diff --git a/library/std/src/net/tcp/tests.rs b/library/std/src/net/tcp/tests.rs index 88f6af0e33df7..cada78a0d55ad 100644 --- a/library/std/src/net/tcp/tests.rs +++ b/library/std/src/net/tcp/tests.rs @@ -733,7 +733,13 @@ fn debug() { // no longer has rounding errors. // VxWorks ignores SO_SNDTIMEO. #[cfg_attr( - any(target_os = "netbsd", target_os = "openbsd", target_os = "vxworks", target_os = "nto"), + any( + target_os = "netbsd", + target_os = "openbsd", + target_os = "vxworks", + target_os = "nto", + target_os = "qnx" + ), ignore )] #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31 diff --git a/library/std/src/net/udp/tests.rs b/library/std/src/net/udp/tests.rs index 9e9d3bf77e50b..eeb6afdb072eb 100644 --- a/library/std/src/net/udp/tests.rs +++ b/library/std/src/net/udp/tests.rs @@ -188,7 +188,13 @@ fn debug() { // no longer has rounding errors. // VxWorks ignores SO_SNDTIMEO. #[cfg_attr( - any(target_os = "netbsd", target_os = "openbsd", target_os = "vxworks", target_os = "nto"), + any( + target_os = "netbsd", + target_os = "openbsd", + target_os = "vxworks", + target_os = "nto", + target_os = "qnx" + ), ignore )] #[cfg_attr(target_os = "wasi", ignore)] // timeout not supported diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 44ddb55c920f4..a7ffd87d84d93 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -121,7 +121,7 @@ pub mod macos; pub mod motor; #[cfg(target_os = "netbsd")] pub mod netbsd; -#[cfg(target_os = "nto")] +#[cfg(any(target_os = "nto", target_os = "qnx"))] pub mod nto; #[cfg(target_os = "nuttx")] pub mod nuttx; diff --git a/library/std/src/os/unix/mod.rs b/library/std/src/os/unix/mod.rs index e3f15a00a0944..25aa3bf7893f4 100644 --- a/library/std/src/os/unix/mod.rs +++ b/library/std/src/os/unix/mod.rs @@ -69,7 +69,7 @@ mod platform { pub use crate::os::linux::*; #[cfg(target_os = "netbsd")] pub use crate::os::netbsd::*; - #[cfg(target_os = "nto")] + #[cfg(any(target_os = "nto", target_os = "qnx"))] pub use crate::os::nto::*; #[cfg(target_os = "nuttx")] pub use crate::os::nuttx::*; diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs index 6876446c25c5d..e7bcd70140d67 100644 --- a/library/std/src/os/unix/net/datagram.rs +++ b/library/std/src/os/unix/net/datagram.rs @@ -9,6 +9,7 @@ target_os = "illumos", target_os = "haiku", target_os = "nto", + target_os = "qnx", target_os = "cygwin" ))] use libc::MSG_NOSIGNAL; @@ -36,6 +37,7 @@ use crate::{fmt, io}; target_os = "illumos", target_os = "haiku", target_os = "nto", + target_os = "qnx", target_os = "cygwin" )))] const MSG_NOSIGNAL: core::ffi::c_int = 0x0; diff --git a/library/std/src/os/unix/net/mod.rs b/library/std/src/os/unix/net/mod.rs index a44b23a77d2d4..137088dd832f7 100644 --- a/library/std/src/os/unix/net/mod.rs +++ b/library/std/src/os/unix/net/mod.rs @@ -20,6 +20,7 @@ mod tests; target_os = "netbsd", target_os = "openbsd", target_os = "nto", + target_os = "qnx", target_vendor = "apple", target_os = "cygwin" ))] @@ -44,6 +45,7 @@ pub use self::stream::*; target_os = "netbsd", target_os = "openbsd", target_os = "nto", + target_os = "qnx", target_vendor = "apple", target_os = "cygwin", ))] diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index a4218bd4da62c..4dfa06d74ce7e 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -6,7 +6,7 @@ cfg_select! { target_os = "openbsd", target_os = "netbsd", target_os = "solaris", target_os = "illumos", target_os = "haiku", target_os = "nto", - target_os = "cygwin", + target_os = "qnx", target_os = "cygwin", ) => { use libc::MSG_NOSIGNAL; } @@ -26,6 +26,7 @@ use super::{SocketAncillary, recv_vectored_with_ancillary_from, send_vectored_wi target_os = "netbsd", target_os = "openbsd", target_os = "nto", + target_os = "qnx", target_vendor = "apple", target_os = "cygwin" ))] diff --git a/library/std/src/os/unix/net/tests.rs b/library/std/src/os/unix/net/tests.rs index d88c97113efeb..f703fc6d54c02 100644 --- a/library/std/src/os/unix/net/tests.rs +++ b/library/std/src/os/unix/net/tests.rs @@ -176,7 +176,7 @@ fn long_path() { } #[test] -#[cfg(not(target_os = "nto"))] +#[cfg(not(any(target_os = "nto", target_os = "qnx")))] #[cfg_attr(target_os = "android", ignore)] // Android SELinux rules prevent creating Unix sockets #[cfg_attr(target_os = "cygwin", ignore)] // Cygwin connect needs handshake #[cfg_attr(target_os = "vxworks", ignore = "Unix sockets are not implemented in VxWorks")] diff --git a/library/std/src/os/unix/net/ucred.rs b/library/std/src/os/unix/net/ucred.rs index 1395d2ef4be3c..36b67cb1163d8 100644 --- a/library/std/src/os/unix/net/ucred.rs +++ b/library/std/src/os/unix/net/ucred.rs @@ -30,7 +30,8 @@ pub(super) use self::impl_apple::peer_cred; target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", - target_os = "nto" + target_os = "nto", + target_os = "qnx" ))] pub(super) use self::impl_bsd::peer_cred; #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))] @@ -79,6 +80,7 @@ mod impl_linux { target_os = "openbsd", target_os = "netbsd", target_os = "nto", + target_os = "qnx", ))] mod impl_bsd { use super::UCred; diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 8a7b94d914ab0..3b3a5794ac4f1 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -16,7 +16,7 @@ cfg_select! { type UserId = u16; type GroupId = u16; } - target_os = "nto" => { + any(target_os = "nto", target_os = "qnx") => { // Both IDs are signed, see `sys/target_nto.h` of the QNX Neutrino SDP. // Only positive values should be used, see e.g. // https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/s/setuid.html diff --git a/library/std/src/sys/args/unix.rs b/library/std/src/sys/args/unix.rs index 7a592c2b079dd..197931d8cc8d2 100644 --- a/library/std/src/sys/args/unix.rs +++ b/library/std/src/sys/args/unix.rs @@ -81,6 +81,7 @@ pub fn args() -> Args { target_os = "horizon", target_os = "aix", target_os = "nto", + target_os = "qnx", target_os = "hurd", target_os = "rtems", target_os = "nuttx", diff --git a/library/std/src/sys/env_consts.rs b/library/std/src/sys/env_consts.rs index 573f540483b1a..b14160cf4ad32 100644 --- a/library/std/src/sys/env_consts.rs +++ b/library/std/src/sys/env_consts.rs @@ -224,6 +224,17 @@ pub mod os { pub const EXE_EXTENSION: &str = ""; } +#[cfg(target_os = "qnx")] +pub mod os { + pub const FAMILY: &str = "unix"; + pub const OS: &str = "qnx"; + pub const DLL_PREFIX: &str = "lib"; + pub const DLL_SUFFIX: &str = ".so"; + pub const DLL_EXTENSION: &str = "so"; + pub const EXE_SUFFIX: &str = ""; + pub const EXE_EXTENSION: &str = ""; +} + #[cfg(target_os = "nuttx")] pub mod os { pub const FAMILY: &str = "unix"; diff --git a/library/std/src/sys/fd/unix.rs b/library/std/src/sys/fd/unix.rs index edb2ffc49995e..392e33a77dc50 100644 --- a/library/std/src/sys/fd/unix.rs +++ b/library/std/src/sys/fd/unix.rs @@ -76,6 +76,7 @@ const fn max_iov() -> usize { target_os = "emscripten", target_os = "linux", target_os = "nto", + target_os = "qnx", ))] const fn max_iov() -> usize { libc::UIO_MAXIOV as usize @@ -91,6 +92,7 @@ const fn max_iov() -> usize { target_os = "netbsd", target_os = "nuttx", target_os = "nto", + target_os = "qnx", target_os = "openbsd", target_os = "horizon", target_os = "vita", @@ -561,6 +563,7 @@ impl FileDesc { target_os = "redox", target_os = "vxworks", target_os = "nto", + target_os = "qnx", target_os = "wasi", )))] pub fn set_cloexec(&self) -> io::Result<()> { @@ -585,6 +588,7 @@ impl FileDesc { target_os = "redox", target_os = "vxworks", target_os = "nto", + target_os = "qnx", target_os = "wasi", ))] pub fn set_cloexec(&self) -> io::Result<()> { diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 3152a22534f6c..8fee56348c071 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -28,6 +28,7 @@ use libc::fstatat64; target_os = "fuchsia", target_os = "illumos", target_os = "nto", + target_os = "qnx", target_os = "redox", target_os = "solaris", target_os = "vita", @@ -45,6 +46,7 @@ use libc::readdir as readdir64; target_os = "l4re", target_os = "linux", target_os = "nto", + target_os = "qnx", target_os = "redox", target_os = "solaris", target_os = "vita", @@ -282,6 +284,7 @@ cfg_select! { target_os = "horizon", target_os = "vita", target_os = "nto", + target_os = "qnx", target_os = "vxworks", ) => { pub use crate::sys::fs::common::Dir; @@ -410,6 +413,7 @@ fn get_path_from_fd(fd: c_int) -> Option { target_os = "illumos", target_os = "linux", target_os = "nto", + target_os = "qnx", target_os = "redox", target_os = "solaris", target_os = "vita", @@ -436,6 +440,7 @@ pub struct DirEntry { target_os = "illumos", target_os = "linux", target_os = "nto", + target_os = "qnx", target_os = "redox", target_os = "solaris", target_os = "vita", @@ -448,6 +453,7 @@ struct dirent64_min { target_os = "illumos", target_os = "aix", target_os = "nto", + target_os = "qnx", target_os = "vita", )))] d_type: u8, @@ -462,6 +468,7 @@ struct dirent64_min { target_os = "illumos", target_os = "linux", target_os = "nto", + target_os = "qnx", target_os = "redox", target_os = "solaris", target_os = "vita", @@ -611,7 +618,13 @@ impl FileAttr { } } -#[cfg(not(any(target_os = "netbsd", target_os = "nto", target_os = "aix", target_os = "wasi")))] +#[cfg(not(any( + target_os = "netbsd", + target_os = "nto", + target_os = "qnx", + target_os = "aix", + target_os = "wasi" +)))] impl FileAttr { #[cfg(not(any( target_os = "vxworks", @@ -736,7 +749,7 @@ impl FileAttr { } } -#[cfg(any(target_os = "nto", target_os = "wasi"))] +#[cfg(any(target_os = "nto", target_os = "qnx", target_os = "wasi"))] impl FileAttr { pub fn modified(&self) -> io::Result { SystemTime::new(self.stat.st_mtim.tv_sec, self.stat.st_mtim.tv_nsec.into()) @@ -854,6 +867,7 @@ impl Iterator for ReadDir { target_os = "illumos", target_os = "linux", target_os = "nto", + target_os = "qnx", target_os = "redox", target_os = "solaris", target_os = "vita", @@ -927,6 +941,7 @@ impl Iterator for ReadDir { target_os = "illumos", target_os = "aix", target_os = "nto", + target_os = "qnx", )))] d_type: (*entry_ptr).d_type as u8, }; @@ -952,6 +967,7 @@ impl Iterator for ReadDir { target_os = "illumos", target_os = "linux", target_os = "nto", + target_os = "qnx", target_os = "redox", target_os = "solaris", target_os = "vita", @@ -1015,6 +1031,7 @@ impl Drop for DirStream { miri, target_os = "redox", target_os = "nto", + target_os = "qnx", target_os = "vita", target_os = "hurd", target_os = "espidf", @@ -1103,6 +1120,7 @@ impl DirEntry { target_os = "vxworks", target_os = "aix", target_os = "nto", + target_os = "qnx", target_os = "vita", ))] pub fn file_type(&self) -> io::Result { @@ -1116,6 +1134,7 @@ impl DirEntry { target_os = "vxworks", target_os = "aix", target_os = "nto", + target_os = "qnx", target_os = "vita", )))] pub fn file_type(&self) -> io::Result { @@ -1146,6 +1165,7 @@ impl DirEntry { target_os = "l4re", target_os = "linux", target_os = "nto", + target_os = "qnx", target_os = "redox", target_os = "rtems", target_os = "solaris", @@ -1205,6 +1225,7 @@ impl DirEntry { target_os = "redox", target_os = "aix", target_os = "nto", + target_os = "qnx", target_os = "vita", target_os = "hurd", target_os = "wasi", @@ -1222,6 +1243,7 @@ impl DirEntry { target_os = "redox", target_os = "aix", target_os = "nto", + target_os = "qnx", target_os = "vita", target_os = "hurd", target_os = "wasi", @@ -1419,6 +1441,7 @@ impl File { target_os = "netbsd", target_os = "openbsd", target_os = "nto", + target_os = "qnx", target_os = "hurd", ))] unsafe fn os_datasync(fd: c_int) -> c_int { @@ -1433,6 +1456,7 @@ impl File { target_os = "netbsd", target_os = "openbsd", target_os = "nto", + target_os = "qnx", target_os = "hurd", target_vendor = "apple", )))] @@ -2405,6 +2429,7 @@ pub use remove_dir_impl::remove_dir_all; target_os = "horizon", target_os = "vita", target_os = "nto", + target_os = "qnx", target_os = "vxworks", miri ))] @@ -2419,6 +2444,7 @@ mod remove_dir_impl { target_os = "horizon", target_os = "vita", target_os = "nto", + target_os = "qnx", target_os = "vxworks", miri )))] diff --git a/library/std/src/sys/io/error/unix.rs b/library/std/src/sys/io/error/unix.rs index 56295578bf7d9..85e3c09782ae2 100644 --- a/library/std/src/sys/io/error/unix.rs +++ b/library/std/src/sys/io/error/unix.rs @@ -27,6 +27,7 @@ unsafe extern "C" { )] #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), link_name = "___errno")] #[cfg_attr(target_os = "nto", link_name = "__get_errno_ptr")] + #[cfg_attr(target_os = "qnx", link_name = "__get_errno_ptr")] #[cfg_attr(any(target_os = "freebsd", target_vendor = "apple"), link_name = "__error")] #[cfg_attr(target_os = "haiku", link_name = "_errnop")] #[cfg_attr(target_os = "aix", link_name = "_Errno")] diff --git a/library/std/src/sys/net/connection/socket/mod.rs b/library/std/src/sys/net/connection/socket/mod.rs index 55c928dc6c5fc..da25cff1d5444 100644 --- a/library/std/src/sys/net/connection/socket/mod.rs +++ b/library/std/src/sys/net/connection/socket/mod.rs @@ -46,6 +46,7 @@ cfg_select! { target_os = "haiku", target_os = "l4re", target_os = "nto", + target_os = "qnx", target_os = "nuttx", target_vendor = "apple", ) => { @@ -66,7 +67,7 @@ cfg_select! { target_os = "openbsd", target_os = "netbsd", target_os = "solaris", target_os = "illumos", target_os = "haiku", target_os = "nto", - target_os = "cygwin", + target_os = "qnx", target_os = "cygwin", ) => { use libc::MSG_NOSIGNAL; } @@ -80,7 +81,7 @@ cfg_select! { target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", target_os = "solaris", target_os = "illumos", - target_os = "nto", + target_os = "nto", target_os = "qnx", ) => { use crate::ffi::c_uchar; type IpV4MultiCastType = c_uchar; diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index 3336dc4cf9233..41850574c96fa 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs @@ -76,6 +76,7 @@ impl Socket { target_os = "openbsd", target_os = "cygwin", target_os = "nto", + target_os = "qnx", target_os = "solaris", ) => { // On platforms that support it we pass the SOCK_CLOEXEC @@ -124,6 +125,7 @@ impl Socket { target_os = "openbsd", target_os = "cygwin", target_os = "nto", + target_os = "qnx", ) => { // Like above, set cloexec atomically cvt(libc::socketpair(fam, ty | libc::SOCK_CLOEXEC, 0, fds.as_mut_ptr()))?; diff --git a/library/std/src/sys/pal/unix/sync/condvar.rs b/library/std/src/sys/pal/unix/sync/condvar.rs index 73768860723d0..51162296ea3fc 100644 --- a/library/std/src/sys/pal/unix/sync/condvar.rs +++ b/library/std/src/sys/pal/unix/sync/condvar.rs @@ -1,9 +1,9 @@ use super::Mutex; use crate::cell::UnsafeCell; use crate::pin::Pin; -#[cfg(not(target_os = "nto"))] +#[cfg(not(any(target_os = "nto", target_os = "qnx")))] use crate::sys::pal::time::TIMESPEC_MAX; -#[cfg(target_os = "nto")] +#[cfg(any(target_os = "nto", target_os = "qnx"))] use crate::sys::pal::time::TIMESPEC_MAX_CAPPED; use crate::time::Duration; @@ -69,10 +69,10 @@ impl Condvar { let timeout = Timespec::now(Self::CLOCK).checked_add_duration(&dur); - #[cfg(not(target_os = "nto"))] + #[cfg(not(any(target_os = "nto", target_os = "qnx")))] let timeout = timeout.and_then(|t| t.to_timespec()).unwrap_or(TIMESPEC_MAX); - #[cfg(target_os = "nto")] + #[cfg(any(target_os = "nto", target_os = "qnx"))] let timeout = timeout.and_then(|t| t.to_timespec_capped()).unwrap_or(TIMESPEC_MAX_CAPPED); let r = unsafe { libc::pthread_cond_timedwait(self.raw(), mutex, &timeout) }; diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index 26fb6d3d7cf2d..26296b5d169a1 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -16,7 +16,7 @@ pub const TIMESPEC_MAX: libc::timespec = { // This additional constant is only used when calling // `libc::pthread_cond_timedwait`. -#[cfg(target_os = "nto")] +#[cfg(any(target_os = "nto", target_os = "qnx"))] pub(in crate::sys) const TIMESPEC_MAX_CAPPED: libc::timespec = libc::timespec { tv_sec: (u64::MAX / NSEC_PER_SEC) as i64, tv_nsec: (u64::MAX % NSEC_PER_SEC) as i64, diff --git a/library/std/src/sys/paths/unix.rs b/library/std/src/sys/paths/unix.rs index e0b1aafda6eb0..36879b7b9bce3 100644 --- a/library/std/src/sys/paths/unix.rs +++ b/library/std/src/sys/paths/unix.rs @@ -269,7 +269,7 @@ pub fn current_exe() -> io::Result { } } -#[cfg(target_os = "nto")] +#[cfg(any(target_os = "nto", target_os = "qnx"))] pub fn current_exe() -> io::Result { let mut e = crate::fs::read("/proc/self/exefile")?; // Current versions of QNX Neutrino provide a null-terminated path. diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index b6ccc6b698fda..55906ed2854f2 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -20,7 +20,7 @@ use crate::sys::process::PidFd; use crate::{fmt, mem, sys}; cfg_select! { - target_os = "nto" => { + any(target_os = "nto", target_os = "qnx") => { use crate::thread; use libc::{c_char, posix_spawn_file_actions_t, posix_spawnattr_t}; use crate::time::Duration; @@ -183,7 +183,12 @@ impl Command { // Attempts to fork the process. If successful, returns Ok((0, -1)) // in the child, and Ok((child_pid, -1)) in the parent. - #[cfg(not(any(target_os = "watchos", target_os = "tvos", target_os = "nto")))] + #[cfg(not(any( + target_os = "watchos", + target_os = "tvos", + target_os = "nto", + target_os = "qnx" + )))] unsafe fn do_fork(&mut self) -> Result { cvt(libc::fork()) } @@ -192,7 +197,7 @@ impl Command { // or closed a file descriptor while the fork() was occurring". // Documentation says "... or try calling fork() again". This is what we do here. // See also https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/f/fork.html - #[cfg(target_os = "nto")] + #[cfg(any(target_os = "nto", target_os = "qnx"))] unsafe fn do_fork(&mut self) -> Result { use crate::sys::io::errno; @@ -424,6 +429,7 @@ impl Command { all(target_os = "linux", target_env = "gnu"), all(target_os = "linux", target_env = "musl"), target_os = "nto", + target_os = "qnx", target_vendor = "apple", target_os = "cygwin", )))] @@ -443,6 +449,7 @@ impl Command { all(target_os = "linux", target_env = "gnu"), all(target_os = "linux", target_env = "musl"), target_os = "nto", + target_os = "qnx", target_vendor = "apple", target_os = "cygwin", ))] @@ -550,7 +557,7 @@ impl Command { // or closed a file descriptor while the posix_spawn() was occurring". // Documentation says "... or try calling posix_spawn() again". This is what we do here. // See also http://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/p/posix_spawn.html - #[cfg(target_os = "nto")] + #[cfg(any(target_os = "nto", target_os = "qnx"))] unsafe fn retrying_libc_posix_spawnp( pid: *mut pid_t, file: *const c_char, @@ -763,9 +770,9 @@ impl Command { let _env_lock = sys::env::env_read_lock(); let envp = envp.map(|c| c.as_ptr()).unwrap_or_else(|| *sys::env::environ() as *const _); - #[cfg(not(target_os = "nto"))] + #[cfg(not(any(target_os = "nto", target_os = "qnx")))] let spawn_fn = libc::posix_spawnp; - #[cfg(target_os = "nto")] + #[cfg(any(target_os = "nto", target_os = "qnx"))] let spawn_fn = retrying_libc_posix_spawnp; #[cfg(target_os = "linux")] @@ -822,7 +829,7 @@ impl Command { envp as *const _, ); - #[cfg(target_os = "nto")] + #[cfg(any(target_os = "nto", target_os = "qnx"))] let spawn_res = spawn_res?; cvt_nz(spawn_res)?; @@ -1202,7 +1209,12 @@ fn signal_string(signal: i32) -> &'static str { ) ))] libc::SIGSTKFLT => " (SIGSTKFLT)", - #[cfg(any(target_os = "linux", target_os = "nto", target_os = "cygwin"))] + #[cfg(any( + target_os = "linux", + target_os = "nto", + target_os = "qnx", + target_os = "cygwin" + ))] libc::SIGPWR => " (SIGPWR)", #[cfg(any( target_os = "freebsd", @@ -1210,6 +1222,7 @@ fn signal_string(signal: i32) -> &'static str { target_os = "openbsd", target_os = "dragonfly", target_os = "nto", + target_os = "qnx", target_vendor = "apple", target_os = "cygwin", ))] diff --git a/library/std/src/sys/random/mod.rs b/library/std/src/sys/random/mod.rs index 12346ef5a2edd..e5a66dc463c6b 100644 --- a/library/std/src/sys/random/mod.rs +++ b/library/std/src/sys/random/mod.rs @@ -54,6 +54,7 @@ cfg_select! { target_os = "hurd", target_os = "l4re", target_os = "nto", + target_os = "qnx", ) => { mod unix_legacy; pub use unix_legacy::fill_bytes; diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs index dd7b7940de510..e52ffff165beb 100644 --- a/library/std/src/sys/thread/unix.rs +++ b/library/std/src/sys/thread/unix.rs @@ -12,7 +12,12 @@ use crate::mem::{self, DropGuard, ManuallyDrop}; use crate::num::NonZero; #[cfg(all(target_os = "linux", target_env = "gnu"))] use crate::sys::weak::dlsym; -#[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto",))] +#[cfg(any( + target_os = "solaris", + target_os = "illumos", + target_os = "nto", + target_os = "qnx", +))] use crate::sys::weak::weak; use crate::thread::ThreadInit; use crate::time::Duration; diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index 4e380d8894781..cb4a3593c51d6 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -193,7 +193,7 @@ unsafe extern "C" {} #[link(name = "unwind")] unsafe extern "C" {} -#[cfg(target_os = "nto")] +#[cfg(any(target_os = "nto", target_os = "qnx"))] cfg_select! { target_env = "nto70" => { #[link(name = "gcc")] diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index 6ebfa4da4906a..99d9c8a04c5c1 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -39,6 +39,8 @@ const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined "powerpc64-unknown-linux-gnuelfv2", "aarch64-unknown-linux-pauthtest", // Stage 0 compiler is not guaranteed to see the target yet. + "aarch64-unknown-qnx", + "x86_64-pc-qnx", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index be64a6cfe3eb9..4ab9663ef50fc 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -277,7 +277,7 @@ target | std | host | notes [`aarch64-unknown-nto-qnx700`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.0 RTOS | [`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS with default network stack (io-pkt) | [`aarch64-unknown-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS with new network stack (io-sock) | -[`aarch64-unknown-nto-qnx800`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 8.0 RTOS | +[`aarch64-unknown-qnx`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX SDP 8.0+ | [`aarch64-unknown-nuttx`](platform-support/nuttx.md) | ✓ | | ARM64 with NuttX [`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD [`aarch64-unknown-redox`](platform-support/redox.md) | ✓ | | ARM64 Redox OS @@ -446,7 +446,7 @@ target | std | host | notes [`x86_64-pc-cygwin`](platform-support/x86_64-pc-cygwin.md) | ✓ | | 64-bit x86 Cygwin | [`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with default network stack (io-pkt) | [`x86_64-pc-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with new network stack (io-sock) | -[`x86_64-pc-nto-qnx800`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 8.0 RTOS | +[`x86_64-pc-qnx`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX SDP 8.0+ | [`x86_64-unikraft-linux-musl`](platform-support/unikraft-linux-musl.md) | ✓ | | 64-bit Unikraft with musl 1.2.5 `x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 9f8960899c169..5c421af97bbf3 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -1,15 +1,8 @@ -# nto-qnx +# Q **Tier: 3** -The [QNX®][qnx.com] Neutrino (nto) Real-time operating system. Known as QNX OS -from version 8 onwards. - -This support has been implemented jointly by [Elektrobit Automotive GmbH][Elektrobit] -and [QNX][qnx.com]. - -[qnx.com]: https://blackberry.qnx.com -[Elektrobit]: https://www.elektrobit.com +Support for the [QNX®][qnx.com] Software Development Platform (SDP), version 7.0, 7.1 and 8.0. ## Target maintainers @@ -20,36 +13,35 @@ and [QNX][qnx.com]. ## Requirements -Currently, the following QNX versions and compilation targets are supported: +The following QNX SDP versions and compilation targets are supported: | Target Tuple | QNX Version | Target Architecture | Full support | `no_std` support | | ----------------------------------- | ----------------------------- | ------------------- | :----------: | :--------------: | -| `aarch64-unknown-nto-qnx800` | QNX OS 8.0 | AArch64 | ? | ✓ | -| `x86_64-pc-nto-qnx800` | QNX OS 8.0 | x86_64 | ? | ✓ | -| `aarch64-unknown-nto-qnx710` | QNX Neutrino 7.1 with io-pkt | AArch64 | ✓ | ✓ | -| `x86_64-pc-nto-qnx710` | QNX Neutrino 7.1 with io-pkt | x86_64 | ✓ | ✓ | -| `aarch64-unknown-nto-qnx710_iosock` | QNX Neutrino 7.1 with io-sock | AArch64 | ? | ✓ | -| `x86_64-pc-nto-qnx710_iosock` | QNX Neutrino 7.1 with io-sock | x86_64 | ? | ✓ | -| `aarch64-unknown-nto-qnx700` | QNX Neutrino 7.0 | AArch64 | ? | ✓ | -| `i686-pc-nto-qnx700` | QNX Neutrino 7.0 | x86 | | ✓ | - -On QNX Neutrino 7.0 and 7.1, `io-pkt` is used as network stack by default. -QNX Neutrino 7.1 includes the optional network stack `io-sock`. -QNX OS 8.0 always uses `io-sock`. QNX OS 8.0 support is currently work in progress. +| `aarch64-unknown-qnx` | QNX SDP 8.0+ | AArch64 | ? | ✓ | +| `x86_64-pc-qnx` | QNX SDP 8.0+ | x86_64 | ? | ✓ | +| `aarch64-unknown-nto-qnx710_iosock` | QNX SDP 7.1 with io-sock | AArch64 | ? | ✓ | +| `x86_64-pc-nto-qnx710_iosock` | QNX SDP 7.1 with io-sock | x86_64 | ? | ✓ | +| `aarch64-unknown-nto-qnx710` | QNX SDP 7.1 with io-pkt | AArch64 | ✓ | ✓ | +| `x86_64-pc-nto-qnx710` | QNX SDP 7.1 with io-pkt | x86_64 | ✓ | ✓ | +| `aarch64-unknown-nto-qnx700` | QNX SDP 7.0 | AArch64 | ? | ✓ | +| `i686-pc-nto-qnx700` | QNX SDP 7.0 | x86 | | ✓ | + +* On QNX SDP 7.0 and 7.1, `io-pkt` is used as network stack by default. +* QNX SDP 7.1 includes the optional network stack `io-sock`. +* QNX SDP 8.0 always uses `io-sock`. Adding other architectures that are supported by QNX is possible. -In the table above, 'full support' indicates support for building Rust applications with the full standard library. A '?' means that support is in-progress. -'`no_std` support' is for building `#![no_std]` applications where only `core` and `alloc` are available. +In the table above, 'full support' indicates support for building Rust applications with the full standard library. A '?' means that support is in-progress. `no_std` support' is for building `#![no_std]` applications where only `core` and `alloc` are available. -For building or using the Rust toolchain for QNX, the -[QNX Software Development Platform (SDP)](https://blackberry.qnx.com/en/products/foundation-software/qnx-software-development-platform) -must be installed and initialized. +For building or using the Rust toolchain for QNX, the relevant version of the [QNX Software Development Platform (SDP)] must be installed and initialized. Initialization is usually done by sourcing `qnxsdp-env.sh` (this will be installed as part of the SDP, see also installation instruction provided with the SDP). -Afterwards [`qcc`](https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.utilities/topic/q/qcc.html) (QNX C/C++ compiler) +Afterwards [`qcc`](https://www.qnx.com/developers/docs/8.0/com.qnx.doc.neutrino.utilities/topic/q/qcc.html) (the QNX C/C++ compiler) should be available (in the `$PATH` variable). `qcc` will be called e.g. for linking executables. +[QNX Software Development Platform (SDP)]: https://qnx.software/en/software/products-and-solutions/qnx-software-development-platform + When linking `no_std` applications, they must link against `libc.so` (see example). This is required because applications always link against the `crt` library and `crt` depends on `libc.so`. This is done automatically when using the standard library. @@ -71,56 +63,15 @@ Resolution scope for Executable->/bin/sh: libc.so.4->/usr/lib/ldqnx-64.so.2 ``` -### Small example application - -Small `no_std` example is shown below. Applications using the standard library work as well. - -```rust,ignore (platform-specific) -#![no_std] -#![no_main] -#![feature(lang_items)] - -// We must always link against libc, even if no external functions are used -// "extern C" - Block can be empty but must be present -#[link(name = "c")] -extern "C" { - pub fn printf(format: *const core::ffi::c_char, ...) -> core::ffi::c_int; -} - -#[no_mangle] -pub extern "C" fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int { - const HELLO: &'static str = "Hello World, the answer is %d\n\0"; - unsafe { - printf(HELLO.as_ptr() as *const _, 42); - } - 0 -} - -use core::panic::PanicInfo; - -#[panic_handler] -fn panic(_panic: &PanicInfo<'_>) -> ! { - loop {} -} - -#[lang = "eh_personality"] -#[no_mangle] -pub extern "C" fn rust_eh_personality() {} -``` - -The QNX support in Rust has been tested with QNX Neutrino 7.0 and 7.1. Support for QNX OS 8.0 is a work in progress. - -There are no further known requirements. - ## Conditional compilation -For conditional compilation, following QNX specific attributes are defined: +For conditional compilation, the following QNX specific attributes are defined: - `target_os` = `"nto"` -- `target_env` = `"nto71"` (for QNX Neutrino 7.1 with "classic" network stack "io_pkt") -- `target_env` = `"nto71_iosock"` (for QNX Neutrino 7.1 with network stack "io_sock") -- `target_env` = `"nto70"` (for QNX Neutrino 7.0) -- `target_env` = `"nto80"` (for QNX OS 8.0) + - `target_env` = `"nto70"` (for QNX SDP 7.0) + - `target_env` = `"nto71"` (for QNX SDP 7.1 with "classic" network stack "io_pkt") + - `target_env` = `"nto71_iosock"` (for QNX SDP 7.1 with "new" network stack "io_sock") +- `target_os` = `"qnx"` (for QNX SDP 8.0 or higher) ## Building the target @@ -212,7 +163,7 @@ env $build_env \ ## Building Rust programs -Rust does not yet ship pre-compiled artifacts for this target. +Rust does not ship pre-compiled artifacts for this target. To compile for this target, you must either build Rust with the target enabled (see "Building the target" above), or build your own copy of `core` by using `build-std` or similar. diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 2950e3b563c1c..74a04b4451040 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -638,11 +638,12 @@ fn human_readable_target_os(os: Symbol) -> Option<&'static str> { Motor => "Motor OS", NetBsd => "NetBSD", None => "bare-metal", - Nto => "QNX Neutrino", + Nto => "QNX SDP 7.x", NuttX => "NuttX", OpenBsd => "OpenBSD", Psp => "Play Station Portable", Psx => "Play Station 1", + Qnx => "QNX SDP 8.0+", Qurt => "QuRT", Redox => "Redox OS", Rtems => "RTEMS OS", @@ -718,10 +719,9 @@ fn human_readable_target_env(env: Symbol) -> Option<&'static str> { Msvc => "MSVC", Musl => "musl", Newlib => "Newlib", - Nto70 => "Neutrino 7.0", - Nto71 => "Neutrino 7.1", - Nto71IoSock => "Neutrino 7.1 with io-sock", - Nto80 => "Neutrino 8.0", + Nto70 => "QNX SDP 7.0", + Nto71 => "QNX SDP 7.1", + Nto71IoSock => "QNX SDP 7.1 with io-sock", Ohos => "OpenHarmony", P1 => "WASIp1", P2 => "WASIp2", diff --git a/src/tools/miri/tests/pass-dep/shims/gettid.rs b/src/tools/miri/tests/pass-dep/shims/gettid.rs index 9b186699ce275..05885ac277f76 100644 --- a/src/tools/miri/tests/pass-dep/shims/gettid.rs +++ b/src/tools/miri/tests/pass-dep/shims/gettid.rs @@ -9,7 +9,7 @@ fn gettid() -> u64 { any(target_os = "android", target_os = "linux") => { gettid_linux_like() } - target_os = "nto" => { + any(target_os = "nto", target_os = "qnx") => { unsafe { libc::gettid() as u64 } } target_os = "openbsd" => { diff --git a/tests/assembly-llvm/targets/targets-elf.rs b/tests/assembly-llvm/targets/targets-elf.rs index 3d7fd936baa88..da4176040a535 100644 --- a/tests/assembly-llvm/targets/targets-elf.rs +++ b/tests/assembly-llvm/targets/targets-elf.rs @@ -85,9 +85,9 @@ //@ revisions: aarch64_unknown_nto_qnx710_iosock //@ [aarch64_unknown_nto_qnx710_iosock] compile-flags: --target aarch64-unknown-nto-qnx710_iosock //@ [aarch64_unknown_nto_qnx710_iosock] needs-llvm-components: aarch64 -//@ revisions: aarch64_unknown_nto_qnx800 -//@ [aarch64_unknown_nto_qnx800] compile-flags: --target aarch64-unknown-nto-qnx800 -//@ [aarch64_unknown_nto_qnx800] needs-llvm-components: aarch64 +//@ revisions: aarch64_unknown_qnx +//@ [aarch64_unknown_qnx] compile-flags: --target aarch64-unknown-qnx +//@ [aarch64_unknown_qnx] needs-llvm-components: aarch64 //@ revisions: aarch64_unknown_openbsd //@ [aarch64_unknown_openbsd] compile-flags: --target aarch64-unknown-openbsd //@ [aarch64_unknown_openbsd] needs-llvm-components: aarch64 @@ -670,9 +670,9 @@ //@ revisions: x86_64_pc_nto_qnx710_iosock //@ [x86_64_pc_nto_qnx710_iosock] compile-flags: --target x86_64-pc-nto-qnx710_iosock //@ [x86_64_pc_nto_qnx710_iosock] needs-llvm-components: x86 -//@ revisions: x86_64_pc_nto_qnx800 -//@ [x86_64_pc_nto_qnx800] compile-flags: --target x86_64-pc-nto-qnx800 -//@ [x86_64_pc_nto_qnx800] needs-llvm-components: x86 +//@ revisions: x86_64_pc_qnx +//@ [x86_64_pc_qnx] compile-flags: --target x86_64-pc-qnx +//@ [x86_64_pc_qnx] needs-llvm-components: x86 //@ revisions: x86_64_pc_solaris //@ [x86_64_pc_solaris] compile-flags: --target x86_64-pc-solaris //@ [x86_64_pc_solaris] needs-llvm-components: x86 diff --git a/tests/rustdoc-html/doc-cfg/all-targets.rs b/tests/rustdoc-html/doc-cfg/all-targets.rs index 605a27a7d8927..7adf1d90de283 100644 --- a/tests/rustdoc-html/doc-cfg/all-targets.rs +++ b/tests/rustdoc-html/doc-cfg/all-targets.rs @@ -16,7 +16,6 @@ target_env = "nto70", target_env = "nto71", target_env = "nto71_iosock", - target_env = "nto80", target_env = "ohos", target_env = "relibc", target_env = "sgx", @@ -112,6 +111,7 @@ pub fn bar() {} target_os = "netbsd", target_os = "none", target_os = "nto", + target_os = "qnx", target_os = "nuttx", target_os = "openbsd", target_os = "psp", diff --git a/tests/rustdoc-html/doc-cfg/sort.rs b/tests/rustdoc-html/doc-cfg/sort.rs index 3aa79b7836271..245a9b7b39d05 100644 --- a/tests/rustdoc-html/doc-cfg/sort.rs +++ b/tests/rustdoc-html/doc-cfg/sort.rs @@ -18,6 +18,7 @@ target_os = "netbsd", target_os = "openbsd", target_os = "nto", + target_os = "qnx", target_vendor = "apple", target_os = "cygwin" )))] @@ -36,6 +37,7 @@ pub fn foo() {} target_os = "netbsd", target_os = "openbsd", target_os = "nto", + target_os = "qnx", target_vendor = "apple", target_os = "cygwin" ))] diff --git a/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs b/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs index f93a2aae5a1e9..6ea36dee947c1 100644 --- a/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs +++ b/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs @@ -18,6 +18,7 @@ target_os = "linux", target_os = "netbsd", target_os = "nto", + target_os = "qnx", target_os = "openbsd", target_os = "fuchsia", target_os = "managarm", diff --git a/tests/ui/check-cfg/cfg-crate-features.stderr b/tests/ui/check-cfg/cfg-crate-features.stderr index 242883995488e..9bf3cef403159 100644 --- a/tests/ui/check-cfg/cfg-crate-features.stderr +++ b/tests/ui/check-cfg/cfg-crate-features.stderr @@ -24,7 +24,7 @@ warning: unexpected `cfg` condition value: `does_not_exist` LL | #![cfg(not(target(os = "does_not_exist")))] | ^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `qurt`, `redox`, `rtems`, `solaris`, and `solid_asp3` and 14 more + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `qnx`, `qurt`, `redox`, `rtems`, and `solaris` and 15 more = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index ebcb439b73498..5c797783e48b8 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -156,7 +156,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_env = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_env` are: ``, `gnu`, `macabi`, `mlibc`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `nto71_iosock`, `nto80`, `ohos`, `p1`, `p2`, `p3`, `relibc`, `sgx`, `sim`, `uclibc`, and `v5` + = note: expected values for `target_env` are: ``, `gnu`, `macabi`, `mlibc`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `nto71_iosock`, `ohos`, `p1`, `p2`, `p3`, `relibc`, `sgx`, `sim`, `uclibc`, and `v5` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -210,7 +210,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_os = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `qurt`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `qnx`, `qurt`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -283,7 +283,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` | | | help: there is a expected value with a similar name: `"linux"` | - = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `qurt`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `helenos`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `qnx`, `qurt`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see for more information about checking conditional configuration warning: 29 warnings emitted diff --git a/tests/ui/intrinsics/intrinsic-alignment.rs b/tests/ui/intrinsics/intrinsic-alignment.rs index 242eea1f8407d..d14bdf35e81f3 100644 --- a/tests/ui/intrinsics/intrinsic-alignment.rs +++ b/tests/ui/intrinsics/intrinsic-alignment.rs @@ -16,6 +16,7 @@ target_os = "solaris", target_os = "vxworks", target_os = "nto", + target_os = "qnx", target_vendor = "apple", ))] mod m { diff --git a/tests/ui/process/process-sigpipe.rs b/tests/ui/process/process-sigpipe.rs index 574d79ee1ddaf..b8eb2a9688b4d 100644 --- a/tests/ui/process/process-sigpipe.rs +++ b/tests/ui/process/process-sigpipe.rs @@ -31,9 +31,9 @@ fn main() { thread::sleep_ms(5000); process::exit(1); }); - // QNX Neutrino does not have `yes`. Therefore, use `while-echo` for `nto` + // QNX does not have `yes`. Therefore, use `while-echo` for `nto` // and `yes` for other platforms. - let command = if cfg!(target_os = "nto") { + let command = if cfg!(any(target_os = "nto", target_os = "qnx")) { "while echo y ; do : ; done | head" } else { "yes | head" diff --git a/tests/ui/structs/rec-align-u64.rs b/tests/ui/structs/rec-align-u64.rs index e49726c7d438f..a3d835799ad62 100644 --- a/tests/ui/structs/rec-align-u64.rs +++ b/tests/ui/structs/rec-align-u64.rs @@ -36,6 +36,7 @@ struct Outer { target_os = "solaris", target_os = "vxworks", target_os = "nto", + target_os = "qnx", target_vendor = "apple", ))] mod m { From 4eec7f5d40dacb0813a95fa1c761c077f11a9911 Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Fri, 26 Jun 2026 17:33:41 +0000 Subject: [PATCH 07/15] Fix rustdoc tests The name of the OS had changed, so the tests needed updating --- tests/rustdoc-html/doc-cfg/all-targets.rs | 8 ++++---- tests/rustdoc-html/doc-cfg/sort.rs | 8 ++------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/rustdoc-html/doc-cfg/all-targets.rs b/tests/rustdoc-html/doc-cfg/all-targets.rs index 7adf1d90de283..d5a8be83bc1d3 100644 --- a/tests/rustdoc-html/doc-cfg/all-targets.rs +++ b/tests/rustdoc-html/doc-cfg/all-targets.rs @@ -3,9 +3,9 @@ //@ has all_targets/fn.foo.html \ // '//*[@id="main-content"]/*[@class="item-info"]/*[@class="stab portability"]' \ // 'Available on target_env=fake_env or Catalyst or GNU or Managarm C Library \ -// or MSVC or musl or Neutrino 7.0 or Neutrino 7.1 or Neutrino 7.1 with io-sock \ -// or Neutrino 8.0 or Newlib or OpenHarmony or relibc or SGX or Simulator or \ -// uClibc or V5 or WASIp1 or WASIp2 or WASIp3 only.' +// or MSVC or musl or Newlib or OpenHarmony or QNX SDP 7.0 or QNX SDP 7.1 or \ +// QNX SDP 7.1 with io-sock or relibc or SGX or Simulator or uClibc or V5 or WASIp1 \ +// or WASIp2 or WASIp3 only.' #[doc(cfg(any( target_env = "gnu", target_env = "macabi", @@ -80,7 +80,7 @@ pub fn bar() {} // and HelenOS and Hermit and Horizon and illumos and iOS and L4Re and Linux \ // and LynxOS-178 and macOS and Managarm and Motor OS and NetBSD and NuttX \ // and OpenBSD and Play Station 1 and Play Station Portable and Play Station Vita \ -// and QNX Neutrino and QuRT and Redox OS and RTEMS OS and Solaris and \ +// and QNX SDP 7.x and QNX SDP 8.0+ and QuRT and Redox OS and RTEMS OS and Solaris and \ // SOLID ASP3 and TEEOS and Trusty and tvOS and UEFI and VEXos and visionOS \ // and VxWorks and WASI and watchOS and Windows and Xous and zero knowledge \ // Virtual Machine only.' diff --git a/tests/rustdoc-html/doc-cfg/sort.rs b/tests/rustdoc-html/doc-cfg/sort.rs index 245a9b7b39d05..2c54e86be67c7 100644 --- a/tests/rustdoc-html/doc-cfg/sort.rs +++ b/tests/rustdoc-html/doc-cfg/sort.rs @@ -9,7 +9,7 @@ // Tests that OS targets are sorted alphabetically. //@ has 'foo/fn.foo.html' //@ has - '//*[@class="stab portability"]' 'Available on Android or Apple or Cygwin \ -// or DragonFly BSD or FreeBSD or Linux or NetBSD or OpenBSD or QNX Neutrino only.' +// or DragonFly BSD or FreeBSD or Linux or NetBSD or OpenBSD only.' #[doc(cfg(any( target_os = "android", target_os = "linux", @@ -17,8 +17,6 @@ target_os = "freebsd", target_os = "netbsd", target_os = "openbsd", - target_os = "nto", - target_os = "qnx", target_vendor = "apple", target_os = "cygwin" )))] @@ -28,7 +26,7 @@ pub fn foo() {} // Tests that targets are sorted alphabetically just like explicit `doc(cfg)`. //@ has 'foo/fn.bar.html' //@ has - '//*[@class="stab portability"]' 'Available on Android or Apple or Cygwin \ -// or DragonFly BSD or FreeBSD or Linux or NetBSD or OpenBSD or QNX Neutrino only.' +// or DragonFly BSD or FreeBSD or Linux or NetBSD or OpenBSD only.' #[cfg(any( target_os = "android", target_os = "linux", @@ -36,8 +34,6 @@ pub fn foo() {} target_os = "freebsd", target_os = "netbsd", target_os = "openbsd", - target_os = "nto", - target_os = "qnx", target_vendor = "apple", target_os = "cygwin" ))] From d5e809513e7074b7743ac116ffeaebedb87323da Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Mon, 29 Jun 2026 09:31:49 +0000 Subject: [PATCH 08/15] Clean up nto-qnx target page - Now explains what SDP is - Moves sections into a more useful order - Re-wrap long blocks of text --- src/doc/rustc/src/platform-support/nto-qnx.md | 138 +++++++++++------- 1 file changed, 83 insertions(+), 55 deletions(-) diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 5c421af97bbf3..045655644fa7d 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -1,8 +1,22 @@ -# Q +# QNX **Tier: 3** -Support for the [QNX®][qnx.com] Software Development Platform (SDP), version 7.0, 7.1 and 8.0. +Support for the [QNX®][qnx.com] [QNX Software Development Platform (SDP)], version 7.0, 7.1 and 8.0. + +[QNX Software Development Platform (SDP)]: https://qnx.software/en/software/products-and-solutions/qnx-software-development-platform + +The [QNX Software Development Platform (SDP)] is a development environment that +you download and install on a host computer. It includes a C toolchain for your +host, an IDE, and various board support packages for different target platforms. +You can then use QNX SDP to build a custom run-time environment which you deploy +onto an embedded device. That run-time environment will include a microkernel, +whatever services you have selected, and perhaps one or more applications +written in Rust. + +In QNX SDP 7.x the run-time environment is based on QNX Neutrino RTOS 7.x, while +in QNX SDP 8.0 the run-time environment is based on QNX OS 8.0. The name change +reflects architectural changes in the RTOS, but both use a microkernel design. ## Target maintainers @@ -24,44 +38,31 @@ The following QNX SDP versions and compilation targets are supported: | `aarch64-unknown-nto-qnx710` | QNX SDP 7.1 with io-pkt | AArch64 | ✓ | ✓ | | `x86_64-pc-nto-qnx710` | QNX SDP 7.1 with io-pkt | x86_64 | ✓ | ✓ | | `aarch64-unknown-nto-qnx700` | QNX SDP 7.0 | AArch64 | ? | ✓ | -| `i686-pc-nto-qnx700` | QNX SDP 7.0 | x86 | | ✓ | - -* On QNX SDP 7.0 and 7.1, `io-pkt` is used as network stack by default. -* QNX SDP 7.1 includes the optional network stack `io-sock`. -* QNX SDP 8.0 always uses `io-sock`. - -Adding other architectures that are supported by QNX is possible. - -In the table above, 'full support' indicates support for building Rust applications with the full standard library. A '?' means that support is in-progress. `no_std` support' is for building `#![no_std]` applications where only `core` and `alloc` are available. - -For building or using the Rust toolchain for QNX, the relevant version of the [QNX Software Development Platform (SDP)] must be installed and initialized. -Initialization is usually done by sourcing `qnxsdp-env.sh` (this will be installed as part of the SDP, see also installation instruction provided with the SDP). -Afterwards [`qcc`](https://www.qnx.com/developers/docs/8.0/com.qnx.doc.neutrino.utilities/topic/q/qcc.html) (the QNX C/C++ compiler) -should be available (in the `$PATH` variable). -`qcc` will be called e.g. for linking executables. - -[QNX Software Development Platform (SDP)]: https://qnx.software/en/software/products-and-solutions/qnx-software-development-platform - -When linking `no_std` applications, they must link against `libc.so` (see example). This is -required because applications always link against the `crt` library and `crt` depends on `libc.so`. -This is done automatically when using the standard library. +| `i686-pc-nto-qnx700` | QNX SDP 7.0 | x86 | - | ✓ | -### Disabling RELocation Read-Only (RELRO) +* QNX SDP 7.0 only offers the `io-pkt` network stack +* QNX SDP 7.1 uses the `io-pkt` network stack by default, but also includes the optional `io-sock` network stack +* QNX SDP 8.0 only offers the `io-sock` network stack -While not recommended by default, some QNX kernel setups may require the `RELRO` to be disabled with `-C relro_level=off`, e.g. by adding it to the `.cargo/config.toml` file: +In the table above, 'full support' indicates support for building Rust +applications with the full standard library. A '?' means that support is +in-progress. `no_std` support is for building `#![no_std]` applications where +only `core` and `alloc` are available. -```toml -[target.aarch64-unknown-nto-qnx700] -rustflags = ["-C", "relro_level=off"] -``` +For building or using the Rust toolchain for QNX, the relevant version of the +[QNX Software Development Platform (SDP)] must be installed and initialized. +Initialization is usually done by sourcing `qnxsdp-env.sh` (this will be +installed as part of the SDP, so see the installation instruction provided with +the SDP). Afterwards [`qcc`] (the QNX C/C++ compiler) should be available in +your system PATH because it will be called during Rust compilation (e.g. for +linking executables). -If your QNX kernel does not allow it, and `relro` is not disabled, running compiled binary would fail with `syntax error: ... unexpected` or similar. This is due to kernel trying to interpret compiled binary with `/bin/sh`, and obviously failing. To verify that this is really the case, run your binary with the `DL_DEBUG=all` env var, and look for this output. If you see it, you should disable `relro` as described above. +[`qcc`]: https://www.qnx.com/developers/docs/8.0/com.qnx.doc.neutrino.utilities/topic/q/qcc.html -```text -Resolution scope for Executable->/bin/sh: - Executable->/bin/sh - libc.so.4->/usr/lib/ldqnx-64.so.2 -``` +When linking `no_std` applications, they must link against `libc.so` (see +example). This is required because applications always link against the `crt` +library and `crt` depends on `libc.so`. This is done automatically when using +the standard library. ## Conditional compilation @@ -127,18 +128,37 @@ For conditional compilation, the following QNX specific attributes are defined: rustc library/core library/alloc library/std ``` +## Building Rust programs + +Rust does not ship pre-compiled artifacts for this target. To compile for this +target, you must either build Rust with the target enabled (see "Building the +target" above), or build your own copy of `core` by using `build-std` or +similar. + +Compiled executables can run directly on QNX, either by including them in the +disk image, or copying them over the network to a running system. + +Compiling C code requires the same environment variables to be set as compiling +the Rust toolchain (see above), to ensure `qcc` is used with proper arguments. +To ensure compatibility, do not specify any further arguments that for example +change calling conventions or memory layout. + ## Running the Rust test suite -The test suites of the Rust compiler and standard library can be executed much like other Rust targets. -The environment for testing should match the one used during compiler compilation (refer to `build_env` and `qcc`/`PATH` above) with the -addition of the TEST_DEVICE_ADDR environment variable. -The TEST_DEVICE_ADDR variable controls the remote runner and should point to the target, despite localhost being shown in the following example. -Note that some tests are failing which is why they are currently excluded by the target maintainers which can be seen in the following example. +The test suites of the Rust compiler and standard library can be executed much +like other Rust targets. The environment for testing should match the one used +during compiler compilation (refer to `build_env` and `qcc`/`PATH` above) with +the addition of the `TEST_DEVICE_ADDR` environment variable. The +`TEST_DEVICE_ADDR` variable controls the remote runner and should point to a +target running the `remote-test-server` executable. + +Note that some tests are failing which is why they are currently excluded by the +target maintainers which can be seen in the following example. To run all tests on a x86_64 QNX Neutrino 7.1 target: ```bash -export TEST_DEVICE_ADDR="localhost:12345" # must address the test target, can be a SSH tunnel +export TEST_DEVICE_ADDR="1.2.3.4:12345" # must address the test target, can be a SSH tunnel export build_env= # Disable tests that only work on the host or don't make sense for this target. @@ -161,16 +181,6 @@ env $build_env \ --target x86_64-pc-nto-qnx710 ``` -## Building Rust programs - -Rust does not ship pre-compiled artifacts for this target. -To compile for this target, you must either build Rust with the target enabled (see "Building the target" above), -or build your own copy of `core` by using `build-std` or similar. - -## Testing - -Compiled executables can run directly on QNX. - ### Rust std library test suite The target needs sufficient resources to execute all tests. The commands below assume that a QEMU image @@ -230,8 +240,26 @@ is used. 64 bytes from 127.0.0.1: icmp_seq=0 ttl=255 time=1 ms ``` -## Cross-compilation toolchains and C code +## Disabling RELocation Read-Only (RELRO) -Compiling C code requires the same environment variables to be set as compiling the Rust toolchain (see above), -to ensure `qcc` is used with proper arguments. -To ensure compatibility, do not specify any further arguments that for example change calling conventions or memory layout. +While not recommended by default, some QNX kernel setups may require the `RELRO` +to be disabled with `-C relro_level=off`, e.g. by adding it to the +`.cargo/config.toml` file: + +```toml +[target.aarch64-unknown-nto-qnx700] +rustflags = ["-C", "relro_level=off"] +``` + +If your QNX kernel does not allow it, and `relro` is not disabled, running +compiled binary would fail with `syntax error: ... unexpected` or similar. This +is due to kernel trying to interpret compiled binary with `/bin/sh`, and +obviously failing. To verify that this is really the case, run your binary with +the `DL_DEBUG=all` env var, and look for this output. If you see it, you should +disable `relro` as described above. + +```text +Resolution scope for Executable->/bin/sh: + Executable->/bin/sh + libc.so.4->/usr/lib/ldqnx-64.so.2 +``` From c4e673690afb1745533530326be5a0f710300fc5 Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Mon, 29 Jun 2026 10:18:47 +0000 Subject: [PATCH 09/15] Use /latest not /8.0 for URL on nto-qnx.md --- src/doc/rustc/src/platform-support/nto-qnx.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 045655644fa7d..d187bda376188 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -57,7 +57,7 @@ the SDP). Afterwards [`qcc`] (the QNX C/C++ compiler) should be available in your system PATH because it will be called during Rust compilation (e.g. for linking executables). -[`qcc`]: https://www.qnx.com/developers/docs/8.0/com.qnx.doc.neutrino.utilities/topic/q/qcc.html +[`qcc`]: https://www.qnx.com/developers/docs/latest/com.qnx.doc.neutrino.utilities/topic/q/qcc.html When linking `no_std` applications, they must link against `libc.so` (see example). This is required because applications always link against the `crt` From c6349f47a7ddcf61943ee5cac0f9776e8d56122a Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Mon, 29 Jun 2026 11:16:51 +0000 Subject: [PATCH 10/15] Fixup cfg ordering Just in case we were deliberately pairing up these OSes --- library/std/src/sys/net/connection/socket/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/net/connection/socket/mod.rs b/library/std/src/sys/net/connection/socket/mod.rs index da25cff1d5444..66aa2a804db22 100644 --- a/library/std/src/sys/net/connection/socket/mod.rs +++ b/library/std/src/sys/net/connection/socket/mod.rs @@ -66,8 +66,9 @@ cfg_select! { target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", target_os = "solaris", target_os = "illumos", - target_os = "haiku", target_os = "nto", - target_os = "qnx", target_os = "cygwin", + target_os = "haiku", + target_os = "nto", target_os = "qnx", + target_os = "cygwin", ) => { use libc::MSG_NOSIGNAL; } From bd2bd8417dcb69572344683f80b0f04ec3986daf Mon Sep 17 00:00:00 2001 From: Jonathan Pallant Date: Tue, 30 Jun 2026 08:17:24 +0000 Subject: [PATCH 11/15] Grammar nit in nto-qnx.md --- src/doc/rustc/src/platform-support/nto-qnx.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index d187bda376188..b3ab1c7c4485b 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -251,9 +251,9 @@ to be disabled with `-C relro_level=off`, e.g. by adding it to the rustflags = ["-C", "relro_level=off"] ``` -If your QNX kernel does not allow it, and `relro` is not disabled, running +If your QNX kernel does not allow it, and `relro` is not disabled, running the compiled binary would fail with `syntax error: ... unexpected` or similar. This -is due to kernel trying to interpret compiled binary with `/bin/sh`, and +is due to kernel trying to interpret the compiled binary with `/bin/sh`, and obviously failing. To verify that this is really the case, run your binary with the `DL_DEBUG=all` env var, and look for this output. If you see it, you should disable `relro` as described above. From 6fdb77631e5d38a531d74e9b71362788abdc97b4 Mon Sep 17 00:00:00 2001 From: kn1g78 Date: Tue, 30 Jun 2026 18:42:13 +0800 Subject: [PATCH 12/15] Reject duplicate codegen backends in bootstrap config --- src/bootstrap/src/core/config/tests.rs | 22 ++++++---------------- src/bootstrap/src/core/config/toml/rust.rs | 6 +++++- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index 3f8a7262b8e23..1e64232e7d6d9 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -22,7 +22,7 @@ use crate::core::config::{ }; use crate::utils::tests::TestCtx; use crate::utils::tests::git::git_test; -use crate::{ChangeId, CodegenBackendKind}; +use crate::ChangeId; pub(crate) fn parse(config: &str) -> Config { TestCtx::new().config("check").with_default_toml_config(config).create_config() @@ -208,21 +208,11 @@ fn rust_optimize() { } #[test] -fn deduplicates_codegen_backends() { - assert_eq!( - parse_codegen_backends( - vec!["llvm", "llvm", "cranelift", "llvm"].into_iter().map(str::to_owned).collect(), - "rust", - ), - [CodegenBackendKind::Llvm, CodegenBackendKind::Cranelift] - ); - - assert_eq!( - parse_codegen_backends( - vec!["cranelift", "llvm", "cranelift"].into_iter().map(str::to_owned).collect(), - "target.x86_64-unknown-linux-gnu", - ), - [CodegenBackendKind::Cranelift, CodegenBackendKind::Llvm] +#[should_panic(expected = "Duplicate value 'llvm' for 'rust.codegen-backends'")] +fn rejects_duplicate_codegen_backends() { + parse_codegen_backends( + vec!["llvm", "llvm", "cranelift"].into_iter().map(str::to_owned).collect(), + "rust", ); } diff --git a/src/bootstrap/src/core/config/toml/rust.rs b/src/bootstrap/src/core/config/toml/rust.rs index 3d423e22a01d2..d2d629e969f6c 100644 --- a/src/bootstrap/src/core/config/toml/rust.rs +++ b/src/bootstrap/src/core/config/toml/rust.rs @@ -430,7 +430,11 @@ pub(crate) fn parse_codegen_backends( }; if found_backends.contains(&backend) { - continue; + panic!( + "Duplicate value '{}' for '{section}.codegen-backends'. \ + Each codegen backend should only be specified once.", + backend.name() + ); } if !BUILTIN_CODEGEN_BACKENDS.contains(&backend.name()) { From 1d4010fdece3482a72eb0c5cd9eb560c3ea03926 Mon Sep 17 00:00:00 2001 From: kn1g78 Date: Tue, 30 Jun 2026 18:56:54 +0800 Subject: [PATCH 13/15] Fix bootstrap config import order --- src/bootstrap/src/core/config/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index 1e64232e7d6d9..89046c0eee779 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -13,6 +13,7 @@ use super::flags::Flags; use super::toml::change_id::ChangeIdWrapper; use super::toml::rust::parse_codegen_backends; use super::{Config, RUSTC_IF_UNCHANGED_ALLOWED_PATHS}; +use crate::ChangeId; use crate::core::build_steps::clippy::{LintConfig, get_clippy_rules_in_order}; use crate::core::build_steps::llvm::LLVM_INVALIDATION_PATHS; use crate::core::build_steps::{llvm, test}; @@ -22,7 +23,6 @@ use crate::core::config::{ }; use crate::utils::tests::TestCtx; use crate::utils::tests::git::git_test; -use crate::ChangeId; pub(crate) fn parse(config: &str) -> Config { TestCtx::new().config("check").with_default_toml_config(config).create_config() From 464fb78b15782ca976709f28bcf671ac16f769a3 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Thu, 18 Jun 2026 00:30:28 +0900 Subject: [PATCH 14/15] Do not increase depth when evaluating nested goals of normalizes-to --- .../src/solve/eval_ctxt/mod.rs | 10 ++-- .../src/solve/project_goals/mod.rs | 15 +++++- .../rustc_type_ir/src/search_graph/mod.rs | 51 ++++++++++++++----- .../rustc_type_ir/src/search_graph/stack.rs | 25 +++++++-- 4 files changed, 80 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index fe573025c87f4..5e1d202f8f994 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -8,7 +8,7 @@ use rustc_type_ir::inherent::*; use rustc_type_ir::region_constraint::RegionConstraint; use rustc_type_ir::relate::Relate; use rustc_type_ir::relate::solver_relating::RelateExt; -use rustc_type_ir::search_graph::{CandidateHeadUsages, PathKind}; +use rustc_type_ir::search_graph::{CandidateHeadUsages, IncreaseDepthForNested, PathKind}; use rustc_type_ir::solve::{ AccessedOpaques, ExternalRegionConstraints, FetchEligibleAssocItemResponse, MaybeInfo, NoSolutionOrRerunNonErased, OpaqueTypesJank, QueryResultOrRerunNonErased, RerunCondition, @@ -484,7 +484,7 @@ where stalled_on: Option>, ) -> Result, NoSolutionOrRerunNonErased> { let (normalization_nested_goals, goal_evaluation) = - self.evaluate_goal_raw(source, goal, stalled_on)?; + self.evaluate_goal_raw(source, goal, stalled_on, IncreaseDepthForNested::Yes)?; assert!(normalization_nested_goals.is_empty()); Ok(goal_evaluation) } @@ -576,6 +576,7 @@ where source: GoalSource, goal: Goal, stalled_on: Option>, + increase_depth_for_nested: IncreaseDepthForNested, ) -> Result<(NestedNormalizationGoals, GoalEvaluation), NoSolutionOrRerunNonErased> { if let RerunStalled::WontMakeProgress(stalled_certainty) = self.rerunning_stalled_goal_may_make_progress(stalled_on.as_ref()) @@ -591,7 +592,7 @@ where )); } - self.evaluate_goal_cold(source, goal) + self.evaluate_goal_cold(source, goal, increase_depth_for_nested) } #[cold] @@ -600,6 +601,7 @@ where &mut self, source: GoalSource, goal: Goal, + increase_depth_for_nested: IncreaseDepthForNested, ) -> Result<(NestedNormalizationGoals, GoalEvaluation), NoSolutionOrRerunNonErased> { // We only care about one entry per `OpaqueTypeKey` here, // so we only canonicalize the lookup table and ignore @@ -663,6 +665,7 @@ where self.cx(), canonical_goal, step_kind, + increase_depth_for_nested, &mut inspect::ProofTreeBuilder::new_noop(), ); @@ -702,6 +705,7 @@ where self.cx(), canonical_goal, step_kind, + increase_depth_for_nested, &mut inspect::ProofTreeBuilder::new_noop(), ); assert!( diff --git a/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs b/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs index e084ae077b561..21cfa0561dd8b 100644 --- a/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/project_goals/mod.rs @@ -3,6 +3,7 @@ mod free_alias; mod inherent; mod opaque_types; +use rustc_type_ir::search_graph::IncreaseDepthForNested; use rustc_type_ir::solve::QueryResultOrRerunNonErased; use rustc_type_ir::{self as ty, Interner, ProjectionPredicate}; use tracing::{instrument, trace}; @@ -67,7 +68,19 @@ where let ( NestedNormalizationGoals(nested_goals), GoalEvaluation { goal: _, certainty, stalled_on: _, has_changed: _ }, - ) = self.evaluate_goal_raw(GoalSource::TypeRelating, normalizes_to, None)?; + ) = self.evaluate_goal_raw( + GoalSource::TypeRelating, + normalizes_to, + None, + // We don't increase depth for nested goals for this `NormalizesTo` goal, as + // evaluating `NormalizesTo` is an extra step only exists in the new solver + // that behaves like a function call rather than an independent nested goal + // evaluation, so increasing the depth may end up regressions which hit the + // recursion limits for crates compiled well with the old solver. Furthermore, + // those nested goals from `NormalizesTo` will be evaluated again as the + // caller's nested goals with increased depths anyway. + IncreaseDepthForNested::No, + )?; trace!(?nested_goals); diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs index 3a962b3832aa3..a42ed8795e127 100644 --- a/compiler/rustc_type_ir/src/search_graph/mod.rs +++ b/compiler/rustc_type_ir/src/search_graph/mod.rs @@ -263,6 +263,12 @@ impl CandidateHeadUsages { } #[derive(Debug, Clone, Copy)] +pub enum IncreaseDepthForNested { + Yes, + No, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] struct AvailableDepth(usize); impl AvailableDepth { /// Returns the remaining depth allowed for nested goals. @@ -276,6 +282,13 @@ impl AvailableDepth { stack: &Stack, ) -> Option { if let Some(last) = stack.last() { + match last.increase_depth_for_nested { + IncreaseDepthForNested::Yes => {} + IncreaseDepthForNested::No => { + return Some(last.available_depth); + } + } + if last.available_depth.0 == 0 { return None; } @@ -566,7 +579,7 @@ impl EvaluationResult { encountered_overflow, // Unlike `encountered_overflow`, we share `heads`, `required_depth`, // and `nested_goals` between evaluations. - required_depth: final_entry.required_depth, + required_depth: final_entry.required_depth(), heads: final_entry.heads, nested_goals: final_entry.nested_goals, // We only care about the final result. @@ -597,7 +610,7 @@ pub struct SearchGraph, X: Cx = ::Cx> { /// don't need to track the nested goals used while computing a provisional /// cache entry. enum UpdateParentGoalCtxt<'a, X: Cx> { - Ordinary(&'a NestedGoals), + Ordinary { nested_goals: &'a NestedGoals, min_reachable_available_depth: AvailableDepth }, CycleOnStack(X::Input), ProvisionalCacheHit, } @@ -619,13 +632,11 @@ impl, X: Cx> SearchGraph { fn update_parent_goal( stack: &mut Stack, step_kind_from_parent: PathKind, - required_depth_for_nested: usize, heads: impl Iterator, encountered_overflow: bool, context: UpdateParentGoalCtxt<'_, X>, ) { if let Some((parent_index, parent)) = stack.last_mut_with_index() { - parent.required_depth = parent.required_depth.max(required_depth_for_nested + 1); parent.encountered_overflow |= encountered_overflow; for (head_index, head) in heads { @@ -650,7 +661,9 @@ impl, X: Cx> SearchGraph { } } let parent_depends_on_cycle = match context { - UpdateParentGoalCtxt::Ordinary(nested_goals) => { + UpdateParentGoalCtxt::Ordinary { nested_goals, min_reachable_available_depth } => { + parent.min_reached_available_depth = + parent.min_reached_available_depth.min(min_reachable_available_depth); parent.nested_goals.extend_from_child(step_kind_from_parent, nested_goals); !nested_goals.is_empty() } @@ -739,8 +752,9 @@ impl, X: Cx> SearchGraph { input, step_kind_from_parent, available_depth, + min_reached_available_depth: available_depth, provisional_result: None, - required_depth: 0, + increase_depth_for_nested: IncreaseDepthForNested::Yes, heads: Default::default(), encountered_overflow: false, usages: None, @@ -761,6 +775,7 @@ impl, X: Cx> SearchGraph { cx: X, input: X::Input, step_kind_from_parent: PathKind, + increase_depth_for_nested: IncreaseDepthForNested, inspect: &mut D::ProofTreeBuilder, ) -> X::Result { let Some(available_depth) = @@ -816,7 +831,8 @@ impl, X: Cx> SearchGraph { step_kind_from_parent, available_depth, provisional_result: None, - required_depth: 0, + min_reached_available_depth: available_depth, + increase_depth_for_nested, heads: Default::default(), encountered_overflow: false, usages: None, @@ -838,10 +854,14 @@ impl, X: Cx> SearchGraph { Self::update_parent_goal( &mut self.stack, step_kind_from_parent, - evaluation_result.required_depth, evaluation_result.heads.iter(), evaluation_result.encountered_overflow, - UpdateParentGoalCtxt::Ordinary(&evaluation_result.nested_goals), + UpdateParentGoalCtxt::Ordinary { + nested_goals: &evaluation_result.nested_goals, + min_reachable_available_depth: AvailableDepth( + available_depth.0 - evaluation_result.required_depth, + ), + }, ); let result = evaluation_result.result; @@ -1116,7 +1136,6 @@ impl, X: Cx> SearchGraph { Self::update_parent_goal( &mut self.stack, step_kind_from_parent, - 0, heads.iter(), encountered_overflow, UpdateParentGoalCtxt::ProvisionalCacheHit, @@ -1239,10 +1258,14 @@ impl, X: Cx> SearchGraph { Self::update_parent_goal( &mut self.stack, step_kind_from_parent, - required_depth, heads, encountered_overflow, - UpdateParentGoalCtxt::Ordinary(nested_goals), + UpdateParentGoalCtxt::Ordinary { + nested_goals, + min_reachable_available_depth: AvailableDepth( + available_depth.0 - required_depth, + ), + }, ); debug!(?required_depth, "global cache hit"); @@ -1271,7 +1294,6 @@ impl, X: Cx> SearchGraph { Self::update_parent_goal( &mut self.stack, step_kind_from_parent, - 0, iter::once((head_index, head)), false, UpdateParentGoalCtxt::CycleOnStack(input), @@ -1407,7 +1429,8 @@ impl, X: Cx> SearchGraph { provisional_result: Some(result), // We can keep these goals from previous iterations as they are only // ever read after finalizing this evaluation. - required_depth: stack_entry.required_depth, + min_reached_available_depth: stack_entry.min_reached_available_depth, + increase_depth_for_nested: stack_entry.increase_depth_for_nested, heads: stack_entry.heads, nested_goals: stack_entry.nested_goals, // We reset these two fields when rerunning this goal. We could diff --git a/compiler/rustc_type_ir/src/search_graph/stack.rs b/compiler/rustc_type_ir/src/search_graph/stack.rs index 8348666be412d..776ab28f9fcdc 100644 --- a/compiler/rustc_type_ir/src/search_graph/stack.rs +++ b/compiler/rustc_type_ir/src/search_graph/stack.rs @@ -4,7 +4,8 @@ use derive_where::derive_where; use rustc_index::IndexVec; use crate::search_graph::{ - AvailableDepth, CandidateHeadUsages, Cx, CycleHeads, HeadUsages, NestedGoals, PathKind, + AvailableDepth, CandidateHeadUsages, Cx, CycleHeads, HeadUsages, IncreaseDepthForNested, + NestedGoals, PathKind, }; rustc_index::newtype_index! { @@ -28,8 +29,20 @@ pub(super) struct StackEntry { /// The available depth of a given goal, immutable. pub available_depth: AvailableDepth, - /// The maximum depth required while evaluating this goal. - pub required_depth: usize, + /// The minimum available depth encountered while evaluating this goal's nested goals. + /// If there's no nested goal, this is equal to the `available_depth`. + pub min_reached_available_depth: AvailableDepth, + + /// Whether evaluating nested goals of a given goal should increase the depth. + /// + /// Normally, it should be `Yes`, but among rustc's predicate goals, `normalizes-to` + /// goals are exceptions. They act like functions that used for normalizing associated + /// terms while evaluating projection goals and since their expected terms are always fully + /// unconstrained intentionally, they often return ambiguous nested goals to the caller's + /// context. As these nested goals are evaluated again in the caller's context, we don't + /// want to increase depths when they are evaluated as nested goals for `normalizes-to` + /// goals, otherwise we will encounter recursion limit overflows more often. + pub increase_depth_for_nested: IncreaseDepthForNested, /// Starts out as `None` and gets set when rerunning this /// goal in case we encounter a cycle. @@ -57,6 +70,12 @@ pub(super) struct StackEntry { pub nested_goals: NestedGoals, } +impl StackEntry { + pub(super) fn required_depth(&self) -> usize { + self.available_depth.0 - self.min_reached_available_depth.0 + } +} + /// The stack of goals currently being computed. /// /// An element is *deeper* in the stack if its index is *lower*. From 7624799cad13d5d34f4df774b27ebddc881173e8 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 30 Jun 2026 18:06:46 -0700 Subject: [PATCH 15/15] linkchecker: upgrade to `html5ever v0.39` No code changes required, and this cleans up recursive dependencies too. --- Cargo.lock | 109 +++++++++++++------------------ src/tools/linkchecker/Cargo.toml | 2 +- 2 files changed, 45 insertions(+), 66 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8dfdd7cae290..b76715ba1457c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1556,16 +1556,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" -[[package]] -name = "futf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" -dependencies = [ - "mac", - "new_debug_unreachable", -] - [[package]] name = "generate-copyright" version = "0.1.0" @@ -1791,14 +1781,12 @@ dependencies = [ [[package]] name = "html5ever" -version = "0.29.1" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c" +checksum = "46a1761807faccc9a19e86944bbf40610014066306f96edcdedc2fb714bcb7b8" dependencies = [ "log", - "mac", "markup5ever", - "match_token", ] [[package]] @@ -2424,35 +2412,15 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "mac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" - [[package]] name = "markup5ever" -version = "0.14.1" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18" +checksum = "7122d987ec5f704ee56f6e5b41a7d93722e9aae27ae07cafa4036c4d3f9757de" dependencies = [ "log", - "phf 0.11.3", - "phf_codegen", - "string_cache", - "string_cache_codegen", "tendril", -] - -[[package]] -name = "match_token" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "web_atoms", ] [[package]] @@ -2986,56 +2954,57 @@ dependencies = [ [[package]] name = "phf" -version = "0.11.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" dependencies = [ - "phf_shared 0.11.3", + "phf_shared 0.12.1", ] [[package]] name = "phf" -version = "0.12.1" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ - "phf_shared 0.12.1", + "phf_shared 0.13.1", + "serde", ] [[package]] name = "phf_codegen" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1" dependencies = [ "phf_generator", - "phf_shared 0.11.3", + "phf_shared 0.13.1", ] [[package]] name = "phf_generator" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" dependencies = [ - "phf_shared 0.11.3", - "rand 0.8.5", + "fastrand", + "phf_shared 0.13.1", ] [[package]] name = "phf_shared" -version = "0.11.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" dependencies = [ "siphasher", ] [[package]] name = "phf_shared" -version = "0.12.1" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" dependencies = [ "siphasher", ] @@ -5426,25 +5395,24 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "string_cache" -version = "0.8.9" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901" dependencies = [ "new_debug_unreachable", "parking_lot", - "phf_shared 0.11.3", + "phf_shared 0.13.1", "precomputed-hash", - "serde", ] [[package]] name = "string_cache_codegen" -version = "0.5.4" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" +checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69" dependencies = [ "phf_generator", - "phf_shared 0.11.3", + "phf_shared 0.13.1", "proc-macro2", "quote", ] @@ -5534,12 +5502,11 @@ dependencies = [ [[package]] name = "tendril" -version = "0.4.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +checksum = "c4790fc369d5a530f4b544b094e31388b9b3a37c0f4652ade4505945f5660d24" dependencies = [ - "futf", - "mac", + "new_debug_unreachable", "utf-8", ] @@ -6504,6 +6471,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web_atoms" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "075474b12bcb3d2e3d4546580e9de478eeeead668a1761e2a8860c836b7ef297" +dependencies = [ + "phf 0.13.1", + "phf_codegen", + "string_cache", + "string_cache_codegen", +] + [[package]] name = "winapi-util" version = "0.1.11" diff --git a/src/tools/linkchecker/Cargo.toml b/src/tools/linkchecker/Cargo.toml index f0886e31b243f..0950122a1710f 100644 --- a/src/tools/linkchecker/Cargo.toml +++ b/src/tools/linkchecker/Cargo.toml @@ -9,5 +9,5 @@ path = "main.rs" [dependencies] regex = "1" -html5ever = "0.29.0" +html5ever = "0.39.0" urlencoding = "2.1.3"