From 54d807cfc7f529ac1812ff1a9f4475c109f308e8 Mon Sep 17 00:00:00 2001 From: John Kugelman Date: Sat, 9 Oct 2021 01:01:40 -0400 Subject: [PATCH] Add #[must_use] to string/char transformation methods These methods could be misconstrued as modifying their arguments instead of returning new values. Where possible I made the note recommend a method that does mutate in place. --- library/alloc/src/slice.rs | 4 ++++ library/alloc/src/str.rs | 6 ++++++ library/core/src/char/methods.rs | 6 ++++++ library/core/src/num/mod.rs | 4 ++++ library/core/src/slice/ascii.rs | 2 ++ library/core/src/str/mod.rs | 16 ++++++++++++++++ library/std/src/ffi/os_str.rs | 2 ++ 7 files changed, 40 insertions(+) diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 4c8ea6902ff..860f21085f3 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -662,6 +662,8 @@ impl [u8] { /// /// [`make_ascii_uppercase`]: slice::make_ascii_uppercase #[cfg(not(no_global_oom_handling))] + #[must_use = "this returns the uppercase bytes as a new Vec, \ + without modifying the original"] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn to_ascii_uppercase(&self) -> Vec { @@ -680,6 +682,8 @@ pub fn to_ascii_uppercase(&self) -> Vec { /// /// [`make_ascii_lowercase`]: slice::make_ascii_lowercase #[cfg(not(no_global_oom_handling))] + #[must_use = "this returns the lowercase bytes as a new Vec, \ + without modifying the original"] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn to_ascii_lowercase(&self) -> Vec { diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index 62ba2e57655..2900d01d9bd 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -367,6 +367,8 @@ pub fn replacen<'a, P: Pattern<'a>>(&'a self, pat: P, to: &str, count: usize) -> /// assert_eq!(new_year, new_year.to_lowercase()); /// ``` #[cfg(not(no_global_oom_handling))] + #[must_use = "this returns the lowercase string as a new String, \ + without modifying the original"] #[stable(feature = "unicode_case_mapping", since = "1.2.0")] pub fn to_lowercase(&self) -> String { let mut s = String::with_capacity(self.len()); @@ -447,6 +449,8 @@ fn case_ignoreable_then_cased>(iter: I) -> bool { /// assert_eq!("TSCHÜSS", s.to_uppercase()); /// ``` #[cfg(not(no_global_oom_handling))] + #[must_use = "this returns the uppercase string as a new String, \ + without modifying the original"] #[stable(feature = "unicode_case_mapping", since = "1.2.0")] pub fn to_uppercase(&self) -> String { let mut s = String::with_capacity(self.len()); @@ -534,6 +538,7 @@ pub fn repeat(&self, n: usize) -> String { /// [`make_ascii_uppercase`]: str::make_ascii_uppercase /// [`to_uppercase`]: #method.to_uppercase #[cfg(not(no_global_oom_handling))] + #[must_use = "to uppercase the value in-place, use `make_ascii_lowercase()`"] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn to_ascii_uppercase(&self) -> String { @@ -565,6 +570,7 @@ pub fn to_ascii_uppercase(&self) -> String { /// [`make_ascii_lowercase`]: str::make_ascii_lowercase /// [`to_lowercase`]: #method.to_lowercase #[cfg(not(no_global_oom_handling))] + #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase()`"] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[inline] pub fn to_ascii_lowercase(&self) -> String { diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index b1dd6aef974..b3af1f1ffb5 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -949,6 +949,8 @@ pub fn is_numeric(self) -> bool { /// // convert into themselves. /// assert_eq!('山'.to_lowercase().to_string(), "山"); /// ``` + #[must_use = "this returns the lowercase character as a new iterator, \ + without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn to_lowercase(self) -> ToLowercase { @@ -1039,6 +1041,8 @@ pub fn to_lowercase(self) -> ToLowercase { /// ``` /// /// holds across languages. + #[must_use = "this returns the uppercase character as a new iterator, \ + without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn to_uppercase(self) -> ToUppercase { @@ -1085,6 +1089,7 @@ pub const fn is_ascii(&self) -> bool { /// /// [`make_ascii_uppercase()`]: #method.make_ascii_uppercase /// [`to_uppercase()`]: #method.to_uppercase + #[must_use = "to uppercase the value in-place, use `make_ascii_uppercase()`"] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")] #[inline] @@ -1118,6 +1123,7 @@ pub const fn to_ascii_uppercase(&self) -> char { /// /// [`make_ascii_lowercase()`]: #method.make_ascii_lowercase /// [`to_lowercase()`]: #method.to_lowercase + #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase()`"] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")] #[inline] diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index d5fb98eff57..d9cac8b4259 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -282,6 +282,7 @@ pub const fn is_ascii(&self) -> bool { /// ``` /// /// [`make_ascii_uppercase`]: Self::make_ascii_uppercase + #[must_use = "to uppercase the value in-place, use `make_ascii_lowercase()`"] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")] #[inline] @@ -306,6 +307,7 @@ pub const fn to_ascii_uppercase(&self) -> u8 { /// ``` /// /// [`make_ascii_lowercase`]: Self::make_ascii_lowercase + #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase()`"] #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] #[rustc_const_stable(feature = "const_ascii_methods_on_intrinsics", since = "1.52.0")] #[inline] @@ -769,6 +771,8 @@ pub const fn is_ascii_control(&self) -> bool { /// assert_eq!("\\\\", b'\\'.escape_ascii().to_string()); /// assert_eq!("\\x9d", b'\x9d'.escape_ascii().to_string()); /// ``` + #[must_use = "this returns the escaped byte as an iterator, \ + without modifying the original"] #[unstable(feature = "inherent_ascii_escape", issue = "77174")] #[inline] pub fn escape_ascii(&self) -> ascii::EscapeDefault { diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index b92ab7e3475..cbb5627cef9 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -72,6 +72,8 @@ pub fn make_ascii_lowercase(&mut self) { /// let escaped = s.escape_ascii().to_string(); /// assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d"); /// ``` + #[must_use = "this returns the escaped bytes as an iterator, \ + without modifying the original"] #[unstable(feature = "inherent_ascii_escape", issue = "77174")] pub fn escape_ascii(&self) -> EscapeAscii<'_> { EscapeAscii { inner: self.iter().flat_map(EscapeByte) } diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 607fb627605..993e22a5b50 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -798,6 +798,8 @@ pub fn bytes(&self) -> Bytes<'_> { /// /// assert_eq!(None, iter.next()); /// ``` + #[must_use = "this returns the split string as an iterator, \ + without modifying the original"] #[stable(feature = "split_whitespace", since = "1.1.0")] #[inline] pub fn split_whitespace(&self) -> SplitWhitespace<'_> { @@ -839,6 +841,8 @@ pub fn split_whitespace(&self) -> SplitWhitespace<'_> { /// /// assert_eq!(None, iter.next()); /// ``` + #[must_use = "this returns the split string as an iterator, \ + without modifying the original"] #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] #[inline] pub fn split_ascii_whitespace(&self) -> SplitAsciiWhitespace<'_> { @@ -914,6 +918,8 @@ pub fn lines_any(&self) -> LinesAny<'_> { /// /// assert!(utf16_len <= utf8_len); /// ``` + #[must_use = "this returns the encoded string as an iterator, \ + without modifying the original"] #[stable(feature = "encode_utf16", since = "1.8.0")] pub fn encode_utf16(&self) -> EncodeUtf16<'_> { EncodeUtf16 { chars: self.chars(), extra: 0 } @@ -1840,6 +1846,8 @@ pub fn trim_end(&self) -> &str { /// let s = " עברית"; /// assert!(Some('ע') == s.trim_left().chars().next()); /// ``` + #[must_use = "this returns the trimmed string as a new slice, \ + without modifying the original"] #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated( @@ -1882,6 +1890,8 @@ pub fn trim_left(&self) -> &str { /// let s = "עברית "; /// assert!(Some('ת') == s.trim_right().chars().rev().next()); /// ``` + #[must_use = "this returns the trimmed string as a new slice, \ + without modifying the original"] #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated( @@ -2346,6 +2356,8 @@ pub fn make_ascii_lowercase(&mut self) { /// ``` /// assert_eq!("❤\n!".escape_debug().to_string(), "❤\\n!"); /// ``` + #[must_use = "this returns the escaped string as an iterator, \ + without modifying the original"] #[stable(feature = "str_escape", since = "1.34.0")] pub fn escape_debug(&self) -> EscapeDebug<'_> { let mut chars = self.chars(); @@ -2390,6 +2402,8 @@ pub fn escape_debug(&self) -> EscapeDebug<'_> { /// ``` /// assert_eq!("❤\n!".escape_default().to_string(), "\\u{2764}\\n!"); /// ``` + #[must_use = "this returns the escaped string as an iterator, \ + without modifying the original"] #[stable(feature = "str_escape", since = "1.34.0")] pub fn escape_default(&self) -> EscapeDefault<'_> { EscapeDefault { inner: self.chars().flat_map(CharEscapeDefault) } @@ -2426,6 +2440,8 @@ pub fn escape_default(&self) -> EscapeDefault<'_> { /// ``` /// assert_eq!("❤\n!".escape_unicode().to_string(), "\\u{2764}\\u{a}\\u{21}"); /// ``` + #[must_use = "this returns the escaped string as an iterator, \ + without modifying the original"] #[stable(feature = "str_escape", since = "1.34.0")] pub fn escape_unicode(&self) -> EscapeUnicode<'_> { EscapeUnicode { inner: self.chars().flat_map(CharEscapeUnicode) } diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 7e70901076c..c305519dd44 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -777,6 +777,7 @@ pub fn make_ascii_uppercase(&mut self) { /// /// assert_eq!("grüße, jürgen ❤", s.to_ascii_lowercase()); /// ``` + #[must_use = "to lowercase the value in-place, use `make_ascii_lowercase`"] #[stable(feature = "osstring_ascii", since = "1.53.0")] pub fn to_ascii_lowercase(&self) -> OsString { OsString::from_inner(self.inner.to_ascii_lowercase()) @@ -798,6 +799,7 @@ pub fn to_ascii_lowercase(&self) -> OsString { /// /// assert_eq!("GRüßE, JüRGEN ❤", s.to_ascii_uppercase()); /// ``` + #[must_use = "to uppercase the value in-place, use `make_ascii_uppercase`"] #[stable(feature = "osstring_ascii", since = "1.53.0")] pub fn to_ascii_uppercase(&self) -> OsString { OsString::from_inner(self.inner.to_ascii_uppercase())