From 081fe300e7f9474d1c3cdf64e4c552b63dada607 Mon Sep 17 00:00:00 2001 From: chrismit3s Date: Fri, 1 Oct 2021 21:55:35 +0200 Subject: [PATCH 01/10] Add paragraph to ControlFlow docs to menion it works with the ? operator (#88715) --- library/core/src/ops/control_flow.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index cd2d57699c92c..d46ed0f84855b 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -7,6 +7,10 @@ use crate::{convert, ops}; /// Having the enum makes it clearer -- no more wondering "wait, what did `false` /// mean again?" -- and allows including a value. /// +/// Similar to [`Option`] and [`Result`], this enum can be used with the `?` operator +/// to return immediatly if the [`Break`] variant is present or to continue normally +/// with the value inside the [`Continue`] variant. +/// /// # Examples /// /// Early-exiting from [`Iterator::try_for_each`]: @@ -46,6 +50,9 @@ use crate::{convert, ops}; /// } /// } /// ``` +/// +/// [`Break`]: ControlFlow::Break +/// [`Continue`]: ControlFlow::Continue #[stable(feature = "control_flow_enum_type", since = "1.55.0")] #[derive(Debug, Clone, Copy, PartialEq)] pub enum ControlFlow { From 825cd8101835cc7af2036c1a8a5f9febb72f42aa Mon Sep 17 00:00:00 2001 From: Christoph Smithmyer <38911273+chrismit3s@users.noreply.github.com> Date: Sat, 2 Oct 2021 13:16:24 +0200 Subject: [PATCH 02/10] Fix typo and change a word in ControlFlow docs Co-authored-by: r00ster --- library/core/src/ops/control_flow.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index d46ed0f84855b..17794eb7ba5ad 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -8,7 +8,7 @@ use crate::{convert, ops}; /// mean again?" -- and allows including a value. /// /// Similar to [`Option`] and [`Result`], this enum can be used with the `?` operator -/// to return immediatly if the [`Break`] variant is present or to continue normally +/// to return immediately if the [`Break`] variant is present or otherwise continue normally /// with the value inside the [`Continue`] variant. /// /// # Examples From 55663a76f4cb9c3fe5c9641b9ab84d19806c33b9 Mon Sep 17 00:00:00 2001 From: Maxwase Date: Fri, 8 Oct 2021 22:17:33 +0300 Subject: [PATCH 03/10] Stabilize `is_symlink()` for `Metadata` and `Path` --- library/std/src/fs.rs | 3 +-- library/std/src/path.rs | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index e999c84f80d47..a2ee6e9af72f9 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -1021,7 +1021,6 @@ impl Metadata { /// #[cfg_attr(unix, doc = "```no_run")] #[cfg_attr(not(unix), doc = "```ignore")] - /// #![feature(is_symlink)] /// use std::fs; /// use std::path::Path; /// use std::os::unix::fs::symlink; @@ -1036,7 +1035,7 @@ impl Metadata { /// Ok(()) /// } /// ``` - #[unstable(feature = "is_symlink", issue = "85748")] + #[stable(feature = "is_symlink", since = "1.57.0")] pub fn is_symlink(&self) -> bool { self.file_type().is_symlink() } diff --git a/library/std/src/path.rs b/library/std/src/path.rs index a45ecf6ea8c63..a5b73c2580be6 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2723,7 +2723,7 @@ impl Path { fs::metadata(self).map(|m| m.is_dir()).unwrap_or(false) } - /// Returns true if the path exists on disk and is pointing at a symbolic link. + /// Returns `true` if the path exists on disk and is pointing at a symbolic link. /// /// This function will not traverse symbolic links. /// In case of a broken symbolic link this will also return true. @@ -2735,7 +2735,6 @@ impl Path { /// #[cfg_attr(unix, doc = "```no_run")] #[cfg_attr(not(unix), doc = "```ignore")] - /// #![feature(is_symlink)] /// use std::path::Path; /// use std::os::unix::fs::symlink; /// @@ -2744,7 +2743,7 @@ impl Path { /// assert_eq!(link_path.is_symlink(), true); /// assert_eq!(link_path.exists(), false); /// ``` - #[unstable(feature = "is_symlink", issue = "85748")] + #[stable(feature = "is_symlink", since = "1.57.0")] pub fn is_symlink(&self) -> bool { fs::symlink_metadata(self).map(|m| m.is_symlink()).unwrap_or(false) } From 36e050b85f5fc9acd27ff5e8cda57a36070f43e2 Mon Sep 17 00:00:00 2001 From: Max Wase Date: Tue, 12 Oct 2021 08:01:24 +0300 Subject: [PATCH 04/10] Update library/std/src/path.rs Co-authored-by: Jane Lusby --- library/std/src/path.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index a5b73c2580be6..4a0df91521268 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2743,6 +2743,12 @@ impl Path { /// assert_eq!(link_path.is_symlink(), true); /// assert_eq!(link_path.exists(), false); /// ``` + /// + /// # See Also + /// + /// This is a convenience function that coerces errors to false. If you want to + /// check errors, call [`fs::symlink_metadata`] and handle its [`Result`]. Then call + /// [`fs::Metadata::is_symlink`] if it was [`Ok`]. #[stable(feature = "is_symlink", since = "1.57.0")] pub fn is_symlink(&self) -> bool { fs::symlink_metadata(self).map(|m| m.is_symlink()).unwrap_or(false) From 5bb99bb02d6d0ec4d9239fd9bce48a41fb084811 Mon Sep 17 00:00:00 2001 From: John Kugelman Date: Tue, 12 Oct 2021 18:27:03 -0400 Subject: [PATCH 05/10] Add #[must_use] to Rc::downgrade --- library/alloc/src/rc.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 493cf3117edf6..e9cded6736474 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -41,7 +41,7 @@ //! use std::rc::Rc; //! //! let my_rc = Rc::new(()); -//! Rc::downgrade(&my_rc); +//! let my_weak = Rc::downgrade(&my_rc); //! ``` //! //! `Rc`'s implementations of traits like `Clone` may also be called using @@ -889,6 +889,8 @@ impl Rc { /// /// let weak_five = Rc::downgrade(&five); /// ``` + #[must_use = "this returns a new `Weak` pointer, \ + without modifying the original `Rc`"] #[stable(feature = "rc_weak", since = "1.4.0")] pub fn downgrade(this: &Self) -> Weak { this.inner().inc_weak(); From 21f467774415b9f237bf1d0ece7236beb2e198a3 Mon Sep 17 00:00:00 2001 From: John Kugelman Date: Tue, 12 Oct 2021 19:09:24 -0400 Subject: [PATCH 06/10] Add #[must_use] to expensive computations The unifying theme for this commit is weak, admittedly. I put together a list of "expensive" functions when I originally proposed this whole effort, but nobody's cared about that criterion. Still, it's a decent way to bite off a not-too-big chunk of work. Given the grab bag nature of this commit, the messages I used vary quite a bit. --- library/alloc/src/collections/btree/set.rs | 8 ++++++++ library/alloc/src/string.rs | 2 ++ library/core/src/slice/ascii.rs | 2 ++ library/core/src/slice/memchr.rs | 2 ++ library/core/src/str/iter.rs | 4 ++++ library/core/src/str/lossy.rs | 1 + library/core/src/str/mod.rs | 2 ++ library/core/tests/ascii.rs | 2 +- library/std/src/collections/hash/set.rs | 8 ++++++++ library/std/src/ffi/os_str.rs | 1 + library/std/src/io/stdio.rs | 1 + 11 files changed, 32 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index d732f65b0d05f..8c80a4fca7008 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -135,6 +135,8 @@ pub struct Range<'a, T: 'a> { /// See its documentation for more. /// /// [`difference`]: BTreeSet::difference +#[must_use = "this returns the difference as an iterator, \ + without modifying either input set"] #[stable(feature = "rust1", since = "1.0.0")] pub struct Difference<'a, T: 'a> { inner: DifferenceInner<'a, T>, @@ -167,6 +169,8 @@ impl fmt::Debug for Difference<'_, T> { /// [`BTreeSet`]. See its documentation for more. /// /// [`symmetric_difference`]: BTreeSet::symmetric_difference +#[must_use = "this returns the difference as an iterator, \ + without modifying either input set"] #[stable(feature = "rust1", since = "1.0.0")] pub struct SymmetricDifference<'a, T: 'a>(MergeIterInner>); @@ -183,6 +187,8 @@ impl fmt::Debug for SymmetricDifference<'_, T> { /// See its documentation for more. /// /// [`intersection`]: BTreeSet::intersection +#[must_use = "this returns the intersection as an iterator, \ + without modifying either input set"] #[stable(feature = "rust1", since = "1.0.0")] pub struct Intersection<'a, T: 'a> { inner: IntersectionInner<'a, T>, @@ -215,6 +221,8 @@ impl fmt::Debug for Intersection<'_, T> { /// See its documentation for more. /// /// [`union`]: BTreeSet::union +#[must_use = "this returns the union as an iterator, \ + without modifying either input set"] #[stable(feature = "rust1", since = "1.0.0")] pub struct Union<'a, T: 'a>(MergeIterInner>); diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index f479bf231b376..01ab562cefdfc 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -552,6 +552,7 @@ impl String { /// /// assert_eq!("Hello �World", output); /// ``` + #[must_use] #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] pub fn from_utf8_lossy(v: &[u8]) -> Cow<'_, str> { @@ -646,6 +647,7 @@ impl String { /// String::from_utf16_lossy(v)); /// ``` #[cfg(not(no_global_oom_handling))] + #[must_use] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn from_utf16_lossy(v: &[u16]) -> String { diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index cbb5627cef982..080256f493f5f 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -11,6 +11,7 @@ use crate::ops; impl [u8] { /// Checks if all bytes in this slice are within the ASCII range. #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] + #[must_use] #[inline] pub fn is_ascii(&self) -> bool { is_ascii(self) @@ -21,6 +22,7 @@ impl [u8] { /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`, /// but without allocating and copying temporaries. #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] + #[must_use] #[inline] pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool { self.len() == other.len() && iter::zip(self, other).all(|(a, b)| a.eq_ignore_ascii_case(b)) diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index 08077c700da69..6da99055f2d5a 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -37,6 +37,7 @@ fn repeat_byte(b: u8) -> usize { } /// Returns the first index matching the byte `x` in `text`. +#[must_use] #[inline] pub fn memchr(x: u8, text: &[u8]) -> Option { // Fast path for small slices @@ -91,6 +92,7 @@ fn memchr_general_case(x: u8, text: &[u8]) -> Option { } /// Returns the last index matching the byte `x` in `text`. +#[must_use] pub fn memrchr(x: u8, text: &[u8]) -> Option { // Scan for a single byte value by reading two `usize` words at a time. // diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs index 94cb81e9d41a1..3efb9560b15e5 100644 --- a/library/core/src/str/iter.rs +++ b/library/core/src/str/iter.rs @@ -27,6 +27,7 @@ use super::{IsAsciiWhitespace, IsNotEmpty, IsWhitespace}; /// [`char`]: prim@char /// [`chars`]: str::chars #[derive(Clone)] +#[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] pub struct Chars<'a> { pub(super) iter: slice::Iter<'a, u8>, @@ -125,6 +126,7 @@ impl<'a> Chars<'a> { /// [`char`]: prim@char /// [`char_indices`]: str::char_indices #[derive(Clone, Debug)] +#[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] pub struct CharIndices<'a> { pub(super) front_offset: usize, @@ -1089,6 +1091,7 @@ generate_pattern_iterators! { /// /// [`lines`]: str::lines #[stable(feature = "rust1", since = "1.0.0")] +#[must_use = "iterators are lazy and do nothing unless consumed"] #[derive(Clone, Debug)] pub struct Lines<'a>(pub(super) Map, LinesAnyMap>); @@ -1128,6 +1131,7 @@ impl FusedIterator for Lines<'_> {} /// [`lines_any`]: str::lines_any #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.4.0", reason = "use lines()/Lines instead now")] +#[must_use = "iterators are lazy and do nothing unless consumed"] #[derive(Clone, Debug)] #[allow(deprecated)] pub struct LinesAny<'a>(pub(super) Lines<'a>); diff --git a/library/core/src/str/lossy.rs b/library/core/src/str/lossy.rs index d3c9d21c3c756..6c21a5e802026 100644 --- a/library/core/src/str/lossy.rs +++ b/library/core/src/str/lossy.rs @@ -29,6 +29,7 @@ impl Utf8Lossy { } /// Iterator over lossy UTF-8 string +#[must_use = "iterators are lazy and do nothing unless consumed"] #[unstable(feature = "str_internals", issue = "none")] #[allow(missing_debug_implementations)] pub struct Utf8LossyChunksIter<'a> { diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 607a0179ff4b9..2ae61d3a05c7a 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2255,6 +2255,7 @@ impl str { /// assert!(!non_ascii.is_ascii()); /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] + #[must_use] #[inline] pub fn is_ascii(&self) -> bool { // We can treat each byte as character here: all multibyte characters @@ -2276,6 +2277,7 @@ impl str { /// assert!(!"Ferrös".eq_ignore_ascii_case("FERRÖS")); /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] + #[must_use] #[inline] pub fn eq_ignore_ascii_case(&self, other: &str) -> bool { self.as_bytes().eq_ignore_ascii_case(other.as_bytes()) diff --git a/library/core/tests/ascii.rs b/library/core/tests/ascii.rs index 66c25e449df2b..6d2cf3e83bce9 100644 --- a/library/core/tests/ascii.rs +++ b/library/core/tests/ascii.rs @@ -115,7 +115,7 @@ fn test_eq_ignore_ascii_case() { #[test] fn inference_works() { let x = "a".to_string(); - x.eq_ignore_ascii_case("A"); + let _ = x.eq_ignore_ascii_case("A"); } // Shorthands used by the is_ascii_* tests. diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 5804701892e6e..39a4a7d6d8d86 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -1320,6 +1320,8 @@ where /// /// let mut intersection = a.intersection(&b); /// ``` +#[must_use = "this returns the intersection as an iterator, \ + without modifying either input set"] #[stable(feature = "rust1", since = "1.0.0")] pub struct Intersection<'a, T: 'a, S: 'a> { // iterator of the first set @@ -1345,6 +1347,8 @@ pub struct Intersection<'a, T: 'a, S: 'a> { /// /// let mut difference = a.difference(&b); /// ``` +#[must_use = "this returns the difference as an iterator, \ + without modifying either input set"] #[stable(feature = "rust1", since = "1.0.0")] pub struct Difference<'a, T: 'a, S: 'a> { // iterator of the first set @@ -1370,6 +1374,8 @@ pub struct Difference<'a, T: 'a, S: 'a> { /// /// let mut intersection = a.symmetric_difference(&b); /// ``` +#[must_use = "this returns the difference as an iterator, \ + without modifying either input set"] #[stable(feature = "rust1", since = "1.0.0")] pub struct SymmetricDifference<'a, T: 'a, S: 'a> { iter: Chain, Difference<'a, T, S>>, @@ -1392,6 +1398,8 @@ pub struct SymmetricDifference<'a, T: 'a, S: 'a> { /// /// let mut union_iter = a.union(&b); /// ``` +#[must_use = "this returns the union as an iterator, \ + without modifying either input set"] #[stable(feature = "rust1", since = "1.0.0")] pub struct Union<'a, T: 'a, S: 'a> { iter: Chain, Difference<'a, T, S>>, diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 3b0e88331449e..c559bad5c28ce 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -823,6 +823,7 @@ impl OsStr { /// assert!(!non_ascii.is_ascii()); /// ``` #[stable(feature = "osstring_ascii", since = "1.53.0")] + #[must_use] #[inline] pub fn is_ascii(&self) -> bool { self.inner.is_ascii() diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 9389501e0129e..96a9da24c7e55 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -487,6 +487,7 @@ impl Stdin { /// println!("got a chunk: {}", String::from_utf8_lossy(&split.unwrap())); /// } /// ``` + #[must_use = "`self` will be dropped if the result is not used"] #[unstable(feature = "stdin_forwarders", issue = "87096")] pub fn split(self, byte: u8) -> Split> { self.into_locked().split(byte) From 63d788257562ecac2614005fea0c9a8aece1ec37 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Sat, 16 Oct 2021 13:23:41 +0200 Subject: [PATCH 07/10] Stabilize `option_result_unwrap_unchecked` Closes https://github.com/rust-lang/rust/issues/81383. Signed-off-by: Miguel Ojeda --- library/alloc/src/lib.rs | 1 - library/core/src/option.rs | 4 +--- library/core/src/result.rs | 8 ++------ library/core/tests/lib.rs | 1 - 4 files changed, 3 insertions(+), 11 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 285d7755c0689..9c6bb5dce1aeb 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -112,7 +112,6 @@ #![feature(maybe_uninit_slice)] #![cfg_attr(test, feature(new_uninit))] #![feature(nonnull_slice_from_raw_parts)] -#![feature(option_result_unwrap_unchecked)] #![feature(pattern)] #![feature(ptr_internals)] #![feature(receiver_trait)] diff --git a/library/core/src/option.rs b/library/core/src/option.rs index f4ce7d1dfb334..5842c185f20a5 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -800,19 +800,17 @@ impl Option { /// # Examples /// /// ``` - /// #![feature(option_result_unwrap_unchecked)] /// let x = Some("air"); /// assert_eq!(unsafe { x.unwrap_unchecked() }, "air"); /// ``` /// /// ```no_run - /// #![feature(option_result_unwrap_unchecked)] /// let x: Option<&str> = None; /// assert_eq!(unsafe { x.unwrap_unchecked() }, "air"); // Undefined behavior! /// ``` #[inline] #[track_caller] - #[unstable(feature = "option_result_unwrap_unchecked", reason = "newly added", issue = "81383")] + #[stable(feature = "option_result_unwrap_unchecked", since = "1.58.0")] pub unsafe fn unwrap_unchecked(self) -> T { debug_assert!(self.is_some()); match self { diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 75f2c222ba834..8fec2e928aae2 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -1096,19 +1096,17 @@ impl Result { /// # Examples /// /// ``` - /// #![feature(option_result_unwrap_unchecked)] /// let x: Result = Ok(2); /// assert_eq!(unsafe { x.unwrap_unchecked() }, 2); /// ``` /// /// ```no_run - /// #![feature(option_result_unwrap_unchecked)] /// let x: Result = Err("emergency failure"); /// unsafe { x.unwrap_unchecked(); } // Undefined behavior! /// ``` #[inline] #[track_caller] - #[unstable(feature = "option_result_unwrap_unchecked", reason = "newly added", issue = "81383")] + #[stable(feature = "option_result_unwrap_unchecked", since = "1.58.0")] pub unsafe fn unwrap_unchecked(self) -> T { debug_assert!(self.is_ok()); match self { @@ -1130,19 +1128,17 @@ impl Result { /// # Examples /// /// ```no_run - /// #![feature(option_result_unwrap_unchecked)] /// let x: Result = Ok(2); /// unsafe { x.unwrap_err_unchecked() }; // Undefined behavior! /// ``` /// /// ``` - /// #![feature(option_result_unwrap_unchecked)] /// let x: Result = Err("emergency failure"); /// assert_eq!(unsafe { x.unwrap_err_unchecked() }, "emergency failure"); /// ``` #[inline] #[track_caller] - #[unstable(feature = "option_result_unwrap_unchecked", reason = "newly added", issue = "81383")] + #[stable(feature = "option_result_unwrap_unchecked", since = "1.58.0")] pub unsafe fn unwrap_err_unchecked(self) -> E { debug_assert!(self.is_err()); match self { diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index ab0295c63143d..1934eb0546229 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -60,7 +60,6 @@ #![feature(const_raw_ptr_deref)] #![feature(never_type)] #![feature(unwrap_infallible)] -#![feature(option_result_unwrap_unchecked)] #![feature(result_into_ok_or_err)] #![feature(ptr_metadata)] #![feature(once_cell)] From 68b0d862945782f215f39980d6ac9ffabdb2031c Mon Sep 17 00:00:00 2001 From: John Kugelman Date: Thu, 14 Oct 2021 18:54:55 -0400 Subject: [PATCH 08/10] Add #[must_use] to remaining core functions --- library/alloc/tests/str.rs | 2 +- library/core/src/alloc/layout.rs | 4 ++++ library/core/src/any.rs | 3 +++ library/core/src/ascii.rs | 1 + library/core/src/cell.rs | 1 + library/core/src/char/decode.rs | 1 + library/core/src/default.rs | 1 + library/core/src/fmt/mod.rs | 9 +++++++++ library/core/src/future/mod.rs | 1 + library/core/src/iter/sources/empty.rs | 1 + library/core/src/num/error.rs | 1 + library/core/src/num/f32.rs | 1 + library/core/src/num/f64.rs | 1 + library/core/src/ops/range.rs | 1 + library/core/src/option.rs | 1 + library/core/src/panic/location.rs | 4 ++++ library/core/src/panic/panic_info.rs | 3 +++ library/core/src/pin.rs | 1 + library/core/src/slice/iter.rs | 3 +++ library/core/src/str/error.rs | 2 ++ library/core/src/str/iter.rs | 2 ++ library/core/src/str/mod.rs | 3 +++ library/core/src/str/validations.rs | 1 + library/core/src/task/wake.rs | 2 ++ library/core/src/time.rs | 3 +++ 25 files changed, 52 insertions(+), 1 deletion(-) diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs index d3a87c056cfb1..dc7d0bff9a404 100644 --- a/library/alloc/tests/str.rs +++ b/library/alloc/tests/str.rs @@ -1031,7 +1031,7 @@ fn test_split_at_mut() { #[should_panic] fn test_split_at_boundscheck() { let s = "ศไทย中华Việt Nam"; - s.split_at(1); + let _ = s.split_at(1); } #[test] diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index 780f82d8afaee..cc32d5223b49f 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -104,6 +104,7 @@ impl Layout { /// The minimum size in bytes for a memory block of this layout. #[stable(feature = "alloc_layout", since = "1.28.0")] #[rustc_const_stable(feature = "const_alloc_layout", since = "1.50.0")] + #[must_use] #[inline] pub const fn size(&self) -> usize { self.size_ @@ -137,6 +138,7 @@ impl Layout { /// allocate backing structure for `T` (which could be a trait /// or other unsized type like a slice). #[stable(feature = "alloc_layout", since = "1.28.0")] + #[must_use] #[inline] pub fn for_value(t: &T) -> Self { let (size, align) = (mem::size_of_val(t), mem::align_of_val(t)); @@ -171,6 +173,7 @@ impl Layout { /// [trait object]: ../../book/ch17-02-trait-objects.html /// [extern type]: ../../unstable-book/language-features/extern-types.html #[unstable(feature = "layout_for_ptr", issue = "69835")] + #[must_use] pub unsafe fn for_value_raw(t: *const T) -> Self { // SAFETY: we pass along the prerequisites of these functions to the caller let (size, align) = unsafe { (mem::size_of_val_raw(t), mem::align_of_val_raw(t)) }; @@ -187,6 +190,7 @@ impl Layout { /// some other means. #[unstable(feature = "alloc_layout_extra", issue = "55724")] #[rustc_const_unstable(feature = "alloc_layout_extra", issue = "55724")] + #[must_use] #[inline] pub const fn dangling(&self) -> NonNull { // SAFETY: align is guaranteed to be non-zero diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 19652106b3d01..1fd5aa27fce46 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -458,6 +458,7 @@ impl TypeId { /// assert_eq!(is_string(&0), false); /// assert_eq!(is_string(&"cookie monster".to_string()), true); /// ``` + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_type_id", issue = "77125")] pub const fn of() -> TypeId { @@ -492,6 +493,7 @@ impl TypeId { /// "core::option::Option", /// ); /// ``` +#[must_use] #[stable(feature = "type_name", since = "1.38.0")] #[rustc_const_unstable(feature = "const_type_name", issue = "63084")] pub const fn type_name() -> &'static str { @@ -534,6 +536,7 @@ pub const fn type_name() -> &'static str { /// let y = 1.0; /// println!("{}", type_name_of_val(&y)); /// ``` +#[must_use] #[unstable(feature = "type_name_of_val", issue = "66359")] #[rustc_const_unstable(feature = "const_type_name", issue = "63084")] pub const fn type_name_of_val(_val: &T) -> &'static str { diff --git a/library/core/src/ascii.rs b/library/core/src/ascii.rs index 0a456ee1eb2d5..532208e41afa2 100644 --- a/library/core/src/ascii.rs +++ b/library/core/src/ascii.rs @@ -18,6 +18,7 @@ use crate::str::from_utf8_unchecked; /// /// This `struct` is created by the [`escape_default`] function. See its /// documentation for more. +#[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct EscapeDefault { diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 2ca077a98f8dc..341fbf5c8d8b8 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1333,6 +1333,7 @@ impl<'b, T: ?Sized> Ref<'b, T> { /// with the widespread use of `r.borrow().clone()` to clone the contents of /// a `RefCell`. #[stable(feature = "cell_extras", since = "1.15.0")] + #[must_use] #[inline] pub fn clone(orig: &Ref<'b, T>) -> Ref<'b, T> { Ref { value: orig.value, borrow: orig.borrow.clone() } diff --git a/library/core/src/char/decode.rs b/library/core/src/char/decode.rs index 4784418f98c50..5dd8c5ef78941 100644 --- a/library/core/src/char/decode.rs +++ b/library/core/src/char/decode.rs @@ -128,6 +128,7 @@ impl> Iterator for DecodeUtf16 { impl DecodeUtf16Error { /// Returns the unpaired surrogate which caused this error. + #[must_use] #[stable(feature = "decode_utf16", since = "1.9.0")] pub fn unpaired_surrogate(&self) -> u16 { self.code diff --git a/library/core/src/default.rs b/library/core/src/default.rs index 0ee8cd59ba4ff..fb862f7df947b 100644 --- a/library/core/src/default.rs +++ b/library/core/src/default.rs @@ -155,6 +155,7 @@ pub trait Default: Sized { /// } /// ``` #[unstable(feature = "default_free_fn", issue = "73014")] +#[must_use] #[inline] pub fn default() -> T { Default::default() diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index b8ad7720e0c55..736959a494c5a 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -1618,6 +1618,7 @@ impl<'a> Formatter<'a> { } /// Flags for formatting + #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated( since = "1.24.0", @@ -1655,6 +1656,7 @@ impl<'a> Formatter<'a> { /// assert_eq!(&format!("{:G>3}", Foo), "GGG"); /// assert_eq!(&format!("{:t>6}", Foo), "tttttt"); /// ``` + #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn fill(&self) -> char { self.fill @@ -1691,6 +1693,7 @@ impl<'a> Formatter<'a> { /// assert_eq!(&format!("{:^}", Foo), "center"); /// assert_eq!(&format!("{}", Foo), "into the void"); /// ``` + #[must_use] #[stable(feature = "fmt_flags_align", since = "1.28.0")] pub fn align(&self) -> Option { match self.align { @@ -1725,6 +1728,7 @@ impl<'a> Formatter<'a> { /// assert_eq!(&format!("{:10}", Foo(23)), "Foo(23) "); /// assert_eq!(&format!("{}", Foo(23)), "Foo(23)"); /// ``` + #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn width(&self) -> Option { self.width @@ -1755,6 +1759,7 @@ impl<'a> Formatter<'a> { /// assert_eq!(&format!("{:.4}", Foo(23.2)), "Foo(23.2000)"); /// assert_eq!(&format!("{}", Foo(23.2)), "Foo(23.20)"); /// ``` + #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn precision(&self) -> Option { self.precision @@ -1785,6 +1790,7 @@ impl<'a> Formatter<'a> { /// assert_eq!(&format!("{:+}", Foo(23)), "Foo(+23)"); /// assert_eq!(&format!("{}", Foo(23)), "Foo(23)"); /// ``` + #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn sign_plus(&self) -> bool { self.flags & (1 << FlagV1::SignPlus as u32) != 0 @@ -1813,6 +1819,7 @@ impl<'a> Formatter<'a> { /// assert_eq!(&format!("{:-}", Foo(23)), "-Foo(23)"); /// assert_eq!(&format!("{}", Foo(23)), "Foo(23)"); /// ``` + #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn sign_minus(&self) -> bool { self.flags & (1 << FlagV1::SignMinus as u32) != 0 @@ -1840,6 +1847,7 @@ impl<'a> Formatter<'a> { /// assert_eq!(&format!("{:#}", Foo(23)), "Foo(23)"); /// assert_eq!(&format!("{}", Foo(23)), "23"); /// ``` + #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn alternate(&self) -> bool { self.flags & (1 << FlagV1::Alternate as u32) != 0 @@ -1865,6 +1873,7 @@ impl<'a> Formatter<'a> { /// /// assert_eq!(&format!("{:04}", Foo(23)), "23"); /// ``` + #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn sign_aware_zero_pad(&self) -> bool { self.flags & (1 << FlagV1::SignAwareZeroPad as u32) != 0 diff --git a/library/core/src/future/mod.rs b/library/core/src/future/mod.rs index cdde094147012..7a3af70d6d97c 100644 --- a/library/core/src/future/mod.rs +++ b/library/core/src/future/mod.rs @@ -90,6 +90,7 @@ where #[lang = "get_context"] #[doc(hidden)] #[unstable(feature = "gen_future", issue = "50547")] +#[must_use] #[inline] pub unsafe fn get_context<'a, 'b>(cx: ResumeTy) -> &'a mut Context<'b> { // SAFETY: the caller must guarantee that `cx.0` is a valid pointer diff --git a/library/core/src/iter/sources/empty.rs b/library/core/src/iter/sources/empty.rs index a7d4646f5c597..7abe01d17c90b 100644 --- a/library/core/src/iter/sources/empty.rs +++ b/library/core/src/iter/sources/empty.rs @@ -25,6 +25,7 @@ pub const fn empty() -> Empty { /// An iterator that yields nothing. /// /// This `struct` is created by the [`empty()`] function. See its documentation for more. +#[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "iter_empty", since = "1.2.0")] pub struct Empty(marker::PhantomData); diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index cdeba9c079273..a88736c3608a7 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -114,6 +114,7 @@ pub enum IntErrorKind { impl ParseIntError { /// Outputs the detailed cause of parsing an integer failing. + #[must_use] #[stable(feature = "int_error_matching", since = "1.55.0")] pub fn kind(&self) -> &IntErrorKind { &self.kind diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index ad8106df198da..86cfce7bfd0e9 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -980,6 +980,7 @@ impl f32 { /// # .all(|(a, b)| a.to_bits() == b.to_bits())) /// ``` #[unstable(feature = "total_cmp", issue = "72599")] + #[must_use] #[inline] pub fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering { let mut left = self.to_bits() as i32; diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 6a48101e04fda..b71f37ddb8a33 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -996,6 +996,7 @@ impl f64 { /// # .all(|(a, b)| a.to_bits() == b.to_bits())) /// ``` #[unstable(feature = "total_cmp", issue = "72599")] + #[must_use] #[inline] pub fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering { let mut left = self.to_bits() as i64; diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs index 347a346359f8c..b74ba92c76eb6 100644 --- a/library/core/src/ops/range.rs +++ b/library/core/src/ops/range.rs @@ -743,6 +743,7 @@ impl Bound<&T> { /// assert_eq!((1..12).start_bound(), Included(&1)); /// assert_eq!((1..12).start_bound().cloned(), Included(1)); /// ``` + #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "bound_cloned", since = "1.55.0")] pub fn cloned(self) -> Bound { match self { diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 401267f5613ee..d89cf96757b1e 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1450,6 +1450,7 @@ impl Option<&T> { /// let copied = opt_x.copied(); /// assert_eq!(copied, Some(12)); /// ``` + #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "copied", since = "1.35.0")] #[rustc_const_unstable(feature = "const_option", issue = "67441")] pub const fn copied(self) -> Option { diff --git a/library/core/src/panic/location.rs b/library/core/src/panic/location.rs index a482414caaf9a..714e9b73c78a6 100644 --- a/library/core/src/panic/location.rs +++ b/library/core/src/panic/location.rs @@ -79,6 +79,7 @@ impl<'a> Location<'a> { /// assert_ne!(this_location.line(), another_location.line()); /// assert_ne!(this_location.column(), another_location.column()); /// ``` + #[must_use] #[stable(feature = "track_caller", since = "1.46.0")] #[rustc_const_unstable(feature = "const_caller_location", issue = "76156")] #[track_caller] @@ -119,6 +120,7 @@ impl<'a> Location<'a> { /// /// panic!("Normal panic"); /// ``` + #[must_use] #[stable(feature = "panic_hooks", since = "1.10.0")] pub fn file(&self) -> &str { self.file @@ -141,6 +143,7 @@ impl<'a> Location<'a> { /// /// panic!("Normal panic"); /// ``` + #[must_use] #[stable(feature = "panic_hooks", since = "1.10.0")] pub fn line(&self) -> u32 { self.line @@ -163,6 +166,7 @@ impl<'a> Location<'a> { /// /// panic!("Normal panic"); /// ``` + #[must_use] #[stable(feature = "panic_col", since = "1.25.0")] pub fn column(&self) -> u32 { self.col diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs index a52a0022e5d2b..b1fdf13821176 100644 --- a/library/core/src/panic/panic_info.rs +++ b/library/core/src/panic/panic_info.rs @@ -81,6 +81,7 @@ impl<'a> PanicInfo<'a> { /// /// panic!("Normal panic"); /// ``` + #[must_use] #[stable(feature = "panic_hooks", since = "1.10.0")] pub fn payload(&self) -> &(dyn Any + Send) { self.payload @@ -89,6 +90,7 @@ impl<'a> PanicInfo<'a> { /// If the `panic!` macro from the `core` crate (not from `std`) /// was used with a formatting string and some additional arguments, /// returns that message ready to be used for example with [`fmt::write`] + #[must_use] #[unstable(feature = "panic_info_message", issue = "66745")] pub fn message(&self) -> Option<&fmt::Arguments<'_>> { self.message @@ -118,6 +120,7 @@ impl<'a> PanicInfo<'a> { /// /// panic!("Normal panic"); /// ``` + #[must_use] #[stable(feature = "panic_hooks", since = "1.10.0")] pub fn location(&self) -> Option<&Location<'_>> { // NOTE: If this is changed to sometimes return None, diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 34fc874ada09b..09fc6df542975 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -705,6 +705,7 @@ impl<'a, T: ?Sized> Pin<&'a T> { /// /// ["pinning projections"]: self#projections-and-structural-pinning #[inline(always)] + #[must_use] #[rustc_const_unstable(feature = "const_pin", issue = "76654")] #[stable(feature = "pin", since = "1.33.0")] pub const fn get_ref(self) -> &'a T { diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index dbf97851b03e4..4e6c2bac274e0 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -1714,6 +1714,7 @@ impl<'a, T> ChunksExact<'a, T> { /// Returns the remainder of the original slice that is not going to be /// returned by the iterator. The returned slice has at most `chunk_size-1` /// elements. + #[must_use] #[stable(feature = "chunks_exact", since = "1.31.0")] pub fn remainder(&self) -> &'a [T] { self.rem @@ -2143,6 +2144,7 @@ impl<'a, T, const N: usize> ArrayChunks<'a, T, N> { /// Returns the remainder of the original slice that is not going to be /// returned by the iterator. The returned slice has at most `N-1` /// elements. + #[must_use] #[unstable(feature = "array_chunks", issue = "74985")] pub fn remainder(&self) -> &'a [T] { self.rem @@ -2718,6 +2720,7 @@ impl<'a, T> RChunksExact<'a, T> { /// Returns the remainder of the original slice that is not going to be /// returned by the iterator. The returned slice has at most `chunk_size-1` /// elements. + #[must_use] #[stable(feature = "rchunks", since = "1.31.0")] pub fn remainder(&self) -> &'a [T] { self.rem diff --git a/library/core/src/str/error.rs b/library/core/src/str/error.rs index aa735a14cbd8f..b6460d72fef32 100644 --- a/library/core/src/str/error.rs +++ b/library/core/src/str/error.rs @@ -72,6 +72,7 @@ impl Utf8Error { /// assert_eq!(1, error.valid_up_to()); /// ``` #[stable(feature = "utf8_error", since = "1.5.0")] + #[must_use] #[inline] pub fn valid_up_to(&self) -> usize { self.valid_up_to @@ -93,6 +94,7 @@ impl Utf8Error { /// /// [U+FFFD]: ../../std/char/constant.REPLACEMENT_CHARACTER.html #[stable(feature = "utf8_error_error_len", since = "1.20.0")] + #[must_use] #[inline] pub fn error_len(&self) -> Option { self.error_len.map(|len| len as usize) diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs index 94cb81e9d41a1..7e0cd7d65ba69 100644 --- a/library/core/src/str/iter.rs +++ b/library/core/src/str/iter.rs @@ -211,6 +211,7 @@ impl<'a> CharIndices<'a> { /// assert_eq!(chars.next(), None); /// ``` #[inline] + #[must_use] #[unstable(feature = "char_indices_offset", issue = "83871")] pub fn offset(&self) -> usize { self.front_offset @@ -223,6 +224,7 @@ impl<'a> CharIndices<'a> { /// See its documentation for more. /// /// [`bytes`]: str::bytes +#[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone, Debug)] pub struct Bytes<'a>(pub(super) Copied>); diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 607a0179ff4b9..ac07dc32d57e6 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -498,6 +498,7 @@ impl str { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.29.0", reason = "use `get_unchecked(begin..end)` instead")] + #[must_use] #[inline] pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str { // SAFETY: the caller must uphold the safety contract for `get_unchecked`; @@ -570,6 +571,7 @@ impl str { /// assert_eq!(" Martin-Löf", last); /// ``` #[inline] + #[must_use] #[stable(feature = "str_split_at", since = "1.4.0")] pub fn split_at(&self, mid: usize) -> (&str, &str) { // is_char_boundary checks that the index is in [0, .len()] @@ -613,6 +615,7 @@ impl str { /// assert_eq!("PER Martin-Löf", s); /// ``` #[inline] + #[must_use] #[stable(feature = "str_split_at", since = "1.4.0")] pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) { // is_char_boundary checks that the index is in [0, .len()] diff --git a/library/core/src/str/validations.rs b/library/core/src/str/validations.rs index 093c9c37b60b4..75f8a2a759314 100644 --- a/library/core/src/str/validations.rs +++ b/library/core/src/str/validations.rs @@ -251,6 +251,7 @@ static UTF8_CHAR_WIDTH: [u8; 256] = [ /// Given a first byte, determines how many bytes are in this UTF-8 character. #[unstable(feature = "str_internals", issue = "none")] +#[must_use] #[inline] pub fn utf8_char_width(b: u8) -> usize { UTF8_CHAR_WIDTH[b as usize] as usize diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 620bff5387994..6cba781c2ed8f 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -167,6 +167,7 @@ impl<'a> Context<'a> { /// Returns a reference to the `Waker` for the current task. #[stable(feature = "futures_api", since = "1.36.0")] + #[must_use] #[inline] pub fn waker(&self) -> &'a Waker { &self.waker @@ -242,6 +243,7 @@ impl Waker { /// /// This function is primarily used for optimization purposes. #[inline] + #[must_use] #[stable(feature = "futures_api", since = "1.36.0")] pub fn will_wake(&self, other: &Waker) -> bool { self.waker == other.waker diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 5a74f39e8bc8b..d0bdf1b7df272 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -357,6 +357,7 @@ impl Duration { /// ``` #[stable(feature = "duration_extras", since = "1.27.0")] #[rustc_const_stable(feature = "duration_extras", since = "1.32.0")] + #[must_use] #[inline] pub const fn subsec_millis(&self) -> u32 { self.nanos / NANOS_PER_MILLI @@ -379,6 +380,7 @@ impl Duration { /// ``` #[stable(feature = "duration_extras", since = "1.27.0")] #[rustc_const_stable(feature = "duration_extras", since = "1.32.0")] + #[must_use] #[inline] pub const fn subsec_micros(&self) -> u32 { self.nanos / NANOS_PER_MICRO @@ -401,6 +403,7 @@ impl Duration { /// ``` #[stable(feature = "duration", since = "1.3.0")] #[rustc_const_stable(feature = "duration", since = "1.32.0")] + #[must_use] #[inline] pub const fn subsec_nanos(&self) -> u32 { self.nanos From 887503ad144a8c4f955be2d1220e78cf8f707360 Mon Sep 17 00:00:00 2001 From: John Kugelman Date: Tue, 12 Oct 2021 22:28:14 -0400 Subject: [PATCH 09/10] Add #[must_use] to mem/ptr functions --- library/core/src/mem/mod.rs | 13 +++++++++++++ library/core/src/ptr/mod.rs | 2 ++ library/core/src/ptr/non_null.rs | 2 ++ library/core/src/ptr/unique.rs | 1 + src/test/ui/issues/issue-31299.rs | 1 + 5 files changed, 19 insertions(+) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 894ae10e1b4ba..7d005666a74a6 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -296,6 +296,7 @@ pub fn forget_unsized(t: T) { /// /// [alignment]: align_of #[inline(always)] +#[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_promotable] #[rustc_const_stable(feature = "const_size_of", since = "1.24.0")] @@ -324,6 +325,7 @@ pub const fn size_of() -> usize { /// assert_eq!(13, mem::size_of_val(y)); /// ``` #[inline] +#[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_size_of_val", issue = "46571")] #[cfg_attr(not(test), rustc_diagnostic_item = "mem_size_of_val")] @@ -373,6 +375,7 @@ pub const fn size_of_val(val: &T) -> usize { /// assert_eq!(13, unsafe { mem::size_of_val_raw(y) }); /// ``` #[inline] +#[must_use] #[unstable(feature = "layout_for_ptr", issue = "69835")] #[rustc_const_unstable(feature = "const_size_of_val_raw", issue = "46571")] pub const unsafe fn size_of_val_raw(val: *const T) -> usize { @@ -397,6 +400,7 @@ pub const unsafe fn size_of_val_raw(val: *const T) -> usize { /// assert_eq!(4, mem::min_align_of::()); /// ``` #[inline] +#[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(reason = "use `align_of` instead", since = "1.2.0")] pub fn min_align_of() -> usize { @@ -418,6 +422,7 @@ pub fn min_align_of() -> usize { /// assert_eq!(4, mem::min_align_of_val(&5i32)); /// ``` #[inline] +#[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(reason = "use `align_of_val` instead", since = "1.2.0")] pub fn min_align_of_val(val: &T) -> usize { @@ -441,6 +446,7 @@ pub fn min_align_of_val(val: &T) -> usize { /// assert_eq!(4, mem::align_of::()); /// ``` #[inline(always)] +#[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_promotable] #[rustc_const_stable(feature = "const_align_of", since = "1.24.0")] @@ -462,6 +468,7 @@ pub const fn align_of() -> usize { /// assert_eq!(4, mem::align_of_val(&5i32)); /// ``` #[inline] +#[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_align_of_val", issue = "46571")] #[allow(deprecated)] @@ -507,6 +514,7 @@ pub const fn align_of_val(val: &T) -> usize { /// assert_eq!(4, unsafe { mem::align_of_val_raw(&5i32) }); /// ``` #[inline] +#[must_use] #[unstable(feature = "layout_for_ptr", issue = "69835")] #[rustc_const_unstable(feature = "const_align_of_val_raw", issue = "46571")] pub const unsafe fn align_of_val_raw(val: *const T) -> usize { @@ -571,6 +579,7 @@ pub const unsafe fn align_of_val_raw(val: *const T) -> usize { /// } /// ``` #[inline] +#[must_use] #[stable(feature = "needs_drop", since = "1.21.0")] #[rustc_const_stable(feature = "const_needs_drop", since = "1.36.0")] #[rustc_diagnostic_item = "needs_drop"] @@ -618,6 +627,7 @@ pub const fn needs_drop() -> bool { /// let _y: fn() = unsafe { mem::zeroed() }; // And again! /// ``` #[inline(always)] +#[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated_in_future)] #[allow(deprecated)] @@ -653,6 +663,7 @@ pub unsafe fn zeroed() -> T { /// [assume_init]: MaybeUninit::assume_init /// [inv]: MaybeUninit#initialization-invariant #[inline(always)] +#[must_use] #[rustc_deprecated(since = "1.39.0", reason = "use `mem::MaybeUninit` instead")] #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated_in_future)] @@ -938,6 +949,7 @@ pub fn drop(_x: T) {} /// assert_eq!(foo_array, [10]); /// ``` #[inline] +#[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_transmute_copy", issue = "83165")] pub const unsafe fn transmute_copy(src: &T) -> U { @@ -1051,6 +1063,7 @@ pub const fn discriminant(v: &T) -> Discriminant { /// assert_eq!(mem::variant_count::>(), 2); /// ``` #[inline(always)] +#[must_use] #[unstable(feature = "variant_count", issue = "73662")] #[rustc_const_unstable(feature = "variant_count", issue = "73662")] #[rustc_diagnostic_item = "mem_variant_count"] diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 014170604ecaa..8ab72e6aeeafa 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -204,6 +204,7 @@ pub unsafe fn drop_in_place(to_drop: *mut T) { /// assert!(p.is_null()); /// ``` #[inline(always)] +#[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_promotable] #[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")] @@ -223,6 +224,7 @@ pub const fn null() -> *const T { /// assert!(p.is_null()); /// ``` #[inline(always)] +#[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_promotable] #[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")] diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index af9daf8297401..8e053688b21f6 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -83,6 +83,7 @@ impl NonNull { /// ``` #[stable(feature = "nonnull", since = "1.25.0")] #[rustc_const_stable(feature = "const_nonnull_dangling", since = "1.36.0")] + #[must_use] #[inline] pub const fn dangling() -> Self { // SAFETY: mem::align_of() returns a non-zero usize which is then casted @@ -419,6 +420,7 @@ impl NonNull<[T]> { /// but `let slice = NonNull::from(&x[..]);` would be a better way to write code like this.) #[unstable(feature = "nonnull_slice_from_raw_parts", issue = "71941")] #[rustc_const_unstable(feature = "const_nonnull_slice_from_raw_parts", issue = "71941")] + #[must_use] #[inline] pub const fn slice_from_raw_parts(data: NonNull, len: usize) -> Self { // SAFETY: `data` is a `NonNull` pointer which is necessarily non-null diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index 5baceefb504a5..51d67436b85d6 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -68,6 +68,7 @@ impl Unique { /// a `T`, which means this must not be used as a "not yet initialized" /// sentinel value. Types that lazily allocate must track initialization by /// some other means. + #[must_use] #[inline] pub const fn dangling() -> Self { // SAFETY: mem::align_of() returns a valid, non-null pointer. The diff --git a/src/test/ui/issues/issue-31299.rs b/src/test/ui/issues/issue-31299.rs index abed18d81f8d3..d93ffcb2262eb 100644 --- a/src/test/ui/issues/issue-31299.rs +++ b/src/test/ui/issues/issue-31299.rs @@ -29,6 +29,7 @@ struct PtrBack(Vec); struct M(PtrBack>); +#[allow(unused_must_use)] fn main() { std::mem::size_of::(); } From 42e0282d5201dc825307582fbb48f05144d78ee0 Mon Sep 17 00:00:00 2001 From: John Kugelman Date: Sat, 30 Oct 2021 22:06:31 -0400 Subject: [PATCH 10/10] Add #[must_use] to alloc functions that would leak memory --- library/alloc/src/alloc.rs | 3 +++ library/alloc/src/sync.rs | 1 + 2 files changed, 4 insertions(+) diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 4a5b0fcf03709..66ef92558d8b5 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -81,6 +81,7 @@ pub use std::alloc::Global; /// } /// ``` #[stable(feature = "global_alloc", since = "1.28.0")] +#[must_use = "losing the pointer will leak memory"] #[inline] pub unsafe fn alloc(layout: Layout) -> *mut u8 { unsafe { __rust_alloc(layout.size(), layout.align()) } @@ -117,6 +118,7 @@ pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { /// /// See [`GlobalAlloc::realloc`]. #[stable(feature = "global_alloc", since = "1.28.0")] +#[must_use = "losing the pointer will leak memory"] #[inline] pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { unsafe { __rust_realloc(ptr, layout.size(), layout.align(), new_size) } @@ -150,6 +152,7 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 /// } /// ``` #[stable(feature = "global_alloc", since = "1.28.0")] +#[must_use = "losing the pointer will leak memory"] #[inline] pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 { unsafe { __rust_alloc_zeroed(layout.size(), layout.align()) } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index b75e9a2f3c71e..00bd69aad4c3b 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -804,6 +804,7 @@ impl Arc { /// let x_ptr = Arc::into_raw(x); /// assert_eq!(unsafe { &*x_ptr }, "hello"); /// ``` + #[must_use = "losing the pointer will leak memory"] #[stable(feature = "rc_raw", since = "1.17.0")] pub fn into_raw(this: Self) -> *const T { let ptr = Self::as_ptr(&this);