Improve LocalDecl creation.
This commit adds some new `LocalDecl` methods: - `with_source_info`, a most general constructor. - `new`, a variant of `with_source_info` which represents the most common use case. - `internal` a modifying method (like the already present `immutable`). It removes some old `LocalDecl` methods: - `new_internal` and `new_local`, because they're subsumed by the new methods. - `new_return_place`, because it was identical to `new_temp`. Finally, it cleans up all the use sites.
This commit is contained in:
parent
a17234ca54
commit
afd8a4e7ec
13 changed files with 70 additions and 137 deletions
|
|
@ -918,10 +918,31 @@ impl<'tcx> LocalDecl<'tcx> {
|
|||
self.source_info.span.desugaring_kind().is_some()
|
||||
}
|
||||
|
||||
/// Creates a new `LocalDecl` for a temporary.
|
||||
/// Creates a new `LocalDecl` for a temporary: mutable, non-internal.
|
||||
#[inline]
|
||||
pub fn new_temp(ty: Ty<'tcx>, span: Span) -> Self {
|
||||
Self::new_local(ty, Mutability::Mut, false, span)
|
||||
pub fn new(ty: Ty<'tcx>, span: Span) -> Self {
|
||||
Self::with_source_info(ty, SourceInfo::outermost(span))
|
||||
}
|
||||
|
||||
/// Like `LocalDecl::new`, but takes a `SourceInfo` instead of a `Span`.
|
||||
#[inline]
|
||||
pub fn with_source_info(ty: Ty<'tcx>, source_info: SourceInfo) -> Self {
|
||||
LocalDecl {
|
||||
mutability: Mutability::Mut,
|
||||
local_info: LocalInfo::Other,
|
||||
internal: false,
|
||||
is_block_tail: None,
|
||||
ty,
|
||||
user_ty: UserTypeProjections::none(),
|
||||
source_info,
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts `self` into same `LocalDecl` except tagged as internal.
|
||||
#[inline]
|
||||
pub fn internal(mut self) -> Self {
|
||||
self.internal = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Converts `self` into same `LocalDecl` except tagged as immutable.
|
||||
|
|
@ -938,41 +959,6 @@ impl<'tcx> LocalDecl<'tcx> {
|
|||
self.is_block_tail = Some(info);
|
||||
self
|
||||
}
|
||||
|
||||
/// Creates a new `LocalDecl` for a internal temporary.
|
||||
#[inline]
|
||||
pub fn new_internal(ty: Ty<'tcx>, span: Span) -> Self {
|
||||
Self::new_local(ty, Mutability::Mut, true, span)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn new_local(ty: Ty<'tcx>, mutability: Mutability, internal: bool, span: Span) -> Self {
|
||||
LocalDecl {
|
||||
mutability,
|
||||
ty,
|
||||
user_ty: UserTypeProjections::none(),
|
||||
source_info: SourceInfo::outermost(span),
|
||||
internal,
|
||||
local_info: LocalInfo::Other,
|
||||
is_block_tail: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a `LocalDecl` for the return place.
|
||||
///
|
||||
/// This must be inserted into the `local_decls` list as the first local.
|
||||
#[inline]
|
||||
pub fn new_return_place(return_ty: Ty<'_>, span: Span) -> LocalDecl<'_> {
|
||||
LocalDecl {
|
||||
mutability: Mutability::Mut,
|
||||
ty: return_ty,
|
||||
user_ty: UserTypeProjections::none(),
|
||||
source_info: SourceInfo::outermost(span),
|
||||
internal: false,
|
||||
is_block_tail: None,
|
||||
local_info: LocalInfo::Other,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Debug information pertaining to a user variable.
|
||||
|
|
|
|||
|
|
@ -145,24 +145,12 @@ enum CallKind {
|
|||
Direct(DefId),
|
||||
}
|
||||
|
||||
fn temp_decl(mutability: Mutability, ty: Ty<'_>, span: Span) -> LocalDecl<'_> {
|
||||
LocalDecl {
|
||||
mutability,
|
||||
ty,
|
||||
user_ty: UserTypeProjections::none(),
|
||||
source_info: SourceInfo::outermost(span),
|
||||
internal: false,
|
||||
local_info: LocalInfo::Other,
|
||||
is_block_tail: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn local_decls_for_sig<'tcx>(
|
||||
sig: &ty::FnSig<'tcx>,
|
||||
span: Span,
|
||||
) -> IndexVec<Local, LocalDecl<'tcx>> {
|
||||
iter::once(temp_decl(Mutability::Mut, sig.output(), span))
|
||||
.chain(sig.inputs().iter().map(|ity| temp_decl(Mutability::Not, ity, span)))
|
||||
iter::once(LocalDecl::new(sig.output(), span))
|
||||
.chain(sig.inputs().iter().map(|ity| LocalDecl::new(ity, span).immutable()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
|
@ -413,7 +401,11 @@ impl CloneShimBuilder<'tcx> {
|
|||
|
||||
fn make_place(&mut self, mutability: Mutability, ty: Ty<'tcx>) -> Place<'tcx> {
|
||||
let span = self.span;
|
||||
Place::from(self.local_decls.push(temp_decl(mutability, ty, span)))
|
||||
let mut local = LocalDecl::new(ty, span);
|
||||
if mutability == Mutability::Not {
|
||||
local = local.immutable();
|
||||
}
|
||||
Place::from(self.local_decls.push(local))
|
||||
}
|
||||
|
||||
fn make_clone_call(
|
||||
|
|
@ -497,7 +489,7 @@ impl CloneShimBuilder<'tcx> {
|
|||
let tcx = self.tcx;
|
||||
let span = self.span;
|
||||
|
||||
let beg = self.local_decls.push(temp_decl(Mutability::Mut, tcx.types.usize, span));
|
||||
let beg = self.local_decls.push(LocalDecl::new(tcx.types.usize, span));
|
||||
let end = self.make_place(Mutability::Not, tcx.types.usize);
|
||||
|
||||
// BB #0
|
||||
|
|
@ -552,7 +544,7 @@ impl CloneShimBuilder<'tcx> {
|
|||
// `let mut beg = 0;`
|
||||
// goto #6;
|
||||
let end = beg;
|
||||
let beg = self.local_decls.push(temp_decl(Mutability::Mut, tcx.types.usize, span));
|
||||
let beg = self.local_decls.push(LocalDecl::new(tcx.types.usize, span));
|
||||
let init = self.make_statement(StatementKind::Assign(box (
|
||||
Place::from(beg),
|
||||
Rvalue::Use(Operand::Constant(self.make_usize(0))),
|
||||
|
|
@ -700,14 +692,16 @@ fn build_call_shim<'tcx>(
|
|||
Adjustment::DerefMove => Operand::Move(tcx.mk_place_deref(rcvr_place())),
|
||||
Adjustment::RefMut => {
|
||||
// let rcvr = &mut rcvr;
|
||||
let ref_rcvr = local_decls.push(temp_decl(
|
||||
Mutability::Not,
|
||||
tcx.mk_ref(
|
||||
tcx.lifetimes.re_erased,
|
||||
ty::TypeAndMut { ty: sig.inputs()[0], mutbl: hir::Mutability::Mut },
|
||||
),
|
||||
span,
|
||||
));
|
||||
let ref_rcvr = local_decls.push(
|
||||
LocalDecl::new(
|
||||
tcx.mk_ref(
|
||||
tcx.lifetimes.re_erased,
|
||||
ty::TypeAndMut { ty: sig.inputs()[0], mutbl: hir::Mutability::Mut },
|
||||
),
|
||||
span,
|
||||
)
|
||||
.immutable(),
|
||||
);
|
||||
let borrow_kind = BorrowKind::Mut { allow_two_phase_borrow: false };
|
||||
statements.push(Statement {
|
||||
source_info,
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ impl TransformVisitor<'tcx> {
|
|||
|
||||
// Create a statement which reads the discriminant into a temporary
|
||||
fn get_discr(&self, body: &mut Body<'tcx>) -> (Statement<'tcx>, Place<'tcx>) {
|
||||
let temp_decl = LocalDecl::new_internal(self.tcx.types.isize, body.span);
|
||||
let temp_decl = LocalDecl::new(self.tcx.types.isize, body.span).internal();
|
||||
let local_decls_len = body.local_decls.push(temp_decl);
|
||||
let temp = Place::from(local_decls_len);
|
||||
|
||||
|
|
@ -395,16 +395,7 @@ fn replace_local<'tcx>(
|
|||
body: &mut Body<'tcx>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> Local {
|
||||
let source_info = SourceInfo::outermost(body.span);
|
||||
let new_decl = LocalDecl {
|
||||
mutability: Mutability::Mut,
|
||||
ty,
|
||||
user_ty: UserTypeProjections::none(),
|
||||
source_info,
|
||||
internal: false,
|
||||
is_block_tail: None,
|
||||
local_info: LocalInfo::Other,
|
||||
};
|
||||
let new_decl = LocalDecl::new(ty, body.span);
|
||||
let new_local = body.local_decls.push(new_decl);
|
||||
body.local_decls.swap(local, new_local);
|
||||
|
||||
|
|
@ -877,28 +868,15 @@ fn create_generator_drop_shim<'tcx>(
|
|||
}
|
||||
|
||||
// Replace the return variable
|
||||
body.local_decls[RETURN_PLACE] = LocalDecl {
|
||||
mutability: Mutability::Mut,
|
||||
ty: tcx.mk_unit(),
|
||||
user_ty: UserTypeProjections::none(),
|
||||
source_info,
|
||||
internal: false,
|
||||
is_block_tail: None,
|
||||
local_info: LocalInfo::Other,
|
||||
};
|
||||
body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(tcx.mk_unit(), source_info);
|
||||
|
||||
make_generator_state_argument_indirect(tcx, &mut body);
|
||||
|
||||
// Change the generator argument from &mut to *mut
|
||||
body.local_decls[SELF_ARG] = LocalDecl {
|
||||
mutability: Mutability::Mut,
|
||||
ty: tcx.mk_ptr(ty::TypeAndMut { ty: gen_ty, mutbl: hir::Mutability::Mut }),
|
||||
user_ty: UserTypeProjections::none(),
|
||||
body.local_decls[SELF_ARG] = LocalDecl::with_source_info(
|
||||
tcx.mk_ptr(ty::TypeAndMut { ty: gen_ty, mutbl: hir::Mutability::Mut }),
|
||||
source_info,
|
||||
internal: false,
|
||||
is_block_tail: None,
|
||||
local_info: LocalInfo::Other,
|
||||
};
|
||||
);
|
||||
if tcx.sess.opts.debugging_opts.mir_emit_retag {
|
||||
// Alias tracking must know we changed the type
|
||||
body.basic_blocks_mut()[START_BLOCK].statements.insert(
|
||||
|
|
|
|||
|
|
@ -480,7 +480,7 @@ impl Inliner<'tcx> {
|
|||
|
||||
let ty = dest.ty(caller_body, self.tcx);
|
||||
|
||||
let temp = LocalDecl::new_temp(ty, callsite.location.span);
|
||||
let temp = LocalDecl::new(ty, callsite.location.span);
|
||||
|
||||
let tmp = caller_body.local_decls.push(temp);
|
||||
let tmp = Place::from(tmp);
|
||||
|
|
@ -631,7 +631,7 @@ impl Inliner<'tcx> {
|
|||
|
||||
let ty = arg.ty(caller_body, self.tcx);
|
||||
|
||||
let arg_tmp = LocalDecl::new_temp(ty, callsite.location.span);
|
||||
let arg_tmp = LocalDecl::new(ty, callsite.location.span);
|
||||
let arg_tmp = caller_body.local_decls.push(arg_tmp);
|
||||
|
||||
let stmt = Statement {
|
||||
|
|
|
|||
|
|
@ -815,7 +815,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
|||
}
|
||||
|
||||
let num_stmts = self.source[loc.block].statements.len();
|
||||
let new_temp = self.promoted.local_decls.push(LocalDecl::new_temp(
|
||||
let new_temp = self.promoted.local_decls.push(LocalDecl::new(
|
||||
self.source.local_decls[temp].ty,
|
||||
self.source.local_decls[temp].source_info.span,
|
||||
));
|
||||
|
|
@ -915,7 +915,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
|||
let tcx = self.tcx;
|
||||
let mut promoted_operand = |ty, span| {
|
||||
promoted.span = span;
|
||||
promoted.local_decls[RETURN_PLACE] = LocalDecl::new_return_place(ty, span);
|
||||
promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span);
|
||||
|
||||
Operand::Constant(Box::new(Constant {
|
||||
span,
|
||||
|
|
@ -963,7 +963,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
|||
// Create a temp to hold the promoted reference.
|
||||
// This is because `*r` requires `r` to be a local,
|
||||
// otherwise we would use the `promoted` directly.
|
||||
let mut promoted_ref = LocalDecl::new_temp(ref_ty, span);
|
||||
let mut promoted_ref = LocalDecl::new(ref_ty, span);
|
||||
promoted_ref.source_info = statement.source_info;
|
||||
let promoted_ref = local_decls.push(promoted_ref);
|
||||
assert_eq!(self.temps.push(TempState::Unpromotable), promoted_ref);
|
||||
|
|
@ -1081,8 +1081,7 @@ pub fn promote_candidates<'tcx>(
|
|||
}
|
||||
|
||||
// Declare return place local so that `mir::Body::new` doesn't complain.
|
||||
let initial_locals =
|
||||
iter::once(LocalDecl::new_return_place(tcx.types.never, body.span)).collect();
|
||||
let initial_locals = iter::once(LocalDecl::new(tcx.types.never, body.span)).collect();
|
||||
|
||||
let mut promoted = Body::new(
|
||||
IndexVec::new(),
|
||||
|
|
|
|||
|
|
@ -83,14 +83,14 @@ impl<'tcx> MirPatch<'tcx> {
|
|||
pub fn new_temp(&mut self, ty: Ty<'tcx>, span: Span) -> Local {
|
||||
let index = self.next_local;
|
||||
self.next_local += 1;
|
||||
self.new_locals.push(LocalDecl::new_temp(ty, span));
|
||||
self.new_locals.push(LocalDecl::new(ty, span));
|
||||
Local::new(index as usize)
|
||||
}
|
||||
|
||||
pub fn new_internal(&mut self, ty: Ty<'tcx>, span: Span) -> Local {
|
||||
let index = self.next_local;
|
||||
self.next_local += 1;
|
||||
self.new_locals.push(LocalDecl::new_internal(ty, span));
|
||||
self.new_locals.push(LocalDecl::new(ty, span).internal());
|
||||
Local::new(index as usize)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -383,7 +383,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let fake_borrow_ty =
|
||||
tcx.mk_imm_ref(tcx.lifetimes.re_erased, fake_borrow_deref_ty);
|
||||
let fake_borrow_temp =
|
||||
self.local_decls.push(LocalDecl::new_temp(fake_borrow_ty, expr_span));
|
||||
self.local_decls.push(LocalDecl::new(fake_borrow_ty, expr_span));
|
||||
let projection = tcx.intern_place_elems(&base_place.projection[..idx]);
|
||||
self.cfg.push_assign(
|
||||
block,
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// The `Box<T>` temporary created here is not a part of the HIR,
|
||||
// and therefore is not considered during generator OIBIT
|
||||
// determination. See the comment about `box` at `yield_in_scope`.
|
||||
let result = this.local_decls.push(LocalDecl::new_internal(expr.ty, expr_span));
|
||||
let result = this.local_decls.push(LocalDecl::new(expr.ty, expr_span).internal());
|
||||
this.cfg.push(
|
||||
block,
|
||||
Statement { source_info, kind: StatementKind::StorageLive(result) },
|
||||
|
|
@ -377,7 +377,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let this = self;
|
||||
|
||||
let source_info = this.source_info(upvar_span);
|
||||
let temp = this.local_decls.push(LocalDecl::new_temp(upvar_ty, upvar_span));
|
||||
let temp = this.local_decls.push(LocalDecl::new(upvar_ty, upvar_span));
|
||||
|
||||
this.cfg.push(block, Statement { source_info, kind: StatementKind::StorageLive(temp) });
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
|
||||
let expr_ty = expr.ty;
|
||||
let temp = {
|
||||
let mut local_decl = LocalDecl::new_temp(expr_ty, expr_span);
|
||||
let mut local_decl = LocalDecl::new(expr_ty, expr_span);
|
||||
if mutability == Mutability::Not {
|
||||
local_decl = local_decl.immutable();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,15 +187,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let ptr_ty = ptr.ty;
|
||||
// Create an *internal* temp for the pointer, so that unsafety
|
||||
// checking won't complain about the raw pointer assignment.
|
||||
let ptr_temp = this.local_decls.push(LocalDecl {
|
||||
mutability: Mutability::Mut,
|
||||
ty: ptr_ty,
|
||||
user_ty: UserTypeProjections::none(),
|
||||
let ptr_temp = this.local_decls.push(LocalDecl::with_source_info(
|
||||
ptr_ty,
|
||||
source_info,
|
||||
internal: true,
|
||||
local_info: LocalInfo::Other,
|
||||
is_block_tail: None,
|
||||
});
|
||||
).internal());
|
||||
let ptr_temp = Place::from(ptr_temp);
|
||||
let block = unpack!(this.into(ptr_temp, block, ptr));
|
||||
this.into(this.hir.tcx().mk_place_deref(ptr_temp), block, val)
|
||||
|
|
@ -348,7 +343,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// value is Sized. Usually, this is caught in type checking, but
|
||||
// in the case of box expr there is no such check.
|
||||
if !destination.projection.is_empty() {
|
||||
this.local_decls.push(LocalDecl::new_temp(expr.ty, expr.span));
|
||||
this.local_decls.push(LocalDecl::new(expr.ty, expr.span));
|
||||
}
|
||||
|
||||
debug_assert!(Category::of(&expr.kind) == Some(Category::Place));
|
||||
|
|
|
|||
|
|
@ -1539,7 +1539,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let fake_borrow_deref_ty = matched_place.ty(&self.local_decls, tcx).ty;
|
||||
let fake_borrow_ty = tcx.mk_imm_ref(tcx.lifetimes.re_erased, fake_borrow_deref_ty);
|
||||
let fake_borrow_temp =
|
||||
self.local_decls.push(LocalDecl::new_temp(fake_borrow_ty, temp_span));
|
||||
self.local_decls.push(LocalDecl::new(fake_borrow_ty, temp_span));
|
||||
|
||||
(matched_place, fake_borrow_temp)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
/// N.B., **No cleanup is scheduled for this temporary.** You should
|
||||
/// call `schedule_drop` once the temporary is initialized.
|
||||
crate fn temp(&mut self, ty: Ty<'tcx>, span: Span) -> Place<'tcx> {
|
||||
let temp = self.local_decls.push(LocalDecl::new_temp(ty, span));
|
||||
let temp = self.local_decls.push(LocalDecl::new(ty, span));
|
||||
let place = Place::from(temp);
|
||||
debug!("temp: created temp {:?} with type {:?}", place, self.local_decls[temp].ty);
|
||||
place
|
||||
|
|
|
|||
|
|
@ -708,15 +708,7 @@ fn construct_error<'a, 'tcx>(hir: Cx<'a, 'tcx>, body_id: hir::BodyId) -> Body<'t
|
|||
// Some MIR passes will expect the number of parameters to match the
|
||||
// function declaration.
|
||||
for _ in 0..num_params {
|
||||
builder.local_decls.push(LocalDecl {
|
||||
mutability: Mutability::Mut,
|
||||
ty,
|
||||
user_ty: UserTypeProjections::none(),
|
||||
source_info,
|
||||
internal: false,
|
||||
local_info: LocalInfo::Other,
|
||||
is_block_tail: None,
|
||||
});
|
||||
builder.local_decls.push(LocalDecl::with_source_info(ty, source_info));
|
||||
}
|
||||
builder.cfg.terminate(START_BLOCK, source_info, TerminatorKind::Unreachable);
|
||||
let mut body = builder.finish();
|
||||
|
|
@ -750,10 +742,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
guard_context: vec![],
|
||||
push_unsafe_count: 0,
|
||||
unpushed_unsafe: safety,
|
||||
local_decls: IndexVec::from_elem_n(
|
||||
LocalDecl::new_return_place(return_ty, return_span),
|
||||
1,
|
||||
),
|
||||
local_decls: IndexVec::from_elem_n(LocalDecl::new(return_ty, return_span), 1),
|
||||
canonical_user_type_annotations: IndexVec::new(),
|
||||
upvar_mutbls: vec![],
|
||||
var_indices: Default::default(),
|
||||
|
|
@ -806,15 +795,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
for &ArgInfo(ty, _, arg_opt, _) in arguments.iter() {
|
||||
let source_info =
|
||||
SourceInfo::outermost(arg_opt.map_or(self.fn_span, |arg| arg.pat.span));
|
||||
let arg_local = self.local_decls.push(LocalDecl {
|
||||
mutability: Mutability::Mut,
|
||||
ty,
|
||||
user_ty: UserTypeProjections::none(),
|
||||
source_info,
|
||||
internal: false,
|
||||
local_info: LocalInfo::Other,
|
||||
is_block_tail: None,
|
||||
});
|
||||
let arg_local = self.local_decls.push(LocalDecl::with_source_info(ty, source_info));
|
||||
|
||||
// If this is a simple binding pattern, give debuginfo a nice name.
|
||||
if let Some(arg) = arg_opt {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue