Skip to content

Commit d7c635b

Browse files
Rollup merge of #77392 - Canop:option_insert, r=m-ou-se
add `insert` to `Option` This removes a cause of `unwrap` and code complexity. This allows replacing ``` option_value = Some(build()); option_value.as_mut().unwrap() ``` with ``` option_value.insert(build()) ``` It's also useful in contexts not requiring the mutability of the reference. Here's a typical cache example: ``` let checked_cache = cache.as_ref().filter(|e| e.is_valid()); let content = match checked_cache { Some(e) => &e.content, None => { cache = Some(compute_cache_entry()); // unwrap is OK because we just filled the option &cache.as_ref().unwrap().content } }; ``` It can be changed into ``` let checked_cache = cache.as_ref().filter(|e| e.is_valid()); let content = match checked_cache { Some(e) => &e.content, None => &cache.insert(compute_cache_entry()).content, }; ``` *(edited: I removed `insert_with`)*
2 parents 8e75669 + 216d0fe commit d7c635b

File tree

1 file changed

+37
-7
lines changed

1 file changed

+37
-7
lines changed

Diff for: library/core/src/option.rs

+37-7
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,36 @@ impl<T> Option<T> {
562562
}
563563
}
564564

565+
/// Inserts `value` into the option then returns a mutable reference to it.
566+
///
567+
/// If the option already contains a value, the old value is dropped.
568+
///
569+
/// # Example
570+
///
571+
/// ```
572+
/// #![feature(option_insert)]
573+
///
574+
/// let mut opt = None;
575+
/// let val = opt.insert(1);
576+
/// assert_eq!(*val, 1);
577+
/// assert_eq!(opt.unwrap(), 1);
578+
/// let val = opt.insert(2);
579+
/// assert_eq!(*val, 2);
580+
/// *val = 3;
581+
/// assert_eq!(opt.unwrap(), 3);
582+
/// ```
583+
#[inline]
584+
#[unstable(feature = "option_insert", reason = "newly added", issue = "78271")]
585+
pub fn insert(&mut self, value: T) -> &mut T {
586+
*self = Some(value);
587+
588+
match self {
589+
Some(v) => v,
590+
// SAFETY: the code above just filled the option
591+
None => unsafe { hint::unreachable_unchecked() },
592+
}
593+
}
594+
565595
/////////////////////////////////////////////////////////////////////////
566596
// Iterator constructors
567597
/////////////////////////////////////////////////////////////////////////
@@ -792,7 +822,7 @@ impl<T> Option<T> {
792822
// Entry-like operations to insert if None and return a reference
793823
/////////////////////////////////////////////////////////////////////////
794824

795-
/// Inserts `v` into the option if it is [`None`], then
825+
/// Inserts `value` into the option if it is [`None`], then
796826
/// returns a mutable reference to the contained value.
797827
///
798828
/// # Examples
@@ -811,12 +841,12 @@ impl<T> Option<T> {
811841
/// ```
812842
#[inline]
813843
#[stable(feature = "option_entry", since = "1.20.0")]
814-
pub fn get_or_insert(&mut self, v: T) -> &mut T {
815-
self.get_or_insert_with(|| v)
844+
pub fn get_or_insert(&mut self, value: T) -> &mut T {
845+
self.get_or_insert_with(|| value)
816846
}
817847

818-
/// Inserts a value computed from `f` into the option if it is [`None`], then
819-
/// returns a mutable reference to the contained value.
848+
/// Inserts a value computed from `f` into the option if it is [`None`],
849+
/// then returns a mutable reference to the contained value.
820850
///
821851
/// # Examples
822852
///
@@ -839,8 +869,8 @@ impl<T> Option<T> {
839869
*self = Some(f());
840870
}
841871

842-
match *self {
843-
Some(ref mut v) => v,
872+
match self {
873+
Some(v) => v,
844874
// SAFETY: a `None` variant for `self` would have been replaced by a `Some`
845875
// variant in the code above.
846876
None => unsafe { hint::unreachable_unchecked() },

0 commit comments

Comments
 (0)