diff --git a/library/core/src/alloc/global.rs b/library/core/src/alloc/global.rs index 6447fde0cd8a..9b80e3b70fa2 100644 --- a/library/core/src/alloc/global.rs +++ b/library/core/src/alloc/global.rs @@ -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: /// diff --git a/library/std/src/sys/thread/mod.rs b/library/std/src/sys/thread/mod.rs index 3460270b15fc..381031e318c9 100644 --- a/library/std/src/sys/thread/mod.rs +++ b/library/std/src/sys/thread/mod.rs @@ -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); } } diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs index b1f27c32fedd..c3d3d78cf1a8 100644 --- a/library/std/src/sys/thread/unix.rs +++ b/library/std/src/sys/thread/unix.rs @@ -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 diff --git a/tests/ui/issues/issue-16819.rs b/tests/ui/cfg/struct-field-empty.rs similarity index 70% rename from tests/ui/issues/issue-16819.rs rename to tests/ui/cfg/struct-field-empty.rs index 2805c82acfb2..eed69a0c03f0 100644 --- a/tests/ui/issues/issue-16819.rs +++ b/tests/ui/cfg/struct-field-empty.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass #![allow(unused_variables)] // `#[cfg]` on struct field permits empty unusable struct diff --git a/tests/ui/issues/issue-74564-if-expr-stack-overflow.rs b/tests/ui/expr/if/expr-stack-overflow.rs similarity index 99% rename from tests/ui/issues/issue-74564-if-expr-stack-overflow.rs rename to tests/ui/expr/if/expr-stack-overflow.rs index c0ffed27e6fb..6fa09345c827 100644 --- a/tests/ui/issues/issue-74564-if-expr-stack-overflow.rs +++ b/tests/ui/expr/if/expr-stack-overflow.rs @@ -1,3 +1,4 @@ +//! regression test for //@ build-pass // ignore-tidy-filelength #![crate_type = "rlib"] diff --git a/tests/ui/issues/issue-47715.rs b/tests/ui/impl-trait/impl-trait-in-generic-param.rs similarity index 87% rename from tests/ui/issues/issue-47715.rs rename to tests/ui/impl-trait/impl-trait-in-generic-param.rs index bf2b03351b29..4a6a76e4f2d1 100644 --- a/tests/ui/issues/issue-47715.rs +++ b/tests/ui/impl-trait/impl-trait-in-generic-param.rs @@ -1,3 +1,5 @@ +//! regression test for + trait Foo {} trait Bar {} diff --git a/tests/ui/issues/issue-47715.stderr b/tests/ui/impl-trait/impl-trait-in-generic-param.stderr similarity index 85% rename from tests/ui/issues/issue-47715.stderr rename to tests/ui/impl-trait/impl-trait-in-generic-param.stderr index 8ed9ff439521..806a3cb22754 100644 --- a/tests/ui/issues/issue-47715.stderr +++ b/tests/ui/impl-trait/impl-trait-in-generic-param.stderr @@ -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> { | ^^^^^^^^ @@ -7,7 +7,7 @@ LL | struct Container> { = 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> { | ^^^^^^^^ @@ -15,7 +15,7 @@ LL | enum Enum> { = 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 + Copy> { | ^^^^^^^^ @@ -23,7 +23,7 @@ LL | union Union + 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; | ^^^^^^^^ diff --git a/tests/ui/issues/auxiliary/issue-11529.rs b/tests/ui/issues/auxiliary/issue-11529.rs deleted file mode 100644 index dd3ef4387057..000000000000 --- a/tests/ui/issues/auxiliary/issue-11529.rs +++ /dev/null @@ -1 +0,0 @@ -pub struct A<'a>(pub &'a isize); diff --git a/tests/ui/issues/issue-11529.rs b/tests/ui/issues/issue-11529.rs deleted file mode 100644 index 73940c22be4c..000000000000 --- a/tests/ui/issues/issue-11529.rs +++ /dev/null @@ -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); -} diff --git a/tests/ui/issues/issue-49934-errors.rs b/tests/ui/issues/issue-49934-errors.rs deleted file mode 100644 index dd14bac5e3a9..000000000000 --- a/tests/ui/issues/issue-49934-errors.rs +++ /dev/null @@ -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() {} diff --git a/tests/ui/issues/issue-49934-errors.stderr b/tests/ui/issues/issue-49934-errors.stderr deleted file mode 100644 index 8c4c54170a10..000000000000 --- a/tests/ui/issues/issue-49934-errors.stderr +++ /dev/null @@ -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 - diff --git a/tests/ui/lifetimes/auxiliary/lifetime-inference-across-mods.rs b/tests/ui/lifetimes/auxiliary/lifetime-inference-across-mods.rs new file mode 100644 index 000000000000..efc2798d916a --- /dev/null +++ b/tests/ui/lifetimes/auxiliary/lifetime-inference-across-mods.rs @@ -0,0 +1,2 @@ +//! auxiliary crate for +pub struct A<'a>(pub &'a isize); diff --git a/tests/ui/issues/issue-17068.rs b/tests/ui/lifetimes/for-loop-region-links.rs similarity index 77% rename from tests/ui/issues/issue-17068.rs rename to tests/ui/lifetimes/for-loop-region-links.rs index af565da3366b..0c86c211a00b 100644 --- a/tests/ui/issues/issue-17068.rs +++ b/tests/ui/lifetimes/for-loop-region-links.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass // Test that regionck creates the right region links in the pattern // binding of a for loop diff --git a/tests/ui/lifetimes/lifetime-inference-across-mods.rs b/tests/ui/lifetimes/lifetime-inference-across-mods.rs new file mode 100644 index 000000000000..224d2193d08c --- /dev/null +++ b/tests/ui/lifetimes/lifetime-inference-across-mods.rs @@ -0,0 +1,11 @@ +//! regression test for +//@ 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); +} diff --git a/tests/ui/issues/issue-11681.rs b/tests/ui/lifetimes/unit-struct-as-rvalue.rs similarity index 84% rename from tests/ui/issues/issue-11681.rs rename to tests/ui/lifetimes/unit-struct-as-rvalue.rs index 6d8810d80520..10c1d2517064 100644 --- a/tests/ui/issues/issue-11681.rs +++ b/tests/ui/lifetimes/unit-struct-as-rvalue.rs @@ -1,3 +1,4 @@ +//! regression test for // This tests verifies that unary structs and enum variants // are treated as rvalues and their lifetime is not bounded to // the static scope. diff --git a/tests/ui/issues/issue-11681.stderr b/tests/ui/lifetimes/unit-struct-as-rvalue.stderr similarity index 89% rename from tests/ui/issues/issue-11681.stderr rename to tests/ui/lifetimes/unit-struct-as-rvalue.stderr index 4f23ba86eecc..afb80331f356 100644 --- a/tests/ui/issues/issue-11681.stderr +++ b/tests/ui/lifetimes/unit-struct-as-rvalue.stderr @@ -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 diff --git a/tests/ui/issues/issue-17877.rs b/tests/ui/match/match-large-array.rs similarity index 76% rename from tests/ui/issues/issue-17877.rs rename to tests/ui/match/match-large-array.rs index 7df0fffa41c8..e72777c443c5 100644 --- a/tests/ui/issues/issue-17877.rs +++ b/tests/ui/match/match-large-array.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass fn main() { diff --git a/tests/ui/issues/issue-16648.rs b/tests/ui/match/match-tuple-slice.rs similarity index 75% rename from tests/ui/issues/issue-16648.rs rename to tests/ui/match/match-tuple-slice.rs index 7f3d3217bee0..aaebf4401d09 100644 --- a/tests/ui/issues/issue-16648.rs +++ b/tests/ui/match/match-tuple-slice.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass fn main() { let x: (isize, &[isize]) = (2, &[1, 2]); diff --git a/tests/ui/issues/issue-49934.rs b/tests/ui/proc-macro/derive-macro-invalid-placement.rs similarity index 75% rename from tests/ui/issues/issue-49934.rs rename to tests/ui/proc-macro/derive-macro-invalid-placement.rs index 119d84a06885..fd24bd7284a9 100644 --- a/tests/ui/issues/issue-49934.rs +++ b/tests/ui/proc-macro/derive-macro-invalid-placement.rs @@ -1,5 +1,14 @@ +//! regression test for + #![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)] diff --git a/tests/ui/issues/issue-49934.stderr b/tests/ui/proc-macro/derive-macro-invalid-placement.stderr similarity index 66% rename from tests/ui/issues/issue-49934.stderr rename to tests/ui/proc-macro/derive-macro-invalid-placement.stderr index f2ff541bb992..48111f4d3a14 100644 --- a/tests/ui/issues/issue-49934.stderr +++ b/tests/ui/proc-macro/derive-macro-invalid-placement.stderr @@ -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`. diff --git a/tests/ui/issues/issue-18353.rs b/tests/ui/unsized/enum-struct-optimization.rs similarity index 75% rename from tests/ui/issues/issue-18353.rs rename to tests/ui/unsized/enum-struct-optimization.rs index 378caa9f3697..2e2bc64008a6 100644 --- a/tests/ui/issues/issue-18353.rs +++ b/tests/ui/unsized/enum-struct-optimization.rs @@ -1,3 +1,4 @@ +//! regression test for //@ run-pass #![allow(dead_code)] // Test that wrapping an unsized struct in an enum which gets optimised does