Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite9eb7de

Browse files
Rollup merge ofrust-lang#127446 - zachs18:miri-stdlib-leaks-core-alloc, r=Mark-Simulacrum
Remove memory leaks in doctests in `core`, `alloc`, and `std`cc `@RalfJung`rust-lang#126067rust-lang/miri#3670Should be no actual *documentation* changes[^1], all added/modified lines in the doctests are hidden with `#`,This PR splits the existing memory leaks in doctests in `core`, `alloc`, and `std` into two general categories:1. "Non-focused" memory leaks that are incidental to the thing being documented, and/or are easy to remove, i.e. they are only there because preventing the leak would make the doctest less clear and/or concise. - These doctests simply have a comment like `# // Prevent leaks for Miri.` above the added line that removes the memory leak. - [^2]Some of these would perhaps be better as part of the public documentation part of the doctest, to clarify that a memory leak can happen if it is not otherwise mentioned explicitly in the documentation (specifically the ones in `(A)Rc::increment_strong_count(_in)`).2. "Focused" memory leaks that are intentional and documented, and/or are possibly fragile to remove. - These doctests have a `# // FIXME` comment above the line that removes the memory leak, with a note that once `-Zmiri-disable-leak-check` can be applied at test granularity, these tests should be "un-unleakified" and have `-Zmiri-disable-leak-check` enabled. - Some of these are possibly fragile (e.g. unleaking the result of `Vec::leak`) and thus should definitely not be made part of the documentation.This should be all of the leaks currently in `core` and `alloc`. I only found one leak in `std`, and it was in the first category (excluding the modules `@RalfJung` mentioned inrust-lang#126067 , and reducing the number of iterations of [one test](https://github.com/rust-lang/rust/blob/master/library/std/src/sync/once_lock.rs#L49-L94) from 1000 to 10)[^1]: assuming [^2] is not added[^2]: backlink
2 parents3ad2560 +294d87f commite9eb7de

File tree

10 files changed

+56
-1
lines changed

10 files changed

+56
-1
lines changed

‎alloc/src/boxed.rs‎

Lines changed: 6 additions & 0 deletions
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]

‎alloc/src/rc.rs‎

Lines changed: 6 additions & 0 deletions
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]

‎alloc/src/string.rs‎

Lines changed: 3 additions & 0 deletions
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]

‎alloc/src/sync.rs‎

Lines changed: 6 additions & 0 deletions
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]

‎alloc/src/vec/into_iter.rs‎

Lines changed: 6 additions & 1 deletion
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

‎alloc/src/vec/mod.rs‎

Lines changed: 6 additions & 0 deletions
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]

‎core/src/mem/manually_drop.rs‎

Lines changed: 3 additions & 0 deletions
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")]

‎core/src/mem/maybe_uninit.rs‎

Lines changed: 15 additions & 0 deletions
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
/// ```

‎core/src/ptr/non_null.rs‎

Lines changed: 2 additions & 0 deletions
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]

‎std/src/sync/condvar.rs‎

Lines changed: 3 additions & 0 deletions
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")]

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp