1
Fork 0

Auto merge of #130816 - matthiaskrgr:rollup-jy25phv, r=matthiaskrgr

Rollup of 6 pull requests

Successful merges:

 - #130549 (Add RISC-V vxworks targets)
 - #130595 (Initial std library support for NuttX)
 - #130734 (Fix: ices on virtual-function-elimination about principal trait)
 - #130787 (Ban combination of GCE and new solver)
 - #130809 (Update llvm triple for OpenHarmony targets)
 - #130810 (Don't trap into the debugger on panics under Linux)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-09-25 08:43:14 +00:00
commit 2933f68abe
50 changed files with 420 additions and 175 deletions

View file

@ -4,9 +4,9 @@ use rustc_ast::{NodeId, PatKind, attr, token};
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Features, GateIssue};
use rustc_session::Session;
use rustc_session::parse::{feature_err, feature_err_issue, feature_warn};
use rustc_span::Span;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol};
use rustc_target::spec::abi;
use thin_vec::ThinVec;
@ -483,6 +483,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
maybe_stage_features(sess, features, krate);
check_incompatible_features(sess, features);
check_new_solver_banned_features(sess, features);
let mut visitor = PostExpansionVisitor { sess, features };
let spans = sess.psess.gated_spans.spans.borrow();
@ -662,3 +664,22 @@ fn check_incompatible_features(sess: &Session, features: &Features) {
}
}
}
fn check_new_solver_banned_features(sess: &Session, features: &Features) {
if !sess.opts.unstable_opts.next_solver.is_some_and(|n| n.globally) {
return;
}
// Ban GCE with the new solver, because it does not implement GCE correctly.
if let Some(&(_, gce_span, _)) = features
.declared_lang_features
.iter()
.find(|&&(feat, _, _)| feat == sym::generic_const_exprs)
{
sess.dcx().emit_err(errors::IncompatibleFeatures {
spans: vec![gce_span],
f1: Symbol::intern("-Znext-solver=globally"),
f2: sym::generic_const_exprs,
});
}
}

View file

@ -37,6 +37,7 @@ use crate::back::write::{
submit_codegened_module_to_llvm, submit_post_lto_module_to_llvm, submit_pre_lto_module_to_llvm,
};
use crate::common::{self, IntPredicate, RealPredicate, TypeKind};
use crate::meth::load_vtable;
use crate::mir::operand::OperandValue;
use crate::mir::place::PlaceRef;
use crate::traits::*;
@ -135,14 +136,8 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
if let Some(entry_idx) = vptr_entry_idx {
let ptr_size = bx.data_layout().pointer_size;
let ptr_align = bx.data_layout().pointer_align.abi;
let vtable_byte_offset = u64::try_from(entry_idx).unwrap() * ptr_size.bytes();
let gep = bx.inbounds_ptradd(old_info, bx.const_usize(vtable_byte_offset));
let new_vptr = bx.load(bx.type_ptr(), gep, ptr_align);
bx.nonnull_metadata(new_vptr);
// VTable loads are invariant.
bx.set_invariant_load(new_vptr);
new_vptr
load_vtable(bx, old_info, bx.type_ptr(), vtable_byte_offset, source, true)
} else {
old_info
}

View file

