From eb03ea4435fe93f4688d1a0ae61e266cfa53f845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 3 Dec 2025 16:20:30 +0100 Subject: [PATCH 1/4] Revert "implement and test `Iterator::{exactly_one, collect_array}`" This reverts commit 699184bba4f5e6df163d5d08883e09509ac79e86. --- library/core/src/iter/traits/iterator.rs | 56 ------------------------ 1 file changed, 56 deletions(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index f898382086512..29230b1665380 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -4034,62 +4034,6 @@ pub trait Iterator { { unreachable!("Always specialized"); } - - /// Checks if the iterator contains *exactly* one element. - /// If so, returns this one element. - /// - /// See also [`collect_array`](Iterator::collect_array) for lengths other than `1`. - /// - /// # Examples - /// - /// ``` - /// #![feature(exact_length_collection)] - /// - /// assert_eq!([1].into_iter().exactly_one(), Some(1)); - /// assert_eq!([].into_iter().exactly_one(), None::<()>); - /// - /// // There is exactly one even integer in the array: - /// assert_eq!([1, 2, 3].into_iter().filter(|x| x % 2 == 0).exactly_one(), Some(2)); - /// // But there are two odds, which is too many: - /// assert_eq!([1, 2, 3].into_iter().filter(|x| x % 2 == 1).exactly_one(), None); - /// ``` - #[inline] - #[unstable(feature = "exact_length_collection", issue = "149266")] - fn exactly_one(self) -> Option - where - Self: Sized, - { - self.collect_array::<1>().map(|[i]| i) - } - - /// Checks if an iterator has *exactly* `N` elements. - /// If so, returns those `N` elements in an array. - /// - /// See also [`exactly_one`](Iterator::exactly_one) when expecting a single element. - /// - /// # Examples - /// - /// ``` - /// #![feature(exact_length_collection)] - /// - /// assert_eq!([1, 2, 3, 4].into_iter().collect_array(), Some([1, 2, 3, 4])); - /// assert_eq!([1, 2].into_iter().chain([3, 4]).collect_array(), Some([1, 2, 3, 4])); - /// - /// // Iterator contains too few elements: - /// assert_eq!([1, 2].into_iter().collect_array::<4>(), None); - /// // Iterator contains too many elements: - /// assert_eq!([1, 2, 3, 4, 5].into_iter().collect_array::<4>(), None); - /// // Taking 4 makes it work again: - /// assert_eq!([1, 2, 3, 4, 5].into_iter().take(4).collect_array(), Some([1, 2, 3, 4])); - /// ``` - #[inline] - #[unstable(feature = "exact_length_collection", issue = "149266")] - fn collect_array(mut self) -> Option<[Self::Item; N]> - where - Self: Sized, - { - self.next_chunk().ok().filter(|_| self.next().is_none()) - } } trait SpecIterEq: Iterator { From b43df9b0c507c884da5efca965fb5d2aeb158f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Wed, 3 Dec 2025 16:22:57 +0100 Subject: [PATCH 2/4] Revert "fixup warnings around the compiler" This reverts commit f20175293aa8372766250e56e2570f3c06640e0b. --- compiler/rustc_codegen_ssa/src/back/metadata.rs | 3 +-- src/librustdoc/html/format.rs | 6 ++---- src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs | 6 ++---- .../crates/hir-expand/src/builtin/fn_macro.rs | 3 +-- .../crates/ide-assists/src/handlers/convert_bool_then.rs | 3 +-- .../ide-assists/src/handlers/convert_range_for_to_while.rs | 2 +- .../crates/ide-completion/src/tests/raw_identifiers.rs | 5 +++-- .../crates/rust-analyzer/tests/slow-tests/support.rs | 3 +-- tests/ui/const-generics/type-dependent/issue-71805.rs | 4 ++-- tests/ui/mir/mir-inlining/ice-issue-77564.rs | 7 +++---- 10 files changed, 17 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 5a49d0f07a490..6dff79374f20f 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -86,8 +86,7 @@ impl MetadataLoader for DefaultMetadataLoader { format!("failed to parse aix dylib '{}': {}", path.display(), e) })?; - // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 - match Itertools::exactly_one(archive.members()) { + match archive.members().exactly_one() { Ok(lib) => { let lib = lib.map_err(|e| { format!("failed to parse aix dylib '{}': {}", path.display(), e) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 2b9562f26574a..eee13ff2b0dc0 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1126,8 +1126,7 @@ pub(crate) fn print_impl( } if impl_.kind.is_fake_variadic() && let Some(generics) = ty.generics() - // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 - && let Ok(inner_type) = Itertools::exactly_one(generics) + && let Ok(inner_type) = generics.exactly_one() { let last = ty.last(); if f.alternate() { @@ -1207,8 +1206,7 @@ impl clean::Impl { } } else if let clean::Type::Path { path } = type_ && let Some(generics) = path.generics() - // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 - && let Ok(ty) = Itertools::exactly_one(generics) + && let Ok(ty) = generics.exactly_one() && self.kind.is_fake_variadic() { print_anchor(path.def_id(), path.last(), cx).fmt(f)?; diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs index 08e7c7593cb27..0d783fde33131 100644 --- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs +++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs @@ -92,8 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { (matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir_attrs(v.hir_id))) .then_some((v.def_id, v.span)) }); - // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 - if let Ok((id, span)) = Itertools::exactly_one(iter) + if let Ok((id, span)) = iter.exactly_one() && !find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::NonExhaustive(..)) { self.potential_enums.push((item.owner_id.def_id, id, item.span, span)); @@ -105,8 +104,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { .iter() .filter(|field| !cx.effective_visibilities.is_exported(field.def_id)); if fields.len() > 1 - // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 - && let Ok(field) = Itertools::exactly_one(private_fields) + && let Ok(field) = private_fields.exactly_one() && let TyKind::Tup([]) = field.ty.kind { span_lint_and_then( diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs index 78fac8ff13517..6fe63f249cd4a 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs @@ -786,8 +786,7 @@ fn parse_string(tt: &tt::TopSubtree) -> Result<(Symbol, Span), ExpandError> { && let DelimiterKind::Parenthesis | DelimiterKind::Invisible = sub.delimiter.kind { tt = - // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 - Itertools::exactly_one(tt_iter).map_err(|_| sub.delimiter.open.cover(sub.delimiter.close))?; + tt_iter.exactly_one().map_err(|_| sub.delimiter.open.cover(sub.delimiter.close))?; } match tt { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs index 91cee59ad8d00..9d5d3f223707a 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs @@ -163,8 +163,7 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_> let name_ref = ctx.find_node_at_offset::()?; let mcall = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast)?; let receiver = mcall.receiver()?; - // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 - let closure_body = Itertools::exactly_one(mcall.arg_list()?.args()).ok()?; + let closure_body = mcall.arg_list()?.args().exactly_one().ok()?; let closure_body = match closure_body { ast::Expr::ClosureExpr(expr) => expr.body()?, _ => return None, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs index ba577b217df78..68cb764030956 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs @@ -113,7 +113,7 @@ fn extract_range(iterable: &ast::Expr) -> Option<(ast::Expr, Option, (range.start()?, range.end(), make::expr_literal("1").into(), inclusive) } ast::Expr::MethodCallExpr(call) if call.name_ref()?.text() == "step_by" => { - let [step] = Itertools::collect_array(call.arg_list()?.args())?; + let [step] = call.arg_list()?.args().collect_array()?; let (start, end, _, inclusive) = extract_range(&call.receiver()?)?; (start, end, step, inclusive) } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/raw_identifiers.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/raw_identifiers.rs index 66b16681f47af..00977ea4e533b 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/raw_identifiers.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/raw_identifiers.rs @@ -8,8 +8,9 @@ fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { let completions = completion_list_with_config_raw(TEST_CONFIG, ra_fixture, true, None); let (db, position) = position(ra_fixture); let mut actual = db.file_text(position.file_id).text(&db).to_string(); - // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 - Itertools::exactly_one(completions.into_iter()) + completions + .into_iter() + .exactly_one() .expect("more than one completion") .text_edit .apply(&mut actual); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs index b1b428e7068dc..3464a9644b19d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs @@ -113,8 +113,7 @@ impl Project<'_> { let mut buf = Vec::new(); flags::Lsif::run( flags::Lsif { - // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 - path: tmp_dir_path.join(Itertools::exactly_one(self.roots.iter()).unwrap()).into(), + path: tmp_dir_path.join(self.roots.iter().exactly_one().unwrap()).into(), exclude_vendored_libraries: false, }, &mut buf, diff --git a/tests/ui/const-generics/type-dependent/issue-71805.rs b/tests/ui/const-generics/type-dependent/issue-71805.rs index de04a809da60f..27c101df107c8 100644 --- a/tests/ui/const-generics/type-dependent/issue-71805.rs +++ b/tests/ui/const-generics/type-dependent/issue-71805.rs @@ -4,7 +4,7 @@ use std::mem::MaybeUninit; trait CollectSlice<'a>: Iterator { fn inner_array(&mut self) -> [Self::Item; N]; - fn custom_collect_array(&mut self) -> [Self::Item; N] { + fn collect_array(&mut self) -> [Self::Item; N] { let result = self.inner_array(); assert!(self.next().is_none()); result @@ -34,5 +34,5 @@ where fn main() { let mut foos = [0u64; 9].iter().cloned(); - let _bar: [u64; 9] = foos.custom_collect_array::<9_usize>(); + let _bar: [u64; 9] = foos.collect_array::<9_usize>(); } diff --git a/tests/ui/mir/mir-inlining/ice-issue-77564.rs b/tests/ui/mir/mir-inlining/ice-issue-77564.rs index 256ff295184d7..fce6d1d174f66 100644 --- a/tests/ui/mir/mir-inlining/ice-issue-77564.rs +++ b/tests/ui/mir/mir-inlining/ice-issue-77564.rs @@ -29,11 +29,10 @@ where fn main() { assert_eq!( - CollectArray::collect_array( - &mut [[1, 2], [3, 4]] + [[1, 2], [3, 4]] .iter() - .map(|row| CollectArray::collect_array(&mut row.iter())) - ), + .map(|row| row.iter().collect_array()) + .collect_array(), [[&1, &2], [&3, &4]] ); } From 4f6d9093ead713aef330282f0bff377883d3f716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 24 Nov 2025 11:36:57 +0100 Subject: [PATCH 3/4] implement and test `Iterator::{exactly_one, collect_array}` --- library/core/src/iter/traits/iterator.rs | 56 ++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 29230b1665380..f898382086512 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -4034,6 +4034,62 @@ pub trait Iterator { { unreachable!("Always specialized"); } + + /// Checks if the iterator contains *exactly* one element. + /// If so, returns this one element. + /// + /// See also [`collect_array`](Iterator::collect_array) for lengths other than `1`. + /// + /// # Examples + /// + /// ``` + /// #![feature(exact_length_collection)] + /// + /// assert_eq!([1].into_iter().exactly_one(), Some(1)); + /// assert_eq!([].into_iter().exactly_one(), None::<()>); + /// + /// // There is exactly one even integer in the array: + /// assert_eq!([1, 2, 3].into_iter().filter(|x| x % 2 == 0).exactly_one(), Some(2)); + /// // But there are two odds, which is too many: + /// assert_eq!([1, 2, 3].into_iter().filter(|x| x % 2 == 1).exactly_one(), None); + /// ``` + #[inline] + #[unstable(feature = "exact_length_collection", issue = "149266")] + fn exactly_one(self) -> Option + where + Self: Sized, + { + self.collect_array::<1>().map(|[i]| i) + } + + /// Checks if an iterator has *exactly* `N` elements. + /// If so, returns those `N` elements in an array. + /// + /// See also [`exactly_one`](Iterator::exactly_one) when expecting a single element. + /// + /// # Examples + /// + /// ``` + /// #![feature(exact_length_collection)] + /// + /// assert_eq!([1, 2, 3, 4].into_iter().collect_array(), Some([1, 2, 3, 4])); + /// assert_eq!([1, 2].into_iter().chain([3, 4]).collect_array(), Some([1, 2, 3, 4])); + /// + /// // Iterator contains too few elements: + /// assert_eq!([1, 2].into_iter().collect_array::<4>(), None); + /// // Iterator contains too many elements: + /// assert_eq!([1, 2, 3, 4, 5].into_iter().collect_array::<4>(), None); + /// // Taking 4 makes it work again: + /// assert_eq!([1, 2, 3, 4, 5].into_iter().take(4).collect_array(), Some([1, 2, 3, 4])); + /// ``` + #[inline] + #[unstable(feature = "exact_length_collection", issue = "149266")] + fn collect_array(mut self) -> Option<[Self::Item; N]> + where + Self: Sized, + { + self.next_chunk().ok().filter(|_| self.next().is_none()) + } } trait SpecIterEq: Iterator { From 16610b1138294ef144870a471d4ae9c2fe553c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Mon, 24 Nov 2025 11:36:57 +0100 Subject: [PATCH 4/4] fixup warnings around the compiler --- compiler/rustc_codegen_ssa/src/back/metadata.rs | 3 ++- src/librustdoc/html/format.rs | 6 ++++-- src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs | 6 ++++-- .../crates/hir-expand/src/builtin/fn_macro.rs | 3 ++- .../crates/ide-assists/src/handlers/convert_bool_then.rs | 3 ++- .../ide-assists/src/handlers/convert_range_for_to_while.rs | 2 +- .../crates/ide-completion/src/tests/raw_identifiers.rs | 5 ++--- .../crates/rust-analyzer/tests/slow-tests/support.rs | 3 ++- tests/ui/const-generics/type-dependent/issue-71805.rs | 4 ++-- tests/ui/mir/mir-inlining/ice-issue-77564.rs | 7 ++++--- 10 files changed, 25 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 6dff79374f20f..5a49d0f07a490 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -86,7 +86,8 @@ impl MetadataLoader for DefaultMetadataLoader { format!("failed to parse aix dylib '{}': {}", path.display(), e) })?; - match archive.members().exactly_one() { + // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 + match Itertools::exactly_one(archive.members()) { Ok(lib) => { let lib = lib.map_err(|e| { format!("failed to parse aix dylib '{}': {}", path.display(), e) diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index eee13ff2b0dc0..2b9562f26574a 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1126,7 +1126,8 @@ pub(crate) fn print_impl( } if impl_.kind.is_fake_variadic() && let Some(generics) = ty.generics() - && let Ok(inner_type) = generics.exactly_one() + // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 + && let Ok(inner_type) = Itertools::exactly_one(generics) { let last = ty.last(); if f.alternate() { @@ -1206,7 +1207,8 @@ impl clean::Impl { } } else if let clean::Type::Path { path } = type_ && let Some(generics) = path.generics() - && let Ok(ty) = generics.exactly_one() + // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 + && let Ok(ty) = Itertools::exactly_one(generics) && self.kind.is_fake_variadic() { print_anchor(path.def_id(), path.last(), cx).fmt(f)?; diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs index 0d783fde33131..08e7c7593cb27 100644 --- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs +++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs @@ -92,7 +92,8 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { (matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir_attrs(v.hir_id))) .then_some((v.def_id, v.span)) }); - if let Ok((id, span)) = iter.exactly_one() + // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 + if let Ok((id, span)) = Itertools::exactly_one(iter) && !find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::NonExhaustive(..)) { self.potential_enums.push((item.owner_id.def_id, id, item.span, span)); @@ -104,7 +105,8 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { .iter() .filter(|field| !cx.effective_visibilities.is_exported(field.def_id)); if fields.len() > 1 - && let Ok(field) = private_fields.exactly_one() + // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 + && let Ok(field) = Itertools::exactly_one(private_fields) && let TyKind::Tup([]) = field.ty.kind { span_lint_and_then( diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs index 6fe63f249cd4a..78fac8ff13517 100644 --- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs +++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/fn_macro.rs @@ -786,7 +786,8 @@ fn parse_string(tt: &tt::TopSubtree) -> Result<(Symbol, Span), ExpandError> { && let DelimiterKind::Parenthesis | DelimiterKind::Invisible = sub.delimiter.kind { tt = - tt_iter.exactly_one().map_err(|_| sub.delimiter.open.cover(sub.delimiter.close))?; + // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 + Itertools::exactly_one(tt_iter).map_err(|_| sub.delimiter.open.cover(sub.delimiter.close))?; } match tt { diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs index 9d5d3f223707a..91cee59ad8d00 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs @@ -163,7 +163,8 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_> let name_ref = ctx.find_node_at_offset::()?; let mcall = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast)?; let receiver = mcall.receiver()?; - let closure_body = mcall.arg_list()?.args().exactly_one().ok()?; + // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 + let closure_body = Itertools::exactly_one(mcall.arg_list()?.args()).ok()?; let closure_body = match closure_body { ast::Expr::ClosureExpr(expr) => expr.body()?, _ => return None, diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs index 68cb764030956..ba577b217df78 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_range_for_to_while.rs @@ -113,7 +113,7 @@ fn extract_range(iterable: &ast::Expr) -> Option<(ast::Expr, Option, (range.start()?, range.end(), make::expr_literal("1").into(), inclusive) } ast::Expr::MethodCallExpr(call) if call.name_ref()?.text() == "step_by" => { - let [step] = call.arg_list()?.args().collect_array()?; + let [step] = Itertools::collect_array(call.arg_list()?.args())?; let (start, end, _, inclusive) = extract_range(&call.receiver()?)?; (start, end, step, inclusive) } diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/raw_identifiers.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/raw_identifiers.rs index 00977ea4e533b..66b16681f47af 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/raw_identifiers.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/raw_identifiers.rs @@ -8,9 +8,8 @@ fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) { let completions = completion_list_with_config_raw(TEST_CONFIG, ra_fixture, true, None); let (db, position) = position(ra_fixture); let mut actual = db.file_text(position.file_id).text(&db).to_string(); - completions - .into_iter() - .exactly_one() + // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 + Itertools::exactly_one(completions.into_iter()) .expect("more than one completion") .text_edit .apply(&mut actual); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs index 3464a9644b19d..b1b428e7068dc 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs @@ -113,7 +113,8 @@ impl Project<'_> { let mut buf = Vec::new(); flags::Lsif::run( flags::Lsif { - path: tmp_dir_path.join(self.roots.iter().exactly_one().unwrap()).into(), + // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266 + path: tmp_dir_path.join(Itertools::exactly_one(self.roots.iter()).unwrap()).into(), exclude_vendored_libraries: false, }, &mut buf, diff --git a/tests/ui/const-generics/type-dependent/issue-71805.rs b/tests/ui/const-generics/type-dependent/issue-71805.rs index 27c101df107c8..de04a809da60f 100644 --- a/tests/ui/const-generics/type-dependent/issue-71805.rs +++ b/tests/ui/const-generics/type-dependent/issue-71805.rs @@ -4,7 +4,7 @@ use std::mem::MaybeUninit; trait CollectSlice<'a>: Iterator { fn inner_array(&mut self) -> [Self::Item; N]; - fn collect_array(&mut self) -> [Self::Item; N] { + fn custom_collect_array(&mut self) -> [Self::Item; N] { let result = self.inner_array(); assert!(self.next().is_none()); result @@ -34,5 +34,5 @@ where fn main() { let mut foos = [0u64; 9].iter().cloned(); - let _bar: [u64; 9] = foos.collect_array::<9_usize>(); + let _bar: [u64; 9] = foos.custom_collect_array::<9_usize>(); } diff --git a/tests/ui/mir/mir-inlining/ice-issue-77564.rs b/tests/ui/mir/mir-inlining/ice-issue-77564.rs index fce6d1d174f66..256ff295184d7 100644 --- a/tests/ui/mir/mir-inlining/ice-issue-77564.rs +++ b/tests/ui/mir/mir-inlining/ice-issue-77564.rs @@ -29,10 +29,11 @@ where fn main() { assert_eq!( - [[1, 2], [3, 4]] + CollectArray::collect_array( + &mut [[1, 2], [3, 4]] .iter() - .map(|row| row.iter().collect_array()) - .collect_array(), + .map(|row| CollectArray::collect_array(&mut row.iter())) + ), [[&1, &2], [&3, &4]] ); }