diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs index 3ea8de957a0..ef368fe7a8b 100644 --- a/src/libcore/dvec.rs +++ b/src/libcore/dvec.rs @@ -137,7 +137,9 @@ impl extensions for dvec { #[doc = "Append a single item to the end of the list"] fn push(t: A) { self.swap { |v| - let mut v <- v; v += [t]; v // more efficient than v + [t] + let mut v <- v; + vec::push(v, t); + v } } @@ -170,7 +172,7 @@ impl extensions for dvec { vec::reserve(v, new_len); let mut i = from_idx; while i < to_idx { - v += [ts[i]]; + vec::push(v, ts[i]); i += 1u; } v diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 2ce5550d951..2a89abc040f 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -10,6 +10,7 @@ export is_null; export is_not_null; export memcpy; export memmove; +export memset; export buf_len; export position; export extensions; @@ -23,6 +24,8 @@ native mod libc_ { fn memcpy(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void; #[rust_stack] fn memmove(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void; + #[rust_stack] + fn memset(dest: *c_void, c: libc::c_int, len: libc::size_t) -> *c_void; } #[abi = "rust-intrinsic"] @@ -108,6 +111,12 @@ unsafe fn memmove(dst: *T, src: *T, count: uint) { libc_::memmove(dst as *c_void, src as *c_void, n as size_t); } +#[inline(always)] +unsafe fn memset(dst: *mut T, c: int, count: uint) { + let n = count * sys::size_of::(); + libc_::memset(dst as *c_void, c as libc::c_int, n as size_t); +} + #[doc = "Extension methods for pointers"] impl extensions for *T { #[doc = "Returns true if the pointer is equal to the null pointer."] diff --git a/src/libcore/str.rs b/src/libcore/str.rs index f1136fde5e2..078243dfaee 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -1743,8 +1743,9 @@ mod unsafe { Does not verify that the vector contains valid UTF-8. "] unsafe fn from_bytes(v: [const u8]) -> str unsafe { - let vcopy = v + [0u8]; - ret ::unsafe::transmute(vcopy); + let mut vcopy : [u8] = ::unsafe::transmute(copy v); + vec::push(vcopy, 0u8); + ::unsafe::transmute(vcopy) } #[doc = " diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 1eab5b12ea0..a1b2ee23f0f 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -4,6 +4,7 @@ import option::{some, none}; import ptr::addr_of; import libc::size_t; +export append; export init_op; export is_empty; export is_not_empty; @@ -187,7 +188,9 @@ pure fn from_elem(n_elts: uint, t: T) -> [T] { let mut v = []; unchecked{reserve(v, n_elts)} let mut i: uint = 0u; - while i < n_elts { v += [t]; i += 1u; } + unsafe { // because push is impure + while i < n_elts { push(v, t); i += 1u; } + } ret v; } @@ -372,11 +375,8 @@ fn shift(&v: [T]) -> T { } #[doc = "Prepend an element to a vector"] -fn unshift(&v: [const T], +t: T) { - // n.b.---for most callers, using unshift() ought not to type check, but - // it does. It's because the type system is unaware of the mutability of - // `v` and so allows the vector to be covariant. - v = [const t] + v; +fn unshift(&v: [T], +t: T) { + v = [t] + v; } #[doc = "Remove the last element from a vector and return it"] @@ -390,12 +390,69 @@ fn pop(&v: [const T]) -> T unsafe { } #[doc = "Append an element to a vector"] +#[inline(always)] fn push(&v: [const T], +initval: T) { - v += [initval]; + let ln = v.len(); + unsafe { + reserve_at_least(v, ln + 1u); + unsafe::set_len(v, ln + 1u); + let p = ptr::mut_addr_of(v[ln]); + + // FIXME: for performance, try replacing the memmove and <- with a + // memset and unsafe::forget. + ptr::memset(p, 0, 1u); // needed to stop drop glue from running on + // garbage data. + *p = initval; + } } +#[inline(always)] +fn push_all(&v: [const T], rhs: [const T]/&) { + for uint::range(0u, rhs.len()) {|i| + push(v, rhs[i]); + } +} // Appending +#[inline(always)] +pure fn append(lhs: [T]/&, rhs: [const T]/&) -> [T] { + let mut v = []; + let mut i = 0u; + while i < lhs.len() { + unsafe { // This is impure, but it appears pure to the caller. + push(v, lhs[i]); + } + i += 1u; + } + i = 0u; + while i < rhs.len() { + unsafe { // This is impure, but it appears pure to the caller. + push(v, rhs[i]); + } + i += 1u; + } + ret v; +} + +#[inline(always)] +pure fn append_mut(lhs: [mut T]/&, rhs: [const T]/&) -> [mut T] { + let mut v = [mut]; + let mut i = 0u; + while i < lhs.len() { + unsafe { // This is impure, but it appears pure to the caller. + push(v, lhs[i]); + } + i += 1u; + } + i = 0u; + while i < rhs.len() { + unsafe { // This is impure, but it appears pure to the caller. + push(v, rhs[i]); + } + i += 1u; + } + ret v; +} #[doc = " Expands a vector in place, initializing the new elements to a given value @@ -409,7 +466,8 @@ Expands a vector in place, initializing the new elements to a given value fn grow(&v: [const T], n: uint, initval: T) { reserve_at_least(v, len(v) + n); let mut i: uint = 0u; - while i < n { v += [initval]; i += 1u; } + + while i < n { push(v, initval); i += 1u; } } #[doc = " @@ -428,7 +486,7 @@ Function `init_op` is called `n` times with the values [0..`n`) fn grow_fn(&v: [const T], n: uint, op: init_op) { reserve_at_least(v, len(v) + n); let mut i: uint = 0u; - while i < n { v += [op(i)]; i += 1u; } + while i < n { push(v, op(i)); i += 1u; } } #[doc = " @@ -453,7 +511,7 @@ Apply a function to each element of a vector and return the results pure fn map(v: [T]/&, f: fn(T) -> U) -> [U] { let mut result = []; unchecked{reserve(result, len(v));} - for each(v) {|elem| result += [f(elem)]; } + for each(v) {|elem| unsafe { push(result, f(elem)); } } ret result; } @@ -486,7 +544,10 @@ pure fn map2(v0: [T]/&, v1: [U]/&, if v0_len != len(v1) { fail; } let mut u: [V] = []; let mut i = 0u; - while i < v0_len { u += [f(copy v0[i], copy v1[i])]; i += 1u; } + while i < v0_len { + unsafe { push(u, f(copy v0[i], copy v1[i])) }; + i += 1u; + } ret u; } @@ -502,7 +563,7 @@ pure fn filter_map(v: [T]/&, f: fn(T) -> option) for each(v) {|elem| alt f(elem) { none {/* no-op */ } - some(result_elem) { result += [result_elem]; } + some(result_elem) { unsafe { push(result, result_elem); } } } } ret result; @@ -518,7 +579,7 @@ only those elements for which `f` returned true. pure fn filter(v: [T]/&, f: fn(T) -> bool) -> [T] { let mut result = []; for each(v) {|elem| - if f(elem) { result += [elem]; } + if f(elem) { unsafe { push(result, elem); } } } ret result; } @@ -530,7 +591,7 @@ Flattens a vector of vectors of T into a single vector of T. "] pure fn concat(v: [[T]]/&) -> [T] { let mut r = []; - for each(v) {|inner| r += inner; } + for each(v) {|inner| unsafe { push_all(r, inner); } } ret r; } @@ -541,7 +602,7 @@ pure fn connect(v: [[T]]/&, sep: T) -> [T] { let mut r: [T] = []; let mut first = true; for each(v) {|inner| - if first { first = false; } else { r += [sep]; } + if first { first = false; } else { unsafe { push(r, sep); } } r += inner; } ret r; @@ -1025,6 +1086,20 @@ pure fn unpack_mut_slice(s: [mut T]/&, f(buf, len / sys::size_of::()) } +impl extensions for [T] { + #[inline(always)] + pure fn +(rhs: [T]/&) -> [T] { + append(self, rhs) + } +} + +impl extensions for [mut T] { + #[inline(always)] + pure fn +(rhs: [mut T]/&) -> [mut T] { + append_mut(self, rhs) + } +} + #[doc = "Extension methods for vectors"] impl extensions/& for [const T]/& { #[doc = "Returns true if a vector contains no elements"] diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index 1e9b2224a63..eafd2776d19 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -33,8 +33,8 @@ fn create() -> t { let nalloc = uint::next_power_of_two(nelts + 1u); while i < nalloc { if i < nelts { - rv += [mut elts[(lo + i) % nelts]]; - } else { rv += [mut none]; } + vec::push(rv, elts[(lo + i) % nelts]); + } else { vec::push(rv, none); } i += 1u; } diff --git a/src/libstd/rope.rs b/src/libstd/rope.rs index 945b23cc47a..a8cd3b65ef8 100644 --- a/src/libstd/rope.rs +++ b/src/libstd/rope.rs @@ -864,7 +864,7 @@ mod node { loop { alt (leaf_iterator::next(it)) { option::none { break; } - option::some(x) { forest += [mut @leaf(x)]; } + option::some(x) { vec::push(forest, @leaf(x)); } } } //2. Rebuild tree from forest diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 09bb2cc5409..e56bb25e55d 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -480,12 +480,17 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> { vfn(id); }, - visit_fn: fn@(fk: visit::fn_kind, d: fn_decl, - _b: blk, _sp: span, id: node_id) { + visit_fn: fn@(fk: visit::fn_kind, d: ast::fn_decl, + _b: ast::blk, _sp: span, id: ast::node_id) { vfn(id); alt fk { - visit::fk_ctor(_, tps, self_id, parent_id) | + visit::fk_ctor(nm, tps, self_id, parent_id) { + vec::iter(tps) {|tp| vfn(tp.id)} + vfn(id); + vfn(self_id); + vfn(parent_id.node); + } visit::fk_dtor(tps, self_id, parent_id) { vec::iter(tps) {|tp| vfn(tp.id)} vfn(id); @@ -500,7 +505,11 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> { vfn(m.self_id); vec::iter(tps) {|tp| vfn(tp.id)} } - visit::fk_anon(*) | visit::fk_fn_block(*) { + visit::fk_anon(_, capture_clause) + | visit::fk_fn_block(capture_clause) { + for vec::each(*capture_clause) {|clause| + vfn(clause.id); + } } } diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index f8292be51fe..b8362eb8734 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -159,7 +159,7 @@ impl parser_common for parser { else { self.expect(t); } } _ { } } - v += [f(self)]; + vec::push(v, f(self)); } ret v; @@ -202,7 +202,7 @@ impl parser_common for parser { _ { } } if sep.trailing_sep_allowed && self.token == ket { break; } - v += [f(self)]; + vec::push(v, f(self)); } ret v; } diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs index b275ebcb3ae..2fae0850187 100644 --- a/src/rustc/middle/astencode.rs +++ b/src/rustc/middle/astencode.rs @@ -66,8 +66,8 @@ type decode_ctxt = @{ type extended_decode_ctxt = @{ dcx: decode_ctxt, - from_id_range: id_range, - to_id_range: id_range + from_id_range: ast_util::id_range, + to_id_range: ast_util::id_range }; iface tr { @@ -86,9 +86,9 @@ fn encode_inlined_item(ecx: @e::encode_ctxt, ast_map::path_to_str(path), *ii.ident(), ebml_w.writer.tell()]; - let id_range = compute_id_range(ii); + let id_range = ast_util::compute_id_range_for_inlined_item(ii); ebml_w.wr_tag(c::tag_ast as uint) {|| - encode_id_range(ebml_w, id_range); + ast_util::serialize_id_range(ebml_w, id_range); encode_ast(ebml_w, simplify_ast(ii)); encode_side_tables_for_ii(ecx, maps, ebml_w, ii); } @@ -108,7 +108,8 @@ fn decode_inlined_item(cdata: cstore::crate_metadata, none { none } some(ast_doc) { #debug["> Decoding inlined fn: %s::?", ast_map::path_to_str(path)]; - let from_id_range = decode_id_range(ast_doc); + let ast_dsr = ebml::ebml_deserializer(ast_doc); + let from_id_range = ast_util::deserialize_id_range(ast_dsr); let to_id_range = reserve_id_range(dcx.tcx.sess, from_id_range); let xcx = @{dcx: dcx, from_id_range: from_id_range, @@ -136,178 +137,10 @@ fn decode_inlined_item(cdata: cstore::crate_metadata, // ______________________________________________________________________ // Enumerating the IDs which appear in an AST -type id_range = {min: ast::node_id, max: ast::node_id}; - -fn empty(range: id_range) -> bool { - range.min >= range.max -} - -fn visit_ids(item: ast::inlined_item, vfn: fn@(ast::node_id)) { - let visitor = visit::mk_simple_visitor(@{ - visit_mod: fn@(_m: ast::_mod, _sp: span, id: ast::node_id) { - vfn(id) - }, - - visit_view_item: fn@(vi: @ast::view_item) { - alt vi.node { - ast::view_item_use(_, _, id) { vfn(id) } - ast::view_item_import(vps) | ast::view_item_export(vps) { - vec::iter(vps) {|vp| - alt vp.node { - ast::view_path_simple(_, _, id) { vfn(id) } - ast::view_path_glob(_, id) { vfn(id) } - ast::view_path_list(_, _, id) { vfn(id) } - } - } - } - } - }, - - visit_native_item: fn@(ni: @ast::native_item) { - vfn(ni.id) - }, - - visit_item: fn@(i: @ast::item) { - vfn(i.id); - alt i.node { - ast::item_res(_, _, _, d_id, c_id, _) { vfn(d_id); vfn(c_id); } - ast::item_enum(vs, _, _) { for vs.each {|v| vfn(v.node.id); } } - _ {} - } - }, - - visit_local: fn@(l: @ast::local) { - vfn(l.node.id); - }, - - visit_block: fn@(b: ast::blk) { - vfn(b.node.id); - }, - - visit_stmt: fn@(s: @ast::stmt) { - vfn(ast_util::stmt_id(*s)); - }, - - visit_arm: fn@(_a: ast::arm) { }, - - visit_pat: fn@(p: @ast::pat) { - vfn(p.id) - }, - - visit_decl: fn@(_d: @ast::decl) { - }, - - visit_expr: fn@(e: @ast::expr) { - vfn(e.id); - alt e.node { - ast::expr_unary(*) | ast::expr_binary(*) | ast::expr_index(*) { - vfn(ast_util::op_expr_callee_id(e)); - } - _ { /* fallthrough */ } - } - }, - - visit_ty: fn@(t: @ast::ty) { - alt t.node { - ast::ty_path(_, id) { - vfn(id) - } - _ { /* fall through */ } - } - }, - - visit_ty_params: fn@(ps: [ast::ty_param]) { - vec::iter(ps) {|p| vfn(p.id) } - }, - - visit_constr: fn@(_p: @ast::path, _sp: span, id: ast::node_id) { - vfn(id); - }, - - visit_fn: fn@(fk: visit::fn_kind, d: ast::fn_decl, - _b: ast::blk, _sp: span, id: ast::node_id) { - vfn(id); - - alt fk { - visit::fk_ctor(nm, tps, self_id, parent_id) { - vec::iter(tps) {|tp| vfn(tp.id)} - vfn(id); - vfn(self_id); - vfn(parent_id.node); - } - visit::fk_dtor(tps, self_id, parent_id) { - vec::iter(tps) {|tp| vfn(tp.id)} - vfn(id); - vfn(self_id); - vfn(parent_id.node); - } - visit::fk_item_fn(_, tps) | - visit::fk_res(_, tps, _) { - vec::iter(tps) {|tp| vfn(tp.id)} - } - visit::fk_method(_, tps, m) { - vfn(m.self_id); - vec::iter(tps) {|tp| vfn(tp.id)} - } - visit::fk_anon(_, capture_clause) - | visit::fk_fn_block(capture_clause) { - for vec::each(*capture_clause) {|clause| - vfn(clause.id); - } - } - } - - vec::iter(d.inputs) {|arg| - vfn(arg.id) - } - }, - - visit_class_item: fn@(c: @ast::class_member) { - alt c.node { - ast::instance_var(_, _, _, id,_) { - vfn(id) - } - ast::class_method(_) { - } - } - } - }); - - item.accept((), visitor) -} - -fn compute_id_range(item: ast::inlined_item) -> id_range { - let min = @mut int::max_value; - let max = @mut int::min_value; - visit_ids(item) {|id| - *min = int::min(*min, id); - *max = int::max(*max, id + 1); - } - ret {min:*min, max:*max}; -} - -fn encode_id_range(ebml_w: ebml::writer, id_range: id_range) { - ebml_w.wr_tag(c::tag_id_range as uint) {|| - ebml_w.emit_tup(2u) {|| - ebml_w.emit_tup_elt(0u) {|| ebml_w.emit_int(id_range.min) } - ebml_w.emit_tup_elt(1u) {|| ebml_w.emit_int(id_range.max) } - } - } -} - -fn decode_id_range(par_doc: ebml::doc) -> id_range { - let range_doc = par_doc[c::tag_id_range]; - let dsr = ebml::ebml_deserializer(range_doc); - dsr.read_tup(2u) {|| - {min: dsr.read_tup_elt(0u) {|| dsr.read_int() }, - max: dsr.read_tup_elt(1u) {|| dsr.read_int() }} - } -} - fn reserve_id_range(sess: session, - from_id_range: id_range) -> id_range { + from_id_range: ast_util::id_range) -> ast_util::id_range { // Handle the case of an empty range: - if empty(from_id_range) { ret from_id_range; } + if ast_util::empty(from_id_range) { ret from_id_range; } let cnt = from_id_range.max - from_id_range.min; let to_id_min = sess.parse_sess.next_id; let to_id_max = sess.parse_sess.next_id + cnt; @@ -318,7 +151,7 @@ fn reserve_id_range(sess: session, impl translation_routines for extended_decode_ctxt { fn tr_id(id: ast::node_id) -> ast::node_id { // from_id_range should be non-empty - assert !empty(self.from_id_range); + assert !ast_util::empty(self.from_id_range); (id - self.from_id_range.min + self.to_id_range.min) } fn tr_def_id(did: ast::def_id) -> ast::def_id { @@ -749,12 +582,14 @@ fn encode_side_tables_for_ii(ecx: @e::encode_ctxt, ebml_w: ebml::writer, ii: ast::inlined_item) { ebml_w.wr_tag(c::tag_table as uint) {|| - visit_ids(ii, fn@(id: ast::node_id, copy ebml_w) { - // Note: this will cause a copy of ebml_w, which is bad as - // it has mut fields. But I believe it's harmless since - // we generate balanced EBML. - encode_side_tables_for_id(ecx, maps, ebml_w, id) - }); + ast_util::visit_ids_for_inlined_item( + ii, + fn@(id: ast::node_id, copy ebml_w) { + // Note: this will cause a copy of ebml_w, which is bad as + // it has mut fields. But I believe it's harmless since + // we generate balanced EBML. + encode_side_tables_for_id(ecx, maps, ebml_w, id) + }); } } diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 5fa7ddd12ac..d308181d8c7 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -1444,7 +1444,7 @@ fn copy_val_no_check(bcx: block, action: copy_action, dst: ValueRef, // doesn't need to be dropped. (Issue #839) fn move_val(cx: block, action: copy_action, dst: ValueRef, src: lval_result, t: ty::t) -> block { - assert !cx.terminated; + let _icx = cx.insn_ctxt("move_val"); let mut src_val = src.val; let tcx = cx.tcx(); @@ -1777,7 +1777,10 @@ fn trans_assign_op(bcx: block, ex: @ast::expr, op: ast::binop, // A user-defined operator method alt bcx.ccx().maps.method_map.find(ex.id) { some(origin) { + let bcx = lhs_res.bcx; let callee_id = ast_util::op_expr_callee_id(ex); + #debug["user-defined method callee_id: %s", + ast_map::node_id_to_str(bcx.tcx().items, callee_id)]; let fty = node_id_type(bcx, callee_id); let dty = expr_ty(bcx, dst); diff --git a/src/rustc/middle/trans/tvec.rs b/src/rustc/middle/trans/tvec.rs index 1eca2db5e7d..164a089dc88 100644 --- a/src/rustc/middle/trans/tvec.rs +++ b/src/rustc/middle/trans/tvec.rs @@ -190,7 +190,7 @@ fn trans_evec(bcx: block, args: [@ast::expr], let lleltptr = InBoundsGEP(bcx, dataptr, [C_uint(ccx, i)]); bcx = base::trans_expr_save_in(bcx, e, lleltptr); add_clean_temp_mem(bcx, lleltptr, unit_ty); - temp_cleanups += [lleltptr]; + vec::push(temp_cleanups, lleltptr); i += 1u; } diff --git a/src/rustc/middle/tstate/annotate.rs b/src/rustc/middle/tstate/annotate.rs index be38692c49e..d20cbcfe4d4 100644 --- a/src/rustc/middle/tstate/annotate.rs +++ b/src/rustc/middle/tstate/annotate.rs @@ -7,16 +7,18 @@ import aux::{num_constraints, get_fn_info, crate_ctxt, add_node}; import ann::empty_ann; import pat_util::pat_binding_ids; -fn collect_ids_expr(e: @expr, rs: @mut [node_id]) { *rs += [e.id]; } +fn collect_ids_expr(e: @expr, rs: @mut [node_id]) { vec::push(*rs, e.id); } -fn collect_ids_block(b: blk, rs: @mut [node_id]) { *rs += [b.node.id]; } +fn collect_ids_block(b: blk, rs: @mut [node_id]) { + vec::push(*rs, b.node.id); +} fn collect_ids_stmt(s: @stmt, rs: @mut [node_id]) { alt s.node { stmt_decl(_, id) | stmt_expr(_, id) | stmt_semi(_, id) { #debug["node_id %s", int::str(id)]; #debug["%s", stmt_to_str(*s)]; - *rs += [id]; + vec::push(*rs, id); } } } diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index 93fcfca31ea..16834c37919 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -921,22 +921,6 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, let lhs_t = fcx.expr_ty(lhs); let lhs_t = structurally_resolved_type(fcx, lhs.span, lhs_t); ret alt (op, ty::get(lhs_t).struct) { - (ast::add, ty::ty_vec(lhs_mt)) { - // For adding vectors with type L=[ML TL] and R=[MR TR], the the - // result [ML T] where TL <: T and TR <: T. In other words, the - // result type is (generally) the LUB of (TL, TR) and takes the - // mutability from the LHS. - let t_var = fcx.infcx.next_ty_var(); - let const_vec_t = ty::mk_vec(tcx, {ty: t_var, - mutbl: ast::m_const}); - demand::suptype(fcx, lhs.span, const_vec_t, lhs_t); - let rhs_bot = check_expr_with(fcx, rhs, const_vec_t); - let result_vec_t = ty::mk_vec(tcx, {ty: t_var, - mutbl: lhs_mt.mutbl}); - fcx.write_ty(expr.id, result_vec_t); - lhs_bot | rhs_bot - } - (_, _) if ty::type_is_integral(lhs_t) && ast_util::is_shift_binop(op) { // Shift is a special case: rhs can be any integral type diff --git a/src/rustc/middle/typeck/check/method.rs b/src/rustc/middle/typeck/check/method.rs index 4af075e8b79..c1793477b2e 100644 --- a/src/rustc/middle/typeck/check/method.rs +++ b/src/rustc/middle/typeck/check/method.rs @@ -154,7 +154,6 @@ class lookup { } fn add_candidates_from_param(n: uint, did: ast::def_id) { - let tcx = self.tcx(); let mut iface_bnd_idx = 0u; // count only iface bounds let bounds = tcx.ty_param_bounds.get(did.node); @@ -202,6 +201,8 @@ class lookup { fn add_candidates_from_iface(did: ast::def_id, iface_substs: ty::substs) { + #debug["method_from_iface"]; + let ms = *ty::iface_methods(self.tcx(), did); for ms.eachi {|i, m| if m.ident != self.m_name { cont; } @@ -235,6 +236,8 @@ class lookup { fn add_candidates_from_class(did: ast::def_id, class_substs: ty::substs) { + #debug["method_from_class"]; + let ms = *ty::iface_methods(self.tcx(), did); for ms.each {|m| @@ -285,6 +288,8 @@ class lookup { let impls_vecs = self.fcx.ccx.impl_map.get(self.expr.id); let mut added_any = false; + #debug["method_from_scope"]; + for list::each(impls_vecs) {|impls| for vec::each(*impls) {|im| // Check whether this impl has a method with the right name. @@ -297,9 +302,11 @@ class lookup { // if we can assign the caller to the callee, that's a // potential match. Collect those in the vector. - alt self.fcx.can_mk_assignty( + let can_assign = self.fcx.can_mk_assignty( self.self_expr, self.borrow_scope, - self.self_ty, impl_ty) { + self.self_ty, impl_ty); + #debug["can_assign = %?", can_assign]; + alt can_assign { result::err(_) { /* keep looking */ } result::ok(_) { let fty = self.ty_from_did(m.did); diff --git a/src/test/bench/core-vec-append.rs b/src/test/bench/core-vec-append.rs index af522ca8bc3..9a29671e184 100644 --- a/src/test/bench/core-vec-append.rs +++ b/src/test/bench/core-vec-append.rs @@ -8,6 +8,8 @@ fn collect_raw(num: uint) -> [uint] { let mut result = []; for uint::range(0u, num) { |i| result += [i]; + //vec::push(result, i); + //result = vec::append(result, [i]); } ret result; } @@ -43,18 +45,18 @@ fn main(args: [str]) { let raw = mid - start; let dvec = end - mid; - + let maxf = max as float; let rawf = raw as float; let dvecf = dvec as float; - + io::stdout().write_str(#fmt("Raw : %? seconds\n", raw)); io::stdout().write_str(#fmt(" : %f op/sec\n", maxf/rawf)); io::stdout().write_str(#fmt("\n")); io::stdout().write_str(#fmt("Dvec : %? seconds\n", dvec)); io::stdout().write_str(#fmt(" : %f op/sec\n", maxf/dvecf)); io::stdout().write_str(#fmt("\n")); - + if dvec < raw { io::stdout().write_str(#fmt("Dvec is %f%% faster than raw\n", (rawf - dvecf) / rawf * 100.0)); diff --git a/src/test/run-fail/zip-different-lengths.rs b/src/test/run-fail/zip-different-lengths.rs index 4a5ac59efd2..736b61cb935 100644 --- a/src/test/run-fail/zip-different-lengths.rs +++ b/src/test/run-fail/zip-different-lengths.rs @@ -10,7 +10,7 @@ fn enum_chars(start: u8, end: u8) -> [char] { assert start < end; let mut i = start; let mut r = []; - while i <= end { r += [i as char]; i += 1u as u8; } + while i <= end { vec::push(r, i as char); i += 1u as u8; } ret r; } @@ -18,7 +18,7 @@ fn enum_uints(start: uint, end: uint) -> [uint] { assert start < end; let mut i = start; let mut r = []; - while i <= end { r += [i]; i += 1u; } + while i <= end { vec::push(r, i); i += 1u; } ret r; } diff --git a/src/test/run-pass/import-glob-crate.rs b/src/test/run-pass/import-glob-crate.rs index 50e7257a6a0..c1473b1a0d4 100644 --- a/src/test/run-pass/import-glob-crate.rs +++ b/src/test/run-pass/import-glob-crate.rs @@ -4,6 +4,6 @@ import vec::*; fn main() { let mut v = from_elem(0u, 0); - v += [4, 2]; + v = vec::append(v, [4, 2]); assert (reversed(v) == [2, 4]); } diff --git a/src/test/run-pass/vec-push.rs b/src/test/run-pass/vec-push.rs index 56661e13a32..15b9239c44b 100644 --- a/src/test/run-pass/vec-push.rs +++ b/src/test/run-pass/vec-push.rs @@ -1,5 +1 @@ - - -fn push(&v: [const T], t: T) { v += [t]; } - -fn main() { let mut v = [1, 2, 3]; push(v, 1); } +fn main() { let mut v = [1, 2, 3]; vec::push(v, 1); } diff --git a/src/test/run-pass/zip-same-length.rs b/src/test/run-pass/zip-same-length.rs index 73a0f66d382..9ffb564ace6 100644 --- a/src/test/run-pass/zip-same-length.rs +++ b/src/test/run-pass/zip-same-length.rs @@ -10,7 +10,7 @@ fn enum_chars(start: u8, end: u8) -> [char] { assert start < end; let mut i = start; let mut r = []; - while i <= end { r += [i as char]; i += 1u as u8; } + while i <= end { vec::push(r, i as char); i += 1u as u8; } ret r; } @@ -18,7 +18,7 @@ fn enum_uints(start: uint, end: uint) -> [uint] { assert start < end; let mut i = start; let mut r = []; - while i <= end { r += [i]; i += 1u; } + while i <= end { vec::push(r, i); i += 1u; } ret r; }