diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 5c8287c0030d4..60c38af3e72ab 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -310,26 +310,23 @@ pub fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, return expr::trans_into(bcx, &**element, Ignore); } SaveIn(lldest) => { - let count = ty::eval_repeat_count(bcx.tcx(), &**count_expr); - if count == 0 { - return bcx; + match ty::eval_repeat_count(bcx.tcx(), &**count_expr) { + 0 => bcx, + 1 => expr::trans_into(bcx, &**element, SaveIn(lldest)), + count => { + let elem = unpack_datum!(bcx, expr::trans(bcx, &**element)); + assert!(!ty::type_moves_by_default(bcx.tcx(), elem.ty)); + + let bcx = iter_vec_loop(bcx, lldest, vt, + C_uint(bcx.ccx(), count), + |set_bcx, lleltptr, _| { + elem.shallow_copy(set_bcx, lleltptr) + }); + + elem.add_clean_if_rvalue(bcx, element.id); + bcx + } } - - // Some cleanup would be required in the case in which panic happens - // during a copy. But given that copy constructors are not overridable, - // this can only happen as a result of OOM. So we just skip out on the - // cleanup since things would *probably* be broken at that point anyways. - - let elem = unpack_datum!(bcx, expr::trans(bcx, &**element)); - assert!(!ty::type_moves_by_default(bcx.tcx(), elem.ty)); - - let bcx = iter_vec_loop(bcx, lldest, vt, - C_uint(bcx.ccx(), count), |set_bcx, lleltptr, _| { - elem.shallow_copy(set_bcx, lleltptr) - }); - - elem.add_clean_if_rvalue(bcx, element.id); - bcx } } } diff --git a/src/test/run-pass/issue-18425.rs b/src/test/run-pass/issue-18425.rs new file mode 100644 index 0000000000000..6bb244bf88f42 --- /dev/null +++ b/src/test/run-pass/issue-18425.rs @@ -0,0 +1,16 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Check that trans doesn't ICE when translating an array repeat +// expression with a count of 1 and a non-Copy element type. + +fn main() { + let _ = [box 1u, ..1]; +}