From 1e617779291cea20ae3ace6edc7135c9d79cd3b0 Mon Sep 17 00:00:00 2001 From: Coca162 Date: Thu, 2 Mar 2023 16:24:22 +0000 Subject: [PATCH 1/7] Implement `.flatten` for nested reference to option --- library/core/src/option.rs | 83 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 994c08d1fb50d..892e43f476947 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2606,3 +2606,86 @@ impl Option> { } } } + +impl<'a, T> Option<&'a Option> { + /// Converts from `Option<&Option>` to `Option<&T>`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// 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) -> 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<&T>`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let x: Option<&mut Option> = Some(&mut Some(6)); + /// assert_eq!(Some(&6), x.flatten_ref()); + /// + /// let x: Option<&mut Option> = Some(&mut None); + /// 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) -> Option<&'a T> { + match self { + Some(inner) => inner.as_ref(), + None => None, + } + } + + /// Converts from `Option<&mut Option>` to `Option<&mut T>`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// 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, + } + } +} From a502ad75663f74e2fd628351a067986beb592e5d Mon Sep 17 00:00:00 2001 From: Coca Date: Thu, 2 Mar 2023 19:51:53 +0000 Subject: [PATCH 2/7] Add option_reference_flattening to rustc_features/active.rs --- compiler/rustc_feature/src/active.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index adc06d9aa108a..5a355f7a5a51d 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -478,6 +478,10 @@ declare_features! ( (active, object_safe_for_dispatch, "1.40.0", Some(43561), None), /// Allows using `#[optimize(X)]`. (active, optimize_attribute, "1.34.0", Some(54882), None), + /// Allows using `Option<&Option>::flatten_ref()`, + /// Option<&mut Option>::flatten_ref()` and + /// Option<&mut Option>::flatten_mut()` + (active, option_reference_flattening, "1.69", None, None), /// Allows `extern "platform-intrinsic" { ... }`. (active, platform_intrinsics, "1.4.0", Some(27731), None), /// Allows using `#![plugin(myplugin)]`. From cce8771893535cd419696ed8b810a3871f9f6e71 Mon Sep 17 00:00:00 2001 From: Coca Date: Thu, 2 Mar 2023 20:13:44 +0000 Subject: [PATCH 3/7] Add option_reference_flattening to symbols.rs --- compiler/rustc_span/src/symbol.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index fb579e4ff772a..902f6f8064e04 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1043,6 +1043,7 @@ symbols! { optin_builtin_traits, option, option_env, + option_reference_flattening, options, or, or_patterns, From bf0ab75ab846c0befc32682ad57cc32fd80f82c6 Mon Sep 17 00:00:00 2001 From: Coca Date: Thu, 2 Mar 2023 21:13:05 +0000 Subject: [PATCH 4/7] Fix active.rs nightly version number --- compiler/rustc_feature/src/active.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 5a355f7a5a51d..b14b4596f82d4 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -481,7 +481,7 @@ declare_features! ( /// Allows using `Option<&Option>::flatten_ref()`, /// Option<&mut Option>::flatten_ref()` and /// Option<&mut Option>::flatten_mut()` - (active, option_reference_flattening, "1.69", None, None), + (active, option_reference_flattening, "1.69.0", None, None), /// Allows `extern "platform-intrinsic" { ... }`. (active, platform_intrinsics, "1.4.0", Some(27731), None), /// Allows using `#![plugin(myplugin)]`. From 76d7caa945655ace317eab7fd1f7e9eb8ff0802a Mon Sep 17 00:00:00 2001 From: Coca162 Date: Fri, 3 Mar 2023 09:30:57 +0000 Subject: [PATCH 5/7] Change `flatten_ref` to return `&Option` --- compiler/rustc_feature/src/active.rs | 2 +- library/core/src/option.rs | 30 +++++++++++++++++----------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index b14b4596f82d4..34fb37d83f205 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -481,7 +481,7 @@ declare_features! ( /// Allows using `Option<&Option>::flatten_ref()`, /// Option<&mut Option>::flatten_ref()` and /// Option<&mut Option>::flatten_mut()` - (active, option_reference_flattening, "1.69.0", None, None), + (active, option_reference_flattening, "CURRENT_RUSTC_VERSION", None, None), /// Allows `extern "platform-intrinsic" { ... }`. (active, platform_intrinsics, "1.4.0", Some(27731), None), /// Allows using `#![plugin(myplugin)]`. diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 892e43f476947..1cc1ee1f141e3 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2615,22 +2615,24 @@ impl<'a, T> Option<&'a Option> { /// Basic usage: /// /// ``` + /// #![feature(option_reference_flattening)] + /// /// let x: Option<&Option> = Some(&Some(6)); - /// assert_eq!(Some(&6), x.flatten_ref()); + /// assert_eq!(&Some(6), x.flatten_ref()); /// /// let x: Option<&Option> = Some(&None); - /// assert_eq!(None, x.flatten_ref()); + /// assert_eq!(&None, x.flatten_ref()); /// /// let x: Option<&Option> = None; - /// assert_eq!(None, x.flatten_ref()); + /// 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) -> Option<&'a T> { + pub const fn flatten_ref(self) -> &'a Option { match self { - Some(inner) => inner.as_ref(), - None => None, + Some(inner) => inner, + None => const { &None }, } } } @@ -2643,21 +2645,23 @@ impl<'a, T> Option<&'a mut Option> { /// Basic usage: /// /// ``` + /// #![feature(option_reference_flattening)] + /// /// let x: Option<&mut Option> = Some(&mut Some(6)); - /// assert_eq!(Some(&6), x.flatten_ref()); + /// assert_eq!(&Some(6), x.flatten_ref()); /// /// let x: Option<&mut Option> = Some(&mut None); - /// assert_eq!(None, x.flatten_ref()); + /// assert_eq!(&None, x.flatten_ref()); /// /// let x: Option<&mut Option> = None; - /// assert_eq!(None, x.flatten_ref()); + /// 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) -> Option<&'a T> { + pub const fn flatten_ref(self) -> &'a Option { match self { - Some(inner) => inner.as_ref(), - None => None, + Some(inner) => inner, + None => const { &None }, } } @@ -2668,6 +2672,8 @@ impl<'a, T> Option<&'a mut Option> { /// 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()); From 2a9c4f0cb5c28a733741662038c1d7fd9c9d4b68 Mon Sep 17 00:00:00 2001 From: Coca162 Date: Sat, 4 Mar 2023 02:29:47 +0000 Subject: [PATCH 6/7] Remove option_reference_flattening from active.rs and symbol.rs --- compiler/rustc_feature/src/active.rs | 4 ---- compiler/rustc_span/src/symbol.rs | 1 - 2 files changed, 5 deletions(-) diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 34fb37d83f205..adc06d9aa108a 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -478,10 +478,6 @@ declare_features! ( (active, object_safe_for_dispatch, "1.40.0", Some(43561), None), /// Allows using `#[optimize(X)]`. (active, optimize_attribute, "1.34.0", Some(54882), None), - /// Allows using `Option<&Option>::flatten_ref()`, - /// Option<&mut Option>::flatten_ref()` and - /// Option<&mut Option>::flatten_mut()` - (active, option_reference_flattening, "CURRENT_RUSTC_VERSION", None, None), /// Allows `extern "platform-intrinsic" { ... }`. (active, platform_intrinsics, "1.4.0", Some(27731), None), /// Allows using `#![plugin(myplugin)]`. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 902f6f8064e04..fb579e4ff772a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1043,7 +1043,6 @@ symbols! { optin_builtin_traits, option, option_env, - option_reference_flattening, options, or, or_patterns, From 4dcfc5d87c03d8917eaaad6b626cff337bf7ad37 Mon Sep 17 00:00:00 2001 From: Coca162 Date: Sat, 4 Mar 2023 02:52:14 +0000 Subject: [PATCH 7/7] Fix docs for flatten_ref on mut inner --- library/core/src/option.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 1cc1ee1f141e3..0d309fe08855b 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2638,7 +2638,7 @@ impl<'a, T> Option<&'a Option> { } impl<'a, T> Option<&'a mut Option> { - /// Converts from `Option<&mut Option>` to `Option<&T>`. + /// Converts from `Option<&mut Option>` to `&Option`. /// /// # Examples /// @@ -2647,10 +2647,12 @@ impl<'a, T> Option<&'a mut Option> { /// ``` /// #![feature(option_reference_flattening)] /// - /// let x: Option<&mut Option> = Some(&mut Some(6)); + /// let y = &mut Some(6); + /// let x: Option<&mut Option> = Some(y); /// assert_eq!(&Some(6), x.flatten_ref()); /// - /// let x: Option<&mut Option> = Some(&mut None); + /// 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;