Skip to content

Commit 8067caf

Browse files
authored
Address MSRV TODOs (#755)
1 parent 6cbbcb4 commit 8067caf

File tree

9 files changed

+39
-114
lines changed

9 files changed

+39
-114
lines changed

build.rs

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,3 @@
1-
use std::{env, ffi::OsString, process::Command};
2-
3-
/// Tries to get the minor version of the Rust compiler in use.
4-
/// If it fails for any reason, returns `None`.
5-
///
6-
/// Based on the `rustc_version` crate.
7-
fn rustc_minor_version() -> Option<u64> {
8-
let rustc = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc"));
9-
let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER").filter(|w| !w.is_empty()) {
10-
let mut cmd = Command::new(wrapper);
11-
cmd.arg(rustc);
12-
cmd
13-
} else {
14-
Command::new(rustc)
15-
};
16-
17-
let out = cmd.arg("-vV").output().ok()?;
18-
19-
if !out.status.success() {
20-
return None;
21-
}
22-
23-
let stdout = std::str::from_utf8(&out.stdout).ok()?;
24-
25-
// Assumes that the first line contains "rustc 1.xx.0-channel (abcdef 2025-01-01)"
26-
// where "xx" is the minor version which we want to extract
27-
let mut lines = stdout.lines();
28-
let first_line = lines.next()?;
29-
let minor_ver_str = first_line.split('.').nth(1)?;
30-
minor_ver_str.parse().ok()
31-
}
32-
331
fn main() {
342
// Automatically detect cfg(sanitize = "memory") even if cfg(sanitize) isn't
353
// supported. Build scripts get cfg() info, even if the cfg is unstable.
@@ -38,20 +6,4 @@ fn main() {
386
if sanitizers.contains("memory") {
397
println!("cargo:rustc-cfg=getrandom_msan");
408
}
41-
42-
// Use `RtlGenRandom` on older compiler versions since win7 targets
43-
// TODO(MSRV 1.78): Remove this check
44-
let target_family = env::var_os("CARGO_CFG_TARGET_FAMILY").and_then(|f| f.into_string().ok());
45-
if target_family.as_deref() == Some("windows") {
46-
/// Minor version of the Rust compiler in which win7 targets were inroduced
47-
const WIN7_INTRODUCED_MINOR_VER: u64 = 78;
48-
49-
match rustc_minor_version() {
50-
Some(minor_ver) if minor_ver < WIN7_INTRODUCED_MINOR_VER => {
51-
println!("cargo:rustc-cfg=getrandom_backend=\"windows_legacy\"");
52-
}
53-
None => println!("cargo:warning=Couldn't detect minor version of the Rust compiler"),
54-
_ => {}
55-
}
56-
}
579
}

src/backends/getrandom.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,10 @@ mod util_libc;
2525

2626
#[inline]
2727
pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
28-
util_libc::sys_fill_exact(dest, |buf| unsafe {
29-
let ret = libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0);
28+
util_libc::sys_fill_exact(dest, |buf| {
29+
let ret = unsafe { libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) };
3030

3131
#[cfg(any(target_os = "android", target_os = "linux"))]
32-
#[allow(unused_unsafe)] // TODO(MSRV 1.65): Remove this.
3332
unsafe {
3433
super::sanitizer::unpoison_linux_getrandom_result(buf, ret);
3534
}

src/backends/linux_raw.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@ unsafe fn getrandom_syscall(buf: *mut u8, buflen: usize, flags: u32) -> isize {
1212

1313
// Based on `rustix` and `linux-raw-sys` code.
1414
cfg_if! {
15-
if #[cfg(target_arch = "arm")] {
16-
// TODO(MSRV-1.78): Also check `target_abi = "eabi"`.
15+
if #[cfg(all(
16+
target_arch = "arm",
17+
any(target_abi = "eabi", target_abi = "eabihf"),
18+
))] {
19+
const __NR_getrandom: u32 = 384;
1720
// In thumb-mode, r7 is the frame pointer and is not permitted to be used in
1821
// an inline asm operand, so we have to use a different register and copy it
1922
// into r7 inside the inline asm.
@@ -23,19 +26,21 @@ unsafe fn getrandom_syscall(buf: *mut u8, buflen: usize, flags: u32) -> isize {
2326
unsafe {
2427
core::arch::asm!(
2528
"mov {tmp}, r7",
26-
// TODO(MSRV-1.82): replace with `nr = const __NR_getrandom,`
27-
"mov r7, #384",
29+
"mov r7, {nr}",
2830
"svc 0",
2931
"mov r7, {tmp}",
3032
tmp = out(reg) _,
33+
nr = const __NR_getrandom,
3134
inlateout("r0") buf => r0,
3235
in("r1") buflen,
3336
in("r2") flags,
3437
options(nostack, preserves_flags)
3538
);
3639
}
37-
} else if #[cfg(target_arch = "aarch64")] {
38-
// TODO(MSRV-1.78): Also check `any(target_abi = "", target_abi = "ilp32")` above.
40+
} else if #[cfg(all(
41+
target_arch = "aarch64",
42+
any(target_abi = "", target_abi = "ilp32"),
43+
))] {
3944
// According to the ILP32 patch for the kernel that hasn't yet
4045
// been merged into the mainline, "AARCH64/ILP32 ABI uses standard
4146
// syscall table [...] with the exceptions listed below," where
@@ -51,8 +56,10 @@ unsafe fn getrandom_syscall(buf: *mut u8, buflen: usize, flags: u32) -> isize {
5156
options(nostack, preserves_flags)
5257
);
5358
}
54-
} else if #[cfg(target_arch = "loongarch64")] {
55-
// TODO(MSRV-1.78): Also check `any(target_abi = "", target_abi = "ilp32")` above.
59+
} else if #[cfg(all(
60+
target_arch = "loongarch64",
61+
any(target_abi = "", target_abi = "ilp32"),
62+
))] {
5663
const __NR_getrandom: u32 = 278;
5764
unsafe {
5865
core::arch::asm!(
@@ -104,8 +111,10 @@ unsafe fn getrandom_syscall(buf: *mut u8, buflen: usize, flags: u32) -> isize {
104111
options(nostack, preserves_flags)
105112
);
106113
}
107-
} else if #[cfg(target_arch = "x86_64")] {
108-
// TODO(MSRV-1.78): Add `any(target_abi = "", target_abi = "x32")` above.
114+
} else if #[cfg(all(
115+
target_arch = "x86_64",
116+
any(target_abi = "", target_abi = "x32"),
117+
))] {
109118
const __X32_SYSCALL_BIT: u32 = 0x40000000;
110119
const OFFSET: u32 = if cfg!(target_pointer_width = "32") { __X32_SYSCALL_BIT } else { 0 };
111120
const __NR_getrandom: u32 = OFFSET + 318;

src/backends/rdrand.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ compile_error!(
5151
#[target_feature(enable = "rdrand")]
5252
unsafe fn self_test() -> bool {
5353
// On AMD, RDRAND returns 0xFF...FF on failure, count it as a collision.
54-
let mut prev = !0; // TODO(MSRV 1.43): Move to usize::MAX
54+
let mut prev = Word::MAX;
5555
let mut fails = 0;
5656
for _ in 0..8 {
5757
match unsafe { rdrand() } {

src/backends/sanitizer.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ pub unsafe fn unpoison(buf: &mut [MaybeUninit<u8>]) {
2020
}
2121
let a = buf.as_mut_ptr().cast();
2222
let size = buf.len();
23-
#[allow(unused_unsafe)] // TODO(MSRV 1.65): Remove this.
2423
unsafe {
2524
__msan_unpoison(a, size);
2625
}
@@ -50,10 +49,7 @@ pub unsafe fn unpoison(buf: &mut [MaybeUninit<u8>]) {
5049
pub unsafe fn unpoison_linux_getrandom_result(buf: &mut [MaybeUninit<u8>], ret: isize) {
5150
if let Ok(bytes_written) = usize::try_from(ret) {
5251
if let Some(written) = buf.get_mut(..bytes_written) {
53-
#[allow(unused_unsafe)] // TODO(MSRV 1.65): Remove this.
54-
unsafe {
55-
unpoison(written)
56-
}
52+
unsafe { unpoison(written) }
5753
}
5854
}
5955
}

src/backends/use_file.rs

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Implementations that just need to read from a file
22
use crate::Error;
33
use core::{
4-
ffi::c_void,
4+
ffi::{CStr, c_void},
55
mem::MaybeUninit,
66
sync::atomic::{AtomicI32, Ordering},
77
};
@@ -18,7 +18,7 @@ pub(super) mod util_libc;
1818
/// - On Redox, only /dev/urandom is provided.
1919
/// - On AIX, /dev/urandom will "provide cryptographically secure output".
2020
/// - On Haiku and QNX Neutrino they are identical.
21-
const FILE_PATH: &[u8] = b"/dev/urandom\0";
21+
const FILE_PATH: &CStr = c"/dev/urandom";
2222

2323
// File descriptor is a "nonnegative integer", so we can safely use negative sentinel values.
2424
const FD_UNINIT: libc::c_int = -1;
@@ -52,20 +52,9 @@ pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
5252
}
5353

5454
/// Open a file in read-only mode.
55-
///
56-
/// # Panics
57-
/// If `path` does not contain any zeros.
58-
// TODO: Move `path` to `CStr` and use `CStr::from_bytes_until_nul` (MSRV 1.69)
59-
// or C-string literals (MSRV 1.77) for statics
60-
fn open_readonly(path: &[u8]) -> Result<libc::c_int, Error> {
61-
assert!(path.contains(&0));
55+
fn open_readonly(path: &CStr) -> Result<libc::c_int, Error> {
6256
loop {
63-
let fd = unsafe {
64-
libc::open(
65-
path.as_ptr().cast::<libc::c_char>(),
66-
libc::O_RDONLY | libc::O_CLOEXEC,
67-
)
68-
};
57+
let fd = unsafe { libc::open(path.as_ptr(), libc::O_RDONLY | libc::O_CLOEXEC) };
6958
if fd >= 0 {
7059
return Ok(fd);
7160
}
@@ -205,7 +194,7 @@ mod sync {
205194
//
206195
// libsodium uses `libc::poll` similarly to this.
207196
pub(super) fn wait_until_rng_ready() -> Result<(), Error> {
208-
let fd = open_readonly(b"/dev/random\0")?;
197+
let fd = open_readonly(c"/dev/random")?;
209198
let mut pfd = libc::pollfd {
210199
fd,
211200
events: libc::POLLIN,

src/backends/windows.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@ use core::mem::MaybeUninit;
2626
pub use crate::util::{inner_u32, inner_u64};
2727

2828
// Binding to the Windows.Win32.Security.Cryptography.ProcessPrng API. As
29-
// bcryptprimitives.dll lacks an import library, we use "raw-dylib". This
30-
// was added in Rust 1.65 for x86_64/aarch64 and in Rust 1.71 for x86.
31-
// We don't need MSRV 1.71, as we only use this backend on Rust 1.78 and later.
29+
// bcryptprimitives.dll lacks an import library, we use "raw-dylib".
3230
#[cfg_attr(
3331
target_arch = "x86",
3432
link(
@@ -44,8 +42,8 @@ pub use crate::util::{inner_u32, inner_u64};
4442
unsafe extern "system" {
4543
fn ProcessPrng(pbdata: *mut u8, cbdata: usize) -> BOOL;
4644
}
47-
#[allow(clippy::upper_case_acronyms, clippy::incompatible_msrv)]
48-
type BOOL = core::ffi::c_int; // MSRV 1.64, similarly OK for this backend.
45+
#[expect(clippy::upper_case_acronyms)]
46+
type BOOL = core::ffi::c_int;
4947
const TRUE: BOOL = 1;
5048

5149
#[inline]

src/util.rs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ use core::{mem::MaybeUninit, ptr, slice};
66
/// `MaybeUninit::slice_assume_init_mut`. Every element of `slice` must have
77
/// been initialized.
88
#[inline(always)]
9-
#[allow(unused_unsafe)] // TODO(MSRV 1.65): Remove this.
109
pub unsafe fn slice_assume_init_mut<T>(slice: &mut [MaybeUninit<T>]) -> &mut [T] {
11-
let ptr = ptr_from_mut::<[MaybeUninit<T>]>(slice) as *mut [T];
10+
let ptr = ptr::from_mut(slice) as *mut [T];
1211
// SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`.
1312
unsafe { &mut *ptr }
1413
}
@@ -21,7 +20,7 @@ pub fn uninit_slice_fill_zero(slice: &mut [MaybeUninit<u8>]) -> &mut [u8] {
2120

2221
#[inline(always)]
2322
pub fn slice_as_uninit<T>(slice: &[T]) -> &[MaybeUninit<T>] {
24-
let ptr = ptr_from_ref::<[T]>(slice) as *const [MaybeUninit<T>];
23+
let ptr = ptr::from_ref(slice) as *const [MaybeUninit<T>];
2524
// SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`.
2625
unsafe { &*ptr }
2726
}
@@ -31,23 +30,12 @@ pub fn slice_as_uninit<T>(slice: &[T]) -> &[MaybeUninit<T>] {
3130
/// This is unsafe because it allows assigning uninitialized values into
3231
/// `slice`, which would be undefined behavior.
3332
#[inline(always)]
34-
#[allow(unused_unsafe)] // TODO(MSRV 1.65): Remove this.
3533
pub unsafe fn slice_as_uninit_mut<T>(slice: &mut [T]) -> &mut [MaybeUninit<T>] {
36-
let ptr = ptr_from_mut::<[T]>(slice) as *mut [MaybeUninit<T>];
34+
let ptr = ptr::from_mut(slice) as *mut [MaybeUninit<T>];
3735
// SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`.
3836
unsafe { &mut *ptr }
3937
}
4038

41-
// TODO: MSRV(1.76.0): Replace with `core::ptr::from_mut`.
42-
fn ptr_from_mut<T: ?Sized>(r: &mut T) -> *mut T {
43-
r
44-
}
45-
46-
// TODO: MSRV(1.76.0): Replace with `core::ptr::from_ref`.
47-
fn ptr_from_ref<T: ?Sized>(r: &T) -> *const T {
48-
r
49-
}
50-
5139
/// Default implementation of `inner_u32` on top of `fill_uninit`
5240
#[inline]
5341
pub fn inner_u32() -> Result<u32, Error> {

tests/mod.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,6 @@ fn num_diff_bits<T: DiffBits>(s1: &[T], s2: &[T]) -> usize {
4040
s1.iter().zip(s2.iter()).map(T::diff_bits).sum()
4141
}
4242

43-
// TODO: use `[const { MaybeUninit::uninit() }; N]` after MSRV is bumped to 1.79+
44-
// or `MaybeUninit::uninit_array`
45-
fn uninit_vec(n: usize) -> Vec<MaybeUninit<u8>> {
46-
vec![MaybeUninit::uninit(); n]
47-
}
48-
4943
// Tests the quality of calling getrandom on two large buffers
5044
#[test]
5145
fn test_diff() {
@@ -55,8 +49,8 @@ fn test_diff() {
5549
fill(&mut v1).unwrap();
5650
fill(&mut v2).unwrap();
5751

58-
let mut t1 = uninit_vec(N);
59-
let mut t2 = uninit_vec(N);
52+
let mut t1 = [MaybeUninit::uninit(); N];
53+
let mut t2 = [MaybeUninit::uninit(); N];
6054
let r1 = fill_uninit(&mut t1).unwrap();
6155
let r2 = fill_uninit(&mut t2).unwrap();
6256
assert_eq!(r1.len(), N);
@@ -148,8 +142,8 @@ fn test_small_uninit() {
148142
let mut num_bytes = 0;
149143
let mut diff_bits = 0;
150144
while num_bytes < 256 {
151-
let mut buf1 = uninit_vec(N);
152-
let mut buf2 = uninit_vec(N);
145+
let mut buf1 = [MaybeUninit::uninit(); N];
146+
let mut buf2 = [MaybeUninit::uninit(); N];
153147

154148
let s1 = &mut buf1[..size];
155149
let s2 = &mut buf2[..size];
@@ -176,7 +170,7 @@ fn test_huge() {
176170
#[test]
177171
fn test_huge_uninit() {
178172
const N: usize = 100_000;
179-
let mut huge = uninit_vec(N);
173+
let mut huge = [MaybeUninit::uninit(); N];
180174
let res = fill_uninit(&mut huge).unwrap();
181175
assert_eq!(res.len(), N);
182176
}

0 commit comments

Comments
 (0)