diff options
| author | Jubilee <46493976+workingjubilee@users.noreply.github.com> | 2024-07-13 20:18:23 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-13 20:18:23 -0700 |
| commit | 285d45d299e82406a94b0a26d3eaf3e6c3958d40 (patch) | |
| tree | 1aa77d5149b684eb4f37da2a1ea53ef3a441511d /library/alloc | |
| parent | 5c565779481efdfac035ac474088e48bd0365bbe (diff) | |
| parent | 51727bae4bb4650d7fa297b983fdc13608ae6e17 (diff) | |
| download | rust-285d45d299e82406a94b0a26d3eaf3e6c3958d40.tar.gz rust-285d45d299e82406a94b0a26d3eaf3e6c3958d40.zip | |
Rollup merge of #127446 - zachs18:miri-stdlib-leaks-core-alloc, r=Mark-Simulacrum
Remove memory leaks in doctests in `core`, `alloc`, and `std`
cc `@RalfJung` https://github.com/rust-lang/rust/issues/126067 https://github.com/rust-lang/miri/issues/3670
Should 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 in https://github.com/rust-lang/rust/issues/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
Diffstat (limited to 'library/alloc')
| -rw-r--r-- | library/alloc/src/boxed.rs | 6 | ||||
| -rw-r--r-- | library/alloc/src/rc.rs | 6 | ||||
| -rw-r--r-- | library/alloc/src/string.rs | 3 | ||||
| -rw-r--r-- | library/alloc/src/sync.rs | 6 | ||||
| -rw-r--r-- | library/alloc/src/vec/into_iter.rs | 7 | ||||
| -rw-r--r-- | library/alloc/src/vec/mod.rs | 6 |
6 files changed, 33 insertions, 1 deletions
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 65bcb241e4a..f299aa0124d 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1213,6 +1213,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { /// let static_ref: &'static mut usize = Box::leak(x); /// *static_ref += 1; /// 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: @@ -1222,6 +1225,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { /// let static_ref = Box::leak(x); /// static_ref[0] = 4; /// 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")] #[inline] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index aa8dd9f79c3..9982c8ea6dc 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1277,6 +1277,8 @@ impl<T: ?Sized> Rc<T> { /// /// let five = Rc::from_raw(ptr); /// assert_eq!(2, Rc::strong_count(&five)); + /// # // Prevent leaks for Miri. + /// # Rc::decrement_strong_count(ptr); /// } /// ``` #[inline] @@ -1345,6 +1347,8 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> { /// let x = Rc::new("hello".to_owned()); /// let x_ptr = Rc::into_raw(x); /// 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"] #[stable(feature = "rc_raw", since = "1.17.0")] @@ -1572,6 +1576,8 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> { /// /// let five = Rc::from_raw_in(ptr, System); /// assert_eq!(2, Rc::strong_count(&five)); + /// # // Prevent leaks for Miri. + /// # Rc::decrement_strong_count_in(ptr, System); /// } /// ``` #[inline] diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 36078da7c35..07ffd3e1519 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1984,6 +1984,9 @@ impl String { /// let x = String::from("bucket"); /// let static_ref: &'static mut str = x.leak(); /// 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")] #[inline] diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 57ac20ba323..a905a1e6b7e 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1414,6 +1414,8 @@ impl<T: ?Sized> Arc<T> { /// // the `Arc` between threads. /// let five = Arc::from_raw(ptr); /// assert_eq!(2, Arc::strong_count(&five)); + /// # // Prevent leaks for Miri. + /// # Arc::decrement_strong_count(ptr); /// } /// ``` #[inline] @@ -1484,6 +1486,8 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> { /// let x = Arc::new("hello".to_owned()); /// let x_ptr = Arc::into_raw(x); /// 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"] #[stable(feature = "rc_raw", since = "1.17.0")] @@ -1766,6 +1770,8 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> { /// // the `Arc` between threads. /// let five = Arc::from_raw_in(ptr, System); /// assert_eq!(2, Arc::strong_count(&five)); + /// # // Prevent leaks for Miri. + /// # Arc::decrement_strong_count_in(ptr, System); /// } /// ``` #[inline] diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 3bd89eaa6cb..10f62e4bb62 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -120,10 +120,15 @@ impl<T, A: Allocator> IntoIter<T, A> { /// 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()); /// (&mut into_iter).for_each(drop); /// 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 diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 6e9b017ad75..729d5dd4fe4 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1473,6 +1473,9 @@ impl<T, A: Allocator> Vec<T, A> { /// // 2. `0 <= capacity` always holds whatever `capacity` is. /// unsafe { /// 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 @@ impl<T, A: Allocator> Vec<T, A> { /// let static_ref: &'static mut [usize] = x.leak(); /// static_ref[0] += 1; /// 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")] #[inline] |