@ -28,27 +28,9 @@ impl<'a, 'tcx> VirtualIndex {
let llty = bx.fn_ptr_backend_type(fn_abi);
let ptr_size = bx.data_layout().pointer_size;
let ptr_align = bx.data_layout().pointer_align.abi;
let vtable_byte_offset = self.0 * ptr_size.bytes();
if bx.cx().sess().opts.unstable_opts.virtual_function_elimination
&& bx.cx().sess().lto() == Lto::Fat
{
let typeid = bx
.typeid_metadata(typeid_for_trait_ref(bx.tcx(), expect_dyn_trait_in_self(ty)))
.unwrap();
let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid);
func
} else {
let gep = bx.inbounds_ptradd(llvtable, bx.const_usize(vtable_byte_offset));
let ptr = bx.load(llty, gep, ptr_align);
// VTable loads are invariant.
bx.set_invariant_load(ptr);
if nonnull {
bx.nonnull_metadata(ptr);
}
ptr
}
load_vtable(bx, llvtable, llty, vtable_byte_offset, ty, nonnull)
}
pub(crate) fn get_optional_fn<Bx: BuilderMethods<'a, 'tcx>>(
@ -75,31 +57,27 @@ impl<'a, 'tcx> VirtualIndex {
self,
bx: &mut Bx,
llvtable: Bx::Value,
ty: Ty<'tcx>,
) -> Bx::Value {
// Load the data pointer from the object.
debug!("get_int({:?}, {:?})", llvtable, self);
let llty = bx.type_isize();
let ptr_size = bx.data_layout().pointer_size;
let ptr_align = bx.data_layout().pointer_align.abi;
let vtable_byte_offset = self.0 * ptr_size.bytes();
let gep = bx.inbounds_ptradd(llvtable, bx.const_usize(vtable_byte_offset));
let ptr = bx.load(llty, gep, ptr_align);
// VTable loads are invariant.
bx.set_invariant_load(ptr);
ptr
load_vtable(bx, llvtable, llty, vtable_byte_offset, ty, false)
}
}
/// This takes a valid `self` receiver type and extracts the principal trait
/// ref of the type.
fn expect_dyn_trait_in_self(ty: Ty<'_>) -> ty::PolyExistentialTraitRef<'_> {
/// ref of the type. Return `None` if there is no principal trait.
fn dyn_trait_in_self(ty: Ty<'_>) -> Option<ty::PolyExistentialTraitRef<'_>> {
for arg in ty.peel_refs().walk() {
if let GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Dynamic(data, _, _) = ty.kind()
{
return data.principal().expect("expected principal trait object");
return data.principal();
}
}
@ -138,3 +116,36 @@ pub(crate) fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
cx.vtables().borrow_mut().insert((ty, trait_ref), vtable);
vtable
}
/// Call this function whenever you need to load a vtable.
pub(crate) fn load_vtable<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx: &mut Bx,
llvtable: Bx::Value,
llty: Bx::Type,
vtable_byte_offset: u64,
ty: Ty<'tcx>,
nonnull: bool,
) -> Bx::Value {
let ptr_align = bx.data_layout().pointer_align.abi;
if bx.cx().sess().opts.unstable_opts.virtual_function_elimination
&& bx.cx().sess().lto() == Lto::Fat
{
if let Some(trait_ref) = dyn_trait_in_self(ty) {
let typeid = bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), trait_ref)).unwrap();
let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid);
return func;
} else if nonnull {
bug!("load nonnull value from a vtable without a principal trait")
}
}
let gep = bx.inbounds_ptradd(llvtable, bx.const_usize(vtable_byte_offset));
let ptr = bx.load(llty, gep, ptr_align);
// VTable loads are invariant.
bx.set_invariant_load(ptr);
if nonnull {
bx.nonnull_metadata(ptr);
}
ptr
}

View file

@ -126,7 +126,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
sym::vtable_align => ty::COMMON_VTABLE_ENTRIES_ALIGN,
_ => bug!(),
};
let value = meth::VirtualIndex::from_index(idx).get_usize(bx, vtable);
let value = meth::VirtualIndex::from_index(idx).get_usize(bx, vtable, callee_ty);
match name {
// Size is always <= isize::MAX.
sym::vtable_size => {

View file

@ -28,9 +28,9 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// Load size/align from vtable.
let vtable = info.unwrap();
let size = meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_SIZE)
.get_usize(bx, vtable);
.get_usize(bx, vtable, t);
let align = meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_ALIGN)
.get_usize(bx, vtable);
.get_usize(bx, vtable, t);
// Size is always <= isize::MAX.
let size_bound = bx.data_layout().ptr_sized_integer().signed_max() as u128;

View file

