Auto merge of #127705 - workingjubilee:rollup-sjlzycu, r=workingjubilee

Rollup of 3 pull requests

Successful merges:

 - #127370 (Windows: Add experimental support for linking std-required system DLLs using raw-dylib)
 - #127446 (Remove memory leaks in doctests in `core`, `alloc`, and `std`)
 - #127677 (using correct tool mode for `run-make-support` crate)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-07-14 03:20:11 +00:00
commit 4cd8dc6335
17 changed files with 145 additions and 75 deletions

View File

@ -1213,6 +1213,9 @@ pub const fn allocator(b: &Self) -> &A {
/// let static_ref: &'static mut usize = Box::leak(x); /// let static_ref: &'static mut usize = Box::leak(x);
/// *static_ref += 1; /// *static_ref += 1;
/// assert_eq!(*static_ref, 42); /// assert_eq!(*static_ref, 42);
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
/// # drop(unsafe { Box::from_raw(static_ref) });
/// ``` /// ```
/// ///
/// Unsized data: /// Unsized data:
@ -1222,6 +1225,9 @@ pub const fn allocator(b: &Self) -> &A {
/// let static_ref = Box::leak(x); /// let static_ref = Box::leak(x);
/// static_ref[0] = 4; /// static_ref[0] = 4;
/// assert_eq!(*static_ref, [4, 2, 3]); /// assert_eq!(*static_ref, [4, 2, 3]);
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
/// # drop(unsafe { Box::from_raw(static_ref) });
/// ``` /// ```
#[stable(feature = "box_leak", since = "1.26.0")] #[stable(feature = "box_leak", since = "1.26.0")]
#[inline] #[inline]

View File

@ -1277,6 +1277,8 @@ pub unsafe fn from_raw(ptr: *const T) -> Self {
/// ///
/// let five = Rc::from_raw(ptr); /// let five = Rc::from_raw(ptr);
/// assert_eq!(2, Rc::strong_count(&five)); /// assert_eq!(2, Rc::strong_count(&five));
/// # // Prevent leaks for Miri.
/// # Rc::decrement_strong_count(ptr);
/// } /// }
/// ``` /// ```
#[inline] #[inline]
@ -1345,6 +1347,8 @@ pub fn allocator(this: &Self) -> &A {
/// let x = Rc::new("hello".to_owned()); /// let x = Rc::new("hello".to_owned());
/// let x_ptr = Rc::into_raw(x); /// let x_ptr = Rc::into_raw(x);
/// assert_eq!(unsafe { &*x_ptr }, "hello"); /// assert_eq!(unsafe { &*x_ptr }, "hello");
/// # // Prevent leaks for Miri.
/// # drop(unsafe { Rc::from_raw(x_ptr) });
/// ``` /// ```
#[must_use = "losing the pointer will leak memory"] #[must_use = "losing the pointer will leak memory"]
#[stable(feature = "rc_raw", since = "1.17.0")] #[stable(feature = "rc_raw", since = "1.17.0")]
@ -1572,6 +1576,8 @@ pub fn strong_count(this: &Self) -> usize {
/// ///
/// let five = Rc::from_raw_in(ptr, System); /// let five = Rc::from_raw_in(ptr, System);
/// assert_eq!(2, Rc::strong_count(&five)); /// assert_eq!(2, Rc::strong_count(&five));
/// # // Prevent leaks for Miri.
/// # Rc::decrement_strong_count_in(ptr, System);
/// } /// }
/// ``` /// ```
#[inline] #[inline]

View File

@ -1984,6 +1984,9 @@ pub fn into_boxed_str(self) -> Box<str> {
/// let x = String::from("bucket"); /// let x = String::from("bucket");
/// let static_ref: &'static mut str = x.leak(); /// let static_ref: &'static mut str = x.leak();
/// assert_eq!(static_ref, "bucket"); /// assert_eq!(static_ref, "bucket");
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
/// # drop(unsafe { Box::from_raw(static_ref) });
/// ``` /// ```
#[stable(feature = "string_leak", since = "1.72.0")] #[stable(feature = "string_leak", since = "1.72.0")]
#[inline] #[inline]

View File

@ -1414,6 +1414,8 @@ pub unsafe fn from_raw(ptr: *const T) -> Self {
/// // the `Arc` between threads. /// // the `Arc` between threads.
/// let five = Arc::from_raw(ptr); /// let five = Arc::from_raw(ptr);
/// assert_eq!(2, Arc::strong_count(&five)); /// assert_eq!(2, Arc::strong_count(&five));
/// # // Prevent leaks for Miri.
/// # Arc::decrement_strong_count(ptr);
/// } /// }
/// ``` /// ```
#[inline] #[inline]
@ -1484,6 +1486,8 @@ pub fn allocator(this: &Self) -> &A {
/// let x = Arc::new("hello".to_owned()); /// let x = Arc::new("hello".to_owned());
/// let x_ptr = Arc::into_raw(x); /// let x_ptr = Arc::into_raw(x);
/// assert_eq!(unsafe { &*x_ptr }, "hello"); /// assert_eq!(unsafe { &*x_ptr }, "hello");
/// # // Prevent leaks for Miri.
/// # drop(unsafe { Arc::from_raw(x_ptr) });
/// ``` /// ```
#[must_use = "losing the pointer will leak memory"] #[must_use = "losing the pointer will leak memory"]
#[stable(feature = "rc_raw", since = "1.17.0")] #[stable(feature = "rc_raw", since = "1.17.0")]
@ -1766,6 +1770,8 @@ pub fn strong_count(this: &Self) -> usize {
/// // the `Arc` between threads. /// // the `Arc` between threads.
/// let five = Arc::from_raw_in(ptr, System); /// let five = Arc::from_raw_in(ptr, System);
/// assert_eq!(2, Arc::strong_count(&five)); /// assert_eq!(2, Arc::strong_count(&five));
/// # // Prevent leaks for Miri.
/// # Arc::decrement_strong_count_in(ptr, System);
/// } /// }
/// ``` /// ```
#[inline] #[inline]

View File

@ -120,10 +120,15 @@ fn as_raw_mut_slice(&mut self) -> *mut [T] {
/// This is roughly equivalent to the following, but more efficient /// This is roughly equivalent to the following, but more efficient
/// ///
/// ``` /// ```
/// # let mut into_iter = Vec::<u8>::with_capacity(10).into_iter(); /// # let mut vec = Vec::<u8>::with_capacity(10);
/// # let ptr = vec.as_mut_ptr();
/// # let mut into_iter = vec.into_iter();
/// let mut into_iter = std::mem::replace(&mut into_iter, Vec::new().into_iter()); /// let mut into_iter = std::mem::replace(&mut into_iter, Vec::new().into_iter());
/// (&mut into_iter).for_each(drop); /// (&mut into_iter).for_each(drop);
/// std::mem::forget(into_iter); /// std::mem::forget(into_iter);
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
/// # drop(unsafe { Vec::<u8>::from_raw_parts(ptr, 0, 10) });
/// ``` /// ```
/// ///
/// This method is used by in-place iteration, refer to the vec::in_place_collect /// This method is used by in-place iteration, refer to the vec::in_place_collect

View File

@ -1473,6 +1473,9 @@ pub fn allocator(&self) -> &A {
/// // 2. `0 <= capacity` always holds whatever `capacity` is. /// // 2. `0 <= capacity` always holds whatever `capacity` is.
/// unsafe { /// unsafe {
/// vec.set_len(0); /// vec.set_len(0);
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
/// # vec.set_len(3);
/// } /// }
/// ``` /// ```
/// ///
@ -2391,6 +2394,9 @@ pub fn resize_with<F>(&mut self, new_len: usize, f: F)
/// let static_ref: &'static mut [usize] = x.leak(); /// let static_ref: &'static mut [usize] = x.leak();
/// static_ref[0] += 1; /// static_ref[0] += 1;
/// assert_eq!(static_ref, &[2, 2, 3]); /// assert_eq!(static_ref, &[2, 2, 3]);
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
/// # drop(unsafe { Box::from_raw(static_ref) });
/// ``` /// ```
#[stable(feature = "vec_leak", since = "1.47.0")] #[stable(feature = "vec_leak", since = "1.47.0")]
#[inline] #[inline]

View File

@ -62,6 +62,9 @@ impl<T> ManuallyDrop<T> {
/// x.truncate(5); // You can still safely operate on the value /// x.truncate(5); // You can still safely operate on the value
/// assert_eq!(*x, "Hello"); /// assert_eq!(*x, "Hello");
/// // But `Drop` will not be run here /// // But `Drop` will not be run here
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
/// # let _ = ManuallyDrop::into_inner(x);
/// ``` /// ```
#[must_use = "if you don't need the wrapper, you can use `mem::forget` instead"] #[must_use = "if you don't need the wrapper, you can use `mem::forget` instead"]
#[stable(feature = "manually_drop", since = "1.20.0")] #[stable(feature = "manually_drop", since = "1.20.0")]

View File

@ -274,6 +274,8 @@ impl<T> MaybeUninit<T> {
/// use std::mem::MaybeUninit; /// use std::mem::MaybeUninit;
/// ///
/// let v: MaybeUninit<Vec<u8>> = MaybeUninit::new(vec![42]); /// let v: MaybeUninit<Vec<u8>> = MaybeUninit::new(vec![42]);
/// # // Prevent leaks for Miri
/// # unsafe { let _ = MaybeUninit::assume_init(v); }
/// ``` /// ```
/// ///
/// [`assume_init`]: MaybeUninit::assume_init /// [`assume_init`]: MaybeUninit::assume_init
@ -446,6 +448,9 @@ pub const fn zeroed() -> MaybeUninit<T> {
/// let mut x = MaybeUninit::<String>::uninit(); /// let mut x = MaybeUninit::<String>::uninit();
/// ///
/// x.write("Hello".to_string()); /// x.write("Hello".to_string());
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
/// # unsafe { MaybeUninit::assume_init_drop(&mut x); }
/// // This leaks the contained string: /// // This leaks the contained string:
/// x.write("hello".to_string()); /// x.write("hello".to_string());
/// // x is initialized now: /// // x is initialized now:
@ -506,6 +511,8 @@ pub const fn write(&mut self, val: T) -> &mut T {
/// // Create a reference into the `MaybeUninit<T>`. This is okay because we initialized it. /// // Create a reference into the `MaybeUninit<T>`. This is okay because we initialized it.
/// let x_vec = unsafe { &*x.as_ptr() }; /// let x_vec = unsafe { &*x.as_ptr() };
/// assert_eq!(x_vec.len(), 3); /// assert_eq!(x_vec.len(), 3);
/// # // Prevent leaks for Miri
/// # unsafe { MaybeUninit::assume_init_drop(&mut x); }
/// ``` /// ```
/// ///
/// *Incorrect* usage of this method: /// *Incorrect* usage of this method:
@ -545,6 +552,8 @@ pub const fn as_ptr(&self) -> *const T {
/// let x_vec = unsafe { &mut *x.as_mut_ptr() }; /// let x_vec = unsafe { &mut *x.as_mut_ptr() };
/// x_vec.push(3); /// x_vec.push(3);
/// assert_eq!(x_vec.len(), 4); /// assert_eq!(x_vec.len(), 4);
/// # // Prevent leaks for Miri
/// # unsafe { MaybeUninit::assume_init_drop(&mut x); }
/// ``` /// ```
/// ///
/// *Incorrect* usage of this method: /// *Incorrect* usage of this method:
@ -746,6 +755,8 @@ pub unsafe fn assume_init_drop(&mut self) {
/// use std::mem::MaybeUninit; /// use std::mem::MaybeUninit;
/// ///
/// let mut x = MaybeUninit::<Vec<u32>>::uninit(); /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
/// # let mut x_mu = x;
/// # let mut x = &mut x_mu;
/// // Initialize `x`: /// // Initialize `x`:
/// x.write(vec![1, 2, 3]); /// x.write(vec![1, 2, 3]);
/// // Now that our `MaybeUninit<_>` is known to be initialized, it is okay to /// // Now that our `MaybeUninit<_>` is known to be initialized, it is okay to
@ -755,6 +766,8 @@ pub unsafe fn assume_init_drop(&mut self) {
/// x.assume_init_ref() /// x.assume_init_ref()
/// }; /// };
/// assert_eq!(x, &vec![1, 2, 3]); /// assert_eq!(x, &vec![1, 2, 3]);
/// # // Prevent leaks for Miri
/// # unsafe { MaybeUninit::assume_init_drop(&mut x_mu); }
/// ``` /// ```
/// ///
/// ### *Incorrect* usages of this method: /// ### *Incorrect* usages of this method:
@ -1088,6 +1101,8 @@ pub fn copy_from_slice<'a>(this: &'a mut [MaybeUninit<T>], src: &[T]) -> &'a mut
/// let init = MaybeUninit::clone_from_slice(&mut dst, &src); /// let init = MaybeUninit::clone_from_slice(&mut dst, &src);
/// ///
/// assert_eq!(init, src); /// assert_eq!(init, src);
/// # // Prevent leaks for Miri
/// # unsafe { std::ptr::drop_in_place(init); }
/// ``` /// ```
/// ///
/// ``` /// ```

View File

@ -1663,6 +1663,8 @@ pub const fn as_mut_ptr(self) -> *mut T {
/// // Note that calling `memory.as_mut()` is not allowed here as the content may be uninitialized. /// // Note that calling `memory.as_mut()` is not allowed here as the content may be uninitialized.
/// # #[allow(unused_variables)] /// # #[allow(unused_variables)]
/// let slice: &mut [MaybeUninit<u8>] = unsafe { memory.as_uninit_slice_mut() }; /// let slice: &mut [MaybeUninit<u8>] = unsafe { memory.as_uninit_slice_mut() };
/// # // Prevent leaks for Miri.
/// # unsafe { Global.deallocate(memory.cast(), Layout::new::<[u8; 32]>()); }
/// # Ok::<_, std::alloc::AllocError>(()) /// # Ok::<_, std::alloc::AllocError>(())
/// ``` /// ```
#[inline] #[inline]

View File

@ -87,6 +87,10 @@ std_detect_file_io = ["std_detect/std_detect_file_io"]
std_detect_dlsym_getauxval = ["std_detect/std_detect_dlsym_getauxval"] std_detect_dlsym_getauxval = ["std_detect/std_detect_dlsym_getauxval"]
std_detect_env_override = ["std_detect/std_detect_env_override"] std_detect_env_override = ["std_detect/std_detect_env_override"]
# Enable using raw-dylib for Windows imports.
# This will eventually be the default.
windows_raw_dylib = []
[package.metadata.fortanix-sgx] [package.metadata.fortanix-sgx]
# Maximum possible number of threads when testing # Maximum possible number of threads when testing
threads = 125 threads = 125

View File

@ -35,6 +35,7 @@ impl WaitTimeoutResult {
/// let pair = Arc::new((Mutex::new(false), Condvar::new())); /// let pair = Arc::new((Mutex::new(false), Condvar::new()));
/// let pair2 = Arc::clone(&pair); /// let pair2 = Arc::clone(&pair);
/// ///
/// # let handle =
/// thread::spawn(move || { /// thread::spawn(move || {
/// let (lock, cvar) = &*pair2; /// let (lock, cvar) = &*pair2;
/// ///
@ -58,6 +59,8 @@ impl WaitTimeoutResult {
/// break /// break
/// } /// }
/// } /// }
/// # // Prevent leaks for Miri.
/// # let _ = handle.join();
/// ``` /// ```
#[must_use] #[must_use]
#[stable(feature = "wait_timeout", since = "1.5.0")] #[stable(feature = "wait_timeout", since = "1.5.0")]

View File

@ -4,7 +4,7 @@
use crate::ffi::c_void; use crate::ffi::c_void;
use crate::ptr; use crate::ptr;
use crate::sync::atomic::{AtomicPtr, Ordering}; use crate::sync::atomic::{AtomicPtr, Ordering};
use crate::sys::c; use crate::sys::c::{self, windows_targets};
use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN}; use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
use core::mem::MaybeUninit; use core::mem::MaybeUninit;
@ -17,74 +17,71 @@
// Flag to indicate that the memory returned by `HeapAlloc` should be zeroed. // Flag to indicate that the memory returned by `HeapAlloc` should be zeroed.
const HEAP_ZERO_MEMORY: c::DWORD = 0x00000008; const HEAP_ZERO_MEMORY: c::DWORD = 0x00000008;
#[link(name = "kernel32")] // Get a handle to the default heap of the current process, or null if the operation fails.
extern "system" { //
// Get a handle to the default heap of the current process, or null if the operation fails. // SAFETY: Successful calls to this function within the same process are assumed to
// // always return the same handle, which remains valid for the entire lifetime of the process.
// SAFETY: Successful calls to this function within the same process are assumed to //
// always return the same handle, which remains valid for the entire lifetime of the process. // See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-getprocessheap
// windows_targets::link!("kernel32.dll" "system" fn GetProcessHeap() -> c::HANDLE);
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-getprocessheap
fn GetProcessHeap() -> c::HANDLE;
// Allocate a block of `dwBytes` bytes of memory from a given heap `hHeap`. // Allocate a block of `dwBytes` bytes of memory from a given heap `hHeap`.
// The allocated memory may be uninitialized, or zeroed if `dwFlags` is // The allocated memory may be uninitialized, or zeroed if `dwFlags` is
// set to `HEAP_ZERO_MEMORY`. // set to `HEAP_ZERO_MEMORY`.
// //
// Returns a pointer to the newly-allocated memory or null if the operation fails. // Returns a pointer to the newly-allocated memory or null if the operation fails.
// The returned pointer will be aligned to at least `MIN_ALIGN`. // The returned pointer will be aligned to at least `MIN_ALIGN`.
// //
// SAFETY: // SAFETY:
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`. // - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
// - `dwFlags` must be set to either zero or `HEAP_ZERO_MEMORY`. // - `dwFlags` must be set to either zero or `HEAP_ZERO_MEMORY`.
// //
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators. // Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
// //
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapalloc // See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapalloc
fn HeapAlloc(hHeap: c::HANDLE, dwFlags: c::DWORD, dwBytes: c::SIZE_T) -> c::LPVOID; windows_targets::link!("kernel32.dll" "system" fn HeapAlloc(hheap: c::HANDLE, dwflags: u32, dwbytes: usize) -> *mut core::ffi::c_void);
// Reallocate a block of memory behind a given pointer `lpMem` from a given heap `hHeap`, // Reallocate a block of memory behind a given pointer `lpMem` from a given heap `hHeap`,
// to a block of at least `dwBytes` bytes, either shrinking the block in place, // to a block of at least `dwBytes` bytes, either shrinking the block in place,
// or allocating at a new location, copying memory, and freeing the original location. // or allocating at a new location, copying memory, and freeing the original location.
// //
// Returns a pointer to the reallocated memory or null if the operation fails. // Returns a pointer to the reallocated memory or null if the operation fails.
// The returned pointer will be aligned to at least `MIN_ALIGN`. // The returned pointer will be aligned to at least `MIN_ALIGN`.
// If the operation fails the given block will never have been freed. // If the operation fails the given block will never have been freed.
// //
// SAFETY: // SAFETY:
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`. // - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
// - `dwFlags` must be set to zero. // - `dwFlags` must be set to zero.
// - `lpMem` must be a non-null pointer to an allocated block returned by `HeapAlloc` or // - `lpMem` must be a non-null pointer to an allocated block returned by `HeapAlloc` or
// `HeapReAlloc`, that has not already been freed. // `HeapReAlloc`, that has not already been freed.
// If the block was successfully reallocated at a new location, pointers pointing to // If the block was successfully reallocated at a new location, pointers pointing to
// the freed memory, such as `lpMem`, must not be dereferenced ever again. // the freed memory, such as `lpMem`, must not be dereferenced ever again.
// //
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators. // Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
// //
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heaprealloc // See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heaprealloc
fn HeapReAlloc( windows_targets::link!("kernel32.dll" "system" fn HeapReAlloc(
hHeap: c::HANDLE, hheap: c::HANDLE,
dwFlags: c::DWORD, dwflags : u32,
lpMem: c::LPVOID, lpmem: *const core::ffi::c_void,
dwBytes: c::SIZE_T, dwbytes: usize
) -> c::LPVOID; ) -> *mut core::ffi::c_void);
// Free a block of memory behind a given pointer `lpMem` from a given heap `hHeap`. // Free a block of memory behind a given pointer `lpMem` from a given heap `hHeap`.
// Returns a nonzero value if the operation is successful, and zero if the operation fails. // Returns a nonzero value if the operation is successful, and zero if the operation fails.
// //
// SAFETY: // SAFETY:
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`. // - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
// - `dwFlags` must be set to zero. // - `dwFlags` must be set to zero.
// - `lpMem` must be a pointer to an allocated block returned by `HeapAlloc` or `HeapReAlloc`, // - `lpMem` must be a pointer to an allocated block returned by `HeapAlloc` or `HeapReAlloc`,
// that has not already been freed. // that has not already been freed.
// If the block was successfully freed, pointers pointing to the freed memory, such as `lpMem`, // If the block was successfully freed, pointers pointing to the freed memory, such as `lpMem`,
// must not be dereferenced ever again. // must not be dereferenced ever again.
// //
// Note that `lpMem` is allowed to be null, which will not cause the operation to fail. // Note that `lpMem` is allowed to be null, which will not cause the operation to fail.
// //
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapfree // See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapfree
fn HeapFree(hHeap: c::HANDLE, dwFlags: c::DWORD, lpMem: c::LPVOID) -> c::BOOL; windows_targets::link!("kernel32.dll" "system" fn HeapFree(hheap: c::HANDLE, dwflags: u32, lpmem: *const core::ffi::c_void) -> c::BOOL);
}
// Cached handle to the default heap of the current process. // Cached handle to the default heap of the current process.
// Either a non-null handle returned by `GetProcessHeap`, or null when not yet initialized or `GetProcessHeap` failed. // Either a non-null handle returned by `GetProcessHeap`, or null when not yet initialized or `GetProcessHeap` failed.

View File

@ -13,7 +13,7 @@
use crate::os::windows::io::{AsRawHandle, BorrowedHandle}; use crate::os::windows::io::{AsRawHandle, BorrowedHandle};
use crate::ptr; use crate::ptr;
mod windows_targets; pub(super) mod windows_targets;
mod windows_sys; mod windows_sys;
pub use windows_sys::*; pub use windows_sys::*;

View File

@ -3,6 +3,18 @@
//! This is a simple wrapper around an `extern` block with a `#[link]` attribute. //! This is a simple wrapper around an `extern` block with a `#[link]` attribute.
//! It's very roughly equivalent to the windows-targets crate. //! It's very roughly equivalent to the windows-targets crate.
#[cfg(feature = "windows_raw_dylib")]
pub macro link {
($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (
#[cfg_attr(not(target_arch = "x86"), link(name = $library, kind = "raw-dylib", modifiers = "+verbatim"))]
#[cfg_attr(target_arch = "x86", link(name = $library, kind = "raw-dylib", modifiers = "+verbatim", import_name_type = "undecorated"))]
extern $abi {
$(#[link_name=$link_name])?
pub fn $($function)*;
}
)
}
#[cfg(not(feature = "windows_raw_dylib"))]
pub macro link { pub macro link {
($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => ( ($library:literal $abi:literal $($link_name:literal)? $(#[$doc:meta])? fn $($function:tt)*) => (
// Note: the windows-targets crate uses a pre-built Windows.lib import library which we don't // Note: the windows-targets crate uses a pre-built Windows.lib import library which we don't
@ -17,6 +29,7 @@
) )
} }
#[cfg(not(feature = "windows_raw_dylib"))]
#[link(name = "advapi32")] #[link(name = "advapi32")]
#[link(name = "ntdll")] #[link(name = "ntdll")]
#[link(name = "userenv")] #[link(name = "userenv")]

View File

@ -27,3 +27,4 @@ profiler = ["std/profiler"]
std_detect_file_io = ["std/std_detect_file_io"] std_detect_file_io = ["std/std_detect_file_io"]
std_detect_dlsym_getauxval = ["std/std_detect_dlsym_getauxval"] std_detect_dlsym_getauxval = ["std/std_detect_dlsym_getauxval"]
std_detect_env_override = ["std/std_detect_env_override"] std_detect_env_override = ["std/std_detect_env_override"]
windows_raw_dylib = ["std/windows_raw_dylib"]

View File

@ -58,9 +58,8 @@ check-aux:
library/core \ library/core \
library/alloc \ library/alloc \
--no-doc --no-doc
# Some doctests have intentional memory leaks. # Some doctests use file system operations to demonstrate dealing with `Result`.
# Some use file system operations to demonstrate dealing with `Result`. $(Q)MIRIFLAGS="-Zmiri-disable-isolation" \
$(Q)MIRIFLAGS="-Zmiri-ignore-leaks -Zmiri-disable-isolation" \
$(BOOTSTRAP) miri --stage 2 \ $(BOOTSTRAP) miri --stage 2 \
library/core \ library/core \
library/alloc \ library/alloc \
@ -70,7 +69,7 @@ check-aux:
$(BOOTSTRAP) miri --stage 2 library/std \ $(BOOTSTRAP) miri --stage 2 library/std \
--no-doc -- \ --no-doc -- \
--skip fs:: --skip net:: --skip process:: --skip sys::pal:: --skip fs:: --skip net:: --skip process:: --skip sys::pal::
$(Q)MIRIFLAGS="-Zmiri-ignore-leaks -Zmiri-disable-isolation" \ $(Q)MIRIFLAGS="-Zmiri-disable-isolation" \
$(BOOTSTRAP) miri --stage 2 library/std \ $(BOOTSTRAP) miri --stage 2 library/std \
--doc -- \ --doc -- \
--skip fs:: --skip net:: --skip process:: --skip sys::pal:: --skip fs:: --skip net:: --skip process:: --skip sys::pal::

View File

@ -682,6 +682,8 @@ fn run(self, builder: &Builder<'_>) {
let mut cargo = tool::prepare_tool_cargo( let mut cargo = tool::prepare_tool_cargo(
builder, builder,
compiler, compiler,
// compiletest uses libtest internals; make it use the in-tree std to make sure it never breaks
// when std sources change.
Mode::ToolStd, Mode::ToolStd,
host, host,
"test", "test",
@ -1321,13 +1323,12 @@ fn make_run(run: RunConfig<'_>) {
/// Runs `cargo test` for run-make-support. /// Runs `cargo test` for run-make-support.
fn run(self, builder: &Builder<'_>) { fn run(self, builder: &Builder<'_>) {
let host = self.host; let host = self.host;
let compiler = builder.compiler(builder.top_stage, host); let compiler = builder.compiler(0, host);
builder.ensure(compile::Std::new(compiler, host));
let mut cargo = tool::prepare_tool_cargo( let mut cargo = tool::prepare_tool_cargo(
builder, builder,
compiler, compiler,
Mode::ToolStd, Mode::ToolBootstrap,
host, host,
"test", "test",
"src/tools/run-make-support", "src/tools/run-make-support",