diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 57098b95f641b..91da3e22667bd 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2737,6 +2737,95 @@ impl Option> { } } +impl<'a, T> Option<&'a Option> { + /// Converts from `Option<&Option>` to `Option<&T>`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(option_reference_flattening)] + /// + /// let x: Option<&Option> = Some(&Some(6)); + /// assert_eq!(Some(&6), x.flatten_ref()); + /// + /// let x: Option<&Option> = Some(&None); + /// assert_eq!(None, x.flatten_ref()); + /// + /// let x: Option<&Option> = None; + /// assert_eq!(None, x.flatten_ref()); + /// ``` + #[inline] + #[unstable(feature = "option_reference_flattening", issue = "149221")] + pub const fn flatten_ref(self) -> Option<&'a T> { + match self { + Some(inner) => inner.as_ref(), + None => None, + } + } +} + +impl<'a, T> Option<&'a mut Option> { + /// Converts from `Option<&mut Option>` to `&Option`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(option_reference_flattening)] + /// + /// let y = &mut Some(6); + /// let x: Option<&mut Option> = Some(y); + /// assert_eq!(Some(&6), x.flatten_ref()); + /// + /// let y: &mut Option = &mut None; + /// let x: Option<&mut Option> = Some(y); + /// assert_eq!(None, x.flatten_ref()); + /// + /// let x: Option<&mut Option> = None; + /// assert_eq!(None, x.flatten_ref()); + /// ``` + #[inline] + #[unstable(feature = "option_reference_flattening", issue = "149221")] + pub const fn flatten_ref(self) -> Option<&'a T> { + match self { + Some(inner) => inner.as_ref(), + None => None, + } + } + + /// Converts from `Option<&mut Option>` to `Option<&mut T>`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(option_reference_flattening)] + /// + /// let y: &mut Option = &mut Some(6); + /// let x: Option<&mut Option> = Some(y); + /// assert_eq!(Some(&mut 6), x.flatten_mut()); + /// + /// let y: &mut Option = &mut None; + /// let x: Option<&mut Option> = Some(y); + /// assert_eq!(None, x.flatten_mut()); + /// + /// let x: Option<&mut Option> = None; + /// assert_eq!(None, x.flatten_mut()); + /// ``` + #[inline] + #[unstable(feature = "option_reference_flattening", issue = "149221")] + pub const fn flatten_mut(self) -> Option<&'a mut T> { + match self { + Some(inner) => inner.as_mut(), + None => None, + } + } +} + impl [Option; N] { /// Transposes a `[Option; N]` into a `Option<[T; N]>`. ///