diff --git a/doc/rust.md b/doc/rust.md index b2429fde89160..f40a3e3a114c5 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -2067,6 +2067,10 @@ The currently implemented features of the compiler are: For now this style of variant is hidden behind a feature flag. +* `once_fns` - Onceness guarantees a closure is only executed once. Defining a + closure as `once` is unlikely to be supported going forward. So + they are hidden behind this feature until they are to be removed. + If a feature is promoted to a language feature, then all existing programs will start to receive compilation warnings about #[feature] directives which enabled the new feature (because the directive is no longer necessary). However, if diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index e4a08c3e16e5d..6c176f04fe8f6 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -74,12 +74,11 @@ pub static statik: uint = 1 << 21; pub static print_link_args: uint = 1 << 22; pub static no_debug_borrows: uint = 1 << 23; pub static lint_llvm: uint = 1 << 24; -pub static once_fns: uint = 1 << 25; -pub static print_llvm_passes: uint = 1 << 26; -pub static no_vectorize_loops: uint = 1 << 27; -pub static no_vectorize_slp: uint = 1 << 28; -pub static no_prepopulate_passes: uint = 1 << 29; -pub static use_softfp: uint = 1 << 30; +pub static print_llvm_passes: uint = 1 << 25; +pub static no_vectorize_loops: uint = 1 << 26; +pub static no_vectorize_slp: uint = 1 << 27; +pub static no_prepopulate_passes: uint = 1 << 28; +pub static use_softfp: uint = 1 << 29; pub fn debugging_opts_map() -> ~[(&'static str, &'static str, uint)] { ~[("verbose", "in general, enable more debug printouts", verbose), @@ -118,9 +117,6 @@ pub fn debugging_opts_map() -> ~[(&'static str, &'static str, uint)] { ("lint-llvm", "Run the LLVM lint pass on the pre-optimization IR", lint_llvm), - ("once-fns", - "Allow 'once fn' closures to deinitialize captured variables", - once_fns), ("print-llvm-passes", "Prints the llvm optimization passes being run", print_llvm_passes), @@ -326,7 +322,6 @@ impl Session_ { pub fn debug_borrows(&self) -> bool { self.opts.optimize == No && !self.debugging_opt(no_debug_borrows) } - pub fn once_fns(&self) -> bool { self.debugging_opt(once_fns) } pub fn print_llvm_passes(&self) -> bool { self.debugging_opt(print_llvm_passes) } diff --git a/src/librustc/front/feature_gate.rs b/src/librustc/front/feature_gate.rs index 5986409c84369..271ce6c0fd982 100644 --- a/src/librustc/front/feature_gate.rs +++ b/src/librustc/front/feature_gate.rs @@ -33,6 +33,7 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[ ("globs", Active), ("macro_rules", Active), ("struct_variant", Active), + ("once_fns", Active), // These are used to test this portion of the compiler, they don't actually // mean anything @@ -126,6 +127,20 @@ impl Visitor<()> for Context { visit::walk_item(self, i, ()); } + + fn visit_ty(&mut self, t: &ast::Ty, _: ()) { + match t.node { + ast::ty_closure(closure) if closure.onceness == ast::Once => { + self.gate_feature("once_fns", t.span, + "once functions are \ + experimental and likely to be removed"); + + }, + _ => {} + } + + visit::walk_ty(self, t, ()); + } } pub fn check_crate(sess: Session, crate: &ast::Crate) { diff --git a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs index a6db028a4919b..7fdc248563153 100644 --- a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -102,25 +102,13 @@ fn check_is_legal_to_move_from(bccx: &BorrowckCtxt, match cmt.cat { mc::cat_deref(_, _, mc::region_ptr(*)) | mc::cat_deref(_, _, mc::gc_ptr(*)) | - mc::cat_deref(_, _, mc::unsafe_ptr(*)) => { - bccx.span_err( - cmt0.span, - format!("cannot move out of {}", - bccx.cmt_to_str(cmt))); - false - } - - // These are separate from the above cases for a better error message. + mc::cat_deref(_, _, mc::unsafe_ptr(*)) | mc::cat_stack_upvar(*) | mc::cat_copied_upvar(mc::CopiedUpvar { onceness: ast::Many, _ }) => { - let once_hint = if bccx.tcx.sess.once_fns() { - " (unless the destination closure type is `once fn')" - } else { - "" - }; bccx.span_err( cmt0.span, - format!("cannot move out of {}{}", bccx.cmt_to_str(cmt), once_hint)); + format!("cannot move out of {}", + bccx.cmt_to_str(cmt))); false } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 19be4d041edfd..3b8ea2c33ec90 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -508,12 +508,10 @@ impl mem_categorization_ctxt { let var_is_refd = match (closure_ty.sigil, closure_ty.onceness) { // Many-shot stack closures can never move out. (ast::BorrowedSigil, ast::Many) => true, - // 1-shot stack closures can move out with "-Z once-fns". - (ast::BorrowedSigil, ast::Once) - if self.tcx.sess.once_fns() => false, - (ast::BorrowedSigil, ast::Once) => true, + // 1-shot stack closures can move out. + (ast::BorrowedSigil, ast::Once) => false, // Heap closures always capture by copy/move, and can - // move out iff they are once. + // move out if they are once. (ast::OwnedSigil, _) | (ast::ManagedSigil, _) => false, diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 27b5fd490e072..e53fd72439aa0 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3645,7 +3645,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { let fty = ty::mk_closure(ccx.tcx, ty::ClosureTy { purity: ast::impure_fn, sigil: ast::BorrowedSigil, - onceness: ast::Once, + onceness: ast::Many, region: ty::re_bound(ty::br_anon(0)), bounds: ty::EmptyBuiltinBounds(), sig: ty::FnSig { diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 7cda2b109d9bc..dee21762a309b 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -331,7 +331,8 @@ extern "rust-intrinsic" { pub fn visit_tydesc(td: *TyDesc, tv: &mut TyVisitor); - pub fn frame_address(f: &once fn(*u8)); + #[cfg(not(stage0))] + pub fn frame_address(f: &fn(*u8)); /// Get the address of the `__morestack` stack growth function. pub fn morestack_addr() -> *(); diff --git a/src/test/compile-fail/once-cant-call-twice-on-heap.rs b/src/test/compile-fail/once-cant-call-twice-on-heap.rs index dddd9a1868c93..e266a56ded44b 100644 --- a/src/test/compile-fail/once-cant-call-twice-on-heap.rs +++ b/src/test/compile-fail/once-cant-call-twice-on-heap.rs @@ -11,6 +11,7 @@ // Testing guarantees provided by once functions. // This program would segfault if it were legal. +#[feature(once_fns)]; extern mod extra; use extra::arc; use std::util; diff --git a/src/test/compile-fail/once-cant-call-twice-on-stack.rs b/src/test/compile-fail/once-cant-call-twice-on-stack.rs index 45110bd4bc68a..9469d123d18d7 100644 --- a/src/test/compile-fail/once-cant-call-twice-on-stack.rs +++ b/src/test/compile-fail/once-cant-call-twice-on-stack.rs @@ -11,7 +11,7 @@ // Testing guarantees provided by once functions. // This program would segfault if it were legal. -// compile-flags:-Z once-fns +#[feature(once_fns)]; extern mod extra; use extra::arc; use std::util; diff --git a/src/test/compile-fail/once-fn-subtyping.rs b/src/test/compile-fail/once-fn-subtyping.rs index 178c04dfc793c..5f7393fdf8b8c 100644 --- a/src/test/compile-fail/once-fn-subtyping.rs +++ b/src/test/compile-fail/once-fn-subtyping.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[feature(once_fns)]; fn main() { let f: &once fn() = ||(); let g: &fn() = f; //~ ERROR mismatched types diff --git a/src/test/run-pass/intrinsic-frame-address.rs b/src/test/run-pass/intrinsic-frame-address.rs index 63635c7addfa0..c7b23790ded76 100644 --- a/src/test/run-pass/intrinsic-frame-address.rs +++ b/src/test/run-pass/intrinsic-frame-address.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -12,7 +12,7 @@ mod rusti { extern "rust-intrinsic" { - pub fn frame_address(f: &once fn(*u8)); + pub fn frame_address(f: &fn(*u8)); } } diff --git a/src/test/run-pass/once-move-out-on-heap.rs b/src/test/run-pass/once-move-out-on-heap.rs index 744cd1066cf7c..858f8ec07c4d9 100644 --- a/src/test/run-pass/once-move-out-on-heap.rs +++ b/src/test/run-pass/once-move-out-on-heap.rs @@ -12,6 +12,7 @@ // xfail-fast +#[feature(once_fns)]; extern mod extra; use extra::arc; use std::util; diff --git a/src/test/run-pass/once-move-out-on-stack.rs b/src/test/run-pass/once-move-out-on-stack.rs index 002503a5566bd..8e340275d7fde 100644 --- a/src/test/run-pass/once-move-out-on-stack.rs +++ b/src/test/run-pass/once-move-out-on-stack.rs @@ -12,7 +12,7 @@ // xfail-fast -// compile-flags:-Z once-fns +#[feature(once_fns)]; extern mod extra; use extra::arc; use std::util;