Auto merge of #151521 - jhpratt:rollup-PFh8sRJ, r=jhpratt

Rollup of 4 pull requests

Successful merges:

 - rust-lang/rust#151450 (std: use `clock_nanosleep` for `sleep` where available)
 - rust-lang/rust#151494 (std: ensure that the deadline has passed in `sleep_until`)
 - rust-lang/rust#151498 (global.rs: improve readability of re-entrance section)
 - rust-lang/rust#151504 (Reorganizing tests/ui/issues 11 tests [3/N])

r? @ghost
This commit is contained in:
bors 2026-01-23 04:07:21 +00:00
commit 165591238e
21 changed files with 115 additions and 60 deletions

View file

@ -118,12 +118,12 @@ use crate::{cmp, ptr};
///
/// # Re-entrance
///
/// When implementing a global allocator one has to be careful not to create an infinitely recursive
/// When implementing a global allocator, one has to be careful not to create an infinitely recursive
/// implementation by accident, as many constructs in the Rust standard library may allocate in
/// their implementation. For example, on some platforms [`std::sync::Mutex`] may allocate, so using
/// their implementation. For example, on some platforms, [`std::sync::Mutex`] may allocate, so using
/// it is highly problematic in a global allocator.
///
/// Generally speaking for this reason one should stick to library features available through
/// For this reason, one should generally stick to library features available through
/// [`core`], and avoid using [`std`] in a global allocator. A few features from [`std`] are
/// guaranteed to not use `#[global_allocator]` to allocate:
///

View file

