From e5d10cdbc36d80dcfa1c25ce6bd64b213674fe74 Mon Sep 17 00:00:00 2001 From: Kyle Matsuda Date: Mon, 20 Feb 2023 12:46:39 -0700 Subject: [PATCH 1/4] make (try_)subst_and_normalize_erasing_regions take EarlyBinder --- .../rustc_codegen_llvm/src/debuginfo/create_scope_map.rs | 2 +- compiler/rustc_codegen_llvm/src/debuginfo/mod.rs | 2 +- compiler/rustc_middle/src/ty/instance.rs | 6 +++--- compiler/rustc_middle/src/ty/normalize_erasing_regions.rs | 8 ++++---- compiler/rustc_monomorphize/src/partitioning/default.rs | 2 +- compiler/rustc_monomorphize/src/util.rs | 4 ++-- compiler/rustc_ty_utils/src/instance.rs | 3 +-- .../clippy_lints/src/methods/unnecessary_to_owned.rs | 2 +- 8 files changed, 14 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs index 2f910c37d6108..3fff112a02056 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs @@ -93,7 +93,7 @@ fn make_mir_scope<'ll, 'tcx>( let callee = cx.tcx.subst_and_normalize_erasing_regions( instance.substs, ty::ParamEnv::reveal_all(), - callee, + ty::EarlyBinder(callee), ); let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty()); cx.dbg_scope_fn(callee, callee_fn_abi, None) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index b138b0c0e70a1..c3f0a0033b0ea 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -529,7 +529,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions( instance.substs, ty::ParamEnv::reveal_all(), - cx.tcx.type_of(impl_def_id).skip_binder(), + cx.tcx.type_of(impl_def_id), ); // Only "class" methods are generally understood by LLVM, diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 6c8f4af759434..be584148595b3 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -115,7 +115,7 @@ impl<'tcx> Instance<'tcx> { /// lifetimes erased, allowing a `ParamEnv` to be specified for use during normalization. pub fn ty(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> { let ty = tcx.type_of(self.def.def_id()); - tcx.subst_and_normalize_erasing_regions(self.substs, param_env, ty.skip_binder()) + tcx.subst_and_normalize_erasing_regions(self.substs, param_env, ty) } /// Finds a crate that contains a monomorphization of this instance that @@ -600,7 +600,7 @@ impl<'tcx> Instance<'tcx> { T: TypeFoldable> + Clone, { if let Some(substs) = self.substs_for_mir_body() { - tcx.subst_and_normalize_erasing_regions(substs, param_env, v) + tcx.subst_and_normalize_erasing_regions(substs, param_env, ty::EarlyBinder(v)) } else { tcx.normalize_erasing_regions(param_env, v) } @@ -617,7 +617,7 @@ impl<'tcx> Instance<'tcx> { T: TypeFoldable> + Clone, { if let Some(substs) = self.substs_for_mir_body() { - tcx.try_subst_and_normalize_erasing_regions(substs, param_env, v) + tcx.try_subst_and_normalize_erasing_regions(substs, param_env, ty::EarlyBinder(v)) } else { tcx.try_normalize_erasing_regions(param_env, v) } diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 7c59879a187fe..9332b0430ffca 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -139,7 +139,7 @@ impl<'tcx> TyCtxt<'tcx> { self, param_substs: SubstsRef<'tcx>, param_env: ty::ParamEnv<'tcx>, - value: T, + value: EarlyBinder, ) -> T where T: TypeFoldable>, @@ -151,7 +151,7 @@ impl<'tcx> TyCtxt<'tcx> { param_env={:?})", param_substs, value, param_env, ); - let substituted = EarlyBinder(value).subst(self, param_substs); + let substituted = value.subst(self, param_substs); self.normalize_erasing_regions(param_env, substituted) } @@ -163,7 +163,7 @@ impl<'tcx> TyCtxt<'tcx> { self, param_substs: SubstsRef<'tcx>, param_env: ty::ParamEnv<'tcx>, - value: T, + value: EarlyBinder, ) -> Result> where T: TypeFoldable>, @@ -175,7 +175,7 @@ impl<'tcx> TyCtxt<'tcx> { param_env={:?})", param_substs, value, param_env, ); - let substituted = EarlyBinder(value).subst(self, param_substs); + let substituted = value.subst(self, param_substs); self.try_normalize_erasing_regions(param_env, substituted) } } diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index 03183a4066033..37b7f6bf8a8fc 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -310,7 +310,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( let impl_self_ty = tcx.subst_and_normalize_erasing_regions( instance.substs, ty::ParamEnv::reveal_all(), - tcx.type_of(impl_def_id).skip_binder(), + tcx.type_of(impl_def_id), ); if let Some(def_id) = characteristic_def_id_of_type(impl_self_ty) { return Some(def_id); diff --git a/compiler/rustc_monomorphize/src/util.rs b/compiler/rustc_monomorphize/src/util.rs index 33e1f6ce3428e..d12bfc6f6bb1d 100644 --- a/compiler/rustc_monomorphize/src/util.rs +++ b/compiler/rustc_monomorphize/src/util.rs @@ -29,12 +29,12 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In let before_feature_tys = tcx.subst_and_normalize_erasing_regions( closure_instance.substs, param_env, - before_feature_tys, + ty::EarlyBinder(before_feature_tys), ); let after_feature_tys = tcx.subst_and_normalize_erasing_regions( closure_instance.substs, param_env, - after_feature_tys, + ty::EarlyBinder(after_feature_tys), ); let new_size = tcx diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index b10aaad5f2af4..ec577072e196f 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -27,8 +27,7 @@ fn resolve_instance<'tcx>( ) } else { let ty = tcx.type_of(def); - let item_type = - tcx.subst_and_normalize_erasing_regions(substs, param_env, ty.skip_binder()); + let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, ty); let def = match *item_type.kind() { ty::FnDef(def_id, ..) if tcx.is_intrinsic(def_id) => { diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index 4c4c003ca4691..87641c686dcfd 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -435,7 +435,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< let output_ty = fn_sig.output(); if output_ty.contains(*param_ty) { if let Ok(new_ty) = cx.tcx.try_subst_and_normalize_erasing_regions( - new_subst, cx.param_env, output_ty) { + new_subst, cx.param_env, EarlyBinder(output_ty)) { expr = parent_expr; ty = new_ty; continue; From 82f57c16b7f362c8f6509b9c334403d81a11beed Mon Sep 17 00:00:00 2001 From: Kyle Matsuda Date: Fri, 14 Apr 2023 09:59:03 -0600 Subject: [PATCH 2/4] use EarlyBinder in tcx.(try_)subst_mir_and_normalize_erasing_regions --- compiler/rustc_codegen_cranelift/src/common.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/mod.rs | 2 +- .../rustc_const_eval/src/interpret/eval_context.rs | 6 +++++- compiler/rustc_middle/src/ty/instance.rs | 12 ++++++------ compiler/rustc_mir_transform/src/inline.rs | 2 +- compiler/rustc_mir_transform/src/inline/cycle.rs | 6 +++++- compiler/rustc_monomorphize/src/collector.rs | 2 +- 7 files changed, 20 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index 264b95e7abd73..ccb3a0c4f27e4 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -361,7 +361,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { self.instance.subst_mir_and_normalize_erasing_regions( self.tcx, ty::ParamEnv::reveal_all(), - value, + ty::EarlyBinder(value), ) } diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index f706ecea97512..1204c99e533e2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -111,7 +111,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.instance.subst_mir_and_normalize_erasing_regions( self.cx.tcx(), ty::ParamEnv::reveal_all(), - value, + ty::EarlyBinder(value), ) } } diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 361ce123c78eb..b2197a0aabbfe 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -495,7 +495,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> Result> { frame .instance - .try_subst_mir_and_normalize_erasing_regions(*self.tcx, self.param_env, value) + .try_subst_mir_and_normalize_erasing_regions( + *self.tcx, + self.param_env, + ty::EarlyBinder(value), + ) .map_err(|_| err_inval!(TooGeneric)) } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index be584148595b3..808f46bb2bb7d 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -594,15 +594,15 @@ impl<'tcx> Instance<'tcx> { &self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - v: T, + v: EarlyBinder, ) -> T where T: TypeFoldable> + Clone, { if let Some(substs) = self.substs_for_mir_body() { - tcx.subst_and_normalize_erasing_regions(substs, param_env, ty::EarlyBinder(v)) + tcx.subst_and_normalize_erasing_regions(substs, param_env, v) } else { - tcx.normalize_erasing_regions(param_env, v) + tcx.normalize_erasing_regions(param_env, v.subst_identity()) } } @@ -611,15 +611,15 @@ impl<'tcx> Instance<'tcx> { &self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - v: T, + v: EarlyBinder, ) -> Result> where T: TypeFoldable> + Clone, { if let Some(substs) = self.substs_for_mir_body() { - tcx.try_subst_and_normalize_erasing_regions(substs, param_env, ty::EarlyBinder(v)) + tcx.try_subst_and_normalize_erasing_regions(substs, param_env, v) } else { - tcx.try_normalize_erasing_regions(param_env, v) + tcx.try_normalize_erasing_regions(param_env, v.subst_identity()) } } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 71bdfd5aae1f9..95978946c4d9f 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -180,7 +180,7 @@ impl<'tcx> Inliner<'tcx> { let Ok(callee_body) = callsite.callee.try_subst_mir_and_normalize_erasing_regions( self.tcx, self.param_env, - callee_body.clone(), + ty::EarlyBinder(callee_body.clone()), ) else { return Err("failed to normalize callee body"); }; diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 6046c3876bee0..1ccf06f6153fc 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -44,7 +44,11 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( ) -> bool { trace!(%caller); for &(callee, substs) in tcx.mir_inliner_callees(caller.def) { - let Ok(substs) = caller.try_subst_mir_and_normalize_erasing_regions(tcx, param_env, substs) else { + let Ok(substs) = caller.try_subst_mir_and_normalize_erasing_regions( + tcx, + param_env, + ty::EarlyBinder(substs), + ) else { trace!(?caller, ?param_env, ?substs, "cannot normalize, skipping"); continue; }; diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 65162477b7bc5..55c937b305a49 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -677,7 +677,7 @@ impl<'a, 'tcx> MirNeighborCollector<'a, 'tcx> { self.instance.subst_mir_and_normalize_erasing_regions( self.tcx, ty::ParamEnv::reveal_all(), - value, + ty::EarlyBinder(value), ) } } From e4f6b8b43b6e9c0373ee45aaa7a6f3094c475137 Mon Sep 17 00:00:00 2001 From: Kyle Matsuda Date: Fri, 14 Apr 2023 10:11:01 -0600 Subject: [PATCH 3/4] make subst_mir take EarlyBinder --- compiler/rustc_middle/src/ty/instance.rs | 7 ++++--- compiler/rustc_mir_transform/src/inline.rs | 10 +++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 808f46bb2bb7d..4bbd7aaf10f70 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -578,14 +578,15 @@ impl<'tcx> Instance<'tcx> { self.def.has_polymorphic_mir_body().then_some(self.substs) } - pub fn subst_mir(&self, tcx: TyCtxt<'tcx>, v: &T) -> T + pub fn subst_mir(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<&T>) -> T where T: TypeFoldable> + Copy, { + let v = v.map_bound(|v| *v); if let Some(substs) = self.substs_for_mir_body() { - EarlyBinder(*v).subst(tcx, substs) + v.subst(tcx, substs) } else { - *v + v.subst_identity() } } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 95978946c4d9f..ece20d8d3e6ed 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -444,7 +444,9 @@ impl<'tcx> Inliner<'tcx> { work_list.push(target); // If the place doesn't actually need dropping, treat it like a regular goto. - let ty = callsite.callee.subst_mir(self.tcx, &place.ty(callee_body, tcx).ty); + let ty = callsite + .callee + .subst_mir(self.tcx, ty::EarlyBinder(&place.ty(callee_body, tcx).ty)); if ty.needs_drop(tcx, self.param_env) && let UnwindAction::Cleanup(unwind) = unwind { work_list.push(unwind); } @@ -788,7 +790,9 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { match terminator.kind { TerminatorKind::Drop { ref place, unwind, .. } => { // If the place doesn't actually need dropping, treat it like a regular goto. - let ty = self.instance.subst_mir(tcx, &place.ty(self.callee_body, tcx).ty); + let ty = self + .instance + .subst_mir(tcx, ty::EarlyBinder(&place.ty(self.callee_body, tcx).ty)); if ty.needs_drop(tcx, self.param_env) { self.cost += CALL_PENALTY; if let UnwindAction::Cleanup(_) = unwind { @@ -799,7 +803,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { } } TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => { - let fn_ty = self.instance.subst_mir(tcx, &f.literal.ty()); + let fn_ty = self.instance.subst_mir(tcx, ty::EarlyBinder(&f.literal.ty())); self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() && tcx.is_intrinsic(def_id) { // Don't give intrinsics the extra penalty for calls INSTR_COST From d27f40175fb7221bc5fa4c19ff75e211947222e8 Mon Sep 17 00:00:00 2001 From: Kyle Matsuda Date: Sat, 6 May 2023 22:56:51 -0600 Subject: [PATCH 4/4] changes from review: add FIXME to clippy and change subst_identity to skip_binder in mir subst methods --- compiler/rustc_middle/src/ty/instance.rs | 6 +++--- .../clippy/clippy_lints/src/methods/unnecessary_to_owned.rs | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 4bbd7aaf10f70..8c69894f5ba7e 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -586,7 +586,7 @@ impl<'tcx> Instance<'tcx> { if let Some(substs) = self.substs_for_mir_body() { v.subst(tcx, substs) } else { - v.subst_identity() + v.skip_binder() } } @@ -603,7 +603,7 @@ impl<'tcx> Instance<'tcx> { if let Some(substs) = self.substs_for_mir_body() { tcx.subst_and_normalize_erasing_regions(substs, param_env, v) } else { - tcx.normalize_erasing_regions(param_env, v.subst_identity()) + tcx.normalize_erasing_regions(param_env, v.skip_binder()) } } @@ -620,7 +620,7 @@ impl<'tcx> Instance<'tcx> { if let Some(substs) = self.substs_for_mir_body() { tcx.try_subst_and_normalize_erasing_regions(substs, param_env, v) } else { - tcx.try_normalize_erasing_regions(param_env, v.subst_identity()) + tcx.try_normalize_erasing_regions(param_env, v.skip_binder()) } } diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index 87641c686dcfd..67b7d3691dc02 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -385,6 +385,9 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< Node::Expr(parent_expr) => { if let Some((callee_def_id, call_substs, recv, call_args)) = get_callee_substs_and_args(cx, parent_expr) { + // FIXME: the `subst_identity()` below seems incorrect, since we eventually + // call `tcx.try_subst_and_normalize_erasing_regions` further down + // (i.e., we are explicitly not in the identity context). let fn_sig = cx.tcx.fn_sig(callee_def_id).subst_identity().skip_binder(); if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id) && let Some(param_ty) = fn_sig.inputs().get(arg_index)