From fb5002d68aa22f23ced3e2b5265f622264e4840a Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 27 Sep 2022 15:21:31 -0700 Subject: [PATCH 1/8] Manually order `DefId` on 64-bit big-endian `DefId` uses different field orders on 64-bit big-endian vs. others, in order to optimize its `Hash` implementation. However, that also made it derive different lexical ordering for `PartialOrd` and `Ord`. That caused spurious differences wherever `DefId`s are sorted, like the candidate sources list in `report_method_error`. Now we manually implement `PartialOrd` and `Ord` on 64-bit big-endian to match the same lexical ordering as other targets, fixing at least one test, `src/test/ui/methods/method-ambig-two-traits-cross-crate.rs`. --- compiler/rustc_span/src/def_id.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 37b8371a8fe28..bbeabdb55a72a 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -218,7 +218,9 @@ impl Decodable for DefIndex { /// index and a def index. /// /// You can create a `DefId` from a `LocalDefId` using `local_def_id.to_def_id()`. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy)] +#[derive(Clone, PartialEq, Eq, Copy)] +// Don't derive order on 64-bit big-endian, so we can be consistent regardless of field order. +#[cfg_attr(not(all(target_pointer_width = "64", target_endian = "big")), derive(PartialOrd, Ord))] // On below-64 bit systems we can simply use the derived `Hash` impl #[cfg_attr(not(target_pointer_width = "64"), derive(Hash))] #[repr(C)] @@ -260,6 +262,22 @@ impl Hash for DefId { } } +// Implement the same comparison as derived with the other field order. +#[cfg(all(target_pointer_width = "64", target_endian = "big"))] +impl Ord for DefId { + #[inline] + fn cmp(&self, other: &DefId) -> std::cmp::Ordering { + Ord::cmp(&(self.index, self.krate), &(other.index, other.krate)) + } +} +#[cfg(all(target_pointer_width = "64", target_endian = "big"))] +impl PartialOrd for DefId { + #[inline] + fn partial_cmp(&self, other: &DefId) -> Option { + Some(Ord::cmp(self, other)) + } +} + impl DefId { /// Makes a local `DefId` from the given `DefIndex`. #[inline] From 523a76a2ebd5c1763665e2d51fa65f8304fc46af Mon Sep 17 00:00:00 2001 From: Yiming Lei Date: Wed, 28 Sep 2022 09:59:03 -0700 Subject: [PATCH 2/8] remove the unused :: between trait and type to give user correct diagnostic information modified: compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs new file: src/test/ui/type/issue-101866.rs new file: src/test/ui/type/issue-101866.stderr --- .../src/traits/error_reporting/mod.rs | 19 ++++++++++++++----- src/test/ui/type/issue-101866.rs | 15 +++++++++++++++ src/test/ui/type/issue-101866.stderr | 18 ++++++++++++++++++ 3 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/type/issue-101866.rs create mode 100644 src/test/ui/type/issue-101866.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index b0cabc6275f5a..5fdadd0b4b41b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2263,13 +2263,22 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { trait_impls.non_blanket_impls().len() ) }; - + let mut suggestions = vec![( + trait_path_segment.ident.span.shrink_to_lo(), + format!("<{} as ", self.tcx.def_path(impl_def_id).to_string_no_crate_verbose()) + )]; + if let Some(generic_arg) = trait_path_segment.args { + let between_span = trait_path_segment.ident.span.between(generic_arg.span_ext); + // get rid of :: between Trait and + // must be '::' between them, otherwise the parser won't accept the code + suggestions.push((between_span, "".to_string(),)); + suggestions.push((generic_arg.span_ext.shrink_to_hi(), format!(">"))); + } else { + suggestions.push((trait_path_segment.ident.span.shrink_to_hi(), format!(">"))); + } err.multipart_suggestion( message, - vec![ - (trait_path_segment.ident.span.shrink_to_lo(), format!("<{} as ", self.tcx.def_path(impl_def_id).to_string_no_crate_verbose())), - (trait_path_segment.ident.span.shrink_to_hi(), format!(">")) - ], + suggestions, Applicability::MaybeIncorrect ); } diff --git a/src/test/ui/type/issue-101866.rs b/src/test/ui/type/issue-101866.rs new file mode 100644 index 0000000000000..d332c4adb0060 --- /dev/null +++ b/src/test/ui/type/issue-101866.rs @@ -0,0 +1,15 @@ +trait TraitA { + fn func(); +} + +struct StructA {} + +impl TraitA for StructA { + fn func() {} +} + +fn main() { + TraitA::::func(); + //~^ ERROR: cannot call associated function on trait without specifying the corresponding `impl` type [E0790] + //~| help: use the fully-qualified path to the only available implementation +} diff --git a/src/test/ui/type/issue-101866.stderr b/src/test/ui/type/issue-101866.stderr new file mode 100644 index 0000000000000..788e54b938190 --- /dev/null +++ b/src/test/ui/type/issue-101866.stderr @@ -0,0 +1,18 @@ +error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type + --> $DIR/issue-101866.rs:12:5 + | +LL | fn func(); + | ---------- `TraitA::func` defined here +... +LL | TraitA::::func(); + | ^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait + | +help: use the fully-qualified path to the only available implementation + | +LL - TraitA::::func(); +LL + <::StructA as TraitA>::func(); + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0790`. From f65eb51b00464dc632f6623e9d7374374d9188b2 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 30 Sep 2022 10:18:36 +1000 Subject: [PATCH 3/8] Reinstate `hir-stats.rs` test for stage 1. It was disabled in #94075 for stage 1 because that PR changed type layouts such that the results for this test were different for stage 1 and stage 2. But now that #94075 is in beta, the results for this test are now the same for stage 1 and stage 2. --- src/test/ui/stats/hir-stats.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/ui/stats/hir-stats.rs b/src/test/ui/stats/hir-stats.rs index 5102574d4be3e..a24b3ada57e59 100644 --- a/src/test/ui/stats/hir-stats.rs +++ b/src/test/ui/stats/hir-stats.rs @@ -1,7 +1,6 @@ // check-pass // compile-flags: -Zhir-stats // only-x86_64 -// ignore-stage1 // The aim here is to include at least one of every different type of top-level // AST/HIR node reported by `-Zhir-stats`. From 1ca33851dfd530c11a942ea4b2e105549179e090 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 30 Sep 2022 15:52:20 +0900 Subject: [PATCH 4/8] specify `DynKind::Dyn` --- .../src/traits/error_reporting/suggestions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index fff26547be075..698fc81c58775 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1425,7 +1425,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let mut spans_and_needs_box = vec![]; match liberated_sig.output().kind() { - ty::Dynamic(predicates, _, _) => { + ty::Dynamic(predicates, _, ty::Dyn) => { let cause = ObligationCause::misc(ret_ty.span, fn_hir_id); let param_env = ty::ParamEnv::empty(); From 19b297c6e1f9dab67d6a6b40c379301ccd462f31 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 29 Sep 2022 23:57:01 -0700 Subject: [PATCH 5/8] rustdoc: remove no-op CSS `h3.variant, .sub-variant h4 { border-bottom: none }` This rule, added in 69df43b041f76251391f11264c1ff763ca2a64a0 to override the default `h4` style, has been obsoleted when a65c98fefb78cddee955b87214732b0de30a769f changed it so that only the top docblock put `border-bottom` on `h4.` --- src/librustdoc/html/static/css/rustdoc.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index e92e9137d6402..36adacaf8506e 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1247,13 +1247,11 @@ h3.variant { font-weight: 600; font-size: 1.125rem; margin-bottom: 10px; - border-bottom: none; } .sub-variant h4 { font-size: 1rem; font-weight: 400; - border-bottom: none; margin-top: 0; margin-bottom: 0; } From b73241aa5b0eab8aebf1600c598180bbd33be31c Mon Sep 17 00:00:00 2001 From: onestacked Date: Fri, 30 Sep 2022 17:16:59 +0200 Subject: [PATCH 6/8] Added more const_closure functionality. --- library/core/src/cmp.rs | 4 +- library/core/src/const_closure.rs | 79 +++++++++---------- .../core/src/iter/adapters/array_chunks.rs | 12 ++- .../core/src/iter/adapters/by_ref_sized.rs | 10 ++- library/core/src/iter/adapters/mod.rs | 6 +- 5 files changed, 62 insertions(+), 49 deletions(-) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index f0fa2e1d2c190..5033e744def02 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1267,7 +1267,7 @@ where { f(v1).cmp(&f(v2)) } - min_by(v1, v2, ConstFnMutClosure::new(&mut f, imp)) + min_by(v1, v2, ConstFnMutClosure { data: &mut f, func: imp }) } /// Compares and returns the maximum of two values. @@ -1352,7 +1352,7 @@ where { f(v1).cmp(&f(v2)) } - max_by(v1, v2, ConstFnMutClosure::new(&mut f, imp)) + max_by(v1, v2, ConstFnMutClosure { data: &mut f, func: imp }) } // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types diff --git a/library/core/src/const_closure.rs b/library/core/src/const_closure.rs index d2e80e8e7e5df..23b3f87e72172 100644 --- a/library/core/src/const_closure.rs +++ b/library/core/src/const_closure.rs @@ -16,48 +16,45 @@ use crate::marker::Destruct; /// assert!(7 == cl(2)); /// assert!(8 == cl(1)); /// ``` -pub(crate) struct ConstFnMutClosure<'a, CapturedData: ?Sized, Function> { - data: &'a mut CapturedData, - func: Function, +pub(crate) struct ConstFnMutClosure { + /// The Data captured by the Closure. + /// Must be either a (mutable) reference or a tuple of (mutable) references. + pub data: CapturedData, + /// The Function of the Closure, must be: Fn(CapturedData, ClosureArgs) -> ClosureReturn + pub 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; +macro_rules! impl_fn_mut_tuple { + ($($var:ident)*) => { + #[allow(unused_parens)] + impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const + FnOnce for ConstFnMutClosure<($(&'a mut $var),*), Function> + where + Function: ~const Fn(($(&mut $var),*), ClosureArguments) -> ClosureReturnValue+ ~const Destruct, + { + type Output = ClosureReturnValue; - extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output { - self.call_mut(args) - } -} + extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output { + self.call_mut(args) + } + } + #[allow(unused_parens)] + impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const + FnMut for ConstFnMutClosure<($(&'a mut $var),*), Function> + where + Function: ~const Fn(($(&mut $var),*), ClosureArguments)-> ClosureReturnValue, + { + extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output { + #[allow(non_snake_case)] + let ($($var),*) = &mut self.data; + (self.func)(($($var),*), 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) - } -} + }; + } +impl_fn_mut_tuple!(A); +impl_fn_mut_tuple!(A B); +impl_fn_mut_tuple!(A B C); +impl_fn_mut_tuple!(A B C D); +impl_fn_mut_tuple!(A B C D E); diff --git a/library/core/src/iter/adapters/array_chunks.rs b/library/core/src/iter/adapters/array_chunks.rs index 489fb13c0dc97..02abce986cb38 100644 --- a/library/core/src/iter/adapters/array_chunks.rs +++ b/library/core/src/iter/adapters/array_chunks.rs @@ -88,7 +88,11 @@ where Self: Sized, F: FnMut(B, Self::Item) -> B, { - self.try_fold(init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp)).0 + self.try_fold( + init, + ConstFnMutClosure { data: &mut f, func: NeverShortCircuit::wrap_mut_2_imp }, + ) + .0 } } @@ -132,7 +136,11 @@ where Self: Sized, F: FnMut(B, Self::Item) -> B, { - self.try_rfold(init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp)).0 + self.try_rfold( + init, + ConstFnMutClosure { data: &mut f, func: 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 1945e402ff50e..f3b8cfdb47b37 100644 --- a/library/core/src/iter/adapters/by_ref_sized.rs +++ b/library/core/src/iter/adapters/by_ref_sized.rs @@ -44,8 +44,12 @@ impl Iterator for ByRefSized<'_, I> { F: FnMut(B, Self::Item) -> B, { // `fold` needs ownership, so this can't forward directly. - I::try_fold(self.0, init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp)) - .0 + I::try_fold( + self.0, + init, + ConstFnMutClosure { data: &mut f, func: NeverShortCircuit::wrap_mut_2_imp }, + ) + .0 } #[inline] @@ -84,7 +88,7 @@ impl DoubleEndedIterator for ByRefSized<'_, I> { I::try_rfold( self.0, init, - ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp), + ConstFnMutClosure { data: &mut f, func: NeverShortCircuit::wrap_mut_2_imp }, ) .0 } diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index de3a534f81b8a..8f8748feae42c 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -209,7 +209,11 @@ where Self: Sized, F: FnMut(B, Self::Item) -> B, { - self.try_fold(init, ConstFnMutClosure::new(&mut fold, NeverShortCircuit::wrap_mut_2_imp)).0 + self.try_fold( + init, + ConstFnMutClosure { data: &mut fold, func: NeverShortCircuit::wrap_mut_2_imp }, + ) + .0 } } From 9a641a533cf3e560bd4133e01dd43250bb784ff5 Mon Sep 17 00:00:00 2001 From: onestacked Date: Fri, 30 Sep 2022 17:16:59 +0200 Subject: [PATCH 7/8] Fixed Documentation for wrap_mut_2_imp --- library/core/src/ops/try_trait.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs index 33df9e6c5cd48..84a69046807c4 100644 --- a/library/core/src/ops/try_trait.rs +++ b/library/core/src/ops/try_trait.rs @@ -379,7 +379,7 @@ pub(crate) type ChangeOutputType = <::Residual as Residual>:: pub(crate) struct NeverShortCircuit(pub T); impl NeverShortCircuit { - /// Wrap a binary `FnMut` to return its result wrapped in a `NeverShortCircuit`. + /// Implementation for building `ConstFnMutClosure` for wrapping the output of a ~const FnMut in a `NeverShortCircuit`. #[inline] pub const fn wrap_mut_2_imp T>( f: &mut F, From 10739d475e95b825a3b57a726da5266f7d50c9e7 Mon Sep 17 00:00:00 2001 From: onestacked Date: Fri, 30 Sep 2022 17:41:01 +0200 Subject: [PATCH 8/8] Add back ConstFnMutClosure::new, fix formatting --- library/core/src/cmp.rs | 4 +- library/core/src/const_closure.rs | 63 ++++++++++++------- .../core/src/iter/adapters/array_chunks.rs | 12 +--- .../core/src/iter/adapters/by_ref_sized.rs | 10 +-- library/core/src/iter/adapters/mod.rs | 6 +- 5 files changed, 48 insertions(+), 47 deletions(-) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 5033e744def02..f0fa2e1d2c190 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1267,7 +1267,7 @@ where { f(v1).cmp(&f(v2)) } - min_by(v1, v2, ConstFnMutClosure { data: &mut f, func: imp }) + min_by(v1, v2, ConstFnMutClosure::new(&mut f, imp)) } /// Compares and returns the maximum of two values. @@ -1352,7 +1352,7 @@ where { f(v1).cmp(&f(v2)) } - max_by(v1, v2, ConstFnMutClosure { data: &mut f, func: imp }) + max_by(v1, v2, ConstFnMutClosure::new(&mut f, imp)) } // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types diff --git a/library/core/src/const_closure.rs b/library/core/src/const_closure.rs index 23b3f87e72172..9e9c02093be20 100644 --- a/library/core/src/const_closure.rs +++ b/library/core/src/const_closure.rs @@ -23,36 +23,53 @@ pub(crate) struct ConstFnMutClosure { /// The Function of the Closure, must be: Fn(CapturedData, ClosureArgs) -> ClosureReturn pub func: Function, } +impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<&'a mut CapturedData, Function> { + /// Function for creating a new closure. + /// + /// `data` is the a mutable borrow of data that is captured from the environment. + /// If you want Data to be a tuple of mutable Borrows, the struct must be constructed manually. + /// + /// `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 } + } +} macro_rules! impl_fn_mut_tuple { ($($var:ident)*) => { - #[allow(unused_parens)] - impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const - FnOnce for ConstFnMutClosure<($(&'a mut $var),*), Function> - where - Function: ~const Fn(($(&mut $var),*), ClosureArguments) -> ClosureReturnValue+ ~const Destruct, - { - type Output = ClosureReturnValue; + #[allow(unused_parens)] + impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const + FnOnce for ConstFnMutClosure<($(&'a mut $var),*), Function> + where + Function: ~const Fn(($(&mut $var),*), ClosureArguments) -> ClosureReturnValue+ ~const Destruct, + { + type Output = ClosureReturnValue; - extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output { - self.call_mut(args) + extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output { + self.call_mut(args) + } } - } - #[allow(unused_parens)] - impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const - FnMut for ConstFnMutClosure<($(&'a mut $var),*), Function> - where - Function: ~const Fn(($(&mut $var),*), ClosureArguments)-> ClosureReturnValue, - { - extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output { - #[allow(non_snake_case)] - let ($($var),*) = &mut self.data; - (self.func)(($($var),*), args) + #[allow(unused_parens)] + impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const + FnMut for ConstFnMutClosure<($(&'a mut $var),*), Function> + where + Function: ~const Fn(($(&mut $var),*), ClosureArguments)-> ClosureReturnValue, + { + extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output { + #[allow(non_snake_case)] + let ($($var),*) = &mut self.data; + (self.func)(($($var),*), args) + } } - } - }; - } +} impl_fn_mut_tuple!(A); impl_fn_mut_tuple!(A B); impl_fn_mut_tuple!(A B C); diff --git a/library/core/src/iter/adapters/array_chunks.rs b/library/core/src/iter/adapters/array_chunks.rs index 02abce986cb38..489fb13c0dc97 100644 --- a/library/core/src/iter/adapters/array_chunks.rs +++ b/library/core/src/iter/adapters/array_chunks.rs @@ -88,11 +88,7 @@ where Self: Sized, F: FnMut(B, Self::Item) -> B, { - self.try_fold( - init, - ConstFnMutClosure { data: &mut f, func: NeverShortCircuit::wrap_mut_2_imp }, - ) - .0 + self.try_fold(init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp)).0 } } @@ -136,11 +132,7 @@ where Self: Sized, F: FnMut(B, Self::Item) -> B, { - self.try_rfold( - init, - ConstFnMutClosure { data: &mut f, func: NeverShortCircuit::wrap_mut_2_imp }, - ) - .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 f3b8cfdb47b37..1945e402ff50e 100644 --- a/library/core/src/iter/adapters/by_ref_sized.rs +++ b/library/core/src/iter/adapters/by_ref_sized.rs @@ -44,12 +44,8 @@ impl Iterator for ByRefSized<'_, I> { F: FnMut(B, Self::Item) -> B, { // `fold` needs ownership, so this can't forward directly. - I::try_fold( - self.0, - init, - ConstFnMutClosure { data: &mut f, func: NeverShortCircuit::wrap_mut_2_imp }, - ) - .0 + I::try_fold(self.0, init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp)) + .0 } #[inline] @@ -88,7 +84,7 @@ impl DoubleEndedIterator for ByRefSized<'_, I> { I::try_rfold( self.0, init, - ConstFnMutClosure { data: &mut f, func: NeverShortCircuit::wrap_mut_2_imp }, + ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp), ) .0 } diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index 8f8748feae42c..de3a534f81b8a 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -209,11 +209,7 @@ where Self: Sized, F: FnMut(B, Self::Item) -> B, { - self.try_fold( - init, - ConstFnMutClosure { data: &mut fold, func: NeverShortCircuit::wrap_mut_2_imp }, - ) - .0 + self.try_fold(init, ConstFnMutClosure::new(&mut fold, NeverShortCircuit::wrap_mut_2_imp)).0 } }