@ -1840,6 +1840,8 @@ supported_targets! {
("powerpc-wrs-vxworks", powerpc_wrs_vxworks),
("powerpc-wrs-vxworks-spe", powerpc_wrs_vxworks_spe),
("powerpc64-wrs-vxworks", powerpc64_wrs_vxworks),
("riscv32-wrs-vxworks", riscv32_wrs_vxworks),
("riscv64-wrs-vxworks", riscv64_wrs_vxworks),
("aarch64-kmc-solid_asp3", aarch64_kmc_solid_asp3),
("armv7a-kmc-solid_asp3-eabi", armv7a_kmc_solid_asp3_eabi),

View file

@ -5,8 +5,7 @@ pub(crate) fn target() -> Target {
base.max_atomic_width = Some(128);
Target {
// LLVM 15 doesn't support OpenHarmony yet, use a linux target instead.
llvm_target: "aarch64-unknown-linux-musl".into(),
llvm_target: "aarch64-unknown-linux-ohos".into(),
metadata: crate::spec::TargetMetadata {
description: Some("ARM64 OpenHarmony".into()),
tier: Some(2),

View file

@ -7,7 +7,7 @@ pub(crate) fn target() -> Target {
description: None,
tier: Some(3),
host_tools: Some(false),
std: None, // ?
std: Some(true),
},
pointer_width: 64,
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),

View file

@ -7,8 +7,7 @@ pub(crate) fn target() -> Target {
// Most of these settings are copied from the armv7_unknown_linux_musleabi
// target.
Target {
// LLVM 15 doesn't support OpenHarmony yet, use a linux target instead.
llvm_target: "armv7-unknown-linux-gnueabi".into(),
llvm_target: "armv7-unknown-linux-ohos".into(),
metadata: crate::spec::TargetMetadata {
description: Some("Armv7-A OpenHarmony".into()),
tier: Some(2),

View file

@ -13,7 +13,7 @@ pub(crate) fn target() -> Target {
description: None,
tier: Some(3),
host_tools: Some(false),
std: None, // ?
std: Some(true),
},
pointer_width: 32,
data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\

View file

@ -2,8 +2,7 @@ use crate::spec::{Target, TargetOptions, base};
pub(crate) fn target() -> Target {
Target {
// LLVM 15 doesn't support OpenHarmony yet, use a linux target instead.
llvm_target: "loongarch64-unknown-linux-musl".into(),
llvm_target: "loongarch64-unknown-linux-ohos".into(),
metadata: crate::spec::TargetMetadata {
description: Some("LoongArch64 OpenHarmony".into()),
tier: Some(3),

View file

@ -14,7 +14,7 @@ pub(crate) fn target() -> Target {
description: None,
tier: Some(3),
host_tools: Some(false),
std: None, // ?
std: Some(true),
},
pointer_width: 64,
data_layout: "E-m:e-Fi64-i64:64-n32:64-S128-v256:256:256-v512:512:512".into(),

View file

@ -13,7 +13,7 @@ pub(crate) fn target() -> Target {
description: None,
tier: Some(3),
host_tools: Some(false),
std: None, // ?
std: Some(true),
},
pointer_width: 32,
data_layout: "E-m:e-p:32:32-Fn32-i64:64-n32".into(),

View file

@ -0,0 +1,24 @@
use crate::spec::{StackProbeType, Target, TargetOptions, base};
pub(crate) fn target() -> Target {
Target {
llvm_target: "riscv32".into(),
metadata: crate::spec::TargetMetadata {
description: None,
tier: Some(3),
host_tools: Some(false),
std: Some(true),
},
pointer_width: 32,
data_layout: "e-m:e-p:32:32-i64:64-n32-S128".into(),
arch: "riscv32".into(),
options: TargetOptions {
cpu: "generic-rv32".into(),
llvm_abiname: "ilp32d".into(),
max_atomic_width: Some(32),
features: "+m,+a,+f,+d,+c".into(),
stack_probes: StackProbeType::Inline,
..base::vxworks::opts()
},
}
}

View file

@ -0,0 +1,24 @@
use crate::spec::{StackProbeType, Target, TargetOptions, base};
pub(crate) fn target() -> Target {
Target {
llvm_target: "riscv64".into(),
metadata: crate::spec::TargetMetadata {
description: None,
tier: Some(3),
host_tools: Some(false),
std: Some(true),
},
pointer_width: 64,
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(),
arch: "riscv64".into(),
options: TargetOptions {
cpu: "generic-rv64".into(),
llvm_abiname: "lp64d".into(),
max_atomic_width: Some(64),
features: "+m,+a,+f,+d,+c".into(),
stack_probes: StackProbeType::Inline,
..base::vxworks::opts()
},
}
}

View file

@ -15,8 +15,7 @@ pub(crate) fn target() -> Target {
base.supports_xray = true;
Target {
// LLVM 15 doesn't support OpenHarmony yet, use a linux target instead.
llvm_target: "x86_64-unknown-linux-musl".into(),
llvm_target: "x86_64-unknown-linux-ohos".into(),
metadata: crate::spec::TargetMetadata {
description: Some("x86_64 OpenHarmony".into()),
tier: Some(2),

View file

@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
description: None,
tier: Some(3),
host_tools: Some(false),
std: None, // ?
std: Some(true),
},
pointer_width: 64,
data_layout:

View file

@ -48,7 +48,7 @@ cfg_if::cfg_if! {
target_os = "psp",
target_os = "xous",
target_os = "solid_asp3",
all(target_family = "unix", not(any(target_os = "espidf", target_os = "rtems"))),
all(target_family = "unix", not(any(target_os = "espidf", target_os = "rtems", target_os = "nuttx"))),
all(target_vendor = "fortanix", target_env = "sgx"),
target_family = "wasm",
))] {

View file

@ -54,6 +54,7 @@ fn main() {
|| target_os == "teeos"
|| target_os == "zkvm"
|| target_os == "rtems"
|| target_os == "nuttx"
// See src/bootstrap/src/core/build_steps/synthetic_targets.rs
|| env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()

View file

@ -139,6 +139,8 @@ pub mod macos;
pub mod netbsd;
#[cfg(target_os = "nto")]
pub mod nto;
#[cfg(target_os = "nuttx")]
pub mod nuttx;
#[cfg(target_os = "openbsd")]
pub mod openbsd;
#[cfg(target_os = "redox")]

View file

@ -0,0 +1,92 @@
#![stable(feature = "metadata_ext", since = "1.1.0")]
use crate::fs::Metadata;
use crate::sys_common::AsInner;
#[stable(feature = "metadata_ext", since = "1.1.0")]
pub trait MetadataExt {
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_dev(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ino(&self) -> u64;
#[stable(feature = "metadata_ext", since = "1.1.0")]
fn st_mode(&self) -> u32;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_nlink(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_uid(&self) -> u32;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_gid(&self) -> u32;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_rdev(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_size(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_atime(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_atime_nsec(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_mtime(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_mtime_nsec(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ctime(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ctime_nsec(&self) -> i64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_blksize(&self) -> u64;
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_blocks(&self) -> u64;
}
#[stable(feature = "metadata_ext", since = "1.1.0")]
impl MetadataExt for Metadata {
fn st_dev(&self) -> u64 {
self.as_inner().as_inner().st_dev as u64
}
fn st_ino(&self) -> u64 {
self.as_inner().as_inner().st_ino as u64
}
fn st_mode(&self) -> u32 {
self.as_inner().as_inner().st_mode as u32
}
fn st_nlink(&self) -> u64 {
self.as_inner().as_inner().st_nlink as u64
}
fn st_uid(&self) -> u32 {
self.as_inner().as_inner().st_uid as u32
}
fn st_gid(&self) -> u32 {
self.as_inner().as_inner().st_gid as u32
}
fn st_rdev(&self) -> u64 {
self.as_inner().as_inner().st_rdev as u64
}
fn st_size(&self) -> u64 {
self.as_inner().as_inner().st_size as u64
}
fn st_atime(&self) -> i64 {
self.as_inner().as_inner().st_atim.tv_sec as i64
}
fn st_atime_nsec(&self) -> i64 {
self.as_inner().as_inner().st_atim.tv_nsec as i64
}
fn st_mtime(&self) -> i64 {
self.as_inner().as_inner().st_mtim.tv_sec as i64
}
fn st_mtime_nsec(&self) -> i64 {
self.as_inner().as_inner().st_mtim.tv_nsec as i64
}
fn st_ctime(&self) -> i64 {
self.as_inner().as_inner().st_ctim.tv_sec as i64
}
fn st_ctime_nsec(&self) -> i64 {
self.as_inner().as_inner().st_ctim.tv_nsec as i64
}
fn st_blksize(&self) -> u64 {
self.as_inner().as_inner().st_blksize as u64
}
fn st_blocks(&self) -> u64 {
self.as_inner().as_inner().st_blocks as u64
}
}

View file

@ -0,0 +1,4 @@
#![stable(feature = "raw_ext", since = "1.1.0")]
#![forbid(unsafe_op_in_unsafe_fn)]
pub mod fs;
pub(crate) mod raw;

View file

@ -0,0 +1,33 @@
//! rtems raw type definitions
#![stable(feature = "raw_ext", since = "1.1.0")]
#![deprecated(
since = "1.8.0",
note = "these type aliases are no longer supported by \
the standard library, the `libc` crate on \
crates.io should be used instead for the correct \
definitions"
)]
#![allow(deprecated)]
#[stable(feature = "pthread_t", since = "1.8.0")]
pub type pthread_t = libc::pthread_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blkcnt_t = libc::blkcnt_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type blksize_t = libc::blksize_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type dev_t = libc::dev_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type ino_t = libc::ino_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type mode_t = libc::mode_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type nlink_t = libc::nlink_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type off_t = libc::off_t;
#[stable(feature = "raw_ext", since = "1.1.0")]
pub type time_t = libc::time_t;

View file

@ -69,6 +69,8 @@ mod platform {
pub use crate::os::netbsd::*;
#[cfg(target_os = "nto")]
pub use crate::os::nto::*;
#[cfg(target_os = "nuttx")]
pub use crate::os::nuttx::*;
#[cfg(target_os = "openbsd")]
pub use crate::os::openbsd::*;
#[cfg(target_os = "redox")]

View file

@ -71,6 +71,7 @@ cfg_if::cfg_if! {
}
} else {
#[inline]
#[cfg_attr(target_os = "vxworks", allow(unused_unsafe))]
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
let mut out = ptr::null_mut();
// We prefer posix_memalign over aligned_alloc since it is more widely available, and

View file

@ -105,84 +105,7 @@ mod os {
}
}
#[cfg(target_os = "linux")]
mod os {
use super::DebuggerPresence;
use crate::fs::File;
use crate::io::Read;
pub(super) fn is_debugger_present() -> Option<DebuggerPresence> {
// This function is crafted with the following goals:
// * Memory efficiency: It avoids crashing the panicking process due to
// out-of-memory (OOM) conditions by not using large heap buffers or
// allocating significant stack space, which could lead to stack overflow.
// * Minimal binary size: The function uses a minimal set of facilities
// from the standard library to avoid increasing the resulting binary size.
//
// To achieve these goals, the function does not use `[std::io::BufReader]`
// and instead reads the file byte by byte using a sliding window approach.
// It's important to note that the "/proc/self/status" pseudo-file is synthesized
// by the Virtual File System (VFS), meaning it is not read from a slow or
// non-volatile storage medium so buffering might not be as beneficial because
// all data is read from memory, though this approach does incur a syscall for
// each byte read.
//
// We cannot make assumptions about the file size or the position of the
// target prefix ("TracerPid:"), so the function does not use
// `[std::fs::read_to_string]` thus not employing UTF-8 to ASCII checking,
// conversion, or parsing as we're looking for an ASCII prefix.
//
// These condiderations make the function deviate from the familiar concise pattern
// of searching for a string in a text file.
fn read_byte(file: &mut File) -> Option<u8> {
let mut buffer = [0];
file.read_exact(&mut buffer).ok()?;
Some(buffer[0])
}
// The ASCII prefix of the datum we're interested in.
const TRACER_PID: &[u8] = b"TracerPid:\t";
let mut file = File::open("/proc/self/status").ok()?;
let mut matched = 0;
// Look for the `TRACER_PID` prefix.
while let Some(byte) = read_byte(&mut file) {
if byte == TRACER_PID[matched] {
matched += 1;
if matched == TRACER_PID.len() {
break;
}
} else {
matched = 0;
}
}
// Was the prefix found?
if matched != TRACER_PID.len() {
return None;
}
// It was; get the ASCII representation of the first digit
// of the PID. That is enough to see if there is a debugger
// attached as the kernel does not pad the PID on the left
// with the leading zeroes.
let byte = read_byte(&mut file)?;
if byte.is_ascii_digit() && byte != b'0' {
Some(DebuggerPresence::Detected)
} else {
Some(DebuggerPresence::NotDetected)
}
}
}
#[cfg(not(any(
target_os = "windows",
target_vendor = "apple",
target_os = "freebsd",
target_os = "linux"
)))]
#[cfg(not(any(target_os = "windows", target_vendor = "apple", target_os = "freebsd")))]
mod os {
pub(super) fn is_debugger_present() -> Option<super::DebuggerPresence> {
None

View file

@ -113,6 +113,7 @@ impl DoubleEndedIterator for Args {
target_os = "nto",
target_os = "hurd",
target_os = "rtems",
target_os = "nuttx",
))]
mod imp {
use crate::ffi::c_char;

View file

@ -283,3 +283,14 @@ pub mod os {
pub const EXE_SUFFIX: &str = "";
pub const EXE_EXTENSION: &str = "";
}
#[cfg(target_os = "nuttx")]
pub mod os {
pub const FAMILY: &str = "unix";
pub const OS: &str = "nuttx";
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 = "";
}

View file

@ -98,7 +98,12 @@ impl FileDesc {
Ok(ret as usize)
}
#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))]
#[cfg(not(any(
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nuttx"
)))]
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
let ret = cvt(unsafe {
libc::readv(
@ -110,14 +115,24 @@ impl FileDesc {
Ok(ret as usize)
}
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))]
#[cfg(any(
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nuttx"
))]
pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
io::default_read_vectored(|b| self.read(b), bufs)
}
#[inline]
pub fn is_read_vectored(&self) -> bool {
cfg!(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))
cfg!(not(any(
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nuttx"
)))
}
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
@ -297,7 +312,12 @@ impl FileDesc {
Ok(ret as usize)
}
#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))]
#[cfg(not(any(
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nuttx"
)))]
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
let ret = cvt(unsafe {
libc::writev(
@ -309,14 +329,24 @@ impl FileDesc {
Ok(ret as usize)
}
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))]
#[cfg(any(
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nuttx"
))]
pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
io::default_write_vectored(|b| self.write(b), bufs)
}
#[inline]
pub fn is_write_vectored(&self) -> bool {
cfg!(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))
cfg!(not(any(
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nuttx"
)))
}
#[cfg_attr(target_os = "vxworks", allow(unused_unsafe))]

