From da73525bdc79280eba8e5a6f23e7f74a6fa86999 Mon Sep 17 00:00:00 2001 From: Kornel Date: Fri, 20 Dec 2024 17:02:46 +0000 Subject: [PATCH] Less unwrap() in documentation --- alloc/src/collections/binary_heap/mod.rs | 3 +-- core/src/cell/once.rs | 12 ++++++---- core/src/fmt/mod.rs | 11 +++++---- core/src/iter/sources/once.rs | 3 ++- core/src/iter/traits/iterator.rs | 6 ++--- core/src/option.rs | 8 ++++++- core/src/ptr/const_ptr.rs | 9 +++++--- core/src/result.rs | 11 ++++++--- core/src/str/converts.rs | 5 ++-- core/src/sync/atomic.rs | 4 ++-- std/src/io/mod.rs | 25 ++++++++++++-------- std/src/process.rs | 29 ++++++++++++------------ 12 files changed, 76 insertions(+), 50 deletions(-) diff --git a/alloc/src/collections/binary_heap/mod.rs b/alloc/src/collections/binary_heap/mod.rs index 116e0e73e9659..965fd63a52981 100644 --- a/alloc/src/collections/binary_heap/mod.rs +++ b/alloc/src/collections/binary_heap/mod.rs @@ -531,8 +531,7 @@ impl BinaryHeap { /// heap.push(1); /// heap.push(5); /// heap.push(2); - /// { - /// let mut val = heap.peek_mut().unwrap(); + /// if let Some(mut val) = heap.peek_mut() { /// *val = 0; /// } /// assert_eq!(heap.peek(), Some(&2)); diff --git a/core/src/cell/once.rs b/core/src/cell/once.rs index c14afe0f4761c..6a85791916a61 100644 --- a/core/src/cell/once.rs +++ b/core/src/cell/once.rs @@ -262,7 +262,9 @@ impl OnceCell { /// /// let value = cell.get_mut_or_try_init(|| "1234".parse()); /// assert_eq!(value, Ok(&mut 1234)); - /// *value.unwrap() += 2; + /// + /// let Ok(value) = value else { return; }; + /// *value += 2; /// assert_eq!(cell.get(), Some(&1236)) /// ``` #[unstable(feature = "once_cell_get_mut", issue = "121641")] @@ -304,8 +306,8 @@ impl OnceCell { /// assert_eq!(cell.into_inner(), None); /// /// let cell = OnceCell::new(); - /// cell.set("hello".to_string()).unwrap(); - /// assert_eq!(cell.into_inner(), Some("hello".to_string())); + /// let _ = cell.set("hello".to_owned()); + /// assert_eq!(cell.into_inner(), Some("hello".to_owned())); /// ``` #[inline] #[stable(feature = "once_cell", since = "1.70.0")] @@ -332,8 +334,8 @@ impl OnceCell { /// assert_eq!(cell.take(), None); /// /// let mut cell = OnceCell::new(); - /// cell.set("hello".to_string()).unwrap(); - /// assert_eq!(cell.take(), Some("hello".to_string())); + /// let _ = cell.set("hello".to_owned()); + /// assert_eq!(cell.take(), Some("hello".to_owned())); /// assert_eq!(cell.get(), None); /// ``` #[inline] diff --git a/core/src/fmt/mod.rs b/core/src/fmt/mod.rs index 14c7006510162..c2c78dd9c67eb 100644 --- a/core/src/fmt/mod.rs +++ b/core/src/fmt/mod.rs @@ -152,8 +152,9 @@ pub trait Write { /// } /// /// let mut buf = String::new(); - /// writer(&mut buf, "hola").unwrap(); + /// writer(&mut buf, "hola")?; /// assert_eq!(&buf, "hola"); + /// # std::fmt::Result::Ok(()) /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn write_str(&mut self, s: &str) -> Result; @@ -179,9 +180,10 @@ pub trait Write { /// } /// /// let mut buf = String::new(); - /// writer(&mut buf, 'a').unwrap(); - /// writer(&mut buf, 'b').unwrap(); + /// writer(&mut buf, 'a')?; + /// writer(&mut buf, 'b')?; /// assert_eq!(&buf, "ab"); + /// # std::fmt::Result::Ok(()) /// ``` #[stable(feature = "fmt_write_char", since = "1.1.0")] fn write_char(&mut self, c: char) -> Result { @@ -208,8 +210,9 @@ pub trait Write { /// } /// /// let mut buf = String::new(); - /// writer(&mut buf, "world").unwrap(); + /// writer(&mut buf, "world")?; /// assert_eq!(&buf, "world"); + /// # std::fmt::Result::Ok(()) /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn write_fmt(&mut self, args: Arguments<'_>) -> Result { diff --git a/core/src/iter/sources/once.rs b/core/src/iter/sources/once.rs index 21be4377da1ca..c4a9860bdd76c 100644 --- a/core/src/iter/sources/once.rs +++ b/core/src/iter/sources/once.rs @@ -34,7 +34,7 @@ use crate::iter::{FusedIterator, TrustedLen}; /// use std::fs; /// use std::path::PathBuf; /// -/// let dirs = fs::read_dir(".foo").unwrap(); +/// let dirs = fs::read_dir(".foo")?; /// /// // we need to convert from an iterator of DirEntry-s to an iterator of /// // PathBufs, so we use map @@ -50,6 +50,7 @@ use crate::iter::{FusedIterator, TrustedLen}; /// for f in files { /// println!("{f:?}"); /// } +/// # std::io::Result::Ok(()) /// ``` #[stable(feature = "iter_once", since = "1.2.0")] pub fn once(value: T) -> Once { diff --git a/core/src/iter/traits/iterator.rs b/core/src/iter/traits/iterator.rs index 38dfbbef39323..ff39e8ac25f8f 100644 --- a/core/src/iter/traits/iterator.rs +++ b/core/src/iter/traits/iterator.rs @@ -2564,7 +2564,7 @@ pub trait Iterator { /// # Example /// /// ``` - /// let reduced: i32 = (1..10).reduce(|acc, e| acc + e).unwrap(); + /// let reduced: i32 = (1..10).reduce(|acc, e| acc + e).unwrap_or(0); /// assert_eq!(reduced, 45); /// /// // Which is equivalent to doing it with `fold`: @@ -3087,7 +3087,7 @@ pub trait Iterator { /// [2.4, f32::NAN, 1.3] /// .into_iter() /// .reduce(f32::max) - /// .unwrap(), + /// .unwrap_or(0.), /// 2.4 /// ); /// ``` @@ -3123,7 +3123,7 @@ pub trait Iterator { /// [2.4, f32::NAN, 1.3] /// .into_iter() /// .reduce(f32::min) - /// .unwrap(), + /// .unwrap_or(0.), /// 1.3 /// ); /// ``` diff --git a/core/src/option.rs b/core/src/option.rs index f4ac7af63961b..a9f06b92ad5dd 100644 --- a/core/src/option.rs +++ b/core/src/option.rs @@ -937,10 +937,16 @@ impl Option { /// Returns the contained [`Some`] value, consuming the `self` value. /// /// Because this function may panic, its use is generally discouraged. + /// Panics are meant for unrecoverable errors, and + /// [may abort the entire program][panic-abort]. + /// /// Instead, prefer to use pattern matching and handle the [`None`] /// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or - /// [`unwrap_or_default`]. + /// [`unwrap_or_default`]. In functions returning `Option`, you can use + /// [the `?` (try) operator][try-option]. /// + /// [panic-abort]: https://doc.rust-lang.org/book/ch09-01-unrecoverable-errors-with-panic.html + /// [try-option]: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#where-the--operator-can-be-used /// [`unwrap_or`]: Option::unwrap_or /// [`unwrap_or_else`]: Option::unwrap_or_else /// [`unwrap_or_default`]: Option::unwrap_or_default diff --git a/core/src/ptr/const_ptr.rs b/core/src/ptr/const_ptr.rs index f100adecbbb76..ac905eceaa803 100644 --- a/core/src/ptr/const_ptr.rs +++ b/core/src/ptr/const_ptr.rs @@ -502,11 +502,12 @@ impl *const T { /// let mut out = String::new(); /// while ptr != end_rounded_up { /// unsafe { - /// write!(&mut out, "{}, ", *ptr).unwrap(); + /// write!(&mut out, "{}, ", *ptr)?; /// } /// ptr = ptr.wrapping_offset(step); /// } /// assert_eq!(out.as_str(), "1, 3, 5, "); + /// # std::fmt::Result::Ok(()) /// ``` #[stable(feature = "ptr_wrapping_offset", since = "1.16.0")] #[must_use = "returns a new pointer rather than modifying its argument"] @@ -1125,11 +1126,12 @@ impl *const T { /// let mut out = String::new(); /// while ptr != end_rounded_up { /// unsafe { - /// write!(&mut out, "{}, ", *ptr).unwrap(); + /// write!(&mut out, "{}, ", *ptr)?; /// } /// ptr = ptr.wrapping_add(step); /// } /// assert_eq!(out, "1, 3, 5, "); + /// # std::fmt::Result::Ok(()) /// ``` #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] @@ -1203,11 +1205,12 @@ impl *const T { /// let mut out = String::new(); /// while ptr != start_rounded_down { /// unsafe { - /// write!(&mut out, "{}, ", *ptr).unwrap(); + /// write!(&mut out, "{}, ", *ptr)?; /// } /// ptr = ptr.wrapping_sub(step); /// } /// assert_eq!(out, "5, 3, 1, "); + /// # std::fmt::Result::Ok(()) /// ``` #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] diff --git a/core/src/result.rs b/core/src/result.rs index 9c7be618bc773..92b5cba153166 100644 --- a/core/src/result.rs +++ b/core/src/result.rs @@ -1065,10 +1065,15 @@ impl Result { /// Returns the contained [`Ok`] value, consuming the `self` value. /// /// Because this function may panic, its use is generally discouraged. - /// Instead, prefer to use pattern matching and handle the [`Err`] - /// case explicitly, or call [`unwrap_or`], [`unwrap_or_else`], or - /// [`unwrap_or_default`]. + /// Panics are meant for unrecoverable errors, and + /// [may abort the entire program][panic-abort]. + /// + /// Instead, prefer to use [the `?` (try) operator][try-operator], or pattern matching + /// to handle the [`Err`] case explicitly, or call [`unwrap_or`], + /// [`unwrap_or_else`], or [`unwrap_or_default`]. /// + /// [panic-abort]: https://doc.rust-lang.org/book/ch09-01-unrecoverable-errors-with-panic.html + /// [try-operator]: https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator /// [`unwrap_or`]: Result::unwrap_or /// [`unwrap_or_else`]: Result::unwrap_or_else /// [`unwrap_or_default`]: Result::unwrap_or_default diff --git a/core/src/str/converts.rs b/core/src/str/converts.rs index c7bae42765f4e..de68f80aa0c8e 100644 --- a/core/src/str/converts.rs +++ b/core/src/str/converts.rs @@ -47,10 +47,11 @@ use crate::{mem, ptr}; /// // some bytes, in a vector /// let sparkle_heart = vec![240, 159, 146, 150]; /// -/// // We know these bytes are valid, so just use `unwrap()`. -/// let sparkle_heart = str::from_utf8(&sparkle_heart).unwrap(); +/// // We can use the ? (try) operator to check if the bytes are valid +/// let sparkle_heart = str::from_utf8(&sparkle_heart)?; /// /// assert_eq!("💖", sparkle_heart); +/// # Ok::<_, str::Utf8Error>(()) /// ``` /// /// Incorrect bytes: diff --git a/core/src/sync/atomic.rs b/core/src/sync/atomic.rs index 487fffba881b3..fda26a672990a 100644 --- a/core/src/sync/atomic.rs +++ b/core/src/sync/atomic.rs @@ -86,7 +86,7 @@ //! // This is fine: `join` synchronizes the code in a way such that the atomic //! // store happens-before the non-atomic write. //! let handle = s.spawn(|| atomic.store(1, Ordering::Relaxed)); // atomic store -//! handle.join().unwrap(); // synchronize +//! handle.join().expect("thread won't panic"); // synchronize //! s.spawn(|| unsafe { atomic.as_ptr().write(2) }); // non-atomic write //! }); //! @@ -103,7 +103,7 @@ //! // This is fine: `join` synchronizes the code in a way such that //! // the 1-byte store happens-before the 2-byte store. //! let handle = s.spawn(|| atomic.store(1, Ordering::Relaxed)); -//! handle.join().unwrap(); +//! handle.join().expect("thread won't panic"); //! s.spawn(|| unsafe { //! let differently_sized = transmute::<&AtomicU16, &AtomicU8>(&atomic); //! differently_sized.store(2, Ordering::Relaxed); diff --git a/std/src/io/mod.rs b/std/src/io/mod.rs index 4ffb04630061f..7912f969bbd9f 100644 --- a/std/src/io/mod.rs +++ b/std/src/io/mod.rs @@ -1083,7 +1083,7 @@ pub trait Read { /// let f = BufReader::new(File::open("foo.txt")?); /// /// for byte in f.bytes() { - /// println!("{}", byte.unwrap()); + /// println!("{}", byte?); /// } /// Ok(()) /// } @@ -1995,15 +1995,16 @@ pub trait Seek { /// .write(true) /// .read(true) /// .create(true) - /// .open("foo.txt").unwrap(); + /// .open("foo.txt")?; /// /// let hello = "Hello!\n"; - /// write!(f, "{hello}").unwrap(); - /// f.rewind().unwrap(); + /// write!(f, "{hello}")?; + /// f.rewind()?; /// /// let mut buf = String::new(); - /// f.read_to_string(&mut buf).unwrap(); + /// f.read_to_string(&mut buf)?; /// assert_eq!(&buf, hello); + /// # std::io::Result::Ok(()) /// ``` #[stable(feature = "seek_rewind", since = "1.55.0")] fn rewind(&mut self) -> Result<()> { @@ -2212,8 +2213,9 @@ fn skip_until(r: &mut R, delim: u8) -> Result { /// /// let stdin = io::stdin(); /// for line in stdin.lock().lines() { -/// println!("{}", line.unwrap()); +/// println!("{}", line?); /// } +/// # std::io::Result::Ok(()) /// ``` /// /// If you have something that implements [`Read`], you can use the [`BufReader` @@ -2236,7 +2238,8 @@ fn skip_until(r: &mut R, delim: u8) -> Result { /// let f = BufReader::new(f); /// /// for line in f.lines() { -/// println!("{}", line.unwrap()); +/// let line = line?; +/// println!("{line}"); /// } /// /// Ok(()) @@ -2274,7 +2277,7 @@ pub trait BufRead: Read { /// let stdin = io::stdin(); /// let mut stdin = stdin.lock(); /// - /// let buffer = stdin.fill_buf().unwrap(); + /// let buffer = stdin.fill_buf()?; /// /// // work with buffer /// println!("{buffer:?}"); @@ -2282,6 +2285,7 @@ pub trait BufRead: Read { /// // ensure the bytes we worked with aren't returned again later /// let length = buffer.len(); /// stdin.consume(length); + /// # std::io::Result::Ok(()) /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn fill_buf(&mut self) -> Result<&[u8]>; @@ -2327,12 +2331,13 @@ pub trait BufRead: Read { /// let stdin = io::stdin(); /// let mut stdin = stdin.lock(); /// - /// while stdin.has_data_left().unwrap() { + /// while stdin.has_data_left()? { /// let mut line = String::new(); - /// stdin.read_line(&mut line).unwrap(); + /// stdin.read_line(&mut line)?; /// // work with line /// println!("{line:?}"); /// } + /// # std::io::Result::Ok(()) /// ``` #[unstable(feature = "buf_read_has_data_left", reason = "recently added", issue = "86423")] fn has_data_left(&mut self) -> Result { diff --git a/std/src/process.rs b/std/src/process.rs index 6933528cdbd0a..929d2b57afe5c 100644 --- a/std/src/process.rs +++ b/std/src/process.rs @@ -224,7 +224,7 @@ pub struct Child { /// has been captured. You might find it helpful to do /// /// ```ignore (incomplete) - /// let stdin = child.stdin.take().unwrap(); + /// let stdin = child.stdin.take().expect("handle present"); /// ``` /// /// to avoid partially moving the `child` and thus blocking yourself from calling @@ -236,7 +236,7 @@ pub struct Child { /// has been captured. You might find it helpful to do /// /// ```ignore (incomplete) - /// let stdout = child.stdout.take().unwrap(); + /// let stdout = child.stdout.take().expect("handle present"); /// ``` /// /// to avoid partially moving the `child` and thus blocking yourself from calling @@ -248,7 +248,7 @@ pub struct Child { /// has been captured. You might find it helpful to do /// /// ```ignore (incomplete) - /// let stderr = child.stderr.take().unwrap(); + /// let stderr = child.stderr.take().expect("handle present"); /// ``` /// /// to avoid partially moving the `child` and thus blocking yourself from calling @@ -1052,14 +1052,14 @@ impl Command { /// use std::io::{self, Write}; /// let output = Command::new("/bin/cat") /// .arg("file.txt") - /// .output() - /// .expect("failed to execute process"); + /// .output()?; /// /// println!("status: {}", output.status); - /// io::stdout().write_all(&output.stdout).unwrap(); - /// io::stderr().write_all(&output.stderr).unwrap(); + /// io::stdout().write_all(&output.stdout)?; + /// io::stderr().write_all(&output.stderr)?; /// /// assert!(output.status.success()); + /// # io::Result::Ok(()) /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn output(&mut self) -> io::Result { @@ -1391,11 +1391,11 @@ impl Stdio { /// let output = Command::new("rev") /// .stdin(Stdio::inherit()) /// .stdout(Stdio::piped()) - /// .output() - /// .expect("Failed to execute command"); + /// .output()?; /// /// print!("You piped in the reverse of: "); - /// io::stdout().write_all(&output.stdout).unwrap(); + /// io::stdout().write_all(&output.stdout)?; + /// # io::Result::Ok(()) /// ``` #[must_use] #[stable(feature = "process", since = "1.0.0")] @@ -1575,14 +1575,14 @@ impl From for Stdio { /// use std::process::Command; /// /// // With the `foo.txt` file containing "Hello, world!" - /// let file = File::open("foo.txt").unwrap(); + /// let file = File::open("foo.txt")?; /// /// let reverse = Command::new("rev") /// .stdin(file) // Implicit File conversion into a Stdio - /// .output() - /// .expect("failed reverse command"); + /// .output()?; /// /// assert_eq!(reverse.stdout, b"!dlrow ,olleH"); + /// # std::io::Result::Ok(()) /// ``` fn from(file: fs::File) -> Stdio { Stdio::from_inner(file.into_inner().into()) @@ -2179,7 +2179,7 @@ impl Child { /// ```no_run /// use std::process::Command; /// - /// let mut child = Command::new("ls").spawn().unwrap(); + /// let mut child = Command::new("ls").spawn()?; /// /// match child.try_wait() { /// Ok(Some(status)) => println!("exited with: {status}"), @@ -2190,6 +2190,7 @@ impl Child { /// } /// Err(e) => println!("error attempting to wait: {e}"), /// } + /// # std::io::Result::Ok(()) /// ``` #[stable(feature = "process_try_wait", since = "1.18.0")] pub fn try_wait(&mut self) -> io::Result> {