diff --git a/src/libextra/c_vec.rs b/src/libextra/c_vec.rs index be7acc7bd9ca..99bb67ad89c3 100644 --- a/src/libextra/c_vec.rs +++ b/src/libextra/c_vec.rs @@ -36,7 +36,6 @@ * still held if needed. */ -use std::cast; use std::ptr; use std::routine::Runnable; use std::util; @@ -57,9 +56,10 @@ struct DtorRes { #[unsafe_destructor] impl Drop for DtorRes { fn drop(&mut self) { - match self.dtor { - option::None => (), - option::Some(f) => f() + let dtor = util::replace(&mut self.dtor, None); + match dtor { + None => (), + Some(f) => f.run() } } } diff --git a/src/libextra/rl.rs b/src/libextra/rl.rs index 9476bcb8926e..7c7b6de9a3a8 100644 --- a/src/libextra/rl.rs +++ b/src/libextra/rl.rs @@ -30,13 +30,11 @@ pub mod rustrt { macro_rules! locked { ($expr:expr) => { - unsafe { - // FIXME #9105: can't use a static mutex in pure Rust yet. - rustrt::rust_take_linenoise_lock(); - let x = $expr; - rustrt::rust_drop_linenoise_lock(); - x - } + // FIXME #9105: can't use a static mutex in pure Rust yet. + rustrt::rust_take_linenoise_lock(); + let x = $expr; + rustrt::rust_drop_linenoise_lock(); + x } } @@ -88,9 +86,13 @@ pub fn read(prompt: &str) -> Option<~str> { } } -pub type CompletionCb = @fn(~str, @fn(~str)); +/// The callback used to perform completions. +pub trait CompletionCb { + /// Performs a completion. + fn complete(&self, line: ~str, suggestion: &fn(~str)); +} -local_data_key!(complete_key: CompletionCb) +local_data_key!(complete_key: @CompletionCb) /// Bind to the main completion callback in the current task. /// @@ -98,25 +100,22 @@ local_data_key!(complete_key: CompletionCb) /// other than the closure that it receives as its second /// argument. Calling such a function will deadlock on the mutex used /// to ensure that the calls are thread-safe. -pub fn complete(cb: CompletionCb) { +pub unsafe fn complete(cb: @CompletionCb) { local_data::set(complete_key, cb); - extern fn callback(c_line: *c_char, completions: *()) { + extern fn callback(line: *c_char, completions: *()) { do local_data::get(complete_key) |opt_cb| { // only fetch completions if a completion handler has been // registered in the current task. match opt_cb { - None => {}, + None => {} Some(cb) => { - let line = unsafe { str::raw::from_c_str(c_line) }; - do (*cb)(line) |suggestion| { - do suggestion.with_c_str |buf| { - // This isn't locked, because `callback` gets - // called inside `rustrt::linenoise`, which - // *is* already inside the mutex, so - // re-locking would be a deadlock. - unsafe { - rustrt::linenoiseAddCompletion(completions, buf); + unsafe { + do cb.complete(str::raw::from_c_str(line)) + |suggestion| { + do suggestion.with_c_str |buf| { + rustrt::linenoiseAddCompletion(completions, + buf); } } } diff --git a/src/libextra/test.rs b/src/libextra/test.rs index cc80da1506aa..7400973c28a8 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -807,11 +807,6 @@ pub fn filter_tests( } } -struct TestFuture { - test: TestDesc, - wait: @fn() -> TestResult, -} - pub fn run_test(force_ignore: bool, test: TestDescAndFn, monitor_ch: SharedChan) { diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 6ca8086efc25..1b3224a2217f 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -218,14 +218,25 @@ fn with_appropriate_checker(cx: Context, id: NodeId, let fty = ty::node_id_to_type(cx.tcx, id); match ty::get(fty).sty { - ty::ty_closure(ty::ClosureTy {sigil: OwnedSigil, bounds: bounds, _}) => { + ty::ty_closure(ty::ClosureTy { + sigil: OwnedSigil, + bounds: bounds, + _ + }) => { b(|cx, fv| check_for_uniq(cx, fv, bounds)) } - ty::ty_closure(ty::ClosureTy {sigil: ManagedSigil, bounds: bounds, _}) => { - b(|cx, fv| check_for_box(cx, fv, bounds)) + ty::ty_closure(ty::ClosureTy { + sigil: ManagedSigil, + _ + }) => { + // can't happen } - ty::ty_closure(ty::ClosureTy {sigil: BorrowedSigil, bounds: bounds, - region: region, _}) => { + ty::ty_closure(ty::ClosureTy { + sigil: BorrowedSigil, + bounds: bounds, + region: region, + _ + }) => { b(|cx, fv| check_for_block(cx, fv, bounds, region)) } ty::ty_bare_fn(_) => { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 0e3c10ef2147..9cc95b873d25 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -187,8 +187,7 @@ pub fn opt_deref_kind(t: ty::t) -> Option { Some(deref_ptr(gc_ptr(m))) } - ty::ty_estr(ty::vstore_box) | - ty::ty_closure(ty::ClosureTy {sigil: ast::ManagedSigil, _}) => { + ty::ty_estr(ty::vstore_box) => { Some(deref_ptr(gc_ptr(ast::MutImmutable))) } @@ -515,7 +514,8 @@ impl mem_categorization_ctxt { (ast::BorrowedSigil, ast::Once) => true, // Heap closures always capture by copy/move, and can // move out iff they are once. - (ast::OwnedSigil, _) | (ast::ManagedSigil, _) => false, + (ast::OwnedSigil, _) | + (ast::ManagedSigil, _) => false, }; if var_is_refd { diff --git a/src/librustc/middle/stack_check.rs b/src/librustc/middle/stack_check.rs index 7ab6cfcdf7bf..5388e64348c6 100644 --- a/src/librustc/middle/stack_check.rs +++ b/src/librustc/middle/stack_check.rs @@ -116,8 +116,7 @@ fn stack_check_fn<'a>(v: StackCheckVisitor, visit::fk_anon(*) | visit::fk_fn_block => { match ty::get(ty::node_id_to_type(in_cx.tcx, id)).sty { ty::ty_bare_fn(*) | - ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, _}) | - ty::ty_closure(ty::ClosureTy {sigil: ast::ManagedSigil, _}) => { + ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, _}) => { false } _ => { diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 605032dc20c8..b5b181e22a6e 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -172,7 +172,7 @@ pub fn allocate_cbox(bcx: @mut Block, sigil: ast::Sigil, cdata_ty: ty::t) // Allocate and initialize the box: match sigil { ast::ManagedSigil => { - malloc_raw(bcx, cdata_ty, heap_managed) + tcx.sess.bug("trying to trans allocation of @fn") } ast::OwnedSigil => { malloc_raw(bcx, cdata_ty, heap_for_unique_closure(bcx, cdata_ty)) @@ -197,7 +197,8 @@ pub struct ClosureResult { // Otherwise, it is stack allocated and copies pointers to the upvars. pub fn store_environment(bcx: @mut Block, bound_values: ~[EnvValue], - sigil: ast::Sigil) -> ClosureResult { + sigil: ast::Sigil) + -> ClosureResult { let _icx = push_ctxt("closure::store_environment"); let ccx = bcx.ccx(); let tcx = ccx.tcx; @@ -444,27 +445,6 @@ pub fn make_closure_glue( } } -pub fn make_opaque_cbox_take_glue( - bcx: @mut Block, - sigil: ast::Sigil, - cboxptr: ValueRef) // ptr to ptr to the opaque closure - -> @mut Block { - // Easy cases: - let _icx = push_ctxt("closure::make_opaque_cbox_take_glue"); - match sigil { - ast::BorrowedSigil => { - return bcx; - } - ast::ManagedSigil => { - glue::incr_refcnt_of_boxed(bcx, Load(bcx, cboxptr)); - return bcx; - } - ast::OwnedSigil => { - fail!("unique closures are not copyable") - } - } -} - pub fn make_opaque_cbox_drop_glue( bcx: @mut Block, sigil: ast::Sigil, @@ -474,9 +454,7 @@ pub fn make_opaque_cbox_drop_glue( match sigil { ast::BorrowedSigil => bcx, ast::ManagedSigil => { - glue::decr_refcnt_maybe_free( - bcx, Load(bcx, cboxptr), Some(cboxptr), - ty::mk_opaque_closure_ptr(bcx.tcx(), sigil)) + bcx.tcx().sess.bug("trying to trans drop glue of @fn") } ast::OwnedSigil => { glue::free_ty( @@ -516,12 +494,8 @@ pub fn make_opaque_cbox_free_glue( abi::tydesc_field_drop_glue, None); // Free the ty descr (if necc) and the box itself - match sigil { - ast::ManagedSigil => glue::trans_free(bcx, cbox), - ast::OwnedSigil => glue::trans_exchange_free(bcx, cbox), - ast::BorrowedSigil => { - bcx.sess().bug("impossible") - } - } + glue::trans_exchange_free(bcx, cbox); + + bcx } } diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 1958d3c9adb4..a760801d73ad 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -581,11 +581,7 @@ pub fn make_take_glue(bcx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block { | ty::ty_estr(ty::vstore_slice(_)) => { bcx } - ty::ty_closure(ty::ClosureTy { sigil: ast::BorrowedSigil, _ }) | - ty::ty_closure(ty::ClosureTy { sigil: ast::ManagedSigil, _ }) => { - closure::make_closure_glue(bcx, v, t, take_ty) - } - ty::ty_closure(ty::ClosureTy { sigil: ast::OwnedSigil, _ }) => bcx, + ty::ty_closure(_) => bcx, ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => { let llbox = Load(bcx, GEPi(bcx, v, [0u, abi::trt_field_box])); incr_refcnt_of_boxed(bcx, llbox); @@ -606,9 +602,7 @@ pub fn make_take_glue(bcx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block { None); bcx } - ty::ty_opaque_closure_ptr(ck) => { - closure::make_opaque_cbox_take_glue(bcx, ck, v) - } + ty::ty_opaque_closure_ptr(_) => bcx, ty::ty_struct(did, _) => { let tcx = bcx.tcx(); let bcx = iter_structural_ty(bcx, v, t, take_ty); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 9abee133290f..bcf4de080733 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2308,12 +2308,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { ast::Many => TC_NONE }; // Prevent noncopyable types captured in the environment from being copied. - let ct = if cty.sigil == ast::ManagedSigil { - TC_NONE - } else { - TC_NONCOPY_TRAIT - }; - st + rt + ot + ct + st + rt + ot + TC_NONCOPY_TRAIT } fn trait_contents(store: TraitStore, mutbl: ast::Mutability, diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 36405136e630..024010e40dfa 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -400,6 +400,11 @@ pub fn ast_ty_to_ty( bf.abis, &bf.lifetimes, &bf.decl)) } ast::ty_closure(ref f) => { + if f.sigil == ast::ManagedSigil { + tcx.sess.span_err(ast_ty.span, + "managed closures are not supported"); + } + let bounds = conv_builtin_bounds(this.tcx(), &f.bounds, match f.sigil { // Use corresponding trait store to figure out default bounds // if none were specified. diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index ac11744f16a1..5d5e895a5ada 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -403,7 +403,7 @@ struct ViewItemVisitor<'self> { sess: session::Session, exec: &'self mut workcache::Exec, c: &'self ast::Crate, - save: @fn(Path), + save: &'self fn(Path), } impl<'self> Visitor<()> for ViewItemVisitor<'self> { @@ -508,7 +508,7 @@ pub fn find_and_install_dependencies(context: &BuildContext, sess: session::Session, exec: &mut workcache::Exec, c: &ast::Crate, - save: @fn(Path)) { + save: &fn(Path)) { debug!("In find_and_install_dependencies..."); let mut visitor = ViewItemVisitor { context: context, diff --git a/src/libstd/io.rs b/src/libstd/io.rs index 890a53690d96..ab8af22e1165 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -1846,31 +1846,38 @@ pub mod fsync { pub struct Arg { val: t, opt_level: Option, - fsync_fn: @fn(f: &t, Level) -> int, + fsync_fn: extern "Rust" fn(f: &t, Level) -> int, } // fsync file after executing blk // FIXME (#2004) find better way to create resources within lifetime of // outer res - pub fn FILE_res_sync(file: &FILERes, opt_level: Option, + pub fn FILE_res_sync(file: &FILERes, + opt_level: Option, blk: &fn(v: Res<*libc::FILE>)) { blk(Res::new(Arg { - val: file.f, opt_level: opt_level, - fsync_fn: |file, l| fsync_fd(fileno(*file), l) + val: file.f, + opt_level: opt_level, + fsync_fn: fsync_FILE, })); fn fileno(stream: *libc::FILE) -> libc::c_int { #[fixed_stack_segment]; #[inline(never)]; unsafe { libc::fileno(stream) } } + + fn fsync_FILE(stream: &*libc::FILE, level: Level) -> int { + fsync_fd(fileno(*stream), level) + } } // fsync fd after executing blk pub fn fd_res_sync(fd: &FdRes, opt_level: Option, blk: &fn(v: Res)) { blk(Res::new(Arg { - val: fd.fd, opt_level: opt_level, - fsync_fn: |fd, l| fsync_fd(*fd, l) + val: fd.fd, + opt_level: opt_level, + fsync_fn: fsync_fd_helper, })); } @@ -1880,6 +1887,10 @@ pub mod fsync { os::fsync_fd(fd, level) as int } + fn fsync_fd_helper(fd_ptr: &libc::c_int, level: Level) -> int { + fsync_fd(*fd_ptr, level) + } + // Type of objects that may want to fsync pub trait FSyncable { fn fsync(&self, l: Level) -> int; } @@ -1887,10 +1898,15 @@ pub mod fsync { pub fn obj_sync(o: @FSyncable, opt_level: Option, blk: &fn(v: Res<@FSyncable>)) { blk(Res::new(Arg { - val: o, opt_level: opt_level, - fsync_fn: |o, l| (*o).fsync(l) + val: o, + opt_level: opt_level, + fsync_fn: obj_fsync_fn, })); } + + fn obj_fsync_fn(o: &@FSyncable, level: Level) -> int { + (*o).fsync(level) + } } #[cfg(test)] diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs index 91e3719e3d05..833a9f5ed825 100644 --- a/src/libstd/reflect.rs +++ b/src/libstd/reflect.rs @@ -485,9 +485,11 @@ impl TyVisitor for MovePtrAdaptor { } fn visit_closure_ptr(&mut self, ck: uint) -> bool { - self.align_to::<@fn()>(); - if ! self.inner.visit_closure_ptr(ck) { return false; } - self.bump_past::<@fn()>(); + self.align_to::<~fn()>(); + if ! self.inner.visit_closure_ptr(ck) { + return false + } + self.bump_past::<~fn()>(); true } } diff --git a/src/libstd/unstable/finally.rs b/src/libstd/unstable/finally.rs index 6833ca6d7cfe..d98c13083dee 100644 --- a/src/libstd/unstable/finally.rs +++ b/src/libstd/unstable/finally.rs @@ -55,7 +55,6 @@ impl<'self,T> Finally for &'self fn() -> T { } finally_fn!(~fn() -> T) -finally_fn!(@fn() -> T) finally_fn!(extern "Rust" fn() -> T) struct Finallyalizer<'self> { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 6cdd6d2517be..867e4fe416b1 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2265,17 +2265,6 @@ pub fn print_fn_header_info(s: @ps, print_opt_sigil(s, opt_sigil); } -pub fn opt_sigil_to_str(opt_p: Option) -> &'static str { - match opt_p { - None => "fn", - Some(p) => match p { - ast::BorrowedSigil => "fn&", - ast::OwnedSigil => "fn~", - ast::ManagedSigil => "fn@" - } - } -} - pub fn purity_to_str(p: ast::purity) -> &'static str { match p { ast::impure_fn => "impure",