diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 994c08d1fb50d..0d309fe08855b 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2606,3 +2606,94 @@ 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 = "none")] + #[rustc_const_unstable(feature = "const_option", issue = "67441")] + pub const fn flatten_ref(self) -> &'a Option { + match self { + Some(inner) => inner, + None => const { &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()); + /// ``` + #[unstable(feature = "option_reference_flattening", issue = "none")] + #[rustc_const_unstable(feature = "const_option", issue = "67441")] + pub const fn flatten_ref(self) -> &'a Option { + match self { + Some(inner) => inner, + None => const { &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 = "none")] + #[rustc_const_unstable(feature = "const_option", issue = "67441")] + pub const fn flatten_mut(self) -> Option<&'a mut T> { + match self { + Some(inner) => inner.as_mut(), + None => None, + } + } +}