@ -139,9 +139,16 @@ cfg_select! {
pub fn sleep_until(deadline: crate::time::Instant) {
use crate::time::Instant;
let now = Instant::now();
if let Some(delay) = deadline.checked_duration_since(now) {
// The clock source used for `sleep` might not be the same used for `Instant`.
// Since this function *must not* return before the deadline, we recheck the
// time after every call to `sleep`. See #149935 for an example of this
// occurring on older Windows systems.
while let Some(delay) = deadline.checked_duration_since(Instant::now()) {
// Sleep for the estimated time remaining until the deadline.
//
// If your system has a better way of estimating the delay time or
// provides a way to sleep until an absolute time, specialize this
// function for your system.
sleep(delay);
}
}

View file

@ -528,8 +528,51 @@ pub fn set_name(name: &CStr) {
debug_assert_eq!(res, libc::OK);
}
#[cfg(not(any(target_os = "espidf", target_os = "wasi")))]
#[cfg(not(target_os = "espidf"))]
pub fn sleep(dur: Duration) {
cfg_select! {
// Any unix that has clock_nanosleep
// If this list changes update the MIRI chock_nanosleep shim
any(
target_os = "freebsd",
target_os = "netbsd",
target_os = "linux",
target_os = "android",
target_os = "solaris",
target_os = "illumos",
target_os = "dragonfly",
target_os = "hurd",
target_os = "fuchsia",
target_os = "vxworks",
target_os = "wasi",
) => {
// POSIX specifies that `nanosleep` uses CLOCK_REALTIME, but is not
// affected by clock adjustments. The timing of `sleep` however should
// be tied to `Instant` where possible. Thus, we use `clock_nanosleep`
// with a relative time interval instead, which allows explicitly
// specifying the clock.
//
// In practice, most systems (like e.g. Linux) actually use
// CLOCK_MONOTONIC for `nanosleep` anyway, but others like FreeBSD don't
// so it's better to be safe.
//
// wasi-libc prior to WebAssembly/wasi-libc#696 has a broken implementation
// of `nanosleep` which used `CLOCK_REALTIME` even though it is unsupported
// on WASIp2. Using `clock_nanosleep` directly bypasses the issue.
unsafe fn nanosleep(rqtp: *const libc::timespec, rmtp: *mut libc::timespec) -> libc::c_int {
unsafe { libc::clock_nanosleep(crate::sys::time::Instant::CLOCK_ID, 0, rqtp, rmtp) }
}
}
_ => {
unsafe fn nanosleep(rqtp: *const libc::timespec, rmtp: *mut libc::timespec) -> libc::c_int {
let r = unsafe { libc::nanosleep(rqtp, rmtp) };
// `clock_nanosleep` returns the error number directly, so mimic
// that behaviour to make the shared code below simpler.
if r == 0 { 0 } else { sys::io::errno() }
}
}
}
let mut secs = dur.as_secs();
let mut nsecs = dur.subsec_nanos() as _;
@ -543,8 +586,9 @@ pub fn sleep(dur: Duration) {
};
secs -= ts.tv_sec as u64;
let ts_ptr = &raw mut ts;
if libc::nanosleep(ts_ptr, ts_ptr) == -1 {
assert_eq!(sys::io::errno(), libc::EINTR);
let r = nanosleep(ts_ptr, ts_ptr);
if r != 0 {
assert_eq!(r, libc::EINTR);
secs += ts.tv_sec as u64;
nsecs = ts.tv_nsec;
} else {
@ -554,13 +598,7 @@ pub fn sleep(dur: Duration) {
}
}
#[cfg(any(
target_os = "espidf",
// wasi-libc prior to WebAssembly/wasi-libc#696 has a broken implementation
// of `nanosleep`, used above by most platforms, so use `usleep` until
// that fix propagates throughout the ecosystem.
target_os = "wasi",
))]
#[cfg(target_os = "espidf")]
pub fn sleep(dur: Duration) {
// ESP-IDF does not have `nanosleep`, so we use `usleep` instead.
// As per the documentation of `usleep`, it is expected to support

View file

@ -1,3 +1,4 @@
//! regression test for <https://github.com/rust-lang/rust/issues/16819>
//@ run-pass
#![allow(unused_variables)]
// `#[cfg]` on struct field permits empty unusable struct

View file

@ -1,3 +1,4 @@
//! regression test for <https://github.com/rust-lang/rust/issues/74564>
//@ build-pass
// ignore-tidy-filelength
#![crate_type = "rlib"]

View file

@ -1,3 +1,5 @@
//! regression test for <https://github.com/rust-lang/rust/issues/47715>
trait Foo {}
trait Bar<T> {}

View file

@ -1,5 +1,5 @@
error[E0562]: `impl Trait` is not allowed in generics
--> $DIR/issue-47715.rs:9:37
--> $DIR/impl-trait-in-generic-param.rs:11:37
|
LL | struct Container<T: Iterable<Item = impl Foo>> {
| ^^^^^^^^
@ -7,7 +7,7 @@ LL | struct Container<T: Iterable<Item = impl Foo>> {
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
error[E0562]: `impl Trait` is not allowed in generics
--> $DIR/issue-47715.rs:14:30
--> $DIR/impl-trait-in-generic-param.rs:16:30
|
LL | enum Enum<T: Iterable<Item = impl Foo>> {
| ^^^^^^^^
@ -15,7 +15,7 @@ LL | enum Enum<T: Iterable<Item = impl Foo>> {
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
error[E0562]: `impl Trait` is not allowed in generics
--> $DIR/issue-47715.rs:19:32
--> $DIR/impl-trait-in-generic-param.rs:21:32
|
LL | union Union<T: Iterable<Item = impl Foo> + Copy> {
| ^^^^^^^^
@ -23,7 +23,7 @@ LL | union Union<T: Iterable<Item = impl Foo> + Copy> {
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
error[E0562]: `impl Trait` is not allowed in generics
--> $DIR/issue-47715.rs:24:30
--> $DIR/impl-trait-in-generic-param.rs:26:30
|
LL | type Type<T: Iterable<Item = impl Foo>> = T;
| ^^^^^^^^

View file

@ -1 +0,0 @@
pub struct A<'a>(pub &'a isize);

View file

@ -1,10 +0,0 @@
//@ run-pass
//@ aux-build:issue-11529.rs
extern crate issue_11529 as a;
fn main() {
let one = 1;
let _a = a::A(&one);
}

View file

@ -1,8 +0,0 @@
fn foo<#[derive(Debug)] T>() { //~ ERROR expected non-macro attribute, found attribute macro
match 0 {
#[derive(Debug)] //~ ERROR expected non-macro attribute, found attribute macro
_ => (),
}
}
fn main() {}

View file

@ -1,14 +0,0 @@
error: expected non-macro attribute, found attribute macro `derive`
--> $DIR/issue-49934-errors.rs:1:10
|
LL | fn foo<#[derive(Debug)] T>() {
| ^^^^^^ not a non-macro attribute
error: expected non-macro attribute, found attribute macro `derive`
--> $DIR/issue-49934-errors.rs:3:11
|
LL | #[derive(Debug)]
| ^^^^^^ not a non-macro attribute
error: aborting due to 2 previous errors

View file

@ -0,0 +1,2 @@
//! auxiliary crate for <https://github.com/rust-lang/rust/issues/11529>
pub struct A<'a>(pub &'a isize);

View file

@ -1,3 +1,4 @@
//! regression test for <https://github.com/rust-lang/rust/issues/17068>
//@ run-pass
// Test that regionck creates the right region links in the pattern
// binding of a for loop

View file

@ -0,0 +1,11 @@
//! regression test for <https://github.com/rust-lang/rust/issues/11529>
//@ run-pass
//@ aux-build:lifetime-inference-across-mods.rs
extern crate lifetime_inference_across_mods as a;
fn main() {
let one = 1;
let _a = a::A(&one);
}

View file

@ -1,3 +1,4 @@
//! regression test for <https://github.com/rust-lang/rust/issues/11681>
// This tests verifies that unary structs and enum variants
// are treated as rvalues and their lifetime is not bounded to
// the static scope.

View file

@ -1,5 +1,5 @@
error[E0515]: cannot return value referencing temporary value
--> $DIR/issue-11681.rs:13:10
--> $DIR/unit-struct-as-rvalue.rs:14:10
|
LL | let testValue = &Test;
| ---- temporary value created here

View file

@ -1,3 +1,4 @@
//! regression test for <https://github.com/rust-lang/rust/issues/17877>
//@ run-pass
fn main() {

View file

@ -1,3 +1,4 @@
//! regression test for <https://github.com/rust-lang/rust/issues/16648>
//@ run-pass
fn main() {
let x: (isize, &[isize]) = (2, &[1, 2]);

View file

@ -1,5 +1,14 @@
//! regression test for <https://github.com/rust-lang/rust/issues/49934>
#![feature(stmt_expr_attributes)]
fn foo<#[derive(Debug)] T>() { //~ ERROR expected non-macro attribute, found attribute macro
match 0 {
#[derive(Debug)] //~ ERROR expected non-macro attribute, found attribute macro
_ => (),
}
}
fn main() {
// fold_stmt (Item)
#[allow(dead_code)]

View file

@ -1,5 +1,17 @@
error: expected non-macro attribute, found attribute macro `derive`
--> $DIR/derive-macro-invalid-placement.rs:5:10
|
LL | fn foo<#[derive(Debug)] T>() {
| ^^^^^^ not a non-macro attribute
error: expected non-macro attribute, found attribute macro `derive`
--> $DIR/derive-macro-invalid-placement.rs:7:11
|
LL | #[derive(Debug)]
| ^^^^^^ not a non-macro attribute
error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-49934.rs:10:5
--> $DIR/derive-macro-invalid-placement.rs:19:5
|
LL | #[derive(Debug)]
| ^^^^^^^^^^^^^^^^ not applicable here
@ -7,7 +19,7 @@ LL | println!("Hello, world!");
| -------------------------- not a `struct`, `enum` or `union`
error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-49934.rs:14:5
--> $DIR/derive-macro-invalid-placement.rs:23:5
|
LL | #[derive(Debug)]
| ^^^^^^^^^^^^^^^^ not applicable here
@ -15,7 +27,7 @@ LL | "Hello, world!";
| ---------------- not a `struct`, `enum` or `union`
error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-49934.rs:18:5
--> $DIR/derive-macro-invalid-placement.rs:27:5
|
LL | #[derive(Debug)]
| ^^^^^^^^^^^^^^^^ not applicable here
@ -23,7 +35,7 @@ LL | let _ = "Hello, world!";
| ------------------------ not a `struct`, `enum` or `union`
error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-49934.rs:22:13
--> $DIR/derive-macro-invalid-placement.rs:31:13
|
LL | let _ = #[derive(Debug)] "Hello, world!";
| ^^^^^^^^^^^^^^^^ --------------- not a `struct`, `enum` or `union`
@ -31,13 +43,13 @@ LL | let _ = #[derive(Debug)] "Hello, world!";
| not applicable here
error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-49934.rs:27:9
--> $DIR/derive-macro-invalid-placement.rs:36:9
|
LL | #[derive(Debug)]
| ^^^^^^^^^^^^^^^^ not applicable here
LL | "Hello, world!",
| --------------- not a `struct`, `enum` or `union`
error: aborting due to 5 previous errors
error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0774`.

View file

@ -1,3 +1,4 @@
//! regression test for <https://github.com/rust-lang/rust/issues/18353>
//@ run-pass
#![allow(dead_code)]
// Test that wrapping an unsized struct in an enum which gets optimised does