View file

@ -479,6 +479,7 @@ impl FileAttr {
target_os = "vita",
target_os = "hurd",
target_os = "rtems",
target_os = "nuttx",
)))]
pub fn modified(&self) -> io::Result<SystemTime> {
#[cfg(target_pointer_width = "32")]
@ -501,7 +502,7 @@ impl FileAttr {
SystemTime::new(self.stat.st_mtime as i64, 0)
}
#[cfg(any(target_os = "horizon", target_os = "hurd"))]
#[cfg(any(target_os = "horizon", target_os = "hurd", target_os = "nuttx"))]
pub fn modified(&self) -> io::Result<SystemTime> {
SystemTime::new(self.stat.st_mtim.tv_sec as i64, self.stat.st_mtim.tv_nsec as i64)
}
@ -513,6 +514,7 @@ impl FileAttr {
target_os = "vita",
target_os = "hurd",
target_os = "rtems",
target_os = "nuttx",
)))]
pub fn accessed(&self) -> io::Result<SystemTime> {
#[cfg(target_pointer_width = "32")]
@ -535,7 +537,7 @@ impl FileAttr {
SystemTime::new(self.stat.st_atime as i64, 0)
}
#[cfg(any(target_os = "horizon", target_os = "hurd"))]
#[cfg(any(target_os = "horizon", target_os = "hurd", target_os = "nuttx"))]
pub fn accessed(&self) -> io::Result<SystemTime> {
SystemTime::new(self.stat.st_atim.tv_sec as i64, self.stat.st_atim.tv_nsec as i64)
}
@ -866,6 +868,7 @@ impl Drop for Dir {
target_os = "horizon",
target_os = "vxworks",
target_os = "rtems",
target_os = "nuttx",
)))]
{
let fd = unsafe { libc::dirfd(self.0) };
@ -1000,6 +1003,13 @@ impl DirEntry {
self.entry.d_fileno as u64
}
#[cfg(target_os = "nuttx")]
pub fn ino(&self) -> u64 {
// Leave this 0 for now, as NuttX does not provide an inode number
// in its directory entries.
0
}
#[cfg(any(
target_os = "netbsd",
target_os = "openbsd",
@ -1327,7 +1337,8 @@ impl File {
target_os = "redox",
target_os = "espidf",
target_os = "horizon",
target_os = "vxworks"
target_os = "vxworks",
target_os = "nuttx",
)))]
let to_timespec = |time: Option<SystemTime>| match time {
Some(time) if let Some(ts) = time.t.to_timespec() => Ok(ts),
@ -1342,7 +1353,7 @@ impl File {
None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }),
};
cfg_if::cfg_if! {
if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "vxworks"))] {
if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "vxworks", target_os = "nuttx"))] {
// Redox doesn't appear to support `UTIME_OMIT`.
// ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore
// the same as for Redox.

View file

@ -222,6 +222,7 @@ static ON_BROKEN_PIPE_FLAG_USED: crate::sync::atomic::AtomicBool =
target_os = "horizon",
target_os = "vxworks",
target_os = "vita",
target_os = "nuttx",
)))]
pub(crate) fn on_broken_pipe_flag_used() -> bool {
ON_BROKEN_PIPE_FLAG_USED.load(crate::sync::atomic::Ordering::Relaxed)
@ -425,7 +426,7 @@ cfg_if::cfg_if! {
}
}
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))]
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))]
mod unsupported {
use crate::io;

View file

@ -38,19 +38,19 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
// We may need to trigger a glibc workaround. See on_resolver_failure() for details.
on_resolver_failure();
#[cfg(not(target_os = "espidf"))]
#[cfg(not(any(target_os = "espidf", target_os = "nuttx")))]
if err == libc::EAI_SYSTEM {
return Err(io::Error::last_os_error());
}
#[cfg(not(target_os = "espidf"))]
#[cfg(not(any(target_os = "espidf", target_os = "nuttx")))]
let detail = unsafe {
// We can't always expect a UTF-8 environment. When we don't get that luxury,
// it's better to give a low-quality error message than none at all.
CStr::from_ptr(libc::gai_strerror(err)).to_string_lossy()
};
#[cfg(target_os = "espidf")]
#[cfg(any(target_os = "espidf", target_os = "nuttx"))]
let detail = "";
Err(io::Error::new(

View file

@ -48,6 +48,7 @@ extern "C" {
target_os = "openbsd",
target_os = "android",
target_os = "redox",
target_os = "nuttx",
target_env = "newlib"
),
link_name = "__errno"
@ -399,6 +400,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
target_os = "linux",
target_os = "hurd",
target_os = "android",
target_os = "nuttx",
target_os = "emscripten"
))]
pub fn current_exe() -> io::Result<PathBuf> {
@ -717,6 +719,7 @@ pub fn home_dir() -> Option<PathBuf> {
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nuttx",
all(target_vendor = "apple", not(target_os = "macos")),
))]
unsafe fn fallback() -> Option<OsString> {
@ -730,6 +733,7 @@ pub fn home_dir() -> Option<PathBuf> {
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nuttx",
all(target_vendor = "apple", not(target_os = "macos")),
)))]
unsafe fn fallback() -> Option<OsString> {

View file

@ -2,10 +2,10 @@ pub use self::process_common::{Command, CommandArgs, ExitCode, Stdio, StdioPipes
pub use self::process_inner::{ExitStatus, ExitStatusError, Process};
pub use crate::ffi::OsString as EnvKey;
#[cfg_attr(any(target_os = "espidf", target_os = "horizon"), allow(unused))]
#[cfg_attr(any(target_os = "espidf", target_os = "horizon", target_os = "nuttx"), allow(unused))]
mod process_common;
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))]
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))]
mod process_unsupported;
cfg_if::cfg_if! {
@ -16,7 +16,7 @@ cfg_if::cfg_if! {
} else if #[cfg(target_os = "vxworks")] {
#[path = "process_vxworks.rs"]
mod process_inner;
} else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita"))] {
} else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] {
mod process_inner {
pub use super::process_unsupported::*;
}

View file

@ -140,7 +140,12 @@ impl Thread {
}
}
#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))]
#[cfg(any(
target_os = "freebsd",
target_os = "dragonfly",
target_os = "openbsd",
target_os = "nuttx"
))]
pub fn set_name(name: &CStr) {
unsafe {
libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr());
@ -747,12 +752,15 @@ unsafe fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
}
// No point in looking up __pthread_get_minstack() on non-glibc platforms.
#[cfg(all(not(all(target_os = "linux", target_env = "gnu")), not(target_os = "netbsd")))]
#[cfg(all(
not(all(target_os = "linux", target_env = "gnu")),
not(any(target_os = "netbsd", target_os = "nuttx"))
))]
unsafe fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
libc::PTHREAD_STACK_MIN
}
#[cfg(target_os = "netbsd")]
#[cfg(any(target_os = "netbsd", target_os = "nuttx"))]
unsafe fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
static STACK: crate::sync::OnceLock<usize> = crate::sync::OnceLock::new();

