Skip to content
2 changes: 1 addition & 1 deletion src/libgreen/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ pub fn start(argc: int, argv: **u8,
let mut ret = None;
simple::task().run(|| {
ret = Some(run(event_loop_factory, main.take_unwrap()));
});
}).destroy();
// unsafe is ok b/c we're sure that the runtime is gone
unsafe { rt::cleanup() }
ret.unwrap()
Expand Down
4 changes: 2 additions & 2 deletions src/libgreen/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ extern fn bootstrap_green_task(task: uint, code: *(), env: *()) -> ! {
// requested. This is the "try/catch" block for this green task and
// is the wrapper for *all* code run in the task.
let mut start = Some(start);
let task = task.swap().run(|| start.take_unwrap()());
let task = task.swap().run(|| start.take_unwrap()()).destroy();

// Once the function has exited, it's time to run the termination
// routine. This means we need to context switch one more time but
Expand All @@ -120,7 +120,7 @@ extern fn bootstrap_green_task(task: uint, code: *(), env: *()) -> ! {
// this we could add a `terminate` function to the `Runtime` trait
// in libstd, but that seems less appropriate since the coversion
// method exists.
GreenTask::convert(task).terminate()
GreenTask::convert(task).terminate();
}

impl GreenTask {
Expand Down
4 changes: 4 additions & 0 deletions src/libnative/io/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,10 @@ fn spawn_process_os(cfg: ProcessConfig,

let dirp = cfg.cwd.map(|c| c.with_ref(|p| p)).unwrap_or(ptr::null());

let cfg = unsafe {
mem::transmute::<ProcessConfig,ProcessConfig<'static>>(cfg)
};

with_envp(cfg.env, proc(envp) {
with_argv(cfg.program, cfg.args, proc(argv) unsafe {
let (mut input, mut output) = try!(pipe());
Expand Down
5 changes: 2 additions & 3 deletions src/libnative/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,12 @@ pub fn start(argc: int, argv: **u8, main: proc()) -> int {
let mut main = Some(main);
let mut task = task::new((my_stack_bottom, my_stack_top));
task.name = Some(str::Slice("<main>"));
let t = task.run(|| {
drop(task.run(|| {
unsafe {
rt::stack::record_stack_bounds(my_stack_bottom, my_stack_top);
}
exit_code = Some(run(main.take_unwrap()));
});
drop(t);
}).destroy());
unsafe { rt::cleanup(); }
// If the exit code wasn't set, then the task block must have failed.
return exit_code.unwrap_or(rt::DEFAULT_ERROR_CODE);
Expand Down
3 changes: 1 addition & 2 deletions src/libnative/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc():Send) {
let mut f = Some(f);
let mut task = task;
task.put_runtime(ops);
let t = task.run(|| { f.take_unwrap()() });
drop(t);
drop(task.run(|| { f.take_unwrap()() }).destroy());
bookkeeping::decrement();
})
}
Expand Down
64 changes: 51 additions & 13 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -975,14 +975,52 @@ declare_lint!(UNNECESSARY_PARENS, Warn,
pub struct UnnecessaryParens;

impl UnnecessaryParens {
fn check_unnecessary_parens_core(&self, cx: &Context, value: &ast::Expr, msg: &str) {
fn check_unnecessary_parens_core(&self, cx: &Context, value: &ast::Expr, msg: &str,
struct_lit_needs_parens: bool) {
match value.node {
ast::ExprParen(_) => {
cx.span_lint(UNNECESSARY_PARENS, value.span,
format!("unnecessary parentheses around {}", msg).as_slice())
ast::ExprParen(ref inner) => {
let necessary = struct_lit_needs_parens && contains_exterior_struct_lit(&**inner);
if !necessary {
cx.span_lint(UNNECESSARY_PARENS, value.span,
format!("unnecessary parentheses around {}",
msg).as_slice())
}
}
_ => {}
}

/// Expressions that syntatically contain an "exterior" struct
/// literal i.e. not surrounded by any parens or other
/// delimiters, e.g. `X { y: 1 }`, `X { y: 1 }.method()`, `foo
/// == X { y: 1 }` and `X { y: 1 } == foo` all do, but `(X {
/// y: 1 }) == foo` does not.
fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
match value.node {
ast::ExprStruct(..) => true,

ast::ExprAssign(ref lhs, ref rhs) |
ast::ExprAssignOp(_, ref lhs, ref rhs) |
ast::ExprBinary(_, ref lhs, ref rhs) => {
// X { y: 1 } + X { y: 2 }
contains_exterior_struct_lit(&**lhs) ||
contains_exterior_struct_lit(&**rhs)
}
ast::ExprUnary(_, ref x) |
ast::ExprCast(ref x, _) |
ast::ExprField(ref x, _, _) |
ast::ExprIndex(ref x, _) => {
// &X { y: 1 }, X { y: 1 }.y
contains_exterior_struct_lit(&**x)
}

ast::ExprMethodCall(_, _, ref exprs) => {
// X { y: 1 }.bar(...)
contains_exterior_struct_lit(&**exprs.get(0))
}

_ => false
}
}
}
}

Expand All @@ -992,16 +1030,16 @@ impl LintPass for UnnecessaryParens {
}

fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
let (value, msg) = match e.node {
ast::ExprIf(cond, _, _) => (cond, "`if` condition"),
ast::ExprWhile(cond, _) => (cond, "`while` condition"),
ast::ExprMatch(head, _) => (head, "`match` head expression"),
ast::ExprRet(Some(value)) => (value, "`return` value"),
ast::ExprAssign(_, value) => (value, "assigned value"),
ast::ExprAssignOp(_, _, value) => (value, "assigned value"),
let (value, msg, struct_lit_needs_parens) = match e.node {
ast::ExprIf(cond, _, _) => (cond, "`if` condition", true),
ast::ExprWhile(cond, _) => (cond, "`while` condition", true),
ast::ExprMatch(head, _) => (head, "`match` head expression", true),
ast::ExprRet(Some(value)) => (value, "`return` value", false),
ast::ExprAssign(_, value) => (value, "assigned value", false),
ast::ExprAssignOp(_, _, value) => (value, "assigned value", false),
_ => return
};
self.check_unnecessary_parens_core(cx, &*value, msg);
self.check_unnecessary_parens_core(cx, &*value, msg, struct_lit_needs_parens);
}

fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
Expand All @@ -1015,7 +1053,7 @@ impl LintPass for UnnecessaryParens {
},
_ => return
};
self.check_unnecessary_parens_core(cx, &*value, msg);
self.check_unnecessary_parens_core(cx, &*value, msg, false);
}
}

Expand Down
10 changes: 8 additions & 2 deletions src/librustc/middle/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,14 @@ fn with_appropriate_checker(cx: &Context,
let fty = ty::node_id_to_type(cx.tcx, id);
match ty::get(fty).sty {
ty::ty_closure(box ty::ClosureTy {
store: ty::UniqTraitStore, bounds, ..
}) => b(|cx, fv| check_for_uniq(cx, fv, bounds)),
store: ty::UniqTraitStore,
bounds: mut bounds, ..
}) => {
// Procs can't close over non-static references!
bounds.add(ty::BoundStatic);

b(|cx, fv| check_for_uniq(cx, fv, bounds))
}

ty::ty_closure(box ty::ClosureTy {
store: ty::RegionTraitStore(region, _), bounds, ..
Expand Down
24 changes: 18 additions & 6 deletions src/librustrt/local_heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,12 @@ impl LocalHeap {
self.memory_region.free(alloc);
}

pub unsafe fn annihilate(&mut self) {
/// Immortalize all pending allocations, forcing them to live forever.
///
/// This function will freeze all allocations to prevent all pending
/// allocations from being deallocated. This is used in preparation for when
/// a task is about to destroy TLD.
pub unsafe fn immortalize(&mut self) {
let mut n_total_boxes = 0u;

// Pass 1: Make all boxes immortal.
Expand All @@ -122,6 +127,17 @@ impl LocalHeap {
(*alloc).ref_count = RC_IMMORTAL;
});

if debug_mem() {
// We do logging here w/o allocation.
rterrln!("total boxes annihilated: {}", n_total_boxes);
}
}

/// Continues deallocation of the all pending allocations in this arena.
///
/// This is invoked from the destructor, and requires that `immortalize` has
/// been called previously.
unsafe fn annihilate(&mut self) {
// Pass 2: Drop all boxes.
//
// In this pass, unique-managed boxes may get freed, but not
Expand All @@ -142,11 +158,6 @@ impl LocalHeap {
self.each_live_alloc(true, |me, alloc| {
me.free(alloc);
});

if debug_mem() {
// We do logging here w/o allocation.
rterrln!("total boxes annihilated: {}", n_total_boxes);
}
}

unsafe fn each_live_alloc(&mut self, read_next_before: bool,
Expand All @@ -170,6 +181,7 @@ impl LocalHeap {

impl Drop for LocalHeap {
fn drop(&mut self) {
unsafe { self.annihilate() }
assert!(self.live_allocs.is_null());
}
}
Expand Down
Loading