Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
0909712
alloc: fix `Debug` implementation of `ExtractIf`
joboet Sep 25, 2025
0d6a313
add doc for va_list APIs
DiuDiu777 Sep 23, 2025
1479928
Add Dir::open(_file) and some trait impls
Qelxiros Sep 8, 2025
d8b6752
describe bors try parent=sha builds
jdonszelmann Nov 12, 2025
9d1c273
update some uses of `master` in the devguide
jdonszelmann Nov 12, 2025
8c1cb5b
Merge pull request #2640 from jdonszelmann/try-parent-and-main-branch
jdonszelmann Nov 12, 2025
f6bc9d5
some updates and improvements
tshepang Nov 12, 2025
4fd2b77
Merge pull request #2639 from rust-lang/tshepang/default-branch
tshepang Nov 12, 2025
7b0c218
sembr implementing_new_features.md
tshepang Nov 12, 2025
4a845a6
typo
tshepang Nov 12, 2025
de3b053
add date marker
tshepang Nov 12, 2025
407da40
reduce overlong physical lines
tshepang Nov 12, 2025
0f497ce
needless repetition
tshepang Nov 12, 2025
7b35dd1
Merge pull request #2641 from rust-lang/tshepang/sembr
tshepang Nov 12, 2025
6d42077
do not ignore lines that are list entries
tshepang Nov 13, 2025
e4ef199
avoid surprising string handling behavior
tshepang Nov 13, 2025
5517b2c
sembr src/stabilization_guide.md
tshepang Nov 13, 2025
aefdfa8
some text improvements
tshepang Nov 13, 2025
9d16bc4
Merge pull request #2642 from rust-lang/tshepang/sembr
tshepang Nov 13, 2025
74caf6d
sembr implementing_new_features.md again
tshepang Nov 13, 2025
cf542b5
Merge pull request #2643 from rust-lang/tshepang/sembr
tshepang Nov 13, 2025
d5f14ae
use latest checkout action
tshepang Nov 13, 2025
662facc
ci: avoid sembr getting rebuilt on every push
tshepang Nov 13, 2025
e7cd6c6
ci: run sembr in release mode
tshepang Nov 13, 2025
d2a8e42
Merge pull request #2644 from rust-lang/tshepang/ci
tshepang Nov 13, 2025
a70b5c6
sembr sanitizers.md again
tshepang Nov 13, 2025
fe3871f
sembr: update lockfile
tshepang Nov 13, 2025
5d1dc38
handle another edge case
tshepang Nov 13, 2025
9ce4c1a
Merge pull request #2645 from rust-lang/tshepang/sembr
tshepang Nov 13, 2025
3dcaf9b
add missing " and -Zoffload=Enable flag
ZuseZ4 Nov 14, 2025
2bf2f44
Merge pull request #2646 from rust-lang/update-offload-docs
ZuseZ4 Nov 14, 2025
ecfc642
Add support for hexagon-unknown-qurt target
androm3da Sep 30, 2025
901183b
Prepare for merging from rust-lang/rust
invalid-email-address Nov 17, 2025
6367ba4
Merge ref '69d4d5fc0e4d' from rust-lang/rust
invalid-email-address Nov 17, 2025
8564d67
Merge pull request #2647 from rust-lang/rustc-pull
tshepang Nov 17, 2025
6766db0
Prepare for merging from rust-lang/rust
invalid-email-address Nov 17, 2025
a76d78b
Merge ref 'cc328c12382f' from rust-lang/rust
invalid-email-address Nov 17, 2025
239cf98
Merge pull request #2648 from rust-lang/rustc-pull
tshepang Nov 17, 2025
bbf7dc0
ignore unsized types in mips64 and sparc64 callconvs
folkertdev Nov 16, 2025
10172d1
disable the fragment_in_dst_padding_gets_overwritten test on s390x
fneddy Nov 18, 2025
0075359
Rollup merge of #146341 - Qelxiros:dirfd-minimum, r=tgross35
matthiaskrgr Nov 19, 2025
7b6176f
Rollup merge of #146925 - DiuDiu777:va-doc-fix, r=tgross35
matthiaskrgr Nov 19, 2025
b352e63
Rollup merge of #147035 - joboet:extract_if_debug, r=tgross35
matthiaskrgr Nov 19, 2025
a69e638
Rollup merge of #147173 - androm3da:bcain/hexagon_qurt, r=davidtwco,t…
matthiaskrgr Nov 19, 2025
0136a1c
Rollup merge of #149041 - folkertdev:sparc64-mips64-ignore-unsized, r…
matthiaskrgr Nov 19, 2025
3dde8a5
Rollup merge of #149056 - fneddy:fix_s390_test_padding_overwrite, r=R…
matthiaskrgr Nov 19, 2025
7322d98
Rollup merge of #149095 - tshepang:rdg-sync, r=tshepang
matthiaskrgr Nov 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_target/src/callconv/mips64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,12 @@ where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout,
{
if !fn_abi.ret.is_ignore() {
if !fn_abi.ret.is_ignore() && fn_abi.ret.layout.is_sized() {
classify_ret(cx, &mut fn_abi.ret);
}

for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
if arg.is_ignore() || !arg.layout.is_sized() {
continue;
}
classify_arg(cx, arg);
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_target/src/callconv/sparc64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,14 @@ where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout + HasTargetSpec,
{
if !fn_abi.ret.is_ignore() {
if !fn_abi.ret.is_ignore() && fn_abi.ret.layout.is_sized() {
classify_arg(cx, &mut fn_abi.ret, Size::from_bytes(32));
}

for arg in fn_abi.args.iter_mut() {
if !arg.layout.is_sized() {
continue;
}
if arg.is_ignore() {
// sparc64-unknown-linux-{gnu,musl,uclibc} doesn't ignore ZSTs.
if cx.target_spec().os == Os::Linux
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1490,6 +1490,7 @@ supported_targets! {
("mips64el-unknown-linux-muslabi64", mips64el_unknown_linux_muslabi64),
("hexagon-unknown-linux-musl", hexagon_unknown_linux_musl),
("hexagon-unknown-none-elf", hexagon_unknown_none_elf),
("hexagon-unknown-qurt", hexagon_unknown_qurt),

("mips-unknown-linux-uclibc", mips_unknown_linux_uclibc),
("mipsel-unknown-linux-uclibc", mipsel_unknown_linux_uclibc),
Expand Down Expand Up @@ -1958,6 +1959,7 @@ crate::target_spec_enum! {
OpenBsd = "openbsd",
Psp = "psp",
Psx = "psx",
Qurt = "qurt",
Redox = "redox",
Rtems = "rtems",
Solaris = "solaris",
Expand Down
45 changes: 45 additions & 0 deletions compiler/rustc_target/src/spec/targets/hexagon_unknown_qurt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use crate::spec::{Arch, Cc, LinkerFlavor, Lld, Os, Target, TargetMetadata, TargetOptions, cvs};

pub(crate) fn target() -> Target {
let mut base = TargetOptions::default();
base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &["-G0"]);

Target {
llvm_target: "hexagon-unknown-elf".into(),
metadata: TargetMetadata {
description: Some("Hexagon QuRT".into()),
tier: Some(3),
host_tools: Some(false),
std: Some(false),
},
pointer_width: 32,
data_layout: "\
e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32\
:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32\
:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048\
:2048:2048"
.into(),
arch: Arch::Hexagon,
options: TargetOptions {
os: Os::Qurt,
vendor: "unknown".into(),
cpu: "hexagonv69".into(),
linker: Some("rust-lld".into()),
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
exe_suffix: ".elf".into(),
dynamic_linking: true,
executables: true,
families: cvs!["unix"],
has_thread_local: true,
has_rpath: false,
crt_static_default: false,
crt_static_respected: true,
crt_static_allows_dylibs: true,
no_default_libraries: false,
max_atomic_width: Some(32),
features: "-small-data,+hvx-length128b".into(),
c_enum_min_bits: Some(8),
..base
},
}
}
15 changes: 14 additions & 1 deletion library/alloc/src/vec/extract_if.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,20 @@ where
A: Allocator,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let peek = if self.idx < self.end { self.vec.get(self.idx) } else { None };
let peek = if self.idx < self.end {
// This has to use pointer arithmetic as `self.vec[self.idx]` or
// `self.vec.get_unchecked(self.idx)` wouldn't work since we
// temporarily set the length of `self.vec` to zero.
//
// SAFETY:
// Since `self.idx` is smaller than `self.end` and `self.end` is
// smaller than `self.old_len`, `idx` is valid for indexing the
// buffer. Also, per the invariant of `self.idx`, this element
// has not been inspected/moved out yet.
Some(unsafe { &*self.vec.as_ptr().add(self.idx) })
} else {
None
};
f.debug_struct("ExtractIf").field("peek", &peek).finish_non_exhaustive()
}
}
11 changes: 11 additions & 0 deletions library/alloctests/tests/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1650,6 +1650,17 @@ fn extract_if_unconsumed() {
assert_eq!(vec, [1, 2, 3, 4]);
}

#[test]
fn extract_if_debug() {
let mut vec = vec![1, 2];
let mut drain = vec.extract_if(.., |&mut x| x % 2 != 0);
assert!(format!("{drain:?}").contains("Some(1)"));
drain.next();
assert!(format!("{drain:?}").contains("Some(2)"));
drain.next();
assert!(format!("{drain:?}").contains("None"));
}

#[test]
fn test_reserve_exact() {
// This is all the same as test_reserve
Expand Down
7 changes: 4 additions & 3 deletions library/core/src/ffi/va_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,11 @@ impl<'f> VaListImpl<'f> {
///
/// # Safety
///
/// This function is only sound to call when the next variable argument:
/// This function is only sound to call when:
///
/// - has a type that is ABI-compatible with the type `T`
/// - has a value that is a properly initialized value of type `T`
/// - there is a next variable argument available.
/// - the next argument's type must be ABI-compatible with the type `T`.
/// - the next argument must have a properly initialized value of type `T`.
///
/// Calling this function with an incompatible type, an invalid value, or when there
/// are no more variable arguments, is unsound.
Expand Down
25 changes: 22 additions & 3 deletions library/core/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3350,22 +3350,41 @@ pub(crate) const fn miri_promise_symbolic_alignment(ptr: *const (), align: usize

/// Copies the current location of arglist `src` to the arglist `dst`.
///
/// FIXME: document safety requirements
/// # Safety
///
/// You must check the following invariants before you call this function:
///
/// - `dest` must be non-null and point to valid, writable memory.
/// - `dest` must not alias `src`.
///
#[rustc_intrinsic]
#[rustc_nounwind]
pub unsafe fn va_copy<'f>(dest: *mut VaListImpl<'f>, src: &VaListImpl<'f>);

/// Loads an argument of type `T` from the `va_list` `ap` and increment the
/// argument `ap` points to.
///
/// FIXME: document safety requirements
/// # Safety
///
/// This function is only sound to call when:
///
/// - there is a next variable argument available.
/// - the next argument's type must be ABI-compatible with the type `T`.
/// - the next argument must have a properly initialized value of type `T`.
///
/// Calling this function with an incompatible type, an invalid value, or when there
/// are no more variable arguments, is unsound.
///
#[rustc_intrinsic]
#[rustc_nounwind]
pub unsafe fn va_arg<T: VaArgSafe>(ap: &mut VaListImpl<'_>) -> T;

/// Destroy the arglist `ap` after initialization with `va_start` or `va_copy`.
///
/// FIXME: document safety requirements
/// # Safety
///
/// `ap` must not be used to access variable arguments after this call.
///
#[rustc_intrinsic]
#[rustc_nounwind]
pub unsafe fn va_end(ap: &mut VaListImpl<'_>);
118 changes: 118 additions & 0 deletions library/std/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,43 @@ pub enum TryLockError {
WouldBlock,
}

/// An object providing access to a directory on the filesystem.
///
/// Directories are automatically closed when they go out of scope. Errors detected
/// on closing are ignored by the implementation of `Drop`.
///
/// # Platform-specific behavior
///
/// On supported systems (including Windows and some UNIX-based OSes), this function acquires a
/// handle/file descriptor for the directory. This allows functions like [`Dir::open_file`] to
/// avoid [TOCTOU] errors when the directory itself is being moved.
///
/// On other systems, it stores an absolute path (see [`canonicalize()`]). In the latter case, no
/// [TOCTOU] guarantees are made.
///
/// # Examples
///
/// Opens a directory and then a file inside it.
///
/// ```no_run
/// #![feature(dirfd)]
/// use std::{fs::Dir, io};
///
/// fn main() -> std::io::Result<()> {
/// let dir = Dir::open("foo")?;
/// let mut file = dir.open_file("bar.txt")?;
/// let contents = io::read_to_string(file)?;
/// assert_eq!(contents, "Hello, world!");
/// Ok(())
/// }
/// ```
///
/// [TOCTOU]: self#time-of-check-to-time-of-use-toctou
#[unstable(feature = "dirfd", issue = "120426")]
pub struct Dir {
inner: fs_imp::Dir,
}

/// Metadata information about a file.
///
/// This structure is returned from the [`metadata`] or
Expand Down Expand Up @@ -1555,6 +1592,87 @@ impl Seek for Arc<File> {
}
}

impl Dir {
/// Attempts to open a directory at `path` in read-only mode.
///
/// # Errors
///
/// This function will return an error if `path` does not point to an existing directory.
/// Other errors may also be returned according to [`OpenOptions::open`].
///
/// # Examples
///
/// ```no_run
/// #![feature(dirfd)]
/// use std::{fs::Dir, io};
///
/// fn main() -> std::io::Result<()> {
/// let dir = Dir::open("foo")?;
/// let mut f = dir.open_file("bar.txt")?;
/// let contents = io::read_to_string(f)?;
/// assert_eq!(contents, "Hello, world!");
/// Ok(())
/// }
/// ```
#[unstable(feature = "dirfd", issue = "120426")]
pub fn open<P: AsRef<Path>>(path: P) -> io::Result<Self> {
fs_imp::Dir::open(path.as_ref(), &OpenOptions::new().read(true).0)
.map(|inner| Self { inner })
}

/// Attempts to open a file in read-only mode relative to this directory.
///
/// # Errors
///
/// This function will return an error if `path` does not point to an existing file.
/// Other errors may also be returned according to [`OpenOptions::open`].
///
/// # Examples
///
/// ```no_run
/// #![feature(dirfd)]
/// use std::{fs::Dir, io};
///
/// fn main() -> std::io::Result<()> {
/// let dir = Dir::open("foo")?;
/// let mut f = dir.open_file("bar.txt")?;
/// let contents = io::read_to_string(f)?;
/// assert_eq!(contents, "Hello, world!");
/// Ok(())
/// }
/// ```
#[unstable(feature = "dirfd", issue = "120426")]
pub fn open_file<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {
self.inner
.open_file(path.as_ref(), &OpenOptions::new().read(true).0)
.map(|f| File { inner: f })
}
}

impl AsInner<fs_imp::Dir> for Dir {
#[inline]
fn as_inner(&self) -> &fs_imp::Dir {
&self.inner
}
}
impl FromInner<fs_imp::Dir> for Dir {
fn from_inner(f: fs_imp::Dir) -> Dir {
Dir { inner: f }
}
}
impl IntoInner<fs_imp::Dir> for Dir {
fn into_inner(self) -> fs_imp::Dir {
self.inner
}
}

#[unstable(feature = "dirfd", issue = "120426")]
impl fmt::Debug for Dir {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}

impl OpenOptions {
/// Creates a blank new set of options ready for configuration.
///
Expand Down
31 changes: 31 additions & 0 deletions library/std/src/fs/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use rand::RngCore;

#[cfg(not(miri))]
use super::Dir;
#[cfg(any(
windows,
target_os = "freebsd",
Expand All @@ -19,6 +21,8 @@ use crate::assert_matches::assert_matches;
))]
use crate::fs::TryLockError;
use crate::fs::{self, File, FileTimes, OpenOptions};
#[cfg(not(miri))]
use crate::io;
use crate::io::prelude::*;
use crate::io::{BorrowedBuf, ErrorKind, SeekFrom};
use crate::mem::MaybeUninit;
Expand Down Expand Up @@ -2450,3 +2454,30 @@ fn test_fs_set_times_nofollow() {
assert_ne!(target_metadata.accessed().unwrap(), accessed);
assert_ne!(target_metadata.modified().unwrap(), modified);
}

#[test]
// FIXME: libc calls fail on miri
#[cfg(not(miri))]
fn test_dir_smoke_test() {
let tmpdir = tmpdir();
let dir = Dir::open(tmpdir.path());
check!(dir);
}

#[test]
// FIXME: libc calls fail on miri
#[cfg(not(miri))]
fn test_dir_read_file() {
let tmpdir = tmpdir();
let mut f = check!(File::create(tmpdir.join("foo.txt")));
check!(f.write(b"bar"));
check!(f.flush());
drop(f);
let dir = check!(Dir::open(tmpdir.path()));
let f = check!(dir.open_file("foo.txt"));
let buf = check!(io::read_to_string(f));
assert_eq!("bar", &buf);
let f = check!(dir.open_file(tmpdir.join("foo.txt")));
let buf = check!(io::read_to_string(f));
assert_eq!("bar", &buf);
}
Loading
Loading