-use rustc::hir;
-use rustc::hir::def_id::DefId;
use rustc::mir::*;
-use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::layout::VariantIdx;
-use rustc::ty::subst::{Subst, InternalSubsts};
use rustc::ty::query::Providers;
+use rustc::ty::subst::{InternalSubsts, Subst};
+use rustc::ty::{self, Ty, TyCtxt};
+use rustc_hir as hir;
+use rustc_hir::def_id::DefId;
-use rustc_index::vec::{IndexVec, Idx};
+use rustc_index::vec::{Idx, IndexVec};
+use rustc_span::{sym, Span};
use rustc_target::spec::abi::Abi;
-use syntax_pos::{Span, sym};
use std::fmt;
use std::iter;
use crate::transform::{
- add_moves_for_packed_drops, add_call_guards,
- remove_noop_landing_pads, no_landing_pads, simplify, run_passes
+ add_call_guards, add_moves_for_packed_drops, no_landing_pads, remove_noop_landing_pads,
+ run_passes, simplify,
};
-use crate::util::elaborate_drops::{self, DropElaborator, DropStyle, DropFlagMode};
-use crate::util::patch::MirPatch;
+use crate::util::elaborate_drops::{self, DropElaborator, DropFlagMode, DropStyle};
use crate::util::expand_aggregate;
+use crate::util::patch::MirPatch;
pub fn provide(providers: &mut Providers<'_>) {
providers.mir_shims = make_shim;
debug!("make_shim({:?})", instance);
let mut result = match instance {
- ty::InstanceDef::Item(..) =>
- bug!("item {:?} passed to make_shim", instance),
+ ty::InstanceDef::Item(..) => bug!("item {:?} passed to make_shim", instance),
ty::InstanceDef::VtableShim(def_id) => {
- build_call_shim(
- tcx,
- instance,
- Adjustment::DerefMove,
- CallKind::Direct(def_id),
- None,
- )
+ build_call_shim(tcx, instance, Adjustment::DerefMove, CallKind::Direct(def_id), None)
}
ty::InstanceDef::FnPtrShim(def_id, ty) => {
let trait_ = tcx.trait_of_item(def_id).unwrap();
let adjustment = match tcx.lang_items().fn_trait_kind(trait_) {
Some(ty::ClosureKind::FnOnce) => Adjustment::Identity,
- Some(ty::ClosureKind::FnMut) |
- Some(ty::ClosureKind::Fn) => Adjustment::Deref,
- None => bug!("fn pointer {:?} is not an fn", ty)
+ Some(ty::ClosureKind::FnMut) | Some(ty::ClosureKind::Fn) => Adjustment::Deref,
+ None => bug!("fn pointer {:?} is not an fn", ty),
};
// HACK: we need the "real" argument types for the MIR,
// but because our substs are (Self, Args), where Args
let sig = tcx.erase_late_bound_regions(&ty.fn_sig(tcx));
let arg_tys = sig.inputs();
- build_call_shim(
- tcx,
- instance,
- adjustment,
- CallKind::Indirect,
- Some(arg_tys)
- )
+ build_call_shim(tcx, instance, adjustment, CallKind::Indirect, Some(arg_tys))
}
// We are generating a call back to our def-id, which the
// codegen backend knows to turn to an actual call, be it
// indirect calls must be codegen'd differently than direct ones
// (such as `#[track_caller]`).
ty::InstanceDef::ReifyShim(def_id) => {
- build_call_shim(
- tcx,
- instance,
- Adjustment::Identity,
- CallKind::Direct(def_id),
- None
- )
+ build_call_shim(tcx, instance, Adjustment::Identity, CallKind::Direct(def_id), None)
}
ty::InstanceDef::ClosureOnceShim { call_once: _ } => {
let fn_mut = tcx.lang_items().fn_mut_trait().unwrap();
let call_mut = tcx
.associated_items(fn_mut)
.find(|it| it.kind == ty::AssocKind::Method)
- .unwrap().def_id;
+ .unwrap()
+ .def_id;
- build_call_shim(
- tcx,
- instance,
- Adjustment::RefMut,
- CallKind::Direct(call_mut),
- None
- )
- }
- ty::InstanceDef::DropGlue(def_id, ty) => {
- build_drop_shim(tcx, def_id, ty)
+ build_call_shim(tcx, instance, Adjustment::RefMut, CallKind::Direct(call_mut), None)
}
+ ty::InstanceDef::DropGlue(def_id, ty) => build_drop_shim(tcx, def_id, ty),
ty::InstanceDef::CloneShim(def_id, ty) => {
let name = tcx.item_name(def_id);
if name == sym::clone {
};
debug!("make_shim({:?}) = untransformed {:?}", instance, result);
- run_passes(tcx, &mut result, instance, None, MirPhase::Const, &[
- &add_moves_for_packed_drops::AddMovesForPackedDrops,
- &no_landing_pads::NoLandingPads::new(tcx),
- &remove_noop_landing_pads::RemoveNoopLandingPads,
- &simplify::SimplifyCfg::new("make_shim"),
- &add_call_guards::CriticalCallEdges,
- ]);
+ run_passes(
+ tcx,
+ &mut result,
+ instance,
+ None,
+ MirPhase::Const,
+ &[
+ &add_moves_for_packed_drops::AddMovesForPackedDrops,
+ &no_landing_pads::NoLandingPads::new(tcx),
+ &remove_noop_landing_pads::RemoveNoopLandingPads,
+ &simplify::SimplifyCfg::new("make_shim"),
+ &add_call_guards::CriticalCallEdges,
+ ],
+ );
debug!("make_shim({:?}) = {:?}", instance, result);
}
}
-fn local_decls_for_sig<'tcx>(sig: &ty::FnSig<'tcx>, span: Span)
- -> IndexVec<Local, LocalDecl<'tcx>>
-{
+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)))
+ .chain(sig.inputs().iter().map(|ity| temp_decl(Mutability::Not, ity, span)))
.collect()
}
fn build_drop_shim<'tcx>(
- tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>
+ tcx: TyCtxt<'tcx>,
+ def_id: DefId,
+ ty: Option<Ty<'tcx>>,
) -> BodyAndCache<'tcx> {
debug!("build_drop_shim(def_id={:?}, ty={:?})", def_id, ty);
blocks.push(BasicBlockData {
statements: vec![],
terminator: Some(Terminator { source_info, kind }),
- is_cleanup: false
+ is_cleanup: false,
})
};
block(&mut blocks, TerminatorKind::Goto { target: return_block });
block(&mut blocks, TerminatorKind::Return);
- let body = new_body(
- blocks,
- local_decls_for_sig(&sig, span),
- sig.inputs().len(),
- span);
+ let body = new_body(blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span);
let mut body = BodyAndCache::new(body);
if let Some(..) = ty {
// The first argument (index 0), but add 1 for the return value.
- let dropee_ptr = Place::from(Local::new(1+0));
+ let dropee_ptr = Place::from(Local::new(1 + 0));
if tcx.sess.opts.debugging_opts.mir_emit_retag {
// Function arguments should be retagged, and we make this one raw.
- body.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
- source_info,
- kind: StatementKind::Retag(RetagKind::Raw, box(dropee_ptr.clone())),
- });
+ body.basic_blocks_mut()[START_BLOCK].statements.insert(
+ 0,
+ Statement {
+ source_info,
+ kind: StatementKind::Retag(RetagKind::Raw, box (dropee_ptr.clone())),
+ },
+ );
}
let patch = {
let param_env = tcx.param_env(def_id).with_reveal_all();
- let mut elaborator = DropShimElaborator {
- body: &body,
- patch: MirPatch::new(&body),
- tcx,
- param_env
- };
+ let mut elaborator =
+ DropShimElaborator { body: &body, patch: MirPatch::new(&body), tcx, param_env };
let dropee = tcx.mk_place_deref(dropee_ptr);
let resume_block = elaborator.patch.resume_block();
elaborate_drops::elaborate_drop(
(),
return_block,
elaborate_drops::Unwind::To(resume_block),
- START_BLOCK
+ START_BLOCK,
);
elaborator.patch
};
impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> {
type Path = ();
- fn patch(&mut self) -> &mut MirPatch<'tcx> { &mut self.patch }
- fn body(&self) -> &'a Body<'tcx> { self.body }
+ fn patch(&mut self) -> &mut MirPatch<'tcx> {
+ &mut self.patch
+ }
+ fn body(&self) -> &'a Body<'tcx> {
+ self.body
+ }
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
- }
- fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env }
+ }
+ fn param_env(&self) -> ty::ParamEnv<'tcx> {
+ self.param_env
+ }
fn drop_style(&self, _path: Self::Path, mode: DropFlagMode) -> DropStyle {
- if let DropFlagMode::Shallow = mode {
- DropStyle::Static
- } else {
- DropStyle::Open
- }
+ if let DropFlagMode::Shallow = mode { DropStyle::Static } else { DropStyle::Open }
}
fn get_drop_flag(&mut self, _path: Self::Path) -> Option<Operand<'tcx>> {
None
}
- fn clear_drop_flag(&mut self, _location: Location, _path: Self::Path, _mode: DropFlagMode) {
- }
+ fn clear_drop_flag(&mut self, _location: Location, _path: Self::Path, _mode: DropFlagMode) {}
fn field_subpath(&self, _path: Self::Path, _field: Field) -> Option<Self::Path> {
None
let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env, builder.span);
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::new(1 + 0)));
match self_ty.kind {
_ if is_copy => builder.copy_shim(),
builder.array_shim(dest, src, ty, len)
}
ty::Closure(def_id, substs) => {
- builder.tuple_like_shim(
- dest, src,
- substs.as_closure().upvar_tys(def_id, tcx)
- )
+ builder.tuple_like_shim(dest, src, substs.as_closure().upvar_tys(def_id, tcx))
}
ty::Tuple(..) => builder.tuple_like_shim(dest, src, self_ty.tuple_fields()),
- _ => {
- bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty)
- }
+ _ => bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty),
};
BodyAndCache::new(builder.into_mir())
}
fn into_mir(self) -> Body<'tcx> {
- new_body(
- self.blocks,
- self.local_decls,
- self.sig.inputs().len(),
- self.span,
- )
+ new_body(self.blocks, self.local_decls, self.sig.inputs().len(), self.span)
}
fn source_info(&self) -> SourceInfo {
&mut self,
statements: Vec<Statement<'tcx>>,
kind: TerminatorKind<'tcx>,
- is_cleanup: bool
+ is_cleanup: bool,
) -> BasicBlock {
let source_info = self.source_info();
self.blocks.push(BasicBlockData {
}
fn make_statement(&self, kind: StatementKind<'tcx>) -> Statement<'tcx> {
- Statement {
- source_info: self.source_info(),
- kind,
- }
+ Statement { source_info: self.source_info(), kind }
}
fn copy_shim(&mut self) {
- let rcvr = self.tcx.mk_place_deref(Place::from(Local::new(1+0)));
- let ret_statement = self.make_statement(
- StatementKind::Assign(
- box(
- Place::return_place(),
- Rvalue::Use(Operand::Copy(rcvr))
- )
- )
- );
+ let rcvr = self.tcx.mk_place_deref(Place::from(Local::new(1 + 0)));
+ let ret_statement = self.make_statement(StatementKind::Assign(box (
+ Place::return_place(),
+ Rvalue::Use(Operand::Copy(rcvr)),
+ )));
self.block(vec![ret_statement], TerminatorKind::Return, false);
}
src: Place<'tcx>,
ty: Ty<'tcx>,
next: BasicBlock,
- cleanup: BasicBlock
+ cleanup: BasicBlock,
) {
let tcx = self.tcx;
let ref_loc = self.make_place(
Mutability::Not,
- tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut {
- ty,
- mutbl: hir::Mutability::Not,
- })
+ tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut { ty, mutbl: hir::Mutability::Not }),
);
// `let ref_loc: &ty = &src;`
- let statement = self.make_statement(
- StatementKind::Assign(
- box(
- ref_loc.clone(),
- Rvalue::Ref(tcx.lifetimes.re_erased, BorrowKind::Shared, src)
- )
- )
- );
+ let statement = self.make_statement(StatementKind::Assign(box (
+ ref_loc.clone(),
+ Rvalue::Ref(tcx.lifetimes.re_erased, BorrowKind::Shared, src),
+ )));
// `let loc = Clone::clone(ref_loc);`
- self.block(vec![statement], TerminatorKind::Call {
- func,
- args: vec![Operand::Move(ref_loc)],
- destination: Some((dest, next)),
- cleanup: Some(cleanup),
- from_hir_call: true,
- }, false);
+ self.block(
+ vec![statement],
+ TerminatorKind::Call {
+ func,
+ args: vec![Operand::Move(ref_loc)],
+ destination: Some((dest, next)),
+ cleanup: Some(cleanup),
+ from_hir_call: true,
+ },
+ false,
+ );
}
fn loop_header(
end: Place<'tcx>,
loop_body: BasicBlock,
loop_end: BasicBlock,
- is_cleanup: bool
+ is_cleanup: bool,
) {
let tcx = self.tcx;
let cond = self.make_place(Mutability::Mut, tcx.types.bool);
- let compute_cond = self.make_statement(
- StatementKind::Assign(
- box(
- cond.clone(),
- Rvalue::BinaryOp(BinOp::Ne, Operand::Copy(end), Operand::Copy(beg))
- )
- )
- );
+ let compute_cond = self.make_statement(StatementKind::Assign(box (
+ cond.clone(),
+ Rvalue::BinaryOp(BinOp::Ne, Operand::Copy(end), Operand::Copy(beg)),
+ )));
// `if end != beg { goto loop_body; } else { goto loop_end; }`
self.block(
vec![compute_cond],
TerminatorKind::if_(tcx, Operand::Move(cond), loop_body, loop_end),
- is_cleanup
+ is_cleanup,
);
}
// `let end = len;`
// `goto #1;`
let inits = vec![
- self.make_statement(
- StatementKind::Assign(
- box(
- Place::from(beg),
- Rvalue::Use(Operand::Constant(self.make_usize(0)))
- )
- )
- ),
- self.make_statement(
- StatementKind::Assign(
- box(
- end.clone(),
- Rvalue::Use(Operand::Constant(self.make_usize(len)))
- )
- )
- )
+ self.make_statement(StatementKind::Assign(box (
+ Place::from(beg),
+ Rvalue::Use(Operand::Constant(self.make_usize(0))),
+ ))),
+ self.make_statement(StatementKind::Assign(box (
+ end.clone(),
+ Rvalue::Use(Operand::Constant(self.make_usize(len))),
+ ))),
];
self.block(inits, TerminatorKind::Goto { target: BasicBlock::new(1) }, false);
// BB #3;
// }
// BB #4;
- self.loop_header(Place::from(beg),
- end,
- BasicBlock::new(2),
- BasicBlock::new(4),
- false);
+ self.loop_header(Place::from(beg), end, BasicBlock::new(2), BasicBlock::new(4), false);
// BB #2
// `dest[i] = Clone::clone(src[beg])`;
// Goto #3 if ok, #5 if unwinding happens.
let dest_field = self.tcx.mk_place_index(dest.clone(), beg);
let src_field = self.tcx.mk_place_index(src, beg);
- self.make_clone_call(dest_field, src_field, ty, BasicBlock::new(3),
- BasicBlock::new(5));
+ self.make_clone_call(dest_field, src_field, ty, BasicBlock::new(3), BasicBlock::new(5));
// BB #3
// `beg = beg + 1;`
// `goto #1`;
- let statements = vec![
- self.make_statement(
- StatementKind::Assign(
- box(
- Place::from(beg),
- Rvalue::BinaryOp(
- BinOp::Add,
- Operand::Copy(Place::from(beg)),
- Operand::Constant(self.make_usize(1))
- )
- )
- )
- )
- ];
+ let statements = vec![self.make_statement(StatementKind::Assign(box (
+ Place::from(beg),
+ Rvalue::BinaryOp(
+ BinOp::Add,
+ Operand::Copy(Place::from(beg)),
+ Operand::Constant(self.make_usize(1)),
+ ),
+ )))];
self.block(statements, TerminatorKind::Goto { target: BasicBlock::new(1) }, false);
// BB #4
// goto #6;
let end = beg;
let beg = self.local_decls.push(temp_decl(Mutability::Mut, tcx.types.usize, span));
- let init = self.make_statement(
- StatementKind::Assign(
- box(
- Place::from(beg),
- Rvalue::Use(Operand::Constant(self.make_usize(0)))
- )
- )
- );
+ let init = self.make_statement(StatementKind::Assign(box (
+ Place::from(beg),
+ Rvalue::Use(Operand::Constant(self.make_usize(0))),
+ )));
self.block(vec![init], TerminatorKind::Goto { target: BasicBlock::new(6) }, true);
// BB #6 (cleanup): loop {
// BB #8;
// }
// BB #9;
- self.loop_header(Place::from(beg), Place::from(end),
- BasicBlock::new(7), BasicBlock::new(9), true);
+ self.loop_header(
+ Place::from(beg),
+ Place::from(end),
+ BasicBlock::new(7),
+ BasicBlock::new(9),
+ true,
+ );
// BB #7 (cleanup)
// `drop(dest[beg])`;
- self.block(vec![], TerminatorKind::Drop {
- location: self.tcx.mk_place_index(dest, beg),
- target: BasicBlock::new(8),
- unwind: None,
- }, true);
+ self.block(
+ vec![],
+ TerminatorKind::Drop {
+ location: self.tcx.mk_place_index(dest, beg),
+ target: BasicBlock::new(8),
+ unwind: None,
+ },
+ true,
+ );
// BB #8 (cleanup)
// `beg = beg + 1;`
// `goto #6;`
- let statement = self.make_statement(
- StatementKind::Assign(
- box(
- Place::from(beg),
- Rvalue::BinaryOp(
- BinOp::Add,
- Operand::Copy(Place::from(beg)),
- Operand::Constant(self.make_usize(1))
- )
- )
- )
- );
+ let statement = self.make_statement(StatementKind::Assign(box (
+ Place::from(beg),
+ Rvalue::BinaryOp(
+ BinOp::Add,
+ Operand::Copy(Place::from(beg)),
+ Operand::Constant(self.make_usize(1)),
+ ),
+ )));
self.block(vec![statement], TerminatorKind::Goto { target: BasicBlock::new(6) }, true);
// BB #9 (resume)
self.block(vec![], TerminatorKind::Resume, true);
}
- fn tuple_like_shim<I>(&mut self, dest: Place<'tcx>,
- src: Place<'tcx>, tys: I)
- where I: Iterator<Item = Ty<'tcx>> {
+ fn tuple_like_shim<I>(&mut self, dest: Place<'tcx>, src: Place<'tcx>, tys: I)
+ where
+ I: Iterator<Item = Ty<'tcx>>,
+ {
let mut previous_field = None;
for (i, ity) in tys.enumerate() {
let field = Field::new(i);
// BB #(2i)
// `dest.i = Clone::clone(&src.i);`
// Goto #(2i + 2) if ok, #(2i + 1) if unwinding happens.
- self.make_clone_call(
- dest_field.clone(),
- src_field,
- ity,
- next_block,
- cleanup_block,
- );
+ self.make_clone_call(dest_field.clone(), src_field, ity, next_block, cleanup_block);
// BB #(2i + 1) (cleanup)
if let Some((previous_field, previous_cleanup)) = previous_field.take() {
// Drop previous field and goto previous cleanup block.
- self.block(vec![], TerminatorKind::Drop {
- location: previous_field,
- target: previous_cleanup,
- unwind: None,
- }, true);
+ self.block(
+ vec![],
+ TerminatorKind::Drop {
+ location: previous_field,
+ target: previous_cleanup,
+ unwind: None,
+ },
+ true,
+ );
} else {
// Nothing to drop, just resume.
self.block(vec![], TerminatorKind::Resume, true);
call_kind: CallKind,
untuple_args: Option<&[Ty<'tcx>]>,
) -> BodyAndCache<'tcx> {
- debug!("build_call_shim(instance={:?}, rcvr_adjustment={:?}, \
+ debug!(
+ "build_call_shim(instance={:?}, rcvr_adjustment={:?}, \
call_kind={:?}, untuple_args={:?})",
- instance, rcvr_adjustment, call_kind, untuple_args);
+ instance, rcvr_adjustment, call_kind, untuple_args
+ );
let def_id = instance.def_id();
let sig = tcx.fn_sig(def_id);
let mut local_decls = local_decls_for_sig(&sig, span);
let source_info = SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE };
- let rcvr_arg = Local::new(1+0);
+ let rcvr_arg = Local::new(1 + 0);
let rcvr_l = Place::from(rcvr_arg);
let mut statements = vec![];
// 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
+ tcx.mk_ref(
+ tcx.lifetimes.re_erased,
+ ty::TypeAndMut { ty: sig.inputs()[0], mutbl: hir::Mutability::Mut },
+ ),
+ span,
));
- let borrow_kind = BorrowKind::Mut {
- allow_two_phase_borrow: false,
- };
+ let borrow_kind = BorrowKind::Mut { allow_two_phase_borrow: false };
statements.push(Statement {
source_info,
- kind: StatementKind::Assign(
- box(
- Place::from(ref_rcvr),
- Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_l)
- )
- )
+ kind: StatementKind::Assign(box (
+ Place::from(ref_rcvr),
+ Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_l),
+ )),
});
Operand::Move(Place::from(ref_rcvr))
}
CallKind::Indirect => (rcvr, vec![]),
CallKind::Direct(def_id) => {
let ty = tcx.type_of(def_id);
- (Operand::Constant(box Constant {
- span,
- user_ty: None,
- literal: ty::Const::zero_sized(tcx, ty),
- }),
- vec![rcvr])
+ (
+ Operand::Constant(box Constant {
+ span,
+ user_ty: None,
+ literal: ty::Const::zero_sized(tcx, ty),
+ }),
+ vec![rcvr],
+ )
}
};
if let Some(untuple_args) = untuple_args {
args.extend(untuple_args.iter().enumerate().map(|(i, ity)| {
- let arg_place = Place::from(Local::new(1+1));
+ let arg_place = Place::from(Local::new(1 + 1));
Operand::Move(tcx.mk_place_field(arg_place, Field::new(i), *ity))
}));
} else {
- args.extend((1..sig.inputs().len()).map(|i| {
- Operand::Move(Place::from(Local::new(1+i)))
- }));
+ args.extend((1..sig.inputs().len()).map(|i| Operand::Move(Place::from(Local::new(1 + i)))));
}
let n_blocks = if let Adjustment::RefMut = rcvr_adjustment { 5 } else { 2 };
blocks.push(BasicBlockData {
statements,
terminator: Some(Terminator { source_info, kind }),
- is_cleanup
+ is_cleanup,
})
};
// BB #0
- block(&mut blocks, statements, TerminatorKind::Call {
- func: callee,
- args,
- destination: Some((Place::return_place(),
- BasicBlock::new(1))),
- cleanup: if let Adjustment::RefMut = rcvr_adjustment {
- Some(BasicBlock::new(3))
- } else {
- None
+ block(
+ &mut blocks,
+ statements,
+ TerminatorKind::Call {
+ func: callee,
+ args,
+ destination: Some((Place::return_place(), BasicBlock::new(1))),
+ cleanup: if let Adjustment::RefMut = rcvr_adjustment {
+ Some(BasicBlock::new(3))
+ } else {
+ None
+ },
+ from_hir_call: true,
},
- from_hir_call: true,
- }, false);
+ false,
+ );
if let Adjustment::RefMut = rcvr_adjustment {
// BB #1 - drop for Self
- block(&mut blocks, vec![], TerminatorKind::Drop {
- location: Place::from(rcvr_arg),
- target: BasicBlock::new(2),
- unwind: None
- }, false);
+ block(
+ &mut blocks,
+ vec![],
+ TerminatorKind::Drop {
+ location: Place::from(rcvr_arg),
+ target: BasicBlock::new(2),
+ unwind: None,
+ },
+ false,
+ );
}
// BB #1/#2 - return
block(&mut blocks, vec![], TerminatorKind::Return, false);
if let Adjustment::RefMut = rcvr_adjustment {
// BB #3 - drop if closure panics
- block(&mut blocks, vec![], TerminatorKind::Drop {
- location: Place::from(rcvr_arg),
- target: BasicBlock::new(4),
- unwind: None
- }, true);
+ block(
+ &mut blocks,
+ vec![],
+ TerminatorKind::Drop {
+ location: Place::from(rcvr_arg),
+ target: BasicBlock::new(4),
+ unwind: None,
+ },
+ true,
+ );
// BB #4 - resume
block(&mut blocks, vec![], TerminatorKind::Resume, true);
}
- let mut body = new_body(
- blocks,
- local_decls,
- sig.inputs().len(),
- span,
- );
+ let mut body = new_body(blocks, local_decls, sig.inputs().len(), span);
if let Abi::RustCall = sig.abi {
body.spread_arg = Some(Local::new(sig.inputs().len()));
pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &BodyAndCache<'_> {
debug_assert!(tcx.is_constructor(ctor_id));
- let span = tcx.hir().span_if_local(ctor_id)
- .unwrap_or_else(|| bug!("no span for ctor {:?}", ctor_id));
+ let span =
+ tcx.hir().span_if_local(ctor_id).unwrap_or_else(|| bug!("no span for ctor {:?}", ctor_id));
let param_env = tcx.param_env(ctor_id);
// Normalize the sig.
- let sig = tcx.fn_sig(ctor_id)
- .no_bound_vars()
- .expect("LBR in ADT constructor signature");
+ let sig = tcx.fn_sig(ctor_id).no_bound_vars().expect("LBR in ADT constructor signature");
let sig = tcx.normalize_erasing_regions(param_env, sig);
let (adt_def, substs) = match sig.output().kind {
ty::Adt(adt_def, substs) => (adt_def, substs),
- _ => bug!("unexpected type for ADT ctor {:?}", sig.output())
+ _ => bug!("unexpected type for ADT ctor {:?}", sig.output()),
};
debug!("build_ctor: ctor_id={:?} sig={:?}", ctor_id, sig);
let local_decls = local_decls_for_sig(&sig, span);
- let source_info = SourceInfo {
- span,
- scope: OUTERMOST_SOURCE_SCOPE
- };
+ let source_info = SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE };
let variant_index = if adt_def.is_enum() {
adt_def.variant_index_with_ctor_id(ctor_id)
let statements = expand_aggregate(
Place::return_place(),
- adt_def
- .variants[variant_index]
- .fields
- .iter()
- .enumerate()
- .map(|(idx, field_def)| (
- Operand::Move(Place::from(Local::new(idx + 1))),
- field_def.ty(tcx, substs),
- )),
+ adt_def.variants[variant_index].fields.iter().enumerate().map(|(idx, field_def)| {
+ (Operand::Move(Place::from(Local::new(idx + 1))), field_def.ty(tcx, substs))
+ }),
AggregateKind::Adt(adt_def, variant_index, substs, None, None),
source_info,
tcx,
- ).collect();
+ )
+ .collect();
let start_block = BasicBlockData {
statements,
- terminator: Some(Terminator {
- source_info,
- kind: TerminatorKind::Return,
- }),
- is_cleanup: false
+ terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }),
+ is_cleanup: false,
};
- let body = new_body(
- IndexVec::from_elem_n(start_block, 1),
- local_decls,
- sig.inputs().len(),
- span,
- );
+ let body =
+ new_body(IndexVec::from_elem_n(start_block, 1), local_decls, sig.inputs().len(), span);
crate::util::dump_mir(
tcx,