diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index 2e6a2962b8760..64c5f5f0c560b 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -176,7 +176,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } // In MIR, argument N is stored in local N+1. - let local = Local::from_usize(argument_index + 1); + let local = Local::arg(argument_index); let mir_input_ty = self.body.local_decls[local].ty; diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 06c81662d6018..61f0f6b1b7690 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -523,7 +523,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if self.fn_abi.c_variadic { // The `VaList` "spoofed" argument is just after all the real arguments. let va_list_arg_idx = self.fn_abi.args.len(); - match self.locals[mir::Local::from_usize(1 + va_list_arg_idx)] { + match self.locals[mir::Local::arg(va_list_arg_idx)] { LocalRef::Place(va_list) => { bx.va_end(va_list.val.llval); diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 36752bba9f722..e46a895aadd16 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -845,6 +845,16 @@ rustc_index::newtype_index! { } } +impl Local { + /// Makes a `Local` for the `i`-th argument to a function. + /// + /// `Local(0)` is the [`RETURN_PLACE`], with the arguments after that, + /// so `arg(i)` will give `Local(i + 1)`. + pub const fn arg(i: usize) -> Local { + Local::from_usize(i + 1) + } +} + impl Atom for Local { fn index(self) -> usize { Idx::index(self) diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index ce6f87668beff..e8d5f1a912d21 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -17,7 +17,7 @@ use crate::{mir, ty}; /// Captures are represented using fields inside a structure. /// This represents accessing self in the closure structure -pub const CAPTURE_STRUCT_LOCAL: mir::Local = mir::Local::from_u32(1); +pub const CAPTURE_STRUCT_LOCAL: mir::Local = mir::Local::arg(0); #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] #[derive(TypeFoldable, TypeVisitable)] diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 8e51ab7d4edb1..5a33963b2b654 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -1068,7 +1068,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Bind the argument patterns for (index, param) in arguments.iter().enumerate() { // Function arguments always get the first Local indices after the return place - let local = Local::new(index + 1); + let local = Local::arg(index); let place = Place::from(local); // Make sure we drop (parts of) the argument even when not matched on. diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 652fd00d54d02..807fe771d0ea2 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -168,8 +168,8 @@ fn replace_base<'tcx>(place: &mut Place<'tcx>, new_base: Place<'tcx>, tcx: TyCtx tracing::trace!(?place); } -const SELF_ARG: Local = Local::from_u32(1); -const CTX_ARG: Local = Local::from_u32(2); +const SELF_ARG: Local = Local::arg(0); +const CTX_ARG: Local = Local::arg(1); /// A `yield` point in the coroutine. struct SuspensionPoint<'tcx> { diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 89423bf885c84..39d5eef844559 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -358,8 +358,8 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) let mut body = new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span); - // The first argument (index 0), but add 1 for the return value. - let dropee_ptr = Place::from(Local::new(1 + 0)); + // The first argument (index 0), but local 1 (after the return place). + let dropee_ptr = Place::from(Local::arg(0)); let dropee_ptr = dropee_emit_retag(tcx, &mut body, dropee_ptr, span); if ty.is_some() { @@ -538,7 +538,7 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) - let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty); let dest = Place::return_place(); - let src = tcx.mk_place_deref(Place::from(Local::new(1 + 0))); + let src = tcx.mk_place_deref(Place::from(Local::arg(0))); match self_ty.kind() { ty::FnDef(..) | ty::FnPtr(..) => builder.copy_shim(), @@ -624,7 +624,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { } fn copy_shim(&mut self) { - let rcvr = self.tcx.mk_place_deref(Place::from(Local::new(1 + 0))); + let rcvr = self.tcx.mk_place_deref(Place::from(Local::arg(0))); let ret_statement = self.make_statement(StatementKind::Assign(Box::new(( Place::return_place(), Rvalue::Use(Operand::Copy(rcvr)), @@ -879,7 +879,7 @@ fn build_call_shim<'tcx>( let rcvr_place = || { assert!(rcvr_adjustment.is_some()); - Place::from(Local::new(1)) + Place::from(Local::arg(0)) }; let mut statements = vec![]; @@ -938,11 +938,11 @@ fn build_call_shim<'tcx>( } // Pass all of the non-special arguments directly. - args.extend(arg_range.map(|i| Operand::Move(Place::from(Local::new(1 + i))))); + args.extend(arg_range.map(|i| Operand::Move(Place::from(Local::arg(i))))); // Untuple the last argument, if we have to. if let Some(untuple_args) = untuple_args { - let tuple_arg = Local::new(1 + (sig.inputs().len() - 1)); + let tuple_arg = Local::arg(sig.inputs().len() - 1); args.extend(untuple_args.iter().enumerate().map(|(i, ity)| { Operand::Move(tcx.mk_place_field(Place::from(tuple_arg), FieldIdx::new(i), *ity)) })); @@ -1074,7 +1074,7 @@ pub(super) fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { Rvalue::Aggregate( Box::new(kind), (0..variant.fields.len()) - .map(|idx| Operand::Move(Place::from(Local::new(idx + 1)))) + .map(|idx| Operand::Move(Place::from(Local::arg(idx)))) .collect(), ), ))), @@ -1125,7 +1125,7 @@ fn build_fn_ptr_addr_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'t // provenance. let rvalue = Rvalue::Cast( CastKind::FnPtrToPtr, - Operand::Move(Place::from(Local::new(1))), + Operand::Move(Place::from(Local::arg(0))), Ty::new_imm_ptr(tcx, tcx.types.unit), ); let stmt = Statement::new( @@ -1148,7 +1148,7 @@ fn build_construct_coroutine_by_move_shim<'tcx>( receiver_by_ref: bool, ) -> Body<'tcx> { let mut self_ty = tcx.type_of(coroutine_closure_def_id).instantiate_identity().skip_norm_wip(); - let mut self_local: Place<'tcx> = Local::from_usize(1).into(); + let mut self_local: Place<'tcx> = Local::arg(0).into(); let ty::CoroutineClosure(_, args) = *self_ty.kind() else { bug!(); }; @@ -1190,7 +1190,7 @@ fn build_construct_coroutine_by_move_shim<'tcx>( // Move all of the closure args. for idx in 1..sig.inputs().len() { - fields.push(Operand::Move(Local::from_usize(idx + 1).into())); + fields.push(Operand::Move(Local::arg(idx).into())); } for (idx, ty) in args.as_coroutine_closure().upvar_tys().iter().enumerate() { diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index 5038afffcd8d2..0897aecb17e0a 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -74,8 +74,8 @@ pub(super) fn build_async_drop_shim<'tcx>( let span = tcx.def_span(def_id); let source_info = SourceInfo::outermost(span); - // The first argument (index 0), but add 1 for the return value. - let coroutine_layout = Place::from(Local::new(1 + 0)); + // The first argument (index 0) which will be local 1 (after the return value). + let coroutine_layout = Place::from(Local::arg(0)); let coroutine_layout_dropee = tcx.mk_place_field(coroutine_layout, FieldIdx::new(0), drop_ptr_ty); diff --git a/compiler/rustc_mir_transform/src/single_use_consts.rs b/compiler/rustc_mir_transform/src/single_use_consts.rs index 91e040d5cbc89..5d0008f9e7472 100644 --- a/compiler/rustc_mir_transform/src/single_use_consts.rs +++ b/compiler/rustc_mir_transform/src/single_use_consts.rs @@ -35,7 +35,7 @@ impl<'tcx> crate::MirPass<'tcx> for SingleUseConsts { locals_in_debug_info: DenseBitSet::new_empty(body.local_decls.len()), }; - finder.ineligible_locals.insert_range(..=Local::from_usize(body.arg_count)); + finder.ineligible_locals.insert_range(..Local::arg(body.arg_count)); finder.visit_body(body); diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index f9ab5f3551221..0fe20e6a46acc 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -87,7 +87,7 @@ fn escaping_locals<'tcx>( }; let mut set = DenseBitSet::new_empty(body.local_decls.len()); - set.insert_range(RETURN_PLACE..=Local::from_usize(body.arg_count)); + set.insert_range(RETURN_PLACE..Local::arg(body.arg_count)); for (local, decl) in body.local_decls().iter_enumerated() { if excluded.contains(local) || is_excluded_ty(decl.ty) { set.insert(local);