diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index d2e3c00bb0c07..dc6bc0a8123e9 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -466,7 +466,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { let spans = sess.psess.gated_spans.spans.borrow(); macro_rules! gate_all { ($feature:ident, $explain:literal $(, $help:literal)?) => { - for &span in spans.get(&sym::$feature).into_iter().flatten() { + for &span in spans.get(&sym::$feature).into_flat_iter() { gate!(visitor, $feature, span, $explain $(, $help)?); } }; @@ -527,13 +527,13 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { ); // `associated_const_equality` will be stabilized as part of `min_generic_const_args`. - for &span in spans.get(&sym::associated_const_equality).into_iter().flatten() { + for &span in spans.get(&sym::associated_const_equality).into_flat_iter() { gate!(visitor, min_generic_const_args, span, "associated const equality is incomplete"); } // `mgca_type_const_syntax` is part of `min_generic_const_args` so if // either or both are enabled we don't need to emit a feature error. - for &span in spans.get(&sym::mgca_type_const_syntax).into_iter().flatten() { + for &span in spans.get(&sym::mgca_type_const_syntax).into_flat_iter() { if visitor.features.min_generic_const_args() || visitor.features.mgca_type_const_syntax() || span.allows_unstable(sym::min_generic_const_args) @@ -561,13 +561,13 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { // it does **not** mean "`T` doesn't implement `Bound` (positively or negatively)"! // The latter would be a SemVer hazard! if !sess.opts.unstable_opts.internal_testing_features || !visitor.features.negative_bounds() { - for &span in spans.get(&sym::negative_bounds).into_iter().flatten() { + for &span in spans.get(&sym::negative_bounds).into_flat_iter() { sess.dcx().emit_err(diagnostics::NegativeBoundUnsupported { span }); } } if !visitor.features.never_patterns() { - for &span in spans.get(&sym::never_patterns).into_iter().flatten() { + for &span in spans.get(&sym::never_patterns).into_flat_iter() { if span.allows_unstable(sym::never_patterns) { continue; } @@ -585,7 +585,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { } // Yield exprs can be enabled either by `yield_expr`, by `coroutines` or by `gen_blocks`. - for &span in spans.get(&sym::yield_expr).into_iter().flatten() { + for &span in spans.get(&sym::yield_expr).into_flat_iter() { if (!visitor.features.coroutines() && !span.allows_unstable(sym::coroutines)) && (!visitor.features.gen_blocks() && !span.allows_unstable(sym::gen_blocks)) && (!visitor.features.yield_expr() && !span.allows_unstable(sym::yield_expr)) @@ -607,7 +607,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { macro_rules! soft_gate_all_legacy_dont_use { ($feature:ident, $explain:literal) => { - for &span in spans.get(&sym::$feature).into_iter().flatten() { + for &span in spans.get(&sym::$feature).into_flat_iter() { if !visitor.features.$feature() && !span.allows_unstable(sym::$feature) { feature_warn(&visitor.sess, sym::$feature, span, $explain); } @@ -625,7 +625,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { soft_gate_all_legacy_dont_use!(try_blocks, "`try` blocks are unstable"); // tidy-alphabetical-end - for &span in spans.get(&sym::min_specialization).into_iter().flatten() { + for &span in spans.get(&sym::min_specialization).into_flat_iter() { if !visitor.features.specialization() && !visitor.features.min_specialization() && !span.allows_unstable(sym::specialization) diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index 86ad758807584..918a623b41752 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -6,6 +6,7 @@ #![feature(deref_patterns)] #![feature(iter_intersperse)] #![feature(iter_is_partitioned)] +#![feature(option_into_flat_iter)] // tidy-alphabetical-end pub mod ast_validation; diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 42af99fc64d81..0bc06ade95ea1 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -476,9 +476,8 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> { .borrow_set .local_map .get(&place.local) - .into_iter() - .flat_map(|bs| bs.iter()) - .copied(); + .map(|bs| bs.iter().copied()) + .into_flat_iter(); // If the borrowed place is a local with no projections, all other borrows of this // local must conflict. This is purely an optimization so we don't have to call diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 22e7d83e5b509..9d66863ef70e1 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -7,6 +7,7 @@ #![feature(file_buffered)] #![feature(negative_impls)] #![feature(never_type)] +#![feature(option_into_flat_iter)] #![feature(rustc_attrs)] #![feature(stmt_expr_attributes)] #![feature(try_blocks)] diff --git a/compiler/rustc_borrowck/src/polonius/constraints.rs b/compiler/rustc_borrowck/src/polonius/constraints.rs index 559b1bdc38d83..2808cbee99fb0 100644 --- a/compiler/rustc_borrowck/src/polonius/constraints.rs +++ b/compiler/rustc_borrowck/src/polonius/constraints.rs @@ -152,7 +152,7 @@ impl LocalizedConstraintGraph { // The physical edges present at this node are: // // 1. the typeck edges that flow from region to region *at this point*. - for &succ in self.edges.get(&node).into_iter().flatten() { + for &succ in self.edges.get(&node).into_flat_iter() { let succ = LocalizedNode { region: succ, point: node.point }; successor_found(succ); } @@ -229,7 +229,7 @@ impl LocalizedConstraintGraph { } // And finally, we have the logical edges, materialized at this point. - for &logical_succ in self.logical_edges.get(&node.region).into_iter().flatten() { + for &logical_succ in self.logical_edges.get(&node.region).into_flat_iter() { let succ = LocalizedNode { region: logical_succ, point: node.point }; successor_found(succ); } diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs index db38879ea1d9b..e7e05e561d13f 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs @@ -49,7 +49,7 @@ pub(super) fn apply_member_constraints<'tcx>( rcx.scc_values.add_region(scc_a, scc_b); } - for defining_use in member_constraints.get(&scc_a).into_iter().flatten() { + for defining_use in member_constraints.get(&scc_a).into_flat_iter() { apply_member_constraint(rcx, scc_a, &defining_use.arg_regions); } } diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index e96dc44fab7c4..841e5713751cd 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -178,7 +178,7 @@ impl LivenessValues { /// Returns an iterator of all the points where `region` is live. fn live_points(&self, region: RegionVid) -> impl Iterator { - self.point_liveness(region).into_iter().flat_map(|set| set.iter()) + self.point_liveness(region).map(|set| set.iter()).into_flat_iter() } /// For debugging purposes, returns a pretty-printed string of the points where the `region` is @@ -348,13 +348,13 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> { pub(crate) fn locations_outlived_by(&self, r: N) -> impl Iterator { self.points .row(r) - .into_iter() - .flat_map(move |set| set.iter().map(move |p| self.location_map.to_location(p))) + .map(move |set| set.iter().map(move |p| self.location_map.to_location(p))) + .into_flat_iter() } /// Returns just the universal regions that are contained in a given region's value. pub(crate) fn universal_regions_outlived_by(&self, r: N) -> impl Iterator { - self.free_regions.row(r).into_iter().flat_map(|set| set.iter()) + self.free_regions.row(r).map(|set| set.iter()).into_flat_iter() } /// Returns all the elements contained in a given region's value. @@ -364,8 +364,8 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> { ) -> impl Iterator> { self.placeholders .row(r) - .into_iter() - .flat_map(|set| set.iter()) + .map(|set| set.iter()) + .into_flat_iter() .map(move |p| self.placeholder_indices.lookup_placeholder(p)) } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 123bc1f568495..a0a2d1c135aa3 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -928,7 +928,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.super_local_decl(local, local_decl); for user_ty in - local_decl.user_ty.as_deref().into_iter().flat_map(UserTypeProjections::projections) + local_decl.user_ty.as_deref().map(UserTypeProjections::projections).into_flat_iter() { let span = self.user_type_annotations[user_ty.base].span; diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs index 39123b8bade59..f34a7b956e040 100644 --- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs +++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs @@ -90,8 +90,7 @@ impl<'tcx> AssertModuleSource<'tcx> { fn check_attrs(&mut self, attrs: &[hir::Attribute]) { for &(span, cgu_fields) in find_attr!(attrs, RustcCguTestAttr(e) => e) - .into_iter() - .flatten() + .into_flat_iter() { let (expected_reuse, comp_kind) = match cgu_fields { CguFields::PartitionReused { .. } => (CguReuse::PreLto, ComparisonKind::AtLeast), diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 07c713a006994..cb04b8a826a25 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1088,9 +1088,7 @@ fn link_natively( let get_objects = |objects: &CrtObjects, kind| { objects .get(&kind) - .iter() - .copied() - .flatten() + .into_flat_iter() .map(|obj| { get_object_file_path(sess, obj, self_contained_crt_objects).into_os_string() }) @@ -2070,7 +2068,7 @@ fn add_pre_link_objects( } else { &empty }; - for obj in objects.get(&link_output_kind).iter().copied().flatten() { + for obj in objects.get(&link_output_kind).into_flat_iter() { cmd.add_object(&get_object_file_path(sess, obj, self_contained)); } } @@ -2087,7 +2085,7 @@ fn add_post_link_objects( } else { &sess.target.post_link_objects }; - for obj in objects.get(&link_output_kind).iter().copied().flatten() { + for obj in objects.get(&link_output_kind).into_flat_iter() { cmd.add_object(&get_object_file_path(sess, obj, self_contained)); } } diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 10ae8a9ee0b38..e24f4748b5987 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -2,6 +2,7 @@ #![feature(deref_patterns)] #![feature(file_buffered)] #![feature(negative_impls)] +#![feature(option_into_flat_iter)] #![feature(string_from_utf8_lossy_owned)] #![feature(trait_alias)] #![feature(try_blocks)] diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 9d8e0a512ab66..f0c5f6b85423c 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -479,10 +479,9 @@ fn fn_sig_suggestion<'tcx>( } } }; - Some(format!("{splat}{arg_ty}")) + format!("{splat}{arg_ty}") }) - .chain(std::iter::once(if sig.c_variadic() { Some("...".to_string()) } else { None })) - .flatten() + .chain(if sig.c_variadic() { Some("...".to_string()) } else { None }) .collect::>() .join(", "); let mut output = sig.output(); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 1d17621be217f..f2a6c2747f380 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1217,7 +1217,7 @@ fn check_eiis_fn(tcx: TyCtxt<'_>, def_id: LocalDefId) { // does the function have an EiiImpl attribute? that contains the defid of a *macro* // that was used to mark the implementation. This is a two step process. for EiiImpl { resolution, span, .. } in - find_attr!(tcx, def_id, EiiImpls(impls) => impls).into_iter().flatten() + find_attr!(tcx, def_id, EiiImpls(impls) => impls).into_flat_iter() { let (foreign_item, name) = match resolution { EiiImplResolution::Macro(def_id) => { @@ -1244,7 +1244,7 @@ fn check_eiis_static<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, ty: Ty<'tcx>) // does the function have an EiiImpl attribute? that contains the defid of a *macro* // that was used to mark the implementation. This is a two step process. for EiiImpl { resolution, span, .. } in - find_attr!(tcx, def_id, EiiImpls(impls) => impls).into_iter().flatten() + find_attr!(tcx, def_id, EiiImpls(impls) => impls).into_flat_iter() { let (foreign_item, name) = match resolution { EiiImplResolution::Macro(def_id) => { diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index c5a6ce75c0e41..6fc5fe8f6e72b 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -60,6 +60,7 @@ This API is completely unstable and subject to change. #![feature(gen_blocks)] #![feature(iter_intersperse)] #![feature(never_type)] +#![feature(option_into_flat_iter)] #![feature(slice_partition_dedup)] #![feature(try_blocks)] #![feature(unwrap_infallible)] diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index f7a58d278a519..4c843eefd5c4c 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -673,7 +673,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let mut coercion = self.unify_and( coerce_target, target, - reborrow.into_iter().flat_map(|(deref, autoref)| [deref, autoref]), + reborrow.map(|(deref, autoref)| [deref, autoref]).into_flat_iter(), Adjust::Pointer(PointerCoercion::Unsize), ForceLeakCheck::No, )?; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 3b3f5caa85c09..335caf571aa6f 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -3,6 +3,7 @@ #![feature(iter_intersperse)] #![feature(iter_order_by)] #![feature(never_type)] +#![feature(option_into_flat_iter)] #![feature(option_reference_flattening)] #![feature(trim_prefix_suffix)] // tidy-alphabetical-end diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index e7116b7492584..0a72f1d47b8b8 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -266,7 +266,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // NOTE: Reporting a method error should also suppress any unused trait errors, // since the method error is very possibly the reason why the trait wasn't used. for &import_id in - self.tcx.in_scope_traits(call_id).into_iter().flatten().flat_map(|c| c.import_ids) + self.tcx.in_scope_traits(call_id).into_flat_iter().flat_map(|c| c.import_ids) { self.typeck_results.borrow_mut().used_trait_imports.insert(import_id); } diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs index 97b7cdc135142..60ee55e299d87 100644 --- a/compiler/rustc_lint/src/if_let_rescope.rs +++ b/compiler/rustc_lint/src/if_let_rescope.rs @@ -349,8 +349,7 @@ impl Subdiagnostic for IfLetRescopeRewrite { closing_brackets .empty_alt .then_some(" _ => {}".chars()) - .into_iter() - .flatten() + .into_flat_iter() .chain(repeat_n('}', closing_brackets.count)) .collect(), )); diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 74bee7d705e3a..5440ae5360de7 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -23,6 +23,7 @@ #![allow(internal_features)] #![feature(deref_patterns)] #![feature(iter_order_by)] +#![feature(option_into_flat_iter)] #![feature(rustc_attrs)] #![feature(titlecase)] #![feature(try_blocks)] diff --git a/compiler/rustc_metadata/src/eii.rs b/compiler/rustc_metadata/src/eii.rs index f3ce07aa75a11..11ea4cc492921 100644 --- a/compiler/rustc_metadata/src/eii.rs +++ b/compiler/rustc_metadata/src/eii.rs @@ -25,7 +25,7 @@ pub(crate) fn collect<'tcx>(tcx: TyCtxt<'tcx>, LocalCrate: LocalCrate) -> EiiMap // iterate over all items in the current crate for id in tcx.hir_crate_items(()).eiis() { - for i in find_attr!(tcx, id, EiiImpls(e) => e).into_iter().flatten() { + for i in find_attr!(tcx, id, EiiImpls(e) => e).into_flat_iter() { let decl = match i.resolution { EiiImplResolution::Macro(macro_defid) => { // find the decl for this one if it wasn't in yet (maybe it's from the local crate? not very useful but not illegal) diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 840b1c4c6fa2f..9ef9422a9e5a0 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -8,6 +8,7 @@ #![feature(macro_metavar_expr)] #![feature(min_specialization)] #![feature(never_type)] +#![feature(option_into_flat_iter)] #![feature(proc_macro_internals)] #![feature(trusted_len)] // tidy-alphabetical-end diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 874d4812502e6..f970be089f2ee 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -325,9 +325,8 @@ impl<'a> CrateLocator<'a> { sess.opts .externs .get(crate_name.as_str()) - .into_iter() - .filter_map(|entry| entry.files()) - .flatten() + .and_then(|entry| entry.files()) + .into_flat_iter() .cloned() .collect() } else { diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index e467cf9bf105b..12174b3719b03 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -223,9 +223,7 @@ impl<'tcx> Collector<'tcx> { return; } - for attr in - find_attr!(self.tcx, def_id, Link(links, _) => links).iter().map(|v| v.iter()).flatten() - { + for attr in find_attr!(self.tcx, def_id, Link(links, _) => links).into_flat_iter() { let dll_imports = match attr.kind { NativeLibKind::RawDylib { .. } => foreign_items .iter() diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index bd3b2445759e7..bed2be51a3468 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -2038,10 +2038,12 @@ impl CrateMetadata { krate: CrateNum, ) -> impl Iterator { gen move { - for def_id in self.root.proc_macro_data.as_ref().into_iter().flat_map(move |data| { - data.macros.decode((self, tcx)).map(move |(index, _)| DefId { index, krate }) - }) { - yield def_id; + if let Some(data) = &self.root.proc_macro_data { + for def_id in + data.macros.decode((self, tcx)).map(move |(index, _)| DefId { index, krate }) + { + yield def_id; + } } } } diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 3ab2690c7a6f4..da7ad32ae9dc0 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -46,6 +46,7 @@ #![feature(min_specialization)] #![feature(negative_impls)] #![feature(never_type)] +#![feature(option_into_flat_iter)] #![feature(ptr_alignment_type)] #![feature(range_bounds_is_empty)] #![feature(rustc_attrs)] diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 0042c87c3eda7..ad3b8e009320d 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -769,25 +769,22 @@ impl<'tcx> Ty<'tcx> { .projection_bounds() .filter(|item| !tcx.generics_require_sized_self(item.item_def_id())) .count(); - let expected_count: usize = obj - .principal_def_id() - .into_iter() - .flat_map(|principal_def_id| { - // IMPORTANT: This has to agree with HIR ty lowering of dyn trait! - elaborate::supertraits( - tcx, - ty::Binder::dummy(ty::TraitRef::identity(tcx, principal_def_id)), - ) - .map(|principal| { - tcx.associated_items(principal.def_id()) - .in_definition_order() - .filter(|item| item.is_type() || item.is_type_const()) - .filter(|item| !item.is_impl_trait_in_trait()) - .filter(|item| !tcx.generics_require_sized_self(item.def_id)) - .count() - }) + let expected_count: usize = obj.principal_def_id().map_or(0, |principal_def_id| { + // IMPORTANT: This has to agree with HIR ty lowering of dyn trait! + elaborate::supertraits( + tcx, + ty::Binder::dummy(ty::TraitRef::identity(tcx, principal_def_id)), + ) + .map(|principal| { + tcx.associated_items(principal.def_id()) + .in_definition_order() + .filter(|item| item.is_type() || item.is_type_const()) + .filter(|item| !item.is_impl_trait_in_trait()) + .filter(|item| !tcx.generics_require_sized_self(item.def_id)) + .count() }) - .sum(); + .sum() + }); assert_eq!( projection_count, expected_count, "expected {obj:?} to have {expected_count} projections, \ diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 77820beef0228..65a713602ed07 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -537,8 +537,8 @@ impl<'tcx> TypeckResults<'tcx> { ) -> impl Iterator> { self.closure_min_captures .get(&closure_def_id) - .map(|closure_min_captures| closure_min_captures.values().flat_map(|v| v.iter())) - .into_iter() + .map(|closure_min_captures| closure_min_captures.values()) + .into_flat_iter() .flatten() } diff --git a/compiler/rustc_mir_transform/src/coverage/counters/balanced_flow.rs b/compiler/rustc_mir_transform/src/coverage/counters/balanced_flow.rs index 4c20722a04347..616d24d87b719 100644 --- a/compiler/rustc_mir_transform/src/coverage/counters/balanced_flow.rs +++ b/compiler/rustc_mir_transform/src/coverage/counters/balanced_flow.rs @@ -126,6 +126,6 @@ where sink_edge = self.sink_edge_nodes.contains(node).then_some(self.sink); } - real_edges.into_iter().flatten().chain(sink_edge) + real_edges.into_flat_iter().chain(sink_edge) } } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index edf0dcca775ca..2bb14589db36a 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -4,6 +4,7 @@ #![feature(deref_patterns)] #![feature(impl_trait_in_assoc_type)] #![feature(iterator_try_collect)] +#![feature(option_into_flat_iter)] #![feature(try_blocks)] #![feature(yeet_expr)] // tidy-alphabetical-end diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index ea26d4043b25f..66cc83b41ac3a 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -4,6 +4,10 @@ //! //! This API is completely unstable and subject to change. +// tidy-alphabetical-start +#![feature(option_into_flat_iter)] +// tidy-alphabetical-end + use rustc_middle::query::Providers; pub mod abi_test; diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 14f631b84a781..bf5a1dc2ec4b8 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -1112,8 +1112,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { .iter() .flat_map(|&cnum| { find_attr!(tcx, cnum.as_def_id(), UnstableRemoved(rem_features) => rem_features) - .into_iter() - .flatten() + .into_flat_iter() }) .collect::>(); diff --git a/compiler/rustc_resolve/src/error_helper.rs b/compiler/rustc_resolve/src/error_helper.rs index 1b7d799cadd35..50571393240b5 100644 --- a/compiler/rustc_resolve/src/error_helper.rs +++ b/compiler/rustc_resolve/src/error_helper.rs @@ -1469,13 +1469,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Scope::DeriveHelpers(expn_id) => { let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper); if filter_fn(res) { - suggestions.extend( - this.helper_attrs.get(&expn_id).into_iter().flatten().map( - |&(ident, orig_ident_span, _)| { - TypoSuggestion::new(ident.name, orig_ident_span, res) - }, - ), - ); + suggestions.extend(this.helper_attrs.get(&expn_id).into_flat_iter().map( + |&(ident, orig_ident_span, _)| { + TypoSuggestion::new(ident.name, orig_ident_span, res) + }, + )); } } Scope::DeriveHelpersCompat => { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index e6cfa469e91d0..c84b0f2f66fae 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -15,6 +15,7 @@ #![feature(default_field_values)] #![feature(deref_patterns)] #![feature(iter_intersperse)] +#![feature(option_into_flat_iter)] #![feature(rustc_attrs)] #![feature(trim_prefix_suffix)] #![recursion_limit = "256"] diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index c5b7a5e8450da..cc83867dc1a9e 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -6,6 +6,7 @@ #![feature(iter_intersperse)] #![feature(macro_derive)] #![feature(macro_metavar_expr)] +#![feature(option_into_flat_iter)] #![feature(rustc_attrs)] // To generate CodegenOptionsTargetModifiers and UnstableOptionsTargetModifiers enums // with macro_rules, it is necessary to use recursive mechanic ("Incremental TT Munchers"). diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index efc8a70f4feb2..2bf6e2f855f81 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1617,7 +1617,7 @@ pub mod parse { let mut seen_instruction_threshold = false; let mut seen_skip_entry = false; let mut seen_skip_exit = false; - for option in v.into_iter().flat_map(|v| v.split(',')) { + for option in v.map(|v| v.split(',')).into_flat_iter() { match option { "always" if !seen_always && !seen_never => { options.always = true; diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 4e3a31f0e84b5..2d0da9d1a20ac 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -1611,7 +1611,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { _ => None, }; - [typeck_results.expr_ty_adjusted_opt(expr)].into_iter().flatten().any(|expr_ty| { + typeck_results.expr_ty_adjusted_opt(expr).is_some_and(|expr_ty| { self.can_eq(obligation.param_env, expr_ty, old_self_ty) || inner_old_self_ty .is_some_and(|inner_ty| self.can_eq(obligation.param_env, expr_ty, inner_ty)) diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 8900687036d41..463555c456264 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -19,6 +19,7 @@ #![feature(iter_intersperse)] #![feature(iterator_try_reduce)] #![feature(never_type)] +#![feature(option_into_flat_iter)] #![feature(try_blocks)] #![feature(unwrap_infallible)] #![feature(yeet_expr)] diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs index 098dcfb30a7b6..0aa7dc79ea121 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -264,8 +264,7 @@ impl<'tcx> BestObligation<'tcx> { let body_id = self.obligation.cause.body_id; for obligation in wf::unnormalized_obligations(infcx, param_env, term, self.span(), body_id) - .into_iter() - .flatten() + .into_flat_iter() { let nested_goal = candidate.instantiate_proof_tree_for_nested_goal( GoalSource::Misc, diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index 233e124fc60f5..a3a73ac56b68a 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -98,8 +98,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( // From the full set of obligations, just filter down to the region relationships. for obligation in wf::unnormalized_obligations(ocx.infcx, param_env, arg, DUMMY_SP, CRATE_DEF_ID) - .into_iter() - .flatten() + .into_flat_iter() { let pred = ocx .deeply_normalize( diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index b278c32cb61ae..90fdc3ff939d2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -1030,10 +1030,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // supertraits. let a_auto_traits: FxIndexSet = a_data .auto_traits() - .chain(principal_def_id_a.into_iter().flat_map(|principal_def_id| { - elaborate::supertrait_def_ids(self.tcx(), principal_def_id) - .filter(|def_id| self.tcx().trait_is_auto(*def_id)) - })) + .chain( + principal_def_id_a + .map(|principal_def_id| { + elaborate::supertrait_def_ids(self.tcx(), principal_def_id) + .filter(|def_id| self.tcx().trait_is_auto(*def_id)) + }) + .into_flat_iter(), + ) .collect(); let auto_traits_compatible = b_data .auto_traits() diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 73dc9bff6343d..f407bec8df60d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2594,10 +2594,15 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // supertraits. let a_auto_traits: FxIndexSet = a_data .auto_traits() - .chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| { - elaborate::supertrait_def_ids(tcx, principal_def_id) - .filter(|def_id| tcx.trait_is_auto(*def_id)) - })) + .chain( + a_data + .principal_def_id() + .map(|principal_def_id| { + elaborate::supertrait_def_ids(tcx, principal_def_id) + .filter(|def_id| tcx.trait_is_auto(*def_id)) + }) + .into_flat_iter(), + ) .collect(); let upcast_principal = normalize_with_depth_to( diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 72f1b51d19e9d..83d493f077539 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -188,8 +188,7 @@ fn prepare_vtable_segments_inner<'tcx, T>( /// Turns option of iterator into an iterator (this is just flatten) fn maybe_iter(i: Option) -> impl Iterator { - // Flatten is bad perf-vise, we could probably implement a special case here that is better - i.into_iter().flatten() + i.into_flat_iter() } fn has_own_existential_vtable_entries(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool { diff --git a/compiler/rustc_transmute/src/layout/dfa.rs b/compiler/rustc_transmute/src/layout/dfa.rs index 6fc40ce42d88c..92f1898658b07 100644 --- a/compiler/rustc_transmute/src/layout/dfa.rs +++ b/compiler/rustc_transmute/src/layout/dfa.rs @@ -257,15 +257,15 @@ where pub(crate) fn bytes_from(&self, start: State) -> impl Iterator { self.transitions .get(&start) - .into_iter() - .flat_map(|transitions| transitions.byte_transitions.iter()) + .map(|transitions| transitions.byte_transitions.iter()) + .into_flat_iter() } pub(crate) fn refs_from(&self, start: State) -> impl Iterator, State)> { self.transitions .get(&start) - .into_iter() - .flat_map(|transitions| transitions.ref_transitions.iter()) + .map(|transitions| transitions.ref_transitions.iter()) + .into_flat_iter() .map(|(r, s)| (*r, *s)) } diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 732881f12d2cb..e504ce0051398 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -1,6 +1,7 @@ // tidy-alphabetical-start #![cfg_attr(test, feature(test))] #![feature(never_type)] +#![feature(option_into_flat_iter)] // tidy-alphabetical-end pub(crate) use rustc_data_structures::fx::{FxIndexMap as Map, FxIndexSet as Set}; diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 58fadff1e6e5d..268386692dc3f 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -32,7 +32,7 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] { let item_def_id = trait_item_ref.owner_id.to_def_id(); [item_def_id] .into_iter() - .chain(rpitit_items.get(&item_def_id).into_iter().flatten().copied()) + .chain(rpitit_items.get(&item_def_id).into_flat_iter().copied()) })) } hir::ItemKind::Impl(impl_) => { @@ -44,7 +44,7 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[DefId] { let item_def_id = impl_item_ref.owner_id.to_def_id(); [item_def_id] .into_iter() - .chain(rpitit_items.get(&item_def_id).into_iter().flatten().copied()) + .chain(rpitit_items.get(&item_def_id).into_flat_iter().copied()) })) } _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"), diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index e83525c16b965..174f1c50964a9 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -176,13 +176,13 @@ fn impl_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator if let hir::ItemKind::Impl(impl_) = item.kind { let trait_args = impl_ .of_trait - .into_iter() - .flat_map(|of_trait| of_trait.trait_ref.path.segments.last().unwrap().args().args) + .map(|of_trait| of_trait.trait_ref.path.segments.last().unwrap().args().args) + .into_flat_iter() .map(|arg| arg.span()); let dummy_spans_for_default_args = impl_ .of_trait - .into_iter() - .flat_map(|of_trait| iter::repeat(of_trait.trait_ref.path.span)); + .map(|of_trait| iter::repeat(of_trait.trait_ref.path.span)) + .into_flat_iter(); iter::once(impl_.self_ty.span).chain(trait_args).chain(dummy_spans_for_default_args) } else { bug!("unexpected item for impl {def_id:?}: {item:?}") diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index cdf280381247a..be0042f697e5d 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -718,8 +718,7 @@ fn layout_of_uncached<'tcx>( let discriminants_iter = || { def.is_enum() .then(|| def.discriminants(tcx).map(|(v, d)| (v, d.val as i128))) - .into_iter() - .flatten() + .into_flat_iter() }; let maybe_unsized = def.is_struct() diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 6d7afba71098a..d775a7bfceff2 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -9,6 +9,7 @@ #![feature(deref_patterns)] #![feature(iterator_try_collect)] #![feature(never_type)] +#![feature(option_into_flat_iter)] // tidy-alphabetical-end use rustc_middle::query::Providers;