impl Copy/Clone for arrays in std, not in compiler
This commit is contained in:
parent
495322d776
commit
ce1143e94d
9 changed files with 30 additions and 187 deletions
|
@ -310,7 +310,6 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -
|
|||
|
||||
match self_ty.kind() {
|
||||
_ if is_copy => builder.copy_shim(),
|
||||
ty::Array(ty, len) => builder.array_shim(dest, src, ty, len),
|
||||
ty::Closure(_, substs) => {
|
||||
builder.tuple_like_shim(dest, src, substs.as_closure().upvar_tys())
|
||||
}
|
||||
|
@ -459,154 +458,6 @@ impl CloneShimBuilder<'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
fn loop_header(
|
||||
&mut self,
|
||||
beg: Place<'tcx>,
|
||||
end: Place<'tcx>,
|
||||
loop_body: BasicBlock,
|
||||
loop_end: BasicBlock,
|
||||
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::new((
|
||||
cond,
|
||||
Rvalue::BinaryOp(BinOp::Ne, Box::new((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,
|
||||
);
|
||||
}
|
||||
|
||||
fn make_usize(&self, value: u64) -> Box<Constant<'tcx>> {
|
||||
Box::new(Constant {
|
||||
span: self.span,
|
||||
user_ty: None,
|
||||
literal: ty::Const::from_usize(self.tcx, value).into(),
|
||||
})
|
||||
}
|
||||
|
||||
fn array_shim(
|
||||
&mut self,
|
||||
dest: Place<'tcx>,
|
||||
src: Place<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
len: &'tcx ty::Const<'tcx>,
|
||||
) {
|
||||
let tcx = self.tcx;
|
||||
let span = self.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
|
||||
// `let mut beg = 0;`
|
||||
// `let end = len;`
|
||||
// `goto #1;`
|
||||
let inits = vec![
|
||||
self.make_statement(StatementKind::Assign(Box::new((
|
||||
Place::from(beg),
|
||||
Rvalue::Use(Operand::Constant(self.make_usize(0))),
|
||||
)))),
|
||||
self.make_statement(StatementKind::Assign(Box::new((
|
||||
end,
|
||||
Rvalue::Use(Operand::Constant(Box::new(Constant {
|
||||
span: self.span,
|
||||
user_ty: None,
|
||||
literal: len.into(),
|
||||
}))),
|
||||
)))),
|
||||
];
|
||||
self.block(inits, TerminatorKind::Goto { target: BasicBlock::new(1) }, false);
|
||||
|
||||
// BB #1: loop {
|
||||
// BB #2;
|
||||
// BB #3;
|
||||
// }
|
||||
// BB #4;
|
||||
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, 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));
|
||||
|
||||
// BB #3
|
||||
// `beg = beg + 1;`
|
||||
// `goto #1`;
|
||||
let statements = vec![self.make_statement(StatementKind::Assign(Box::new((
|
||||
Place::from(beg),
|
||||
Rvalue::BinaryOp(
|
||||
BinOp::Add,
|
||||
Box::new((Operand::Copy(Place::from(beg)), Operand::Constant(self.make_usize(1)))),
|
||||
),
|
||||
))))];
|
||||
self.block(statements, TerminatorKind::Goto { target: BasicBlock::new(1) }, false);
|
||||
|
||||
// BB #4
|
||||
// `return dest;`
|
||||
self.block(vec![], TerminatorKind::Return, false);
|
||||
|
||||
// BB #5 (cleanup)
|
||||
// `let end = beg;`
|
||||
// `let mut beg = 0;`
|
||||
// goto #6;
|
||||
let end = beg;
|
||||
let beg = self.local_decls.push(LocalDecl::new(tcx.types.usize, span));
|
||||
let init = self.make_statement(StatementKind::Assign(Box::new((
|
||||
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 #7;
|
||||
// BB #8;
|
||||
// }
|
||||
// BB #9;
|
||||
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 {
|
||||
place: 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::new((
|
||||
Place::from(beg),
|
||||
Rvalue::BinaryOp(
|
||||
BinOp::Add,
|
||||
Box::new((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>>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue