Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don’t worry, you can still create the pull request.
  • 2 commits
  • 4 files changed
  • 0 commit comments
  • 1 contributor
View
82 src/rustc/middle/trans/base.rs
@@ -50,7 +50,6 @@ import type_of::type_of; // Issue #1873
import syntax::ast_map::{path, path_mod, path_name};
import std::smallintmap;
-import option::is_none;
// Destinations
@@ -1212,8 +1211,7 @@ fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
}
}
-// See [Note-arg-mode]
-fn call_tydesc_glue_full(++cx: block, v: ValueRef, tydesc: ValueRef,
+fn call_tydesc_glue_full(cx: block, v: ValueRef, tydesc: ValueRef,
field: uint, static_ti: option<@tydesc_info>) {
let _icx = cx.insn_ctxt("call_tydesc_glue_full");
lazily_emit_tydesc_glue(cx.ccx(), field, static_ti);
@@ -1251,9 +1249,8 @@ fn call_tydesc_glue_full(++cx: block, v: ValueRef, tydesc: ValueRef,
C_null(T_ptr(T_ptr(cx.ccx().tydesc_type))), llrawptr]);
}
-// See [Note-arg-mode]
-fn call_tydesc_glue(++cx: block, v: ValueRef, t: ty::t, field: uint)
- -> block {
+fn call_tydesc_glue(cx: block, v: ValueRef, t: ty::t, field: uint) ->
+ block {
let _icx = cx.insn_ctxt("call_tydesc_glue");
let mut ti = none;
let td = get_tydesc(cx.ccx(), t, ti);
@@ -1439,6 +1436,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();
@@ -1721,7 +1719,11 @@ fn trans_assign_op(bcx: block, ex: @ast::expr, op: ast::binop,
some(origin) {
let callee_id = ast_util::op_expr_callee_id(ex);
let fty = node_id_type(bcx, callee_id);
- ret trans_call_inner(
+
+ let dty = expr_ty(bcx, dst);
+ let target = alloc_ty(bcx, dty);
+
+ let bcx = trans_call_inner(
bcx, ex.info(), fty,
expr_ty(bcx, ex),
{|bcx|
@@ -1729,7 +1731,12 @@ fn trans_assign_op(bcx: block, ex: @ast::expr, op: ast::binop,
// #2528
impl::trans_method_callee(bcx, callee_id, dst, origin)
},
- arg_exprs([src]), save_in(lhs_res.val));
+ arg_exprs([src]), save_in(target));
+
+ ret move_val(bcx, DROP_EXISTING, lhs_res.val,
+ // FIXME: should kind be owned?
+ {bcx: bcx, val: target, kind: owned},
+ dty);
}
_ {}
}
@@ -3127,9 +3134,8 @@ fn body_contains_ret(body: ast::blk) -> bool {
cx.found
}
-// See [Note-arg-mode]
fn trans_call_inner(
- ++in_cx: block,
+ in_cx: block,
call_info: option<node_info>,
fn_expr_ty: ty::t,
ret_ty: ty::t,
@@ -3257,8 +3263,8 @@ fn need_invoke(bcx: block) -> bool {
_ { }
}
cur = alt cur.parent {
- some(next) { next }
- none { ret false; }
+ parent_some(next) { next }
+ parent_none { ret false; }
}
}
}
@@ -3279,7 +3285,7 @@ fn in_lpad_scope_cx(bcx: block, f: fn(scope_info)) {
loop {
alt bcx.kind {
block_scope(inf) {
- if inf.cleanups.len() > 0u || is_none(bcx.parent) {
+ if inf.cleanups.len() > 0u || bcx.parent == parent_none {
f(inf); ret;
}
}
@@ -3488,11 +3494,11 @@ fn add_root_cleanup(bcx: block, scope_id: ast::node_id,
some({id, _}) if id == scope_id { ret bcx_sid; }
_ {
alt bcx_sid.parent {
- none {
+ parent_none {
bcx.tcx().sess.bug(
#fmt["no enclosing scope with id %d", scope_id]);
}
- some(bcx_par) { bcx_par }
+ parent_some(bcx_par) { bcx_par }
}
}
}
@@ -3802,10 +3808,7 @@ fn do_spill(bcx: block, v: ValueRef, t: ty::t) -> ValueRef {
// Since this function does *not* root, it is the caller's responsibility to
// ensure that the referent is pointed to by a root.
-// [Note-arg-mode]
-// ++ mode is temporary, due to how borrowck treats enums. With hope,
-// will go away anyway when we get rid of modes.
-fn do_spill_noroot(++cx: block, v: ValueRef) -> ValueRef {
+fn do_spill_noroot(cx: block, v: ValueRef) -> ValueRef {
let llptr = alloca(cx, val_ty(v));
Store(cx, v, llptr);
ret llptr;
@@ -3987,9 +3990,9 @@ fn trans_break_cont(bcx: block, to_end: bool)
_ {}
}
unwind = alt unwind.parent {
- some(cx) { cx }
+ parent_some(cx) { cx }
// This is a return from a loop body block
- none {
+ parent_none {
Store(bcx, C_bool(!to_end), bcx.fcx.llretptr);
cleanup_and_leave(bcx, none, some(bcx.fcx.llreturn));
Unreachable(bcx);
@@ -4107,7 +4110,7 @@ fn trans_stmt(cx: block, s: ast::stmt) -> block {
// You probably don't want to use this one. See the
// next three functions instead.
-fn new_block(cx: fn_ctxt, parent: option<block>, +kind: block_kind,
+fn new_block(cx: fn_ctxt, parent: block_parent, +kind: block_kind,
name: str, opt_node_info: option<node_info>) -> block {
let s = if cx.ccx.sess.opts.save_temps || cx.ccx.sess.opts.debuginfo {
@@ -4116,10 +4119,19 @@ fn new_block(cx: fn_ctxt, parent: option<block>, +kind: block_kind,
let llbb: BasicBlockRef = str::as_c_str(s, {|buf|
llvm::LLVMAppendBasicBlock(cx.llfn, buf)
});
- let bcx = mk_block(llbb, parent, kind, opt_node_info, cx);
- option::iter(parent) {|cx|
+ let bcx = @{llbb: llbb,
+ mut terminated: false,
+ mut unreachable: false,
+ parent: parent,
+ kind: kind,
+ node_info: opt_node_info,
+ fcx: cx};
+ alt parent {
+ parent_some(cx) {
if cx.unreachable { Unreachable(bcx); }
- };
+ }
+ _ {}
+ }
ret bcx;
}
@@ -4130,20 +4142,20 @@ fn simple_block_scope() -> block_kind {
// Use this when you're at the top block of a function or the like.
fn top_scope_block(fcx: fn_ctxt, opt_node_info: option<node_info>) -> block {
- ret new_block(fcx, none, simple_block_scope(),
+ ret new_block(fcx, parent_none, simple_block_scope(),
"function top level", opt_node_info);
}
fn scope_block(bcx: block,
opt_node_info: option<node_info>,
n: str) -> block {
- ret new_block(bcx.fcx, some(bcx), simple_block_scope(),
+ ret new_block(bcx.fcx, parent_some(bcx), simple_block_scope(),
n, opt_node_info);
}
fn loop_scope_block(bcx: block, loop_break: block, n: str,
opt_node_info: option<node_info>) -> block {
- ret new_block(bcx.fcx, some(bcx), block_scope({
+ ret new_block(bcx.fcx, parent_some(bcx), block_scope({
loop_break: some(loop_break),
mut cleanups: [],
mut cleanup_paths: [],
@@ -4154,11 +4166,17 @@ fn loop_scope_block(bcx: block, loop_break: block, n: str,
// Use this when you're making a general CFG BB within a scope.
fn sub_block(bcx: block, n: str) -> block {
- new_block(bcx.fcx, some(bcx), block_non_scope, n, none)
+ ret new_block(bcx.fcx, parent_some(bcx), block_non_scope, n, none);
}
fn raw_block(fcx: fn_ctxt, llbb: BasicBlockRef) -> block {
- mk_block(llbb, none, block_non_scope, none, fcx)
+ ret @{llbb: llbb,
+ mut terminated: false,
+ mut unreachable: false,
+ parent: parent_none,
+ kind: block_non_scope,
+ node_info: none,
+ fcx: fcx};
}
@@ -4233,8 +4251,8 @@ fn cleanup_and_leave(bcx: block, upto: option<BasicBlockRef>,
_ {}
}
cur = alt cur.parent {
- some(next) { next }
- none { assert is_none(upto); break; }
+ parent_some(next) { next }
+ parent_none { assert option::is_none(upto); break; }
};
}
alt leave {
View
44 src/rustc/middle/trans/common.rs
@@ -350,44 +350,32 @@ type node_info = {
// code. Each basic block we generate is attached to a function, typically
// with many basic blocks per function. All the basic blocks attached to a
// function are organized as a directed graph.
-class block_ {
+type block = @{
// The BasicBlockRef returned from a call to
// llvm::LLVMAppendBasicBlock(llfn, name), which adds a basic
// block to the function pointed to by llfn. We insert
// instructions into that block by way of this block context.
// The block pointing to this one in the function's digraph.
- let llbb: BasicBlockRef;
- let mut terminated: bool;
- let mut unreachable: bool;
- let parent: option<block>;
+ llbb: BasicBlockRef,
+ mut terminated: bool,
+ mut unreachable: bool,
+ parent: block_parent,
// The 'kind' of basic block this is.
- let kind: block_kind;
+ kind: block_kind,
// info about the AST node this block originated from, if any
- let node_info: option<node_info>;
+ node_info: option<node_info>,
// The function context for the function to which this block is
// attached.
- let fcx: fn_ctxt;
- new(llbb: BasicBlockRef, parent: option<block>, -kind: block_kind,
- node_info: option<node_info>, fcx: fn_ctxt) {
- // sigh
- self.llbb = llbb; self.terminated = false; self.unreachable = false;
- self.parent = parent; self.kind = kind; self.node_info = node_info;
- self.fcx = fcx;
- }
-}
-
-/* This must be enum and not type, or trans goes into an infinite loop (#2572)
- */
-enum block = @block_;
-
-fn mk_block(llbb: BasicBlockRef, parent: option<block>, -kind: block_kind,
- node_info: option<node_info>, fcx: fn_ctxt) -> block {
- block(@block_(llbb, parent, kind, node_info, fcx))
-}
+ fcx: fn_ctxt
+};
// First two args are retptr, env
const first_real_arg: uint = 2u;
+// FIXME move blocks to a class once those are finished, and simply use
+// option<block> for this. (#2532)
+enum block_parent { parent_none, parent_some(block), }
+
type result = {bcx: block, val: ValueRef};
type result_t = {bcx: block, val: ValueRef, ty: ty::t};
@@ -424,11 +412,7 @@ fn in_scope_cx(cx: block, f: fn(scope_info)) {
}
fn block_parent(cx: block) -> block {
- alt cx.parent {
- some(b) { b }
- none { cx.sess().bug(#fmt("block_parent called on root block %?",
- cx)); }
- }
+ alt check cx.parent { parent_some(b) { b } }
}
// Accessors
View
17 src/rustc/middle/trans/debuginfo.rs
@@ -236,8 +236,8 @@ fn create_block(cx: block) -> @metadata<block_md> {
let mut cx = cx;
while option::is_none(cx.node_info) {
alt cx.parent {
- some(b) { cx = b; }
- none { fail; }
+ parent_some(b) { cx = b; }
+ parent_none { fail; }
}
}
let sp = option::get(cx.node_info).span;
@@ -254,8 +254,8 @@ fn create_block(cx: block) -> @metadata<block_md> {
}*/
let parent = alt cx.parent {
- none { create_function(cx.fcx).node }
- some(bcx) { create_block(bcx).node }
+ parent_none { create_function(cx.fcx).node }
+ parent_some(bcx) { create_block(bcx).node }
};
let file_node = create_file(cx.ccx(), fname);
let unique_id = alt cache.find(LexicalBlockTag) {
@@ -658,8 +658,8 @@ fn create_local_var(bcx: block, local: @ast::local)
let tymd = create_ty(cx, ty, local.node.ty);
let filemd = create_file(cx, loc.file.name);
let context = alt bcx.parent {
- none { create_function(bcx.fcx).node }
- some(_) { create_block(bcx).node }
+ parent_none { create_function(bcx.fcx).node }
+ parent_some(_) { create_block(bcx).node }
};
let mdnode = create_var(tg, context, name, filemd.node,
loc.line as int, tymd.node);
@@ -761,10 +761,9 @@ fn create_function(fcx: fn_ctxt) -> @metadata<subprogram_md> {
(nm, decl.output, ctor_id)
}
ast_map::class_ctor(ctor,_) {
- // FIXME: output type may be wrong (#2194)
- (nm, ctor.node.dec.output, ctor.node.id)
+ fcx.ccx.sess.span_bug(ctor.span, "create_function: \
+ expected a resource ctor here"); }
}
- }
}
ast_map::node_expr(expr) {
alt expr.node {
View
74 src/test/run-pass/operator-overloading-leaks.rs
@@ -0,0 +1,74 @@
+// The cases commented as "Leaks" need to not leak. Issue #2581
+
+impl methods<T: copy> for [T] {
+ fn -(x: [T]/&) -> [T] {
+ [x[0], x[0], x[0]]
+ }
+
+ fn foo(x: [T]/&) -> [T] {
+ [x[0], x[0], x[0]]
+ }
+}
+
+impl methods<T: copy> for ~T {
+ fn +(rhs: ~T) -> ~T {
+ rhs
+ }
+}
+
+impl methods for ~int {
+ fn -(rhs: ~int) -> ~int {
+ ~(*self - *rhs)
+ }
+}
+
+impl methods for @int {
+ fn +(rhs: @int) -> @int {
+ @(*self + *rhs)
+ }
+}
+
+fn main() {
+ // leaks
+ let mut bar = [1, 2, 3];
+ bar -= [3, 2, 1];
+ bar -= [4, 5, 6];
+
+ io::println(#fmt("%?", bar));
+
+ // okay
+ let mut bar = [1, 2, 3];
+ bar = bar.foo([3, 2, 1]);
+ bar = bar.foo([4, 5, 6]);
+
+ io::println(#fmt("%?", bar));
+
+ // okay
+ let mut bar = [1, 2, 3];
+ bar = bar - [3, 2, 1];
+ bar = bar - [4, 5, 6];
+
+ io::println(#fmt("%?", bar));
+
+ // Leaks
+ let mut bar = ~1;
+ bar += ~2;
+ bar += ~3;
+
+ io:: println(#fmt("%?", bar));
+
+ // Leaks
+ let mut bar = ~1;
+ bar -= ~2;
+ bar -= ~3;
+
+ io:: println(#fmt("%?", bar));
+
+ // Leaks
+ let mut bar = @1;
+ bar += @2;
+ bar += @3;
+
+ io:: println(#fmt("%?", bar));
+
+}

No commit comments for this range

Something went wrong with that request. Please try again.