View file

@ -31,7 +31,7 @@ cfg_if::cfg_if! {
target_os = "psp",
target_os = "xous",
target_os = "solid_asp3",
all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re"), not(target_os = "rtems")),
all(target_family = "unix", not(target_os = "espidf"), not(target_os = "l4re"), not(target_os = "rtems"), not(target_os = "nuttx")),
all(target_vendor = "fortanix", target_env = "sgx"),
))] {
mod gcc;

View file

@ -42,6 +42,7 @@ cfg_if::cfg_if! {
target_os = "hurd",
target_os = "l4re",
target_os = "nto",
target_os = "nuttx",
))] {
mod unix_legacy;
pub use unix_legacy::fill_bytes;

View file

@ -21,6 +21,7 @@ cfg_if::cfg_if! {
target_os = "haiku",
target_os = "l4re",
target_os = "nto",
target_os = "nuttx",
target_vendor = "apple",
))] {
use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP;

View file

@ -23,6 +23,7 @@ cfg_if::cfg_if! {
target_os = "none",
target_os = "espidf",
target_os = "rtems",
target_os = "nuttx",
))] {
// These "unix" family members do not have unwinder.
} else if #[cfg(any(

View file

@ -358,12 +358,14 @@ target | std | host | notes
[`riscv32imc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF
[`riscv32imac-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF
[`riscv32imafc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF
[`riscv32-wrs-vxworks`](platform-support/vxworks.md) | ✓ | |
[`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ | | RISC-V Hermit
`riscv64gc-unknown-freebsd` | | | RISC-V FreeBSD
`riscv64gc-unknown-fuchsia` | | | RISC-V Fuchsia
[`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD
[`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64
[`riscv64-linux-android`](platform-support/android.md) | | | RISC-V 64-bit Android
[`riscv64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | |
`s390x-unknown-linux-musl` | | | S390x Linux (kernel 3.2, musl 1.2.3)
`sparc-unknown-linux-gnu` | ✓ | | 32-bit SPARC Linux
[`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * | | Bare 32-bit SPARC V7+

View file

@ -14,6 +14,8 @@ Target triplets available:
- `powerpc-wrs-vxworks`
- `powerpc64-wrs-vxworks`
- `powerpc-wrs-vxworks-spe`
- `riscv32-wrs-vxworks`
- `riscv64-wrs-vxworks`
## Target maintainers

View file

@ -372,6 +372,9 @@
//@ revisions: powerpc_wrs_vxworks_spe
//@ [powerpc_wrs_vxworks_spe] compile-flags: --target powerpc-wrs-vxworks-spe
//@ [powerpc_wrs_vxworks_spe] needs-llvm-components: powerpc
//@ revisions: riscv32_wrs_vxworks
//@ [riscv32_wrs_vxworks] compile-flags: --target riscv32-wrs-vxworks
//@ [riscv32_wrs_vxworks] needs-llvm-components: riscv
//@ revisions: riscv32gc_unknown_linux_gnu
//@ [riscv32gc_unknown_linux_gnu] compile-flags: --target riscv32gc-unknown-linux-gnu
//@ [riscv32gc_unknown_linux_gnu] needs-llvm-components: riscv
@ -414,6 +417,9 @@
//@ revisions: riscv64_linux_android
//@ [riscv64_linux_android] compile-flags: --target riscv64-linux-android
//@ [riscv64_linux_android] needs-llvm-components: riscv
//@ revisions: riscv64_wrs_vxworks
//@ [riscv64_wrs_vxworks] compile-flags: --target riscv64-wrs-vxworks
//@ [riscv64_wrs_vxworks] needs-llvm-components: riscv
//@ revisions: riscv64gc_unknown_freebsd
//@ [riscv64gc_unknown_freebsd] compile-flags: --target riscv64gc-unknown-freebsd
//@ [riscv64gc_unknown_freebsd] needs-llvm-components: riscv

View file

@ -1,6 +0,0 @@
//@ known-bug: #123955
//@ compile-flags: -Clto -Zvirtual-function-elimination
//@ only-x86_64
pub fn main() {
_ = Box::new(()) as Box<dyn Send>;
}

View file

@ -1,7 +0,0 @@
//@ known-bug: #124092
//@ compile-flags: -Zvirtual-function-elimination=true -Clto=true
//@ only-x86_64
const X: for<'b> fn(&'b ()) = |&()| ();
fn main() {
let dyn_debug = Box::new(X) as Box<fn(&'static ())> as Box<dyn Send>;
}

View file

@ -0,0 +1,17 @@
//@ build-pass
//@ compile-flags: -Zvirtual-function-elimination=true -Clto=true
//@ only-x86_64
//@ no-prefer-dynamic
// issue #123955
pub fn test0() {
_ = Box::new(()) as Box<dyn Send>;
}
// issue #124092
const X: for<'b> fn(&'b ()) = |&()| ();
pub fn test1() {
let _dyn_debug = Box::new(X) as Box<fn(&'static ())> as Box<dyn Send>;
}
fn main() {}

View file

@ -1,3 +1,11 @@
error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed
--> $DIR/unify-op-with-fn-call.rs:3:12
|
LL | #![feature(generic_const_exprs, adt_const_params, const_trait_impl, effects)]
| ^^^^^^^^^^^^^^^^^^^
|
= help: remove one of these features
error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
--> $DIR/unify-op-with-fn-call.rs:10:12
|
@ -67,7 +75,7 @@ error[E0284]: type annotations needed: cannot normalize `foo2<N>::{constant#0}`
LL | bar2::<{ std::ops::Add::add(N, N) }>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo2<N>::{constant#0}`
error: aborting due to 8 previous errors
error: aborting due to 9 previous errors
Some errors have detailed explanations: E0284, E0741.
For more information about an error, try `rustc --explain E0284`.

View file

@ -1,3 +1,11 @@
error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed
--> $DIR/issue-88119.rs:4:39
|
LL | #![feature(const_trait_impl, effects, generic_const_exprs)]
| ^^^^^^^^^^^^^^^^^^^
|
= help: remove one of these features
error[E0284]: type annotations needed: cannot normalize `<&T as ConstName>::{constant#0}`
--> $DIR/issue-88119.rs:19:49
|
@ -28,6 +36,6 @@ LL | where
LL | [(); name_len::<T>()]:,
| --------------------- unsatisfied trait bound introduced here
error: aborting due to 2 previous errors
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0284`.

View file

@ -1,3 +1,11 @@
error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed
--> $DIR/const-trait-bounds.rs:4:39
|
LL | #![feature(const_trait_impl, effects, generic_const_exprs)]
| ^^^^^^^^^^^^^^^^^^^
|
= help: remove one of these features
error[E0284]: type annotations needed: cannot normalize `process<T>::{constant#0}`
--> $DIR/const-trait-bounds.rs:12:35
|
@ -16,6 +24,6 @@ error[E0284]: type annotations needed: cannot normalize `process<T>::{constant#1
LL | input
| ^^^^^ cannot normalize `process<T>::{constant#1}`
error: aborting due to 3 previous errors
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0284`.

View file

@ -1,3 +1,4 @@
//@ known-bug: unknown
// Ensure that we print unsatisfied always-const trait bounds as `const Trait` in diagnostics.
//@ compile-flags: -Znext-solver
@ -19,7 +20,7 @@ impl Trait for Ty {
fn main() {
// FIXME(effects): improve diagnostics on this
require::<Ty>(); //~ ERROR the trait bound `Trait::{synthetic#0}: const Compat` is not satisfied
require::<Ty>();
}
struct Container<const N: u32>;
@ -27,9 +28,7 @@ struct Container<const N: u32>;
// FIXME(effects): Somehow emit `the trait bound `T: const Trait` is not satisfied` here instead
// and suggest changing `Trait` to `const Trait`.
fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
//~^ ERROR mismatched types
// FIXME(effects): Instead of suggesting `+ const Trait`, suggest
// changing `~const Trait` to `const Trait`.
const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
//~^ ERROR mismatched types

View file

@ -1,5 +1,13 @@
error: `-Znext-solver=globally` and `generic_const_exprs` are incompatible, using them at the same time is not allowed
--> $DIR/unsatisfied-const-trait-bound.rs:5:39
|
LL | #![feature(const_trait_impl, effects, generic_const_exprs)]
| ^^^^^^^^^^^^^^^^^^^
|
= help: remove one of these features
error[E0308]: mismatched types
--> $DIR/unsatisfied-const-trait-bound.rs:29:37
--> $DIR/unsatisfied-const-trait-bound.rs:30:37
|
LL | fn accept0<T: Trait>(_: Container<{ T::make() }>) {}
| ^^^^^^^^^ expected `false`, found `true`
@ -17,18 +25,18 @@ LL | const fn accept1<T: ~const Trait>(_: Container<{ T::make() }>) {}
found constant `host`
error[E0277]: the trait bound `Trait::{synthetic#0}: const Compat` is not satisfied
--> $DIR/unsatisfied-const-trait-bound.rs:22:15
--> $DIR/unsatisfied-const-trait-bound.rs:23:15
|
LL | require::<Ty>();
| ^^ the trait `const Compat` is not implemented for `Trait::{synthetic#0}`
|
note: required by a bound in `require`
--> $DIR/unsatisfied-const-trait-bound.rs:7:15
--> $DIR/unsatisfied-const-trait-bound.rs:8:15
|
LL | fn require<T: const Trait>() {}
| ^^^^^^^^^^^ required by this bound in `require`
error: aborting due to 3 previous errors
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.