From bcf0ec019172ccb34e2f53c07cd3b76d506d249a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 16 Feb 2023 11:47:50 +1100 Subject: [PATCH 1/7] Replace `mk_foo` calls with `infer_foo` where possible. There are several `mk_foo`/`intern_foo` pairs, where the former takes an iterator and the latter takes a slice. (This naming convention is bad, but that's a fix for another PR.) This commit changes several `mk_foo` occurrences into `intern_foo`, avoiding the need for some `.iter()`/`.into_iter()` calls. Affected cases: - mk_type_list - mk_tup - mk_substs - mk_const_list --- compiler/rustc_borrowck/src/type_check/mod.rs | 2 +- .../src/codegen_i128.rs | 4 ++-- .../src/intrinsics/llvm_x86.rs | 2 +- .../rustc_codegen_cranelift/src/main_shim.rs | 2 +- compiler/rustc_codegen_cranelift/src/num.rs | 2 +- .../interpret/intrinsics/caller_location.rs | 2 +- .../rustc_hir_analysis/src/check/intrinsic.rs | 2 +- compiler/rustc_hir_typeck/src/upvar.rs | 6 ++--- compiler/rustc_metadata/src/native_libs.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 12 ++++------ compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_middle/src/ty/layout.rs | 2 +- compiler/rustc_middle/src/ty/relate.rs | 2 +- .../rustc_middle/src/ty/structural_impls.rs | 2 +- compiler/rustc_mir_transform/src/shim.rs | 2 +- .../src/typeid/typeid_itanium_cxx_abi.rs | 23 ++++++++----------- .../solve/trait_goals/structural_traits.rs | 4 ++-- .../src/traits/project.rs | 2 +- compiler/rustc_ty_utils/src/consts.rs | 2 +- .../src/methods/needless_collect.rs | 2 +- 20 files changed, 37 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 1ec1f0cb1105..004b945eada1 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2589,7 +2589,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { DefKind::InlineConst => substs.as_inline_const().parent_substs(), other => bug!("unexpected item {:?}", other), }; - let parent_substs = tcx.mk_substs(parent_substs.iter()); + let parent_substs = tcx.intern_substs(parent_substs); assert_eq!(typeck_root_substs.len(), parent_substs.len()); if let Err(_) = self.eq_substs( diff --git a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs index 638b2d573b5d..b4a2537b5ea9 100644 --- a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs +++ b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs @@ -56,7 +56,7 @@ pub(crate) fn maybe_codegen<'tcx>( Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty)) } } else { - let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter()); + let out_ty = fx.tcx.intern_tup(&[lhs.layout().ty, fx.tcx.types.bool]); let oflow = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32)); let lhs = lhs.load_scalar(fx); let rhs = rhs.load_scalar(fx); @@ -78,7 +78,7 @@ pub(crate) fn maybe_codegen<'tcx>( } BinOp::Add | BinOp::Sub | BinOp::Mul => { assert!(checked); - let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter()); + let out_ty = fx.tcx.intern_tup(&[lhs.layout().ty, fx.tcx.types.bool]); let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty)); let (param_types, args) = if fx.tcx.sess.target.is_like_windows { let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs index d2ae6978ca2a..cbac2e667652 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs @@ -191,7 +191,7 @@ fn llvm_add_sub<'tcx>( // carry0 | carry1 -> carry or borrow respectively let cb_out = fx.bcx.ins().bor(cb0, cb1); - let layout = fx.layout_of(fx.tcx.mk_tup([fx.tcx.types.u8, fx.tcx.types.u64].iter())); + let layout = fx.layout_of(fx.tcx.intern_tup(&[fx.tcx.types.u8, fx.tcx.types.u64])); let val = CValue::by_val_pair(cb_out, c, layout); ret.write_cvalue(fx, val); } diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs index 3e3b68571342..26327107df4c 100644 --- a/compiler/rustc_codegen_cranelift/src/main_shim.rs +++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs @@ -119,7 +119,7 @@ pub(crate) fn maybe_create_entry_wrapper( tcx, ParamEnv::reveal_all(), report.def_id, - tcx.mk_substs([GenericArg::from(main_ret_ty)].iter()), + tcx.intern_substs(&[GenericArg::from(main_ret_ty)]), ) .unwrap() .unwrap() diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs index afacbec64458..05905a7bcdf3 100644 --- a/compiler/rustc_codegen_cranelift/src/num.rs +++ b/compiler/rustc_codegen_cranelift/src/num.rs @@ -289,7 +289,7 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( _ => bug!("binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", bin_op, in_lhs, in_rhs), }; - let out_layout = fx.layout_of(fx.tcx.mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter())); + let out_layout = fx.layout_of(fx.tcx.intern_tup(&[in_lhs.layout().ty, fx.tcx.types.bool])); CValue::by_val_pair(res, has_overflow, out_layout) } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs index ec5707505c89..f6a3937870ed 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs @@ -96,7 +96,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let loc_ty = self .tcx .type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None)) - .subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_erased.into()].iter())); + .subst(*self.tcx, self.tcx.intern_substs(&[self.tcx.lifetimes.re_erased.into()])); let loc_layout = self.layout_of(loc_ty).unwrap(); let location = self.allocate(loc_layout, MemoryKind::CallerLocation).unwrap(); diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 82562ac75e1a..51700cf846ba 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -378,7 +378,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { ( 1, vec![tcx.mk_imm_ref(tcx.mk_re_late_bound(ty::INNERMOST, br), param(0))], - tcx.mk_projection(discriminant_def_id, tcx.mk_substs([param(0).into()].iter())), + tcx.mk_projection(discriminant_def_id, tcx.intern_substs(&[param(0).into()])), ) } diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index e12a575d5acd..7c8abb4186f1 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -301,7 +301,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Build a tuple (U0..Un) of the final upvar types U0..Un // and unify the upvar tuple type in the closure with it: - let final_tupled_upvars_type = self.tcx.mk_tup(final_upvar_tys.iter()); + let final_tupled_upvars_type = self.tcx.intern_tup(&final_upvar_tys); self.demand_suptype(span, substs.tupled_upvars_ty(), final_tupled_upvars_type); let fake_reads = delegate @@ -315,8 +315,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.typeck_results.borrow_mut().closure_size_eval.insert( closure_def_id, ClosureSizeProfileData { - before_feature_tys: self.tcx.mk_tup(before_feature_tys.into_iter()), - after_feature_tys: self.tcx.mk_tup(after_feature_tys.into_iter()), + before_feature_tys: self.tcx.intern_tup(&before_feature_tys), + after_feature_tys: self.tcx.intern_tup(&after_feature_tys), }, ); } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index ffb52d167b17..d823989bb02b 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -502,7 +502,7 @@ impl<'tcx> Collector<'tcx> { .subst_identity() .fn_sig(self.tcx) .inputs() - .map_bound(|slice| self.tcx.mk_type_list(slice.iter())), + .map_bound(|slice| self.tcx.intern_type_list(slice)), ); argument_types diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index f955b312b238..46184cddd51f 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2525,14 +2525,12 @@ impl<'tcx> ConstantKind<'tcx> { } let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); - let parent_substs = if let Some(parent_hir_id) = tcx.hir().opt_parent_id(hir_id) { - if let Some(parent_did) = parent_hir_id.as_owner() { - InternalSubsts::identity_for_item(tcx, parent_did.to_def_id()) - } else { - tcx.mk_substs(Vec::>::new().into_iter()) - } + let parent_substs = if let Some(parent_hir_id) = tcx.hir().opt_parent_id(hir_id) + && let Some(parent_did) = parent_hir_id.as_owner() + { + InternalSubsts::identity_for_item(tcx, parent_did.to_def_id()) } else { - tcx.mk_substs(Vec::>::new().into_iter()) + tcx.intern_substs(&[]) }; debug!(?parent_substs); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 117f3decd1a6..79879ea20ab8 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1190,7 +1190,7 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_imm_ref( self.lifetimes.re_static, self.type_of(self.require_lang_item(LangItem::PanicLocation, None)) - .subst(self, self.mk_substs([self.lifetimes.re_static.into()].iter())), + .subst(self, self.intern_substs(&[self.lifetimes.re_static.into()])), ) } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 1d76f435e26d..3d0f9a5053cb 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -686,7 +686,7 @@ where Increase this counter if you tried to implement this but failed to do it without duplicating a lot of code from other places in the compiler: 2 - tcx.mk_tup(&[ + tcx.intern_tup(&[ tcx.mk_array(tcx.types.usize, 3), tcx.mk_array(Option), ]) diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 322afeb2d340..2ba25e8bfadc 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -673,7 +673,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( for (a_arg, b_arg) in aa.iter().zip(ba.iter()) { related_args.push(r.consts(a_arg, b_arg)?); } - let related_args = tcx.mk_const_list(related_args.iter()); + let related_args = tcx.intern_const_list(&related_args); Expr::FunctionCall(func, related_args) } _ => return Err(TypeError::ConstMismatch(expected_found(r, a, b))), diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 97ee2b1fc5dd..9c1a6f716d02 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -418,7 +418,7 @@ impl<'tcx> ir::TypeFoldable> for &'tcx ty::List ir::TypeFoldable> for &'tcx ty::List> { fn try_fold_with>(self, folder: &mut F) -> Result { - ty::util::fold_list(self, folder, |tcx, v| tcx.mk_const_list(v.iter())) + ty::util::fold_list(self, folder, |tcx, v| tcx.intern_const_list(v)) } } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 7f388b065ade..682ad081f5cf 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -597,7 +597,7 @@ fn build_call_shim<'tcx>( let untuple_args = sig.inputs(); // Create substitutions for the `Self` and `Args` generic parameters of the shim body. - let arg_tup = tcx.mk_tup(untuple_args.iter()); + let arg_tup = tcx.intern_tup(untuple_args); (Some([ty.into(), arg_tup.into()]), Some(untuple_args)) } else { diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 949ef04dd4d0..fb8695e7eafa 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -813,21 +813,18 @@ fn transform_substs<'tcx>( substs: SubstsRef<'tcx>, options: TransformTyOptions, ) -> SubstsRef<'tcx> { - let substs: Vec> = substs - .iter() - .map(|subst| { - if let GenericArgKind::Type(ty) = subst.unpack() { - if is_c_void_ty(tcx, ty) { - tcx.mk_unit().into() - } else { - transform_ty(tcx, ty, options).into() - } + let substs = substs.iter().map(|subst| { + if let GenericArgKind::Type(ty) = subst.unpack() { + if is_c_void_ty(tcx, ty) { + tcx.mk_unit().into() } else { - subst + transform_ty(tcx, ty, options).into() } - }) - .collect(); - tcx.mk_substs(substs.iter()) + } else { + subst + } + }); + tcx.mk_substs(substs) } /// Returns a type metadata identifier for the specified FnAbi using the Itanium C++ ABI with vendor diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs index b6847b976be6..3662463178f8 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs @@ -191,10 +191,10 @@ pub(crate) fn extract_tupled_inputs_and_output_from_callable<'tcx>( ty::FnDef(def_id, substs) => Ok(Some( tcx.fn_sig(def_id) .subst(tcx, substs) - .map_bound(|sig| (tcx.mk_tup(sig.inputs().iter()), sig.output())), + .map_bound(|sig| (tcx.intern_tup(sig.inputs()), sig.output())), )), ty::FnPtr(sig) => { - Ok(Some(sig.map_bound(|sig| (tcx.mk_tup(sig.inputs().iter()), sig.output())))) + Ok(Some(sig.map_bound(|sig| (tcx.intern_tup(sig.inputs()), sig.output())))) } ty::Closure(_, substs) => { let closure_substs = substs.as_closure(); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 011fe742a69c..9143d28b8eed 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1923,7 +1923,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>( ) -> Progress<'tcx> { let tcx = selcx.tcx(); let self_ty = obligation.predicate.self_ty(); - let substs = tcx.mk_substs([self_ty.into()].iter()); + let substs = tcx.intern_substs(&[self_ty.into()]); let lang_items = tcx.lang_items(); let item_def_id = obligation.predicate.def_id; let trait_def_id = tcx.trait_of_item(item_def_id).unwrap(); diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index a9fbad55dac5..852156c24f42 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -144,7 +144,7 @@ fn recurse_build<'tcx>( for &id in args.iter() { new_args.push(recurse_build(tcx, body, id, root_span)?); } - let new_args = tcx.mk_const_list(new_args.iter()); + let new_args = tcx.intern_const_list(&new_args); tcx.mk_const(Expr::FunctionCall(fun, new_args), node.ty) } &ExprKind::Binary { op, lhs, rhs } if check_binop(op) => { diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs index 82d3b830d4f3..8ddbacc3d7ad 100644 --- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs @@ -173,7 +173,7 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) - && let Some(iter_item) = cx.tcx .associated_items(iter_trait) .find_by_name_and_kind(cx.tcx, Ident::with_dummy_span(Symbol::intern("Item")), AssocKind::Type, iter_trait) - && let substs = cx.tcx.mk_substs([GenericArg::from(typeck.expr_ty_adjusted(iter_expr))].into_iter()) + && let substs = cx.tcx.intern_substs(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))]) && let proj_ty = cx.tcx.mk_projection(iter_item.def_id, substs) && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty) { From 28184e749160d4707d5006b52ee7aeff8ba9a9b5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 16 Feb 2023 11:55:23 +1100 Subject: [PATCH 2/7] Clarify `mk_fn_sig` signature. Giving the item type a name `T` avoids duplication. --- compiler/rustc_middle/src/ty/context.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 79879ea20ab8..a28e236d860f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2210,16 +2210,17 @@ impl<'tcx> TyCtxt<'tcx> { if ts.is_empty() { List::empty() } else { self._intern_bound_variable_kinds(ts) } } - pub fn mk_fn_sig( + pub fn mk_fn_sig( self, inputs: I, output: I::Item, c_variadic: bool, unsafety: hir::Unsafety, abi: abi::Abi, - ) -> , ty::FnSig<'tcx>>>::Output + ) -> T::Output where - I: Iterator, ty::FnSig<'tcx>>>, + I: Iterator, + T: InternIteratorElement, ty::FnSig<'tcx>>, { inputs.chain(iter::once(output)).intern_with(|xs| ty::FnSig { inputs_and_output: self.intern_type_list(xs), From 9d5cf0f0bf2f241c2d7a6250ad7f8e3a7dbf3d95 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 16 Feb 2023 12:06:04 +1100 Subject: [PATCH 3/7] Remove the `InternIteratorElement` impl for `&'a T`. `InternIteratorElement` is a trait used to intern values produces by iterators. There are three impls, corresponding to iterators that produce different types: - One for `T`, which operates straightforwardly. - One for `Result`, which is fallible, and will fail early with an error result if any of the iterator elements are errors. - One for `&'a T`, which clones the items as it iterates. That last one is bad: it's extremely easy to use it without realizing that it clones, which goes against Rust's normal "explicit is better" approach to cloning. So this commit just removes it. In practice, there weren't many use sites. For all but one of them `into_iter()` could be used, which avoids the need for cloning. And for the one remaining case `copied()` is used. --- compiler/rustc_hir_typeck/src/check.rs | 2 +- .../rustc_hir_typeck/src/generator_interior/mod.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 2 +- .../src/typeid/typeid_itanium_cxx_abi.rs | 4 ++-- .../rustc_trait_selection/src/solve/trait_goals.rs | 2 +- compiler/rustc_ty_utils/src/abi.rs | 4 ++-- compiler/rustc_type_ir/src/lib.rs | 11 ----------- 7 files changed, 8 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 3feb23d3481e..2b3678d98755 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -264,7 +264,7 @@ fn check_lang_start_fn<'tcx>( let fn_generic = generics.param_at(0, tcx); let generic_ty = tcx.mk_ty_param(fn_generic.index, fn_generic.name); let expected_fn_sig = - tcx.mk_fn_sig([].iter(), &generic_ty, false, hir::Unsafety::Normal, Abi::Rust); + tcx.mk_fn_sig([].into_iter(), generic_ty, false, hir::Unsafety::Normal, Abi::Rust); let expected_ty = tcx.mk_fn_ptr(Binder::dummy(expected_fn_sig)); // we emit the same error to suggest changing the arg no matter what's wrong with the arg diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index 3f61a1a83e5a..d0a66acd5a12 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -312,7 +312,7 @@ pub fn resolve_interior<'a, 'tcx>( // Extract type components to build the witness type. let type_list = fcx.tcx.mk_type_list(type_causes.iter().map(|cause| cause.ty)); - let bound_vars = fcx.tcx.mk_bound_variable_kinds(bound_vars.iter()); + let bound_vars = fcx.tcx.mk_bound_variable_kinds(bound_vars.into_iter()); let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind_with_vars(type_list, bound_vars.clone())); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a28e236d860f..7b144d478e07 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2387,7 +2387,7 @@ impl<'tcx> TyCtxt<'tcx> { .unwrap_or_else(|| { bug!("No bound vars found for {}", self.hir().node_to_string(id)) }) - .iter(), + .into_iter(), ) } diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index fb8695e7eafa..c2eccbcbc3cb 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -781,8 +781,8 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio let output = transform_ty(tcx, fn_sig.skip_binder().output(), options); ty = tcx.mk_fn_ptr(ty::Binder::bind_with_vars( tcx.mk_fn_sig( - parameters.iter(), - &output, + parameters.into_iter(), + output, fn_sig.c_variadic(), fn_sig.unsafety(), fn_sig.abi(), diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 0921fb5756d6..d12e5f797fb9 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -359,7 +359,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { let b_last_ty = b_tys.last().unwrap(); // Substitute just the tail field of B., and require that they're equal. - let unsized_a_ty = tcx.mk_tup(a_rest_tys.iter().chain([b_last_ty])); + let unsized_a_ty = tcx.mk_tup(a_rest_tys.iter().chain([b_last_ty]).copied()); let mut nested_goals = ecx.infcx.eq(goal.param_env, unsized_a_ty, b_ty)?; // Similar to ADTs, require that the rest of the fields are equal. diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 8b32c0119e0e..76ecb86efb83 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -141,8 +141,8 @@ fn fn_sig_for_fn_abi<'tcx>( ty::Binder::bind_with_vars( tcx.mk_fn_sig( - [env_ty, resume_ty].iter(), - &ret_ty, + [env_ty, resume_ty].into_iter(), + ret_ty, false, hir::Unsafety::Normal, rustc_target::spec::abi::Abi::Rust, diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index cb28731681ba..d3c0a410bfc2 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -127,17 +127,6 @@ impl InternIteratorElement for T { } } -impl<'a, T, R> InternIteratorElement for &'a T -where - T: Clone + 'a, -{ - type Output = R; - fn intern_with, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output { - // This code isn't hot. - f(&iter.cloned().collect::>()) - } -} - impl InternIteratorElement for Result { type Output = Result; fn intern_with, F: FnOnce(&[T]) -> R>( From c8237db3eed2c91c14ce46b482b3d479a39d328d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 16 Feb 2023 12:06:36 +1100 Subject: [PATCH 4/7] Clarify iterator interners. There are two traits, `InternAs` and `InternIteratorElement`. I found them confusing to use, particularly this: ``` pub fn mk_tup, Ty<'tcx>>>(self, iter: I) -> I::Output { iter.intern_with(|ts| self.intern_tup(ts)) } ``` where I thought there might have been two levels of interning going on (there isn't) due to the `intern_with`/`InternAs` + `intern_tup` naming. And then I found the actual traits and impls themselves *very* confusing. - `InternAs` has a single impl, for iterators, with four type variables. - `InternAs` is only implemented for iterators because it wouldn't really make sense to implement for any other type. And you can't really understand the trait without seeing that single impl, which is suspicious. - `InternAs` is basically just a wrapper for `InternIteratorElement` which does all the actual work. - Neither trait actually does any interning. They just have `Intern` in their name because they are used *by* interning code. - There are no comments. So this commit improves things. - It removes `InternAs` completely. This makes the `mk_*` function signatures slightly more verbose -- two trait bounds instead of one -- but much easier to read, because you only need to understand one trait instead of two. - It renames `InternIteratorElement` as `CollectAndApply`. Likewise, it renames its method `intern_with` as `collect_and_apply`. These names describe better what's going on: we collect the iterator elements into a slice and then apply a function to the slice. - It adds comments, making clear that all this is all there just to provide an optimized version of `f(&iter.collect::>())`. It took me a couple of attempts to come up with this commit. My initial attempt kept `InternAs` around, but renamed things and added comments, and I wasn't happy with it. I think this version is much better. The resulting code is shorter, despite the addition of the comments. --- compiler/rustc_middle/src/ty/context.rs | 95 ++++++++++++++----------- compiler/rustc_type_ir/src/lib.rs | 62 ++++++++-------- 2 files changed, 87 insertions(+), 70 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 7b144d478e07..7b4434a38435 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -67,7 +67,7 @@ use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx}; use rustc_target::spec::abi; use rustc_type_ir::sty::TyKind::*; use rustc_type_ir::WithCachedTypeInfo; -use rustc_type_ir::{DynKind, InternAs, InternIteratorElement, Interner, TypeFlags}; +use rustc_type_ir::{CollectAndApply, DynKind, Interner, TypeFlags}; use std::any::Any; use std::borrow::Borrow; @@ -1835,8 +1835,12 @@ impl<'tcx> TyCtxt<'tcx> { if ts.is_empty() { self.types.unit } else { self.mk_ty(Tuple(self.intern_type_list(&ts))) } } - pub fn mk_tup, Ty<'tcx>>>(self, iter: I) -> I::Output { - iter.intern_with(|ts| self.intern_tup(ts)) + pub fn mk_tup(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply, Ty<'tcx>>, + { + T::collect_and_apply(iter, |ts| self.intern_tup(ts)) } #[inline] @@ -2157,11 +2161,12 @@ impl<'tcx> TyCtxt<'tcx> { } } - pub fn mk_const_list, &'tcx List>>>( - self, - iter: I, - ) -> I::Output { - iter.intern_with(|xs| self.intern_const_list(xs)) + pub fn mk_const_list(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply, &'tcx List>>, + { + T::collect_and_apply(iter, |xs| self.intern_const_list(xs)) } pub fn intern_const_list(self, cs: &[ty::Const<'tcx>]) -> &'tcx List> { @@ -2220,9 +2225,9 @@ impl<'tcx> TyCtxt<'tcx> { ) -> T::Output where I: Iterator, - T: InternIteratorElement, ty::FnSig<'tcx>>, + T: CollectAndApply, ty::FnSig<'tcx>>, { - inputs.chain(iter::once(output)).intern_with(|xs| ty::FnSig { + T::collect_and_apply(inputs.chain(iter::once(output)), |xs| ty::FnSig { inputs_and_output: self.intern_type_list(xs), c_variadic, unsafety, @@ -2230,38 +2235,47 @@ impl<'tcx> TyCtxt<'tcx> { }) } - pub fn mk_poly_existential_predicates< - I: InternAs, &'tcx List>>, - >( - self, - iter: I, - ) -> I::Output { - iter.intern_with(|xs| self.intern_poly_existential_predicates(xs)) + pub fn mk_poly_existential_predicates(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply< + PolyExistentialPredicate<'tcx>, + &'tcx List>, + >, + { + T::collect_and_apply(iter, |xs| self.intern_poly_existential_predicates(xs)) } - pub fn mk_predicates, &'tcx List>>>( - self, - iter: I, - ) -> I::Output { - iter.intern_with(|xs| self.intern_predicates(xs)) + pub fn mk_predicates(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply, &'tcx List>>, + { + T::collect_and_apply(iter, |xs| self.intern_predicates(xs)) } - pub fn mk_type_list, &'tcx List>>>(self, iter: I) -> I::Output { - iter.intern_with(|xs| self.intern_type_list(xs)) + pub fn mk_type_list(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply, &'tcx List>>, + { + T::collect_and_apply(iter, |xs| self.intern_type_list(xs)) } - pub fn mk_substs, &'tcx List>>>( - self, - iter: I, - ) -> I::Output { - iter.intern_with(|xs| self.intern_substs(xs)) + pub fn mk_substs(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply, &'tcx List>>, + { + T::collect_and_apply(iter, |xs| self.intern_substs(xs)) } - pub fn mk_place_elems, &'tcx List>>>( - self, - iter: I, - ) -> I::Output { - iter.intern_with(|xs| self.intern_place_elems(xs)) + pub fn mk_place_elems(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply, &'tcx List>>, + { + T::collect_and_apply(iter, |xs| self.intern_place_elems(xs)) } pub fn mk_substs_trait( @@ -2290,13 +2304,12 @@ impl<'tcx> TyCtxt<'tcx> { ty::AliasTy { def_id, substs, _use_mk_alias_ty_instead: () } } - pub fn mk_bound_variable_kinds< - I: InternAs>, - >( - self, - iter: I, - ) -> I::Output { - iter.intern_with(|xs| self.intern_bound_variable_kinds(xs)) + pub fn mk_bound_variable_kinds(self, iter: I) -> T::Output + where + I: Iterator, + T: CollectAndApply>, + { + T::collect_and_apply(iter, |xs| self.intern_bound_variable_kinds(xs)) } /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`, diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index d3c0a410bfc2..5a991e03dee5 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -69,38 +69,37 @@ pub trait Interner: Sized { type PlaceholderRegion: Clone + Debug + Hash + Ord; } -pub trait InternAs { +/// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter` +/// that produces `T` items. You could combine them with +/// `f(&iter.collect::>())`, but this requires allocating memory for the +/// `Vec`. +/// +/// This trait allows for faster implementations, intended for cases where the +/// number of items produced by the iterator is small. There is a blanket impl +/// for `T` items, but there is also a fallible impl for `Result` items. +pub trait CollectAndApply: Sized { type Output; - fn intern_with(self, f: F) -> Self::Output + + /// Produce a result of type `Self::Output` from `iter`. The result will + /// typically be produced by applying `f` on the elements produced by + /// `iter`, though this may not happen in some impls, e.g. if an error + /// occured during iteration. + fn collect_and_apply(iter: I, f: F) -> Self::Output where + I: Iterator, F: FnOnce(&[T]) -> R; } -impl InternAs for I -where - E: InternIteratorElement, - I: Iterator, -{ - type Output = E::Output; - fn intern_with(self, f: F) -> Self::Output +/// The blanket impl that always collects all elements and applies `f`. +impl CollectAndApply for T { + type Output = R; + + /// Equivalent to `f(&iter.collect::>())`. + fn collect_and_apply(mut iter: I, f: F) -> R where + I: Iterator, F: FnOnce(&[T]) -> R, { - E::intern_with(self, f) - } -} - -pub trait InternIteratorElement: Sized { - type Output; - fn intern_with, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output; -} - -impl InternIteratorElement for T { - type Output = R; - fn intern_with, F: FnOnce(&[T]) -> R>( - mut iter: I, - f: F, - ) -> Self::Output { // This code is hot enough that it's worth specializing for the most // common length lists, to avoid the overhead of `SmallVec` creation. // Lengths 0, 1, and 2 typically account for ~95% of cases. If @@ -127,12 +126,17 @@ impl InternIteratorElement for T { } } -impl InternIteratorElement for Result { +/// A fallible impl that will fail, without calling `f`, if there are any +/// errors during collection. +impl CollectAndApply for Result { type Output = Result; - fn intern_with, F: FnOnce(&[T]) -> R>( - mut iter: I, - f: F, - ) -> Self::Output { + + /// Equivalent to `Ok(f(&iter.collect::>>()?))`. + fn collect_and_apply(mut iter: I, f: F) -> Result + where + I: Iterator>, + F: FnOnce(&[T]) -> R, + { // This code is hot enough that it's worth specializing for the most // common length lists, to avoid the overhead of `SmallVec` creation. // Lengths 0, 1, and 2 typically account for ~95% of cases. If From 2017aeff8887617fb7eef66d4b8dc81ca6e925c5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 16 Feb 2023 16:05:08 +1100 Subject: [PATCH 5/7] Use `IntoIterator` for `mk_fn_sig`. This makes a lot of call sites nicer. --- .../rustc_codegen_llvm/src/coverageinfo/mod.rs | 4 +--- compiler/rustc_codegen_llvm/src/intrinsic.rs | 7 +++---- compiler/rustc_hir_analysis/src/astconv/mod.rs | 2 +- .../rustc_hir_analysis/src/check/intrinsic.rs | 16 ++++------------ compiler/rustc_hir_analysis/src/lib.rs | 5 ++--- compiler/rustc_hir_typeck/src/check.rs | 2 +- compiler/rustc_hir_typeck/src/closure.rs | 4 ++-- compiler/rustc_middle/src/ty/context.rs | 15 ++++++++++----- .../src/typeid/typeid_itanium_cxx_abi.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 4 ++-- compiler/rustc_ty_utils/src/abi.rs | 2 +- 11 files changed, 28 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index ace15cfb0247..3dc0ac03312e 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -27,8 +27,6 @@ use rustc_middle::ty::Instance; use std::cell::RefCell; use std::ffi::CString; -use std::iter; - pub mod mapgen; const UNUSED_FUNCTION_COUNTER_ID: CounterValueReference = CounterValueReference::START; @@ -201,7 +199,7 @@ fn declare_unused_fn<'tcx>(cx: &CodegenCx<'_, 'tcx>, def_id: DefId) -> Instance< tcx.symbol_name(instance).name, cx.fn_abi_of_fn_ptr( ty::Binder::dummy(tcx.mk_fn_sig( - iter::once(tcx.mk_unit()), + [tcx.mk_unit()], tcx.mk_unit(), false, hir::Unsafety::Unsafe, diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index b0295481ca5a..39afb4af6f68 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -22,7 +22,6 @@ use rustc_target::abi::{self, Align, HasDataLayout, Primitive}; use rustc_target::spec::{HasTargetSpec, PanicStrategy}; use std::cmp::Ordering; -use std::iter; fn get_simple_intrinsic<'ll>( cx: &CodegenCx<'ll, '_>, @@ -798,7 +797,7 @@ fn get_rust_try_fn<'ll, 'tcx>( let i8p = tcx.mk_mut_ptr(tcx.types.i8); // `unsafe fn(*mut i8) -> ()` let try_fn_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig( - iter::once(i8p), + [i8p], tcx.mk_unit(), false, hir::Unsafety::Unsafe, @@ -806,7 +805,7 @@ fn get_rust_try_fn<'ll, 'tcx>( ))); // `unsafe fn(*mut i8, *mut i8) -> ()` let catch_fn_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig( - [i8p, i8p].iter().cloned(), + [i8p, i8p], tcx.mk_unit(), false, hir::Unsafety::Unsafe, @@ -814,7 +813,7 @@ fn get_rust_try_fn<'ll, 'tcx>( ))); // `unsafe fn(unsafe fn(*mut i8) -> (), *mut i8, unsafe fn(*mut i8, *mut i8) -> ()) -> i32` let rust_fn_sig = ty::Binder::dummy(cx.tcx.mk_fn_sig( - [try_fn_ty, i8p, catch_fn_ty].into_iter(), + [try_fn_ty, i8p, catch_fn_ty], tcx.types.i32, false, hir::Unsafety::Unsafe, diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 5bb78d172531..4cf159237939 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -3109,7 +3109,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!(?output_ty); - let fn_ty = tcx.mk_fn_sig(input_tys.into_iter(), output_ty, decl.c_variadic, unsafety, abi); + let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi); let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars); if !self.allow_ty_infer() && !(visitor.0.is_empty() && infer_replacements.is_empty()) { diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 51700cf846ba..8d9d8fa56547 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -15,8 +15,6 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_target::spec::abi::Abi; -use std::iter; - fn equate_intrinsic_type<'tcx>( tcx: TyCtxt<'tcx>, it: &hir::ForeignItem<'_>, @@ -385,14 +383,14 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { kw::Try => { let mut_u8 = tcx.mk_mut_ptr(tcx.types.u8); let try_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig( - iter::once(mut_u8), + [mut_u8], tcx.mk_unit(), false, hir::Unsafety::Normal, Abi::Rust, )); let catch_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig( - [mut_u8, mut_u8].iter().cloned(), + [mut_u8, mut_u8], tcx.mk_unit(), false, hir::Unsafety::Normal, @@ -447,7 +445,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { }; (n_tps, 0, inputs, output, unsafety) }; - let sig = tcx.mk_fn_sig(inputs.into_iter(), output, false, unsafety, Abi::RustIntrinsic); + let sig = tcx.mk_fn_sig(inputs, output, false, unsafety, Abi::RustIntrinsic); let sig = ty::Binder::bind_with_vars(sig, bound_vars); equate_intrinsic_type(tcx, it, n_tps, n_lts, sig) } @@ -545,13 +543,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) } }; - let sig = tcx.mk_fn_sig( - inputs.into_iter(), - output, - false, - hir::Unsafety::Unsafe, - Abi::PlatformIntrinsic, - ); + let sig = tcx.mk_fn_sig(inputs, output, false, hir::Unsafety::Unsafe, Abi::PlatformIntrinsic); let sig = ty::Binder::dummy(sig); equate_intrinsic_type(tcx, it, n_tps, 0, sig) } diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 6111046a5195..11240cf22e4b 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -113,7 +113,6 @@ use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode}; -use std::iter; use std::ops::Not; use astconv::AstConv; @@ -348,7 +347,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { } let se_ty = tcx.mk_fn_ptr(expected_return_type.map_bound(|expected_return_type| { - tcx.mk_fn_sig(iter::empty(), expected_return_type, false, hir::Unsafety::Normal, Abi::Rust) + tcx.mk_fn_sig([], expected_return_type, false, hir::Unsafety::Normal, Abi::Rust) })); require_same_types( @@ -434,7 +433,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) { } let se_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig( - [tcx.types.isize, tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))].iter().cloned(), + [tcx.types.isize, tcx.mk_imm_ptr(tcx.mk_imm_ptr(tcx.types.u8))], tcx.types.isize, false, hir::Unsafety::Normal, diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 2b3678d98755..bf8259ff70fa 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -264,7 +264,7 @@ fn check_lang_start_fn<'tcx>( let fn_generic = generics.param_at(0, tcx); let generic_ty = tcx.mk_ty_param(fn_generic.index, fn_generic.name); let expected_fn_sig = - tcx.mk_fn_sig([].into_iter(), generic_ty, false, hir::Unsafety::Normal, Abi::Rust); + tcx.mk_fn_sig([], generic_ty, false, hir::Unsafety::Normal, Abi::Rust); let expected_ty = tcx.mk_fn_ptr(Binder::dummy(expected_fn_sig)); // we emit the same error to suggest changing the arg no matter what's wrong with the arg diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index b1268c5f7923..cf296a7bf653 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -126,7 +126,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // the `closures` table. let sig = bound_sig.map_bound(|sig| { self.tcx.mk_fn_sig( - iter::once(self.tcx.intern_tup(sig.inputs())), + [self.tcx.intern_tup(sig.inputs())], sig.output(), sig.c_variadic, sig.unsafety, @@ -326,7 +326,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!(?ret_param_ty); let sig = projection.rebind(self.tcx.mk_fn_sig( - input_tys.iter(), + input_tys, ret_param_ty, false, hir::Unsafety::Normal, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 7b4434a38435..e1a72c70145f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1660,11 +1660,11 @@ impl<'tcx> TyCtxt<'tcx> { unsafety: hir::Unsafety, ) -> PolyFnSig<'tcx> { sig.map_bound(|s| { - let params_iter = match s.inputs()[0].kind() { - ty::Tuple(params) => params.into_iter(), + let params = match s.inputs()[0].kind() { + ty::Tuple(params) => *params, _ => bug!(), }; - self.mk_fn_sig(params_iter, s.output(), s.c_variadic, unsafety, abi::Abi::Rust) + self.mk_fn_sig(params, s.output(), s.c_variadic, unsafety, abi::Abi::Rust) }) } @@ -2215,6 +2215,11 @@ impl<'tcx> TyCtxt<'tcx> { if ts.is_empty() { List::empty() } else { self._intern_bound_variable_kinds(ts) } } + // Unlike various other `mk_*` functions, this one uses `I: IntoIterator` + // instead of `I: Iterator`. Unlike those other functions, this one doesn't + // have a `intern_fn_sig` variant that can be used for cases where `I` is + // something like a `Vec`. That's because of the need to combine `inputs` + // and `output`. pub fn mk_fn_sig( self, inputs: I, @@ -2224,10 +2229,10 @@ impl<'tcx> TyCtxt<'tcx> { abi: abi::Abi, ) -> T::Output where - I: Iterator, + I: IntoIterator, T: CollectAndApply, ty::FnSig<'tcx>>, { - T::collect_and_apply(inputs.chain(iter::once(output)), |xs| ty::FnSig { + T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig { inputs_and_output: self.intern_type_list(xs), c_variadic, unsafety, diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index c2eccbcbc3cb..59a2227cd364 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -781,7 +781,7 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio let output = transform_ty(tcx, fn_sig.skip_binder().output(), options); ty = tcx.mk_fn_ptr(ty::Binder::bind_with_vars( tcx.mk_fn_sig( - parameters.into_iter(), + parameters, output, fn_sig.c_variadic(), fn_sig.unsafety(), 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 a0c67f480d02..91b463800a81 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2012,7 +2012,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let sig = match inputs.kind() { ty::Tuple(inputs) if infcx.tcx.is_fn_trait(trait_ref.def_id()) => { infcx.tcx.mk_fn_sig( - inputs.iter(), + *inputs, infcx.next_ty_var(TypeVariableOrigin { span: DUMMY_SP, kind: TypeVariableOriginKind::MiscVariable, @@ -2023,7 +2023,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) } _ => infcx.tcx.mk_fn_sig( - std::iter::once(inputs), + [inputs], infcx.next_ty_var(TypeVariableOrigin { span: DUMMY_SP, kind: TypeVariableOriginKind::MiscVariable, diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 76ecb86efb83..41924dc2a6d9 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -141,7 +141,7 @@ fn fn_sig_for_fn_abi<'tcx>( ty::Binder::bind_with_vars( tcx.mk_fn_sig( - [env_ty, resume_ty].into_iter(), + [env_ty, resume_ty], ret_ty, false, hir::Unsafety::Normal, From 107f14d2cac563608d31f08819380e4ed47e120a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 16 Feb 2023 16:27:05 +1100 Subject: [PATCH 6/7] Replace more `mk_foo` calls with `infer_foo`. --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 2 +- .../src/check/compare_impl_item.rs | 2 +- compiler/rustc_hir_analysis/src/check/intrinsic.rs | 12 ++++-------- .../rustc_hir_typeck/src/generator_interior/mod.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 8 ++++---- compiler/rustc_mir_build/src/thir/cx/mod.rs | 6 +++--- .../src/traits/select/confirmation.rs | 4 ++-- .../clippy/clippy_lints/src/redundant_slicing.rs | 4 +--- src/tools/miri/src/eval.rs | 2 +- 9 files changed, 18 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 4cf159237939..5e77cfa39f6d 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1608,7 +1608,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .collect::>(); v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); v.dedup(); - let existential_predicates = tcx.mk_poly_existential_predicates(v.into_iter()); + let existential_predicates = tcx.intern_poly_existential_predicates(&v); // Use explicitly-specified region bound. let region_bound = if !lifetime.is_elided() { diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 4fd06c23e102..5e25a4554ed4 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1936,7 +1936,7 @@ pub(super) fn check_type_bounds<'tcx>( .into() } }); - let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); + let bound_vars = tcx.intern_bound_variable_kinds(&bound_vars); let impl_ty_substs = tcx.intern_substs(&substs); let container_id = impl_ty.container_id(tcx); diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 8d9d8fa56547..4720fea8ef4a 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -137,14 +137,10 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { let intrinsic_name = tcx.item_name(intrinsic_id); let name_str = intrinsic_name.as_str(); - let bound_vars = tcx.mk_bound_variable_kinds( - [ - ty::BoundVariableKind::Region(ty::BrAnon(0, None)), - ty::BoundVariableKind::Region(ty::BrEnv), - ] - .iter() - .copied(), - ); + let bound_vars = tcx.intern_bound_variable_kinds(&[ + ty::BoundVariableKind::Region(ty::BrAnon(0, None)), + ty::BoundVariableKind::Region(ty::BrEnv), + ]); let mk_va_list_ty = |mutbl| { tcx.lang_items().va_list().map(|did| { let region = tcx.mk_re_late_bound( diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index d0a66acd5a12..14e3ba83b103 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -312,7 +312,7 @@ pub fn resolve_interior<'a, 'tcx>( // Extract type components to build the witness type. let type_list = fcx.tcx.mk_type_list(type_causes.iter().map(|cause| cause.ty)); - let bound_vars = fcx.tcx.mk_bound_variable_kinds(bound_vars.into_iter()); + let bound_vars = fcx.tcx.intern_bound_variable_kinds(&bound_vars); let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind_with_vars(type_list, bound_vars.clone())); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index e1a72c70145f..e2f32cdca3ca 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2399,13 +2399,13 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn late_bound_vars(self, id: HirId) -> &'tcx List { - self.mk_bound_variable_kinds( - self.late_bound_vars_map(id.owner) + self.intern_bound_variable_kinds( + &self + .late_bound_vars_map(id.owner) .and_then(|map| map.get(&id.local_id).cloned()) .unwrap_or_else(|| { bug!("No bound vars found for {}", self.hir().node_to_string(id)) - }) - .into_iter(), + }), ) } diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 3b7ceb3adccb..74c35ef0fc24 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -133,9 +133,9 @@ impl<'tcx> Cx<'tcx> { bug!("closure expr does not have closure type: {:?}", closure_ty); }; - let bound_vars = self.tcx.mk_bound_variable_kinds(std::iter::once( - ty::BoundVariableKind::Region(ty::BrEnv), - )); + let bound_vars = self + .tcx + .intern_bound_variable_kinds(&[ty::BoundVariableKind::Region(ty::BrEnv)]); let br = ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind: ty::BrEnv, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 1309df18e15b..60a78e642c38 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -564,10 +564,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .into() } }); - let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); + let bound_vars = tcx.intern_bound_variable_kinds(&bound_vars); let assoc_ty_substs = tcx.intern_substs(&substs); - let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); + let bound_vars = tcx.intern_bound_variable_kinds(&bound_vars); let bound = bound.map_bound(|b| b.kind().skip_binder()).subst(tcx, assoc_ty_substs); tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars)) diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs index 245a02ea26e6..398329e455bf 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs @@ -11,8 +11,6 @@ use rustc_middle::ty::adjustment::{Adjust, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::subst::GenericArg; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use std::iter; - declare_clippy_lint! { /// ### What it does /// Checks for redundant slicing expressions which use the full range, and @@ -136,7 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing { } else if let Some(target_id) = cx.tcx.lang_items().deref_target() { if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions( cx.param_env, - cx.tcx.mk_projection(target_id, cx.tcx.mk_substs(iter::once(GenericArg::from(indexed_ty)))), + cx.tcx.mk_projection(target_id, cx.tcx.intern_substs(&[GenericArg::from(indexed_ty)])), ) { if deref_ty == expr_ty { let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0; diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index d61e17cbf9a4..ebb71b57ae39 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -363,7 +363,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( tcx, ty::ParamEnv::reveal_all(), start_id, - tcx.mk_substs(::std::iter::once(ty::subst::GenericArg::from(main_ret_ty))), + tcx.intern_substs(&[ty::subst::GenericArg::from(main_ret_ty)]), ) .unwrap() .unwrap(); From af32411f20d4e4f79a2c8b4b645b2693a46c3d7d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 16 Feb 2023 16:31:47 +1100 Subject: [PATCH 7/7] Avoid double-interning some `BoundVariableKind`s. This function has this line twice: ``` let bound_vars = tcx.intern_bound_variable_kinds(&bound_vars); ``` The second occurrence is effectively a no-op, because the first occurrence interned any that needed it. --- .../rustc_trait_selection/src/traits/select/confirmation.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 60a78e642c38..e4a832e47281 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -566,8 +566,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }); let bound_vars = tcx.intern_bound_variable_kinds(&bound_vars); let assoc_ty_substs = tcx.intern_substs(&substs); - - let bound_vars = tcx.intern_bound_variable_kinds(&bound_vars); let bound = bound.map_bound(|b| b.kind().skip_binder()).subst(tcx, assoc_ty_substs); tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars))