Skip to content

Commit 4cd8dc6

Browse files
committed
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
2 parents 00167ab + 9201f18 commit 4cd8dc6

File tree

17 files changed

+145
-75
lines changed

17 files changed

+145
-75
lines changed

library/alloc/src/boxed.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1213,6 +1213,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
12131213
/// let static_ref: &'static mut usize = Box::leak(x);
12141214
/// *static_ref += 1;
12151215
/// assert_eq!(*static_ref, 42);
1216+
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
1217+
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
1218+
/// # drop(unsafe { Box::from_raw(static_ref) });
12161219
/// ```
12171220
///
12181221
/// Unsized data:
@@ -1222,6 +1225,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
12221225
/// let static_ref = Box::leak(x);
12231226
/// static_ref[0] = 4;
12241227
/// assert_eq!(*static_ref, [4, 2, 3]);
1228+
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
1229+
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
1230+
/// # drop(unsafe { Box::from_raw(static_ref) });
12251231
/// ```
12261232
#[stable(feature = "box_leak", since = "1.26.0")]
12271233
#[inline]

library/alloc/src/rc.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1277,6 +1277,8 @@ impl<T: ?Sized> Rc<T> {
12771277
///
12781278
/// let five = Rc::from_raw(ptr);
12791279
/// assert_eq!(2, Rc::strong_count(&five));
1280+
/// # // Prevent leaks for Miri.
1281+
/// # Rc::decrement_strong_count(ptr);
12801282
/// }
12811283
/// ```
12821284
#[inline]
@@ -1345,6 +1347,8 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
13451347
/// let x = Rc::new("hello".to_owned());
13461348
/// let x_ptr = Rc::into_raw(x);
13471349
/// assert_eq!(unsafe { &*x_ptr }, "hello");
1350+
/// # // Prevent leaks for Miri.
1351+
/// # drop(unsafe { Rc::from_raw(x_ptr) });
13481352
/// ```
13491353
#[must_use = "losing the pointer will leak memory"]
13501354
#[stable(feature = "rc_raw", since = "1.17.0")]
@@ -1572,6 +1576,8 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
15721576
///
15731577
/// let five = Rc::from_raw_in(ptr, System);
15741578
/// assert_eq!(2, Rc::strong_count(&five));
1579+
/// # // Prevent leaks for Miri.
1580+
/// # Rc::decrement_strong_count_in(ptr, System);
15751581
/// }
15761582
/// ```
15771583
#[inline]

library/alloc/src/string.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1984,6 +1984,9 @@ impl String {
19841984
/// let x = String::from("bucket");
19851985
/// let static_ref: &'static mut str = x.leak();
19861986
/// assert_eq!(static_ref, "bucket");
1987+
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
1988+
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
1989+
/// # drop(unsafe { Box::from_raw(static_ref) });
19871990
/// ```
19881991
#[stable(feature = "string_leak", since = "1.72.0")]
19891992
#[inline]

library/alloc/src/sync.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1414,6 +1414,8 @@ impl<T: ?Sized> Arc<T> {
14141414
/// // the `Arc` between threads.
14151415
/// let five = Arc::from_raw(ptr);
14161416
/// assert_eq!(2, Arc::strong_count(&five));
1417+
/// # // Prevent leaks for Miri.
1418+
/// # Arc::decrement_strong_count(ptr);
14171419
/// }
14181420
/// ```
14191421
#[inline]
@@ -1484,6 +1486,8 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
14841486
/// let x = Arc::new("hello".to_owned());
14851487
/// let x_ptr = Arc::into_raw(x);
14861488
/// assert_eq!(unsafe { &*x_ptr }, "hello");
1489+
/// # // Prevent leaks for Miri.
1490+
/// # drop(unsafe { Arc::from_raw(x_ptr) });
14871491
/// ```
14881492
#[must_use = "losing the pointer will leak memory"]
14891493
#[stable(feature = "rc_raw", since = "1.17.0")]
@@ -1766,6 +1770,8 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
17661770
/// // the `Arc` between threads.
17671771
/// let five = Arc::from_raw_in(ptr, System);
17681772
/// assert_eq!(2, Arc::strong_count(&five));
1773+
/// # // Prevent leaks for Miri.
1774+
/// # Arc::decrement_strong_count_in(ptr, System);
17691775
/// }
17701776
/// ```
17711777
#[inline]

library/alloc/src/vec/into_iter.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,15 @@ impl<T, A: Allocator> IntoIter<T, A> {
120120
/// This is roughly equivalent to the following, but more efficient
121121
///
122122
/// ```
123-
/// # let mut into_iter = Vec::<u8>::with_capacity(10).into_iter();
123+
/// # let mut vec = Vec::<u8>::with_capacity(10);
124+
/// # let ptr = vec.as_mut_ptr();
125+
/// # let mut into_iter = vec.into_iter();
124126
/// let mut into_iter = std::mem::replace(&mut into_iter, Vec::new().into_iter());
125127
/// (&mut into_iter).for_each(drop);
126128
/// std::mem::forget(into_iter);
129+
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
130+
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
131+
/// # drop(unsafe { Vec::<u8>::from_raw_parts(ptr, 0, 10) });
127132
/// ```
128133
///
129134
/// This method is used by in-place iteration, refer to the vec::in_place_collect

library/alloc/src/vec/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1473,6 +1473,9 @@ impl<T, A: Allocator> Vec<T, A> {
14731473
/// // 2. `0 <= capacity` always holds whatever `capacity` is.
14741474
/// unsafe {
14751475
/// vec.set_len(0);
1476+
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
1477+
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
1478+
/// # vec.set_len(3);
14761479
/// }
14771480
/// ```
14781481
///
@@ -2391,6 +2394,9 @@ impl<T, A: Allocator> Vec<T, A> {
23912394
/// let static_ref: &'static mut [usize] = x.leak();
23922395
/// static_ref[0] += 1;
23932396
/// assert_eq!(static_ref, &[2, 2, 3]);
2397+
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
2398+
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
2399+
/// # drop(unsafe { Box::from_raw(static_ref) });
23942400
/// ```
23952401
#[stable(feature = "vec_leak", since = "1.47.0")]
23962402
#[inline]

library/core/src/mem/manually_drop.rs

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

library/core/src/mem/maybe_uninit.rs

+15
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ impl<T> MaybeUninit<T> {
274274
/// use std::mem::MaybeUninit;
275275
///
276276
/// let v: MaybeUninit<Vec<u8>> = MaybeUninit::new(vec![42]);
277+
/// # // Prevent leaks for Miri
278+
/// # unsafe { let _ = MaybeUninit::assume_init(v); }
277279
/// ```
278280
///
279281
/// [`assume_init`]: MaybeUninit::assume_init
@@ -446,6 +448,9 @@ impl<T> MaybeUninit<T> {
446448
/// let mut x = MaybeUninit::<String>::uninit();
447449
///
448450
/// x.write("Hello".to_string());
451+
/// # // FIXME(https://github.com/rust-lang/miri/issues/3670):
452+
/// # // use -Zmiri-disable-leak-check instead of unleaking in tests meant to leak.
453+
/// # unsafe { MaybeUninit::assume_init_drop(&mut x); }
449454
/// // This leaks the contained string:
450455
/// x.write("hello".to_string());
451456
/// // x is initialized now:
@@ -506,6 +511,8 @@ impl<T> MaybeUninit<T> {
506511
/// // Create a reference into the `MaybeUninit<T>`. This is okay because we initialized it.
507512
/// let x_vec = unsafe { &*x.as_ptr() };
508513
/// assert_eq!(x_vec.len(), 3);
514+
/// # // Prevent leaks for Miri
515+
/// # unsafe { MaybeUninit::assume_init_drop(&mut x); }
509516
/// ```
510517
///
511518
/// *Incorrect* usage of this method:
@@ -545,6 +552,8 @@ impl<T> MaybeUninit<T> {
545552
/// let x_vec = unsafe { &mut *x.as_mut_ptr() };
546553
/// x_vec.push(3);
547554
/// assert_eq!(x_vec.len(), 4);
555+
/// # // Prevent leaks for Miri
556+
/// # unsafe { MaybeUninit::assume_init_drop(&mut x); }
548557
/// ```
549558
///
550559
/// *Incorrect* usage of this method:
@@ -746,6 +755,8 @@ impl<T> MaybeUninit<T> {
746755
/// use std::mem::MaybeUninit;
747756
///
748757
/// let mut x = MaybeUninit::<Vec<u32>>::uninit();
758+
/// # let mut x_mu = x;
759+
/// # let mut x = &mut x_mu;
749760
/// // Initialize `x`:
750761
/// x.write(vec![1, 2, 3]);
751762
/// // Now that our `MaybeUninit<_>` is known to be initialized, it is okay to
@@ -755,6 +766,8 @@ impl<T> MaybeUninit<T> {
755766
/// x.assume_init_ref()
756767
/// };
757768
/// assert_eq!(x, &vec![1, 2, 3]);
769+
/// # // Prevent leaks for Miri
770+
/// # unsafe { MaybeUninit::assume_init_drop(&mut x_mu); }
758771
/// ```
759772
///
760773
/// ### *Incorrect* usages of this method:
@@ -1088,6 +1101,8 @@ impl<T> MaybeUninit<T> {
10881101
/// let init = MaybeUninit::clone_from_slice(&mut dst, &src);
10891102
///
10901103
/// assert_eq!(init, src);
1104+
/// # // Prevent leaks for Miri
1105+
/// # unsafe { std::ptr::drop_in_place(init); }
10911106
/// ```
10921107
///
10931108
/// ```

library/core/src/ptr/non_null.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1663,6 +1663,8 @@ impl<T> NonNull<[T]> {
16631663
/// // Note that calling `memory.as_mut()` is not allowed here as the content may be uninitialized.
16641664
/// # #[allow(unused_variables)]
16651665
/// let slice: &mut [MaybeUninit<u8>] = unsafe { memory.as_uninit_slice_mut() };
1666+
/// # // Prevent leaks for Miri.
1667+
/// # unsafe { Global.deallocate(memory.cast(), Layout::new::<[u8; 32]>()); }
16661668
/// # Ok::<_, std::alloc::AllocError>(())
16671669
/// ```
16681670
#[inline]

library/std/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ std_detect_file_io = ["std_detect/std_detect_file_io"]
8787
std_detect_dlsym_getauxval = ["std_detect/std_detect_dlsym_getauxval"]
8888
std_detect_env_override = ["std_detect/std_detect_env_override"]
8989

90+
# Enable using raw-dylib for Windows imports.
91+
# This will eventually be the default.
92+
windows_raw_dylib = []
93+
9094
[package.metadata.fortanix-sgx]
9195
# Maximum possible number of threads when testing
9296
threads = 125

library/std/src/sync/condvar.rs

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ impl WaitTimeoutResult {
3535
/// let pair = Arc::new((Mutex::new(false), Condvar::new()));
3636
/// let pair2 = Arc::clone(&pair);
3737
///
38+
/// # let handle =
3839
/// thread::spawn(move || {
3940
/// let (lock, cvar) = &*pair2;
4041
///
@@ -58,6 +59,8 @@ impl WaitTimeoutResult {
5859
/// break
5960
/// }
6061
/// }
62+
/// # // Prevent leaks for Miri.
63+
/// # let _ = handle.join();
6164
/// ```
6265
#[must_use]
6366
#[stable(feature = "wait_timeout", since = "1.5.0")]

library/std/src/sys/pal/windows/alloc.rs

+63-66
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::alloc::{GlobalAlloc, Layout, System};
44
use crate::ffi::c_void;
55
use crate::ptr;
66
use crate::sync::atomic::{AtomicPtr, Ordering};
7-
use crate::sys::c;
7+
use crate::sys::c::{self, windows_targets};
88
use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
99
use core::mem::MaybeUninit;
1010

@@ -17,74 +17,71 @@ mod tests;
1717
// Flag to indicate that the memory returned by `HeapAlloc` should be zeroed.
1818
const HEAP_ZERO_MEMORY: c::DWORD = 0x00000008;
1919

20-
#[link(name = "kernel32")]
21-
extern "system" {
22-
// Get a handle to the default heap of the current process, or null if the operation fails.
23-
//
24-
// SAFETY: Successful calls to this function within the same process are assumed to
25-
// always return the same handle, which remains valid for the entire lifetime of the process.
26-
//
27-
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-getprocessheap
28-
fn GetProcessHeap() -> c::HANDLE;
20+
// Get a handle to the default heap of the current process, or null if the operation fails.
21+
//
22+
// SAFETY: Successful calls to this function within the same process are assumed to
23+
// always return the same handle, which remains valid for the entire lifetime of the process.
24+
//
25+
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-getprocessheap
26+
windows_targets::link!("kernel32.dll" "system" fn GetProcessHeap() -> c::HANDLE);
2927

30-
// Allocate a block of `dwBytes` bytes of memory from a given heap `hHeap`.
31-
// The allocated memory may be uninitialized, or zeroed if `dwFlags` is
32-
// set to `HEAP_ZERO_MEMORY`.
33-
//
34-
// Returns a pointer to the newly-allocated memory or null if the operation fails.
35-
// The returned pointer will be aligned to at least `MIN_ALIGN`.
36-
//
37-
// SAFETY:
38-
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
39-
// - `dwFlags` must be set to either zero or `HEAP_ZERO_MEMORY`.
40-
//
41-
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
42-
//
43-
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapalloc
44-
fn HeapAlloc(hHeap: c::HANDLE, dwFlags: c::DWORD, dwBytes: c::SIZE_T) -> c::LPVOID;
28+
// Allocate a block of `dwBytes` bytes of memory from a given heap `hHeap`.
29+
// The allocated memory may be uninitialized, or zeroed if `dwFlags` is
30+
// set to `HEAP_ZERO_MEMORY`.
31+
//
32+
// Returns a pointer to the newly-allocated memory or null if the operation fails.
33+
// The returned pointer will be aligned to at least `MIN_ALIGN`.
34+
//
35+
// SAFETY:
36+
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
37+
// - `dwFlags` must be set to either zero or `HEAP_ZERO_MEMORY`.
38+
//
39+
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
40+
//
41+
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapalloc
42+
windows_targets::link!("kernel32.dll" "system" fn HeapAlloc(hheap: c::HANDLE, dwflags: u32, dwbytes: usize) -> *mut core::ffi::c_void);
4543

46-
// Reallocate a block of memory behind a given pointer `lpMem` from a given heap `hHeap`,
47-
// to a block of at least `dwBytes` bytes, either shrinking the block in place,
48-
// or allocating at a new location, copying memory, and freeing the original location.
49-
//
50-
// Returns a pointer to the reallocated memory or null if the operation fails.
51-
// The returned pointer will be aligned to at least `MIN_ALIGN`.
52-
// If the operation fails the given block will never have been freed.
53-
//
54-
// SAFETY:
55-
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
56-
// - `dwFlags` must be set to zero.
57-
// - `lpMem` must be a non-null pointer to an allocated block returned by `HeapAlloc` or
58-
// `HeapReAlloc`, that has not already been freed.
59-
// If the block was successfully reallocated at a new location, pointers pointing to
60-
// the freed memory, such as `lpMem`, must not be dereferenced ever again.
61-
//
62-
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
63-
//
64-
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heaprealloc
65-
fn HeapReAlloc(
66-
hHeap: c::HANDLE,
67-
dwFlags: c::DWORD,
68-
lpMem: c::LPVOID,
69-
dwBytes: c::SIZE_T,
70-
) -> c::LPVOID;
44+
// Reallocate a block of memory behind a given pointer `lpMem` from a given heap `hHeap`,
45+
// to a block of at least `dwBytes` bytes, either shrinking the block in place,
46+
// or allocating at a new location, copying memory, and freeing the original location.
47+
//
48+
// Returns a pointer to the reallocated memory or null if the operation fails.
49+
// The returned pointer will be aligned to at least `MIN_ALIGN`.
50+
// If the operation fails the given block will never have been freed.
51+
//
52+
// SAFETY:
53+
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
54+
// - `dwFlags` must be set to zero.
55+
// - `lpMem` must be a non-null pointer to an allocated block returned by `HeapAlloc` or
56+
// `HeapReAlloc`, that has not already been freed.
57+
// If the block was successfully reallocated at a new location, pointers pointing to
58+
// the freed memory, such as `lpMem`, must not be dereferenced ever again.
59+
//
60+
// Note that `dwBytes` is allowed to be zero, contrary to some other allocators.
61+
//
62+
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heaprealloc
63+
windows_targets::link!("kernel32.dll" "system" fn HeapReAlloc(
64+
hheap: c::HANDLE,
65+
dwflags : u32,
66+
lpmem: *const core::ffi::c_void,
67+
dwbytes: usize
68+
) -> *mut core::ffi::c_void);
7169

72-
// Free a block of memory behind a given pointer `lpMem` from a given heap `hHeap`.
73-
// Returns a nonzero value if the operation is successful, and zero if the operation fails.
74-
//
75-
// SAFETY:
76-
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
77-
// - `dwFlags` must be set to zero.
78-
// - `lpMem` must be a pointer to an allocated block returned by `HeapAlloc` or `HeapReAlloc`,
79-
// that has not already been freed.
80-
// If the block was successfully freed, pointers pointing to the freed memory, such as `lpMem`,
81-
// must not be dereferenced ever again.
82-
//
83-
// Note that `lpMem` is allowed to be null, which will not cause the operation to fail.
84-
//
85-
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapfree
86-
fn HeapFree(hHeap: c::HANDLE, dwFlags: c::DWORD, lpMem: c::LPVOID) -> c::BOOL;
87-
}
70+
// Free a block of memory behind a given pointer `lpMem` from a given heap `hHeap`.
71+
// Returns a nonzero value if the operation is successful, and zero if the operation fails.
72+
//
73+
// SAFETY:
74+
// - `hHeap` must be a non-null handle returned by `GetProcessHeap`.
75+
// - `dwFlags` must be set to zero.
76+
// - `lpMem` must be a pointer to an allocated block returned by `HeapAlloc` or `HeapReAlloc`,
77+
// that has not already been freed.
78+
// If the block was successfully freed, pointers pointing to the freed memory, such as `lpMem`,
79+
// must not be dereferenced ever again.
80+
//
81+
// Note that `lpMem` is allowed to be null, which will not cause the operation to fail.
82+
//
83+
// See https://docs.microsoft.com/windows/win32/api/heapapi/nf-heapapi-heapfree
84+
windows_targets::link!("kernel32.dll" "system" fn HeapFree(hheap: c::HANDLE, dwflags: u32, lpmem: *const core::ffi::c_void) -> c::BOOL);
8885

8986
// Cached handle to the default heap of the current process.
9087
// Either a non-null handle returned by `GetProcessHeap`, or null when not yet initialized or `GetProcessHeap` failed.

library/std/src/sys/pal/windows/c.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort, c_vo
1313
use crate::os::windows::io::{AsRawHandle, BorrowedHandle};
1414
use crate::ptr;
1515

16-
mod windows_targets;
16+
pub(super) mod windows_targets;
1717

1818
mod windows_sys;
1919
pub use windows_sys::*;

0 commit comments

Comments
 (0)