From 0b2f717dfaf4835aa644d925a12c93db8f15dd61 Mon Sep 17 00:00:00 2001 From: onestacked Date: Fri, 23 Sep 2022 13:42:31 +0200 Subject: [PATCH 1/6] Added const_closure --- library/core/src/const_closure.rs | 178 ++++++++++++++++++++++++++++++ library/core/src/lib.rs | 2 + 2 files changed, 180 insertions(+) create mode 100644 library/core/src/const_closure.rs diff --git a/library/core/src/const_closure.rs b/library/core/src/const_closure.rs new file mode 100644 index 0000000000000..bd24c10bd0053 --- /dev/null +++ b/library/core/src/const_closure.rs @@ -0,0 +1,178 @@ +use crate::marker::Destruct; + +/// Struct representing a closure with owned data. +/// +/// Example: +/// ```rust +/// use const_closure::ConstFnOnceClosure; +/// const fn imp(state: i32, (arg,): (i32,)) -> i32 { +/// state + arg +/// } +/// let i = 5; +/// let cl = ConstFnOnceClosure::new(i, imp); +/// +/// assert!(7 == cl(2)); +/// ``` +pub(crate) struct ConstFnOnceClosure { + data: CapturedData, + func: Function, +} +impl ConstFnOnceClosure { + /// Function for creating a new closure. + /// + /// `data` is the owned data that is captured from the environment (this data must be `~const Destruct`). + /// + /// `func` is the function of the closure, it gets the data and a tuple of the arguments closure + /// and return the return value of the closure. + #[allow(dead_code)] + pub(crate) const fn new( + data: CapturedData, + func: Function, + ) -> Self + where + CapturedData: ~const Destruct, + Function: ~const Fn(CapturedData, ClosureArguments) -> ClosureReturnValue + ~const Destruct, + { + Self { data, func } + } +} +impl const FnOnce + for ConstFnOnceClosure +where + CapturedData: ~const Destruct, + Function: ~const Fn<(CapturedData, ClosureArguments)> + ~const Destruct, +{ + type Output = Function::Output; + + extern "rust-call" fn call_once(self, args: ClosureArguments) -> Self::Output { + (self.func)(self.data, args) + } +} +/// Struct representing a closure with mutably borrowed data. +/// +/// Example: +/// ```rust +/// #![feature(const_mut_refs)] +/// use const_closure::ConstFnMutClosure; +/// const fn imp(state: &mut i32, (arg,): (i32,)) -> i32 { +/// *state += arg; +/// *state +/// } +/// let mut i = 5; +/// let mut cl = ConstFnMutClosure::new(&mut i, imp); +/// +/// assert!(7 == cl(2)); +/// assert!(8 == cl(1)); +/// ``` +pub(crate) struct ConstFnMutClosure<'a, CapturedData: ?Sized, Function> { + data: &'a mut CapturedData, + func: Function, +} +impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<'a, CapturedData, Function> { + /// Function for creating a new closure. + /// + /// `data` is the a mutable borrow of data that is captured from the environment. + /// + /// `func` is the function of the closure, it gets the data and a tuple of the arguments closure + /// and return the return value of the closure. + pub(crate) const fn new( + data: &'a mut CapturedData, + func: Function, + ) -> Self + where + Function: ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue, + { + Self { data, func } + } +} +impl<'a, CapturedData: ?Sized, ClosureArguments, Function, ClosureReturnValue> const + FnOnce for ConstFnMutClosure<'a, CapturedData, Function> +where + Function: + ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue + ~const Destruct, +{ + type Output = ClosureReturnValue; + + extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output { + self.call_mut(args) + } +} +impl<'a, CapturedData: ?Sized, ClosureArguments, Function, ClosureReturnValue> const + FnMut for ConstFnMutClosure<'a, CapturedData, Function> +where + Function: ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue, +{ + extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output { + (self.func)(self.data, args) + } +} + +/// Struct representing a closure with borrowed data. +/// +/// Example: +/// ```rust +/// use const_closure::ConstFnClosure; +/// +/// const fn imp(state: &i32, (arg,): (i32,)) -> i32 { +/// *state + arg +/// } +/// let i = 5; +/// let cl = ConstFnClosure::new(&i, imp); +/// +/// assert!(7 == cl(2)); +/// assert!(6 == cl(1)); +/// ``` +pub(crate) struct ConstFnClosure<'a, CapturedData: ?Sized, Function> { + data: &'a CapturedData, + func: Function, +} +impl<'a, CapturedData: ?Sized, Function> ConstFnClosure<'a, CapturedData, Function> { + /// Function for creating a new closure. + /// + /// `data` is the a mutable borrow of data that is captured from the environment. + /// + /// `func` is the function of the closure, it gets the data and a tuple of the arguments closure + /// and return the return value of the closure. + #[allow(dead_code)] + pub(crate) const fn new( + data: &'a CapturedData, + func: Function, + ) -> Self + where + Function: ~const Fn(&CapturedData, ClosureArguments) -> ClosureReturnValue, + { + Self { data, func } + } +} +impl<'a, CapturedData: ?Sized, Function, ClosureArguments, ClosureReturnValue> const + FnOnce for ConstFnClosure<'a, CapturedData, Function> +where + Function: ~const Fn(&CapturedData, ClosureArguments) -> ClosureReturnValue + ~const Destruct, +{ + type Output = ClosureReturnValue; + + extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output { + self.call_mut(args) + } +} +impl<'a, CapturedData: ?Sized, Function, ClosureArguments, ClosureReturnValue> const + FnMut for ConstFnClosure<'a, CapturedData, Function> +where + Function: ~const Fn(&CapturedData, ClosureArguments) -> ClosureReturnValue, +{ + extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output { + self.call(args) + } +} +impl< + 'a, + CapturedData: ?Sized, + Function: ~const Fn(&CapturedData, ClosureArguments) -> ClosureReturnValue, + ClosureArguments, + ClosureReturnValue, +> const Fn for ConstFnClosure<'a, CapturedData, Function> +{ + extern "rust-call" fn call(&self, args: ClosureArguments) -> Self::Output { + (self.func)(self.data, args) + } +} diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 21775c0a6ab0b..6fbe7ade73255 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -356,6 +356,8 @@ mod bool; mod tuple; mod unit; +mod const_closure; + #[stable(feature = "core_primitive", since = "1.43.0")] pub mod primitive; From 8e0ea60a04c463bf52fc81dbbf182f4739525681 Mon Sep 17 00:00:00 2001 From: onestacked Date: Fri, 23 Sep 2022 13:43:34 +0200 Subject: [PATCH 2/6] Constifed Try trait --- .../core/src/iter/adapters/array_chunks.rs | 9 +++++---- .../core/src/iter/adapters/by_ref_sized.rs | 19 ++++++++++++++----- library/core/src/iter/adapters/mod.rs | 5 +++-- library/core/src/ops/control_flow.rs | 2 +- library/core/src/ops/try_trait.rs | 18 +++++++++++------- 5 files changed, 34 insertions(+), 19 deletions(-) diff --git a/library/core/src/iter/adapters/array_chunks.rs b/library/core/src/iter/adapters/array_chunks.rs index 9b479a9f8adfb..489fb13c0dc97 100644 --- a/library/core/src/iter/adapters/array_chunks.rs +++ b/library/core/src/iter/adapters/array_chunks.rs @@ -1,4 +1,5 @@ use crate::array; +use crate::const_closure::ConstFnMutClosure; use crate::iter::{ByRefSized, FusedIterator, Iterator}; use crate::ops::{ControlFlow, NeverShortCircuit, Try}; @@ -82,12 +83,12 @@ where } } - fn fold(mut self, init: B, f: F) -> B + fn fold(mut self, init: B, mut f: F) -> B where Self: Sized, F: FnMut(B, Self::Item) -> B, { - self.try_fold(init, NeverShortCircuit::wrap_mut_2(f)).0 + self.try_fold(init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp)).0 } } @@ -126,12 +127,12 @@ where try { acc } } - fn rfold(mut self, init: B, f: F) -> B + fn rfold(mut self, init: B, mut f: F) -> B where Self: Sized, F: FnMut(B, Self::Item) -> B, { - self.try_rfold(init, NeverShortCircuit::wrap_mut_2(f)).0 + self.try_rfold(init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp)).0 } } diff --git a/library/core/src/iter/adapters/by_ref_sized.rs b/library/core/src/iter/adapters/by_ref_sized.rs index 477e7117c3ea1..1945e402ff50e 100644 --- a/library/core/src/iter/adapters/by_ref_sized.rs +++ b/library/core/src/iter/adapters/by_ref_sized.rs @@ -1,4 +1,7 @@ -use crate::ops::{NeverShortCircuit, Try}; +use crate::{ + const_closure::ConstFnMutClosure, + ops::{NeverShortCircuit, Try}, +}; /// Like `Iterator::by_ref`, but requiring `Sized` so it can forward generics. /// @@ -36,12 +39,13 @@ impl Iterator for ByRefSized<'_, I> { } #[inline] - fn fold(self, init: B, f: F) -> B + fn fold(self, init: B, mut f: F) -> B where F: FnMut(B, Self::Item) -> B, { // `fold` needs ownership, so this can't forward directly. - I::try_fold(self.0, init, NeverShortCircuit::wrap_mut_2(f)).0 + I::try_fold(self.0, init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp)) + .0 } #[inline] @@ -72,12 +76,17 @@ impl DoubleEndedIterator for ByRefSized<'_, I> { } #[inline] - fn rfold(self, init: B, f: F) -> B + fn rfold(self, init: B, mut f: F) -> B where F: FnMut(B, Self::Item) -> B, { // `rfold` needs ownership, so this can't forward directly. - I::try_rfold(self.0, init, NeverShortCircuit::wrap_mut_2(f)).0 + I::try_rfold( + self.0, + init, + ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp), + ) + .0 } #[inline] diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index bf4fabad32a37..de3a534f81b8a 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -1,3 +1,4 @@ +use crate::const_closure::ConstFnMutClosure; use crate::iter::{InPlaceIterable, Iterator}; use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, NeverShortCircuit, Residual, Try}; @@ -203,12 +204,12 @@ where .into_try() } - fn fold(mut self, init: B, fold: F) -> B + fn fold(mut self, init: B, mut fold: F) -> B where Self: Sized, F: FnMut(B, Self::Item) -> B, { - self.try_fold(init, NeverShortCircuit::wrap_mut_2(fold)).0 + self.try_fold(init, ConstFnMutClosure::new(&mut fold, NeverShortCircuit::wrap_mut_2_imp)).0 } } diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index fd567a8c68492..8d236a9fecaea 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -126,7 +126,7 @@ impl const ops::FromResidual for ControlFlow { } #[unstable(feature = "try_trait_v2_residual", issue = "91285")] -impl ops::Residual for ControlFlow { +impl const ops::Residual for ControlFlow { type TryType = ControlFlow; } diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs index dfde0b37acf43..4d0d4e12adbf8 100644 --- a/library/core/src/ops/try_trait.rs +++ b/library/core/src/ops/try_trait.rs @@ -129,7 +129,7 @@ use crate::ops::ControlFlow; #[doc(alias = "?")] #[lang = "Try"] #[const_trait] -pub trait Try: FromResidual { +pub trait Try: ~const FromResidual { /// The type of the value produced by `?` when *not* short-circuiting. #[unstable(feature = "try_trait_v2", issue = "84277")] type Output; @@ -438,10 +438,11 @@ where /// and in the other direction, /// ` as Residual>::TryType = Result`. #[unstable(feature = "try_trait_v2_residual", issue = "91285")] +#[const_trait] pub trait Residual { /// The "return" type of this meta-function. #[unstable(feature = "try_trait_v2_residual", issue = "91285")] - type TryType: Try; + type TryType: ~const Try; } #[unstable(feature = "pub_crate_should_not_need_unstable_attr", issue = "none")] @@ -460,14 +461,17 @@ pub(crate) struct NeverShortCircuit(pub T); impl NeverShortCircuit { /// Wrap a binary `FnMut` to return its result wrapped in a `NeverShortCircuit`. #[inline] - pub fn wrap_mut_2(mut f: impl FnMut(A, B) -> T) -> impl FnMut(A, B) -> Self { - move |a, b| NeverShortCircuit(f(a, b)) + pub const fn wrap_mut_2_imp T>( + f: &mut F, + (a, b): (A, B), + ) -> NeverShortCircuit { + NeverShortCircuit(f(a, b)) } } pub(crate) enum NeverShortCircuitResidual {} -impl Try for NeverShortCircuit { +impl const Try for NeverShortCircuit { type Output = T; type Residual = NeverShortCircuitResidual; @@ -482,14 +486,14 @@ impl Try for NeverShortCircuit { } } -impl FromResidual for NeverShortCircuit { +impl const FromResidual for NeverShortCircuit { #[inline] fn from_residual(never: NeverShortCircuitResidual) -> Self { match never {} } } -impl Residual for NeverShortCircuitResidual { +impl const Residual for NeverShortCircuitResidual { type TryType = NeverShortCircuit; } From 53049f7dcd382246fb1f7ad975b81e9a293acccd Mon Sep 17 00:00:00 2001 From: onestacked Date: Fri, 23 Sep 2022 15:39:13 +0200 Subject: [PATCH 3/6] Fixed Doc-Tests --- library/core/src/const_closure.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library/core/src/const_closure.rs b/library/core/src/const_closure.rs index bd24c10bd0053..536c3eb0022fd 100644 --- a/library/core/src/const_closure.rs +++ b/library/core/src/const_closure.rs @@ -3,8 +3,8 @@ use crate::marker::Destruct; /// Struct representing a closure with owned data. /// /// Example: -/// ```rust -/// use const_closure::ConstFnOnceClosure; +/// ```no_build +/// use crate::const_closure::ConstFnOnceClosure; /// const fn imp(state: i32, (arg,): (i32,)) -> i32 { /// state + arg /// } @@ -51,9 +51,9 @@ where /// Struct representing a closure with mutably borrowed data. /// /// Example: -/// ```rust +/// ```no_build /// #![feature(const_mut_refs)] -/// use const_closure::ConstFnMutClosure; +/// use crate::const_closure::ConstFnMutClosure; /// const fn imp(state: &mut i32, (arg,): (i32,)) -> i32 { /// *state += arg; /// *state @@ -110,8 +110,8 @@ where /// Struct representing a closure with borrowed data. /// /// Example: -/// ```rust -/// use const_closure::ConstFnClosure; +/// ```no_build +/// use crate::const_closure::ConstFnClosure; /// /// const fn imp(state: &i32, (arg,): (i32,)) -> i32 { /// *state + arg From 6267c60f6a1eb8bb135bb3d37edd4ab9ab352d6e Mon Sep 17 00:00:00 2001 From: onestacked Date: Fri, 23 Sep 2022 18:20:57 +0200 Subject: [PATCH 4/6] Added some spacing in const closure --- library/core/src/const_closure.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/library/core/src/const_closure.rs b/library/core/src/const_closure.rs index 536c3eb0022fd..6ea94c95473dd 100644 --- a/library/core/src/const_closure.rs +++ b/library/core/src/const_closure.rs @@ -17,6 +17,7 @@ pub(crate) struct ConstFnOnceClosure { data: CapturedData, func: Function, } + impl ConstFnOnceClosure { /// Function for creating a new closure. /// @@ -36,6 +37,7 @@ impl ConstFnOnceClosure { Self { data, func } } } + impl const FnOnce for ConstFnOnceClosure where @@ -48,6 +50,7 @@ where (self.func)(self.data, args) } } + /// Struct representing a closure with mutably borrowed data. /// /// Example: @@ -68,6 +71,7 @@ pub(crate) struct ConstFnMutClosure<'a, CapturedData: ?Sized, Function> { data: &'a mut CapturedData, func: Function, } + impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<'a, CapturedData, Function> { /// Function for creating a new closure. /// @@ -85,6 +89,7 @@ impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<'a, CapturedData, Fun Self { data, func } } } + impl<'a, CapturedData: ?Sized, ClosureArguments, Function, ClosureReturnValue> const FnOnce for ConstFnMutClosure<'a, CapturedData, Function> where @@ -97,6 +102,7 @@ where self.call_mut(args) } } + impl<'a, CapturedData: ?Sized, ClosureArguments, Function, ClosureReturnValue> const FnMut for ConstFnMutClosure<'a, CapturedData, Function> where @@ -126,6 +132,7 @@ pub(crate) struct ConstFnClosure<'a, CapturedData: ?Sized, Function> { data: &'a CapturedData, func: Function, } + impl<'a, CapturedData: ?Sized, Function> ConstFnClosure<'a, CapturedData, Function> { /// Function for creating a new closure. /// @@ -144,6 +151,7 @@ impl<'a, CapturedData: ?Sized, Function> ConstFnClosure<'a, CapturedData, Functi Self { data, func } } } + impl<'a, CapturedData: ?Sized, Function, ClosureArguments, ClosureReturnValue> const FnOnce for ConstFnClosure<'a, CapturedData, Function> where @@ -155,6 +163,7 @@ where self.call_mut(args) } } + impl<'a, CapturedData: ?Sized, Function, ClosureArguments, ClosureReturnValue> const FnMut for ConstFnClosure<'a, CapturedData, Function> where @@ -164,6 +173,7 @@ where self.call(args) } } + impl< 'a, CapturedData: ?Sized, From d78bc41785aaa5be7eff96b100268d3c5daa5401 Mon Sep 17 00:00:00 2001 From: onestacked Date: Fri, 23 Sep 2022 19:55:51 +0200 Subject: [PATCH 5/6] Remove unused `ConstFn(Once)Closure` structs. --- library/core/src/const_closure.rs | 125 ------------------------------ 1 file changed, 125 deletions(-) diff --git a/library/core/src/const_closure.rs b/library/core/src/const_closure.rs index 6ea94c95473dd..d2e80e8e7e5df 100644 --- a/library/core/src/const_closure.rs +++ b/library/core/src/const_closure.rs @@ -1,56 +1,5 @@ use crate::marker::Destruct; -/// Struct representing a closure with owned data. -/// -/// Example: -/// ```no_build -/// use crate::const_closure::ConstFnOnceClosure; -/// const fn imp(state: i32, (arg,): (i32,)) -> i32 { -/// state + arg -/// } -/// let i = 5; -/// let cl = ConstFnOnceClosure::new(i, imp); -/// -/// assert!(7 == cl(2)); -/// ``` -pub(crate) struct ConstFnOnceClosure { - data: CapturedData, - func: Function, -} - -impl ConstFnOnceClosure { - /// Function for creating a new closure. - /// - /// `data` is the owned data that is captured from the environment (this data must be `~const Destruct`). - /// - /// `func` is the function of the closure, it gets the data and a tuple of the arguments closure - /// and return the return value of the closure. - #[allow(dead_code)] - pub(crate) const fn new( - data: CapturedData, - func: Function, - ) -> Self - where - CapturedData: ~const Destruct, - Function: ~const Fn(CapturedData, ClosureArguments) -> ClosureReturnValue + ~const Destruct, - { - Self { data, func } - } -} - -impl const FnOnce - for ConstFnOnceClosure -where - CapturedData: ~const Destruct, - Function: ~const Fn<(CapturedData, ClosureArguments)> + ~const Destruct, -{ - type Output = Function::Output; - - extern "rust-call" fn call_once(self, args: ClosureArguments) -> Self::Output { - (self.func)(self.data, args) - } -} - /// Struct representing a closure with mutably borrowed data. /// /// Example: @@ -112,77 +61,3 @@ where (self.func)(self.data, args) } } - -/// Struct representing a closure with borrowed data. -/// -/// Example: -/// ```no_build -/// use crate::const_closure::ConstFnClosure; -/// -/// const fn imp(state: &i32, (arg,): (i32,)) -> i32 { -/// *state + arg -/// } -/// let i = 5; -/// let cl = ConstFnClosure::new(&i, imp); -/// -/// assert!(7 == cl(2)); -/// assert!(6 == cl(1)); -/// ``` -pub(crate) struct ConstFnClosure<'a, CapturedData: ?Sized, Function> { - data: &'a CapturedData, - func: Function, -} - -impl<'a, CapturedData: ?Sized, Function> ConstFnClosure<'a, CapturedData, Function> { - /// Function for creating a new closure. - /// - /// `data` is the a mutable borrow of data that is captured from the environment. - /// - /// `func` is the function of the closure, it gets the data and a tuple of the arguments closure - /// and return the return value of the closure. - #[allow(dead_code)] - pub(crate) const fn new( - data: &'a CapturedData, - func: Function, - ) -> Self - where - Function: ~const Fn(&CapturedData, ClosureArguments) -> ClosureReturnValue, - { - Self { data, func } - } -} - -impl<'a, CapturedData: ?Sized, Function, ClosureArguments, ClosureReturnValue> const - FnOnce for ConstFnClosure<'a, CapturedData, Function> -where - Function: ~const Fn(&CapturedData, ClosureArguments) -> ClosureReturnValue + ~const Destruct, -{ - type Output = ClosureReturnValue; - - extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output { - self.call_mut(args) - } -} - -impl<'a, CapturedData: ?Sized, Function, ClosureArguments, ClosureReturnValue> const - FnMut for ConstFnClosure<'a, CapturedData, Function> -where - Function: ~const Fn(&CapturedData, ClosureArguments) -> ClosureReturnValue, -{ - extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output { - self.call(args) - } -} - -impl< - 'a, - CapturedData: ?Sized, - Function: ~const Fn(&CapturedData, ClosureArguments) -> ClosureReturnValue, - ClosureArguments, - ClosureReturnValue, -> const Fn for ConstFnClosure<'a, CapturedData, Function> -{ - extern "rust-call" fn call(&self, args: ClosureArguments) -> Self::Output { - (self.func)(self.data, args) - } -} From 84666afb36365c3dafe0acfdcd17ea177f58af19 Mon Sep 17 00:00:00 2001 From: onestacked Date: Fri, 23 Sep 2022 20:17:31 +0200 Subject: [PATCH 6/6] Constify Residual behind const_try --- library/core/src/ops/control_flow.rs | 1 + library/core/src/option.rs | 3 ++- library/core/src/result.rs | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index 8d236a9fecaea..72ebe653caff3 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -126,6 +126,7 @@ impl const ops::FromResidual for ControlFlow { } #[unstable(feature = "try_trait_v2_residual", issue = "91285")] +#[rustc_const_unstable(feature = "const_try", issue = "74935")] impl const ops::Residual for ControlFlow { type TryType = ControlFlow; } diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 934175863630f..96b16b13256ce 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2321,7 +2321,8 @@ impl ops::FromResidual> for Option { } #[unstable(feature = "try_trait_v2_residual", issue = "91285")] -impl ops::Residual for Option { +#[rustc_const_unstable(feature = "const_try", issue = "74935")] +impl const ops::Residual for Option { type TryType = Option; } diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 76eaa191f7811..dc90e90402c8e 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -2116,6 +2116,7 @@ impl> ops::FromResidual> for Result { } #[unstable(feature = "try_trait_v2_residual", issue = "91285")] -impl ops::Residual for Result { +#[rustc_const_unstable(feature = "const_try", issue = "74935")] +impl const ops::Residual for Result { type TryType = Result; }