From dd4d45062d8a9715250e2b912d8fcf4817e3995e Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 7 Mar 2013 18:45:22 -0800 Subject: [PATCH 01/43] Make debug!, etc. macros not require a format string The one thing `log` can still do is polymorphically log anything, but debug!, etc. require a format string. With this patch you can equivalently write `debug!(foo)` or `debug!("%?", foo)` --- src/libsyntax/ext/expand.rs | 40 ++++++++++++++++++++++++++++------- src/test/run-pass/log-poly.rs | 10 +++++++++ 2 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 src/test/run-pass/log-poly.rs diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 7b4f92ab3ca83..16f087085cc86 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -409,14 +409,38 @@ pub fn core_macros() -> ~str { ~"pub mod macros { macro_rules! ignore (($($x:tt)*) => (())) - macro_rules! error ( ($( $arg:expr ),+) => ( - log(::core::error, fmt!( $($arg),+ )) )) - macro_rules! warn ( ($( $arg:expr ),+) => ( - log(::core::warn, fmt!( $($arg),+ )) )) - macro_rules! info ( ($( $arg:expr ),+) => ( - log(::core::info, fmt!( $($arg),+ )) )) - macro_rules! debug ( ($( $arg:expr ),+) => ( - log(::core::debug, fmt!( $($arg),+ )) )) + macro_rules! error ( + ($arg:expr) => ( + log(::core::error, fmt!( \"%?\", $arg )) + ); + ($( $arg:expr ),+) => ( + log(::core::error, fmt!( $($arg),+ )) + ) + ) + macro_rules! warn ( + ($arg:expr) => ( + log(::core::warn, fmt!( \"%?\", $arg )) + ); + ($( $arg:expr ),+) => ( + log(::core::warn, fmt!( $($arg),+ )) + ) + ) + macro_rules! info ( + ($arg:expr) => ( + log(::core::info, fmt!( \"%?\", $arg )) + ); + ($( $arg:expr ),+) => ( + log(::core::info, fmt!( $($arg),+ )) + ) + ) + macro_rules! debug ( + ($arg:expr) => ( + log(::core::debug, fmt!( \"%?\", $arg )) + ); + ($( $arg:expr ),+) => ( + log(::core::debug, fmt!( $($arg),+ )) + ) + ) macro_rules! fail( ($msg: expr) => ( diff --git a/src/test/run-pass/log-poly.rs b/src/test/run-pass/log-poly.rs new file mode 100644 index 0000000000000..3588016b8ba28 --- /dev/null +++ b/src/test/run-pass/log-poly.rs @@ -0,0 +1,10 @@ +enum Numbers { + Three +} + +fn main() { + debug!(1); + info!(2.0); + warn!(Three); + error!(~[4]); +} From cf9e958fe0b235b2d6cc39bfd0100adc0c46f62f Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Fri, 8 Mar 2013 12:34:43 -0500 Subject: [PATCH 02/43] rm obsolete iter-trait/option.rs file --- src/libcore/iter-trait/option.rs | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 src/libcore/iter-trait/option.rs diff --git a/src/libcore/iter-trait/option.rs b/src/libcore/iter-trait/option.rs deleted file mode 100644 index 986dbf7f3d186..0000000000000 --- a/src/libcore/iter-trait/option.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -mod inst { - use option::{None, Option, Some}; - - #[allow(non_camel_case_types)] - pub type IMPL_T = Option; - - #[inline(always)] - pub pure fn EACH(self: &IMPL_T, f: fn(v: &A) -> bool) { - match *self { - None => (), - Some(ref a) => { f(a); } - } - } - - #[inline(always)] - pub pure fn SIZE_HINT(self: &IMPL_T) -> Option { - match *self { - None => Some(0), - Some(_) => Some(1) - } - } -} From 8453f3110c7b84fe4a29c743b57f846fb5f654d3 Mon Sep 17 00:00:00 2001 From: Jed Davis Date: Sun, 10 Feb 2013 11:16:54 -0800 Subject: [PATCH 03/43] rust-mode.el uses the 'cl macros, so it should actually require them Without this change, rust-mode doesn't work if 'cl hasn't been required by something else, apparently. I'm not entirely sure what changed such that I started seeing this problem instead of not, but maybe the emacs world has been making progress towards not loading 'cl at runtime if it's only needed at compile time. --- src/etc/emacs/rust-mode.el | 1 + 1 file changed, 1 insertion(+) diff --git a/src/etc/emacs/rust-mode.el b/src/etc/emacs/rust-mode.el index 5a6acbaddda0a..f81f6bb618187 100644 --- a/src/etc/emacs/rust-mode.el +++ b/src/etc/emacs/rust-mode.el @@ -7,6 +7,7 @@ (require 'cm-mode) (require 'cc-mode) +(eval-when-compile (require 'cl)) (defun rust-electric-brace (arg) (interactive "*P") From b69fb75348b5aeb0988489d748373b1900f2766b Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Fri, 8 Mar 2013 18:19:30 -0500 Subject: [PATCH 04/43] implement BaseIter for dlist (removing iter-trait) Closes #2827 --- src/libcore/core.rc | 2 - src/libcore/dlist.rs | 44 +++++++++++++++- src/libcore/iter-trait.rs | 89 --------------------------------- src/libcore/iter-trait/dlist.rs | 59 ---------------------- 4 files changed, 43 insertions(+), 151 deletions(-) delete mode 100644 src/libcore/iter-trait.rs delete mode 100644 src/libcore/iter-trait/dlist.rs diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 79a5d297178e3..42312d96d1bec 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -142,8 +142,6 @@ pub mod option; pub mod result; pub mod either; pub mod dlist; -#[path="iter-trait.rs"] #[merge = "iter-trait/dlist.rs"] -pub mod dlist_iter; pub mod hashmap; pub mod cell; pub mod trie; diff --git a/src/libcore/dlist.rs b/src/libcore/dlist.rs index 5654d4b9c9b58..9cb872a0542a1 100644 --- a/src/libcore/dlist.rs +++ b/src/libcore/dlist.rs @@ -18,6 +18,8 @@ Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate. */ +use iter; +use iter::BaseIter; use kinds::Copy; use managed; use option::{None, Option, Some}; @@ -489,7 +491,7 @@ pub impl DList { let mut v = vec::with_capacity(self.size); unsafe { // Take this out of the unchecked when iter's functions are pure - for self.eachi |index,data| { + for iter::eachi(&self) |index,data| { v[index] = *data; } } @@ -497,6 +499,46 @@ pub impl DList { } } +impl BaseIter for @mut DList { + /** + * Iterates through the current contents. + * + * Attempts to access this dlist during iteration are allowed (to + * allow for e.g. breadth-first search with in-place enqueues), but + * removing the current node is forbidden. + */ + pure fn each(&self, f: fn(v: &T) -> bool) { + let mut link = self.peek_n(); + while option::is_some(&link) { + let nobe = option::get(link); + fail_unless!(nobe.linked); + + { + let frozen_nobe = &*nobe; + if !f(&frozen_nobe.data) { break; } + } + + // Check (weakly) that the user didn't do a remove. + if self.size == 0 { + fail!(~"The dlist became empty during iteration??") + } + if !nobe.linked || + (!((nobe.prev.is_some() + || managed::mut_ptr_eq(self.hd.expect(~"headless dlist?"), + nobe)) + && (nobe.next.is_some() + || managed::mut_ptr_eq(self.tl.expect(~"tailless dlist?"), + nobe)))) { + fail!(~"Removing a dlist node during iteration is forbidden!") + } + link = nobe.next_link(); + } + } + + #[inline(always)] + pure fn size_hint(&self) -> Option { Some(self.len()) } +} + #[cfg(test)] mod tests { use dlist::{DList, concat, from_vec, new_dlist_node}; diff --git a/src/libcore/iter-trait.rs b/src/libcore/iter-trait.rs deleted file mode 100644 index 7c4a99133bbdb..0000000000000 --- a/src/libcore/iter-trait.rs +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// This makes use of a clever hack that brson came up with to -// workaround our lack of traits and lack of macros. See core.{rc,rs} for -// how this file is used. - -use cmp::{Eq, Ord}; -use iter::BaseIter; -use iter; -use kinds::Copy; -use option::Option; - -use self::inst::{IMPL_T, EACH, SIZE_HINT}; - -impl iter::BaseIter for IMPL_T { - #[inline(always)] - pure fn each(&self, blk: fn(v: &A) -> bool) { EACH(self, blk) } - #[inline(always)] - pure fn size_hint(&self) -> Option { SIZE_HINT(self) } -} - -impl iter::ExtendedIter for IMPL_T { - #[inline(always)] - pure fn eachi(&self, blk: fn(uint, v: &A) -> bool) { - iter::eachi(self, blk) - } - #[inline(always)] - pure fn all(&self, blk: fn(&A) -> bool) -> bool { - iter::all(self, blk) - } - #[inline(always)] - pure fn any(&self, blk: fn(&A) -> bool) -> bool { - iter::any(self, blk) - } - #[inline(always)] - pure fn foldl(&self, b0: B, blk: fn(&B, &A) -> B) -> B { - iter::foldl(self, b0, blk) - } - #[inline(always)] - pure fn position(&self, f: fn(&A) -> bool) -> Option { - iter::position(self, f) - } - #[inline(always)] - pure fn map_to_vec(&self, op: fn(&A) -> B) -> ~[B] { - iter::map_to_vec(self, op) - } - #[inline(always)] - pure fn flat_map_to_vec>(&self, op: fn(&A) -> IB) - -> ~[B] { - iter::flat_map_to_vec(self, op) - } - -} - -impl iter::EqIter for IMPL_T { - #[inline(always)] - pure fn contains(&self, x: &A) -> bool { iter::contains(self, x) } - #[inline(always)] - pure fn count(&self, x: &A) -> uint { iter::count(self, x) } -} - -impl iter::CopyableIter for IMPL_T { - #[inline(always)] - pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { - iter::filter_to_vec(self, pred) - } - #[inline(always)] - pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) } - #[inline(always)] - pure fn find(&self, f: fn(&A) -> bool) -> Option { - iter::find(self, f) - } -} - -impl iter::CopyableOrderedIter for IMPL_T { - #[inline(always)] - pure fn min(&self) -> A { iter::min(self) } - #[inline(always)] - pure fn max(&self) -> A { iter::max(self) } -} - diff --git a/src/libcore/iter-trait/dlist.rs b/src/libcore/iter-trait/dlist.rs deleted file mode 100644 index 245c1db2bb4b8..0000000000000 --- a/src/libcore/iter-trait/dlist.rs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -mod inst { - use dlist::DList; - use managed; - use option::{Option, Some}; - use option; - - #[allow(non_camel_case_types)] - pub type IMPL_T = @mut DList; - - /** - * Iterates through the current contents. - * - * Attempts to access this dlist during iteration are allowed (to - * allow for e.g. breadth-first search with in-place enqueues), but - * removing the current node is forbidden. - */ - pub pure fn EACH(self: &IMPL_T, f: fn(v: &A) -> bool) { - let mut link = self.peek_n(); - while option::is_some(&link) { - let nobe = option::get(link); - fail_unless!(nobe.linked); - - { - let frozen_nobe = &*nobe; - if !f(&frozen_nobe.data) { break; } - } - - // Check (weakly) that the user didn't do a remove. - if self.size == 0 { - fail!(~"The dlist became empty during iteration??") - } - if !nobe.linked || - (!((nobe.prev.is_some() - || managed::mut_ptr_eq(self.hd.expect(~"headless dlist?"), - nobe)) - && (nobe.next.is_some() - || managed::mut_ptr_eq(self.tl.expect(~"tailless dlist?"), - nobe)))) { - fail!(~"Removing a dlist node during iteration is forbidden!") - } - link = nobe.next_link(); - } - } - - #[inline(always)] - pub pure fn SIZE_HINT(self: &IMPL_T) -> Option { - Some(self.len()) - } -} From fdf69dd7b0f0be63ea811e0e01f799f2e077d52d Mon Sep 17 00:00:00 2001 From: Ben Striegel Date: Fri, 8 Mar 2013 19:34:39 -0500 Subject: [PATCH 05/43] Finish de-implicit-selfing everything but the test suite --- src/libcore/core.rc | 1 + src/libfuzzer/fuzzer.rc | 1 + src/librust/rust.rc | 2 ++ src/librustc/middle/astencode.rs | 6 +++--- src/librustc/middle/liveness.rs | 2 +- src/librustc/middle/resolve.rs | 12 ++++++------ src/librustc/middle/typeck/check/method.rs | 5 +++-- src/librustc/middle/typeck/coherence.rs | 10 ++++------ src/librustc/middle/typeck/infer/mod.rs | 6 +++--- src/librustc/rustc.rc | 2 +- src/librustdoc/rustdoc.rc | 1 + src/librusti/rusti.rc | 1 + src/librustpkg/rustpkg.rc | 1 + 13 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 42312d96d1bec..4d686c8ab33a1 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -51,6 +51,7 @@ Implicitly, all crates behave as if they included the following prologue: #[warn(vecs_implicitly_copyable)]; #[deny(non_camel_case_types)]; #[allow(deprecated_mutable_fields)]; +#[deny(deprecated_self)]; // On Linux, link to the runtime with -lrt. #[cfg(target_os = "linux")] diff --git a/src/libfuzzer/fuzzer.rc b/src/libfuzzer/fuzzer.rc index 19afbc4b2b7ff..f21029a8a4f0f 100644 --- a/src/libfuzzer/fuzzer.rc +++ b/src/libfuzzer/fuzzer.rc @@ -25,6 +25,7 @@ #[allow(non_camel_case_types)]; #[allow(deprecated_mode)]; #[allow(deprecated_pattern)]; +#[deny(deprecated_self)]; extern mod core(vers = "0.6"); extern mod std(vers = "0.6"); diff --git a/src/librust/rust.rc b/src/librust/rust.rc index 023383b3dccc8..082861e0ae01f 100644 --- a/src/librust/rust.rc +++ b/src/librust/rust.rc @@ -12,6 +12,8 @@ // XXX: Make commands run and test emit proper file endings on winds // XXX: Make run only accept source that emits an executable +#[deny(deprecated_self)]; + #[link(name = "rust", vers = "0.6", uuid = "4a24da33-5cc8-4037-9352-2cbe9bd9d27c", diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 6f0bfbb197fac..48fddec00797a 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -721,12 +721,12 @@ impl vtable_decoder_helpers for reader::Decoder { // Encoding and decoding the side tables trait get_ty_str_ctxt { - fn ty_str_ctxt() -> @tyencode::ctxt; + fn ty_str_ctxt(@self) -> @tyencode::ctxt; } -impl get_ty_str_ctxt for @e::EncodeContext { +impl get_ty_str_ctxt for e::EncodeContext { // IMPLICIT SELF WARNING: fix this! - fn ty_str_ctxt() -> @tyencode::ctxt { + fn ty_str_ctxt(@self) -> @tyencode::ctxt { @tyencode::ctxt {diag: self.tcx.sess.diagnostic(), ds: e::def_to_str, tcx: self.tcx, diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index f0c06ceca989c..068327dc74167 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -816,7 +816,7 @@ pub impl Liveness { } } - fn indices2(ln: LiveNode, succ_ln: LiveNode, + fn indices2(&self, ln: LiveNode, succ_ln: LiveNode, op: fn(uint, uint)) { let node_base_idx = self.idx(ln, Variable(0u)); let succ_base_idx = self.idx(succ_ln, Variable(0u)); diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 391990eed95de..d1e35f7a19df2 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -592,7 +592,7 @@ pub impl NameBindings { } /// Returns the module node if applicable. - fn get_module_if_available() -> Option<@mut Module> { + fn get_module_if_available(&self) -> Option<@mut Module> { match self.type_def { Some(ref type_def) => (*type_def).module_def, None => None @@ -613,14 +613,14 @@ pub impl NameBindings { } } - fn defined_in_namespace(namespace: Namespace) -> bool { + fn defined_in_namespace(&self, namespace: Namespace) -> bool { match namespace { TypeNS => return self.type_def.is_some(), ValueNS => return self.value_def.is_some() } } - fn defined_in_public_namespace(namespace: Namespace) -> bool { + fn defined_in_public_namespace(&self, namespace: Namespace) -> bool { match namespace { TypeNS => match self.type_def { Some(def) => def.privacy != Private, @@ -633,7 +633,7 @@ pub impl NameBindings { } } - fn def_for_namespace(namespace: Namespace) -> Option { + fn def_for_namespace(&self, namespace: Namespace) -> Option { match namespace { TypeNS => { match self.type_def { @@ -666,7 +666,7 @@ pub impl NameBindings { } } - fn privacy_for_namespace(namespace: Namespace) -> Option { + fn privacy_for_namespace(&self, namespace: Namespace) -> Option { match namespace { TypeNS => { match self.type_def { @@ -683,7 +683,7 @@ pub impl NameBindings { } } - fn span_for_namespace(namespace: Namespace) -> Option { + fn span_for_namespace(&self, namespace: Namespace) -> Option { if self.defined_in_namespace(namespace) { match namespace { TypeNS => self.type_span, diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 0bcbb3012cf10..3395d9b445146 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -235,7 +235,8 @@ pub impl LookupContext/&self { self.search_for_autosliced_method(self_ty, autoderefs) } - fn deref(ty: ty::t, enum_dids: &mut ~[ast::def_id]) -> Option { + fn deref(&self, ty: ty::t, enum_dids: &mut ~[ast::def_id]) + -> Option { match ty::get(ty).sty { ty_enum(did, _) => { // Watch out for newtype'd enums like "enum t = @T". @@ -599,7 +600,7 @@ pub impl LookupContext/&self { } } - fn push_inherent_impl_candidates_for_type(did: def_id) { + fn push_inherent_impl_candidates_for_type(&self, did: def_id) { let opt_impl_infos = self.fcx.ccx.coherence_info.inherent_methods.find(&did); for opt_impl_infos.each |impl_infos| { diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 3e45323807212..00352ba29582a 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -191,15 +191,14 @@ pub struct CoherenceChecker { } pub impl CoherenceChecker { - // IMPLICIT SELF WARNING: fix this! - fn check_coherence(crate: @crate) { + fn check_coherence(self, crate: @crate) { // Check implementations and traits. This populates the tables // containing the inherent methods and extension methods. It also // builds up the trait inheritance table. visit_crate(*crate, (), mk_simple_visitor(@SimpleVisitor { visit_item: |item| { - debug!("(checking coherence) item '%s'", - *self.crate_context.tcx.sess.str_of(item.ident)); +// debug!("(checking coherence) item '%s'", +// self.crate_context.tcx.sess.str_of(item.ident)); match item.node { item_impl(_, opt_trait, _, _) => { @@ -617,8 +616,7 @@ pub impl CoherenceChecker { } // Privileged scope checking - // IMPLICIT SELF WARNING: fix this! - fn check_privileged_scopes(crate: @crate) { + fn check_privileged_scopes(self, crate: @crate) { visit_crate(*crate, (), mk_vt(@Visitor { visit_item: |item, _context, visitor| { match /*bad*/copy item.node { diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index 9cb6c473d586b..a334ba57e6e04 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -584,7 +584,7 @@ pub impl @mut InferCtxt { } /// Execute `f` and commit the bindings if successful - fn commit(f: fn() -> Result) -> Result { + fn commit(&self, f: fn() -> Result) -> Result { fail_unless!(!self.in_snapshot()); debug!("commit()"); @@ -599,7 +599,7 @@ pub impl @mut InferCtxt { } /// Execute `f`, unroll bindings on failure - fn try(f: fn() -> Result) -> Result { + fn try(&self, f: fn() -> Result) -> Result { debug!("try()"); do indent { let snapshot = self.start_snapshot(); @@ -613,7 +613,7 @@ pub impl @mut InferCtxt { } /// Execute `f` then unroll any bindings it creates - fn probe(f: fn() -> Result) -> Result { + fn probe(&self, f: fn() -> Result) -> Result { debug!("probe()"); do indent { let snapshot = self.start_snapshot(); diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index 355ecaed7d7e0..296c94f3299cb 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -24,7 +24,7 @@ #[allow(non_camel_case_types)]; #[allow(deprecated_mode)]; #[warn(deprecated_pattern)]; -#[allow(deprecated_self)]; +#[deny(deprecated_self)]; #[no_core]; diff --git a/src/librustdoc/rustdoc.rc b/src/librustdoc/rustdoc.rc index 9bd78e54b78be..f17f7ffd9cf4a 100644 --- a/src/librustdoc/rustdoc.rc +++ b/src/librustdoc/rustdoc.rc @@ -22,6 +22,7 @@ #[no_core]; #[allow(non_implicitly_copyable_typarams)]; +#[deny(deprecated_self)]; extern mod core(vers = "0.6"); extern mod std(vers = "0.6"); diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index 3e1b0c03bd702..6674885a6e28a 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -22,6 +22,7 @@ #[allow(vecs_implicitly_copyable, non_implicitly_copyable_typarams)]; +#[deny(deprecated_self)]; extern mod core(vers = "0.6"); extern mod std(vers = "0.6"); diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rc index 0f8463b0b3c93..5b9f3c3cd229e 100644 --- a/src/librustpkg/rustpkg.rc +++ b/src/librustpkg/rustpkg.rc @@ -20,6 +20,7 @@ #[no_core]; #[allow(vecs_implicitly_copyable, non_implicitly_copyable_typarams)]; +#[deny(deprecated_self)]; extern mod core(vers = "0.6"); extern mod std(vers = "0.6"); From bef5396af68b5a7d181bef70a920a910416d9094 Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Sat, 9 Mar 2013 12:14:12 -0500 Subject: [PATCH 06/43] core: implement Clone for primitive types --- src/libcore/clone.rs | 28 ++++++++++++++++++++++ src/test/run-pass/deriving-clone-struct.rs | 22 ++++++++++++++--- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index 6580ce55ddd66..297c4438039f0 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -19,3 +19,31 @@ impl Clone for () { #[inline(always)] fn clone(&self) -> () { () } } + +macro_rules! clone_impl( + ($t:ty) => { + impl Clone for $t { + #[inline(always)] + fn clone(&self) -> $t { *self } + } + } +) + +clone_impl!(int) +clone_impl!(i8) +clone_impl!(i16) +clone_impl!(i32) +clone_impl!(i64) + +clone_impl!(uint) +clone_impl!(u8) +clone_impl!(u16) +clone_impl!(u32) +clone_impl!(u64) + +clone_impl!(float) +clone_impl!(f32) +clone_impl!(f64) + +clone_impl!(bool) +clone_impl!(char) diff --git a/src/test/run-pass/deriving-clone-struct.rs b/src/test/run-pass/deriving-clone-struct.rs index 2f371c8920be5..07830e7ee096b 100644 --- a/src/test/run-pass/deriving-clone-struct.rs +++ b/src/test/run-pass/deriving-clone-struct.rs @@ -1,8 +1,24 @@ #[deriving_clone] struct S { - foo: (), - bar: () + _int: int, + _i8: i8, + _i16: i16, + _i32: i32, + _i64: i64, + + _uint: uint, + _u8: u8, + _u16: u16, + _u32: u32, + _u64: u64, + + _float: float, + _f32: f32, + _f64: f64, + + _bool: bool, + _char: char, + _nil: () } fn main() {} - From 78b6e375dfd9b1b80bde0881a39501186e82999f Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Thu, 7 Mar 2013 06:53:46 -0500 Subject: [PATCH 07/43] kate: add Not to list of traits --- src/etc/kate/rust.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/etc/kate/rust.xml b/src/etc/kate/rust.xml index 0359a56f7c184..35b54f4982846 100644 --- a/src/etc/kate/rust.xml +++ b/src/etc/kate/rust.xml @@ -69,6 +69,7 @@ Shl Shr Index + Not bool From b4f57d46e66c98e571e869926cb9a7466d412e54 Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Thu, 7 Mar 2013 06:54:22 -0500 Subject: [PATCH 08/43] kate: remove assert keyword --- src/etc/kate/rust.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/etc/kate/rust.xml b/src/etc/kate/rust.xml index 35b54f4982846..1551cebcf02c2 100644 --- a/src/etc/kate/rust.xml +++ b/src/etc/kate/rust.xml @@ -17,7 +17,6 @@ as - assert break const copy From 06a336ae791ea8a8e618ff43a97b1e6e510c6601 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 9 Mar 2013 16:23:25 -0500 Subject: [PATCH 09/43] vec: renovate the BaseIter impl * add 'self region to the borrowed pointer parameter * rm workaround for #2263 * inline (wrappers) * iter-trait is gone --- src/libcore/vec.rs | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 365de1ac3e2b9..6bcf396a15045 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -2268,45 +2268,27 @@ pub mod bytes { // ___________________________________________________________________________ // ITERATION TRAIT METHODS -// -// This cannot be used with iter-trait.rs because of the region pointer -// required in the slice. impl iter::BaseIter for &self/[A] { - pub pure fn each(&self, blk: fn(v: &A) -> bool) { - // FIXME(#2263)---should be able to call each(self, blk) - for each(*self) |e| { - if (!blk(e)) { - return; - } - } - } + #[inline(always)] + pure fn each(&self, blk: fn(v: &'self A) -> bool) { each(*self, blk) } + #[inline(always)] pure fn size_hint(&self) -> Option { Some(len(*self)) } } // FIXME(#4148): This should be redundant impl iter::BaseIter for ~[A] { - pub pure fn each(&self, blk: fn(v: &A) -> bool) { - // FIXME(#2263)---should be able to call each(self, blk) - for each(*self) |e| { - if (!blk(e)) { - return; - } - } - } + #[inline(always)] + pure fn each(&self, blk: fn(v: &'self A) -> bool) { each(*self, blk) } + #[inline(always)] pure fn size_hint(&self) -> Option { Some(len(*self)) } } // FIXME(#4148): This should be redundant impl iter::BaseIter for @[A] { - pub pure fn each(&self, blk: fn(v: &A) -> bool) { - // FIXME(#2263)---should be able to call each(self, blk) - for each(*self) |e| { - if (!blk(e)) { - return; - } - } - } + #[inline(always)] + pure fn each(&self, blk: fn(v: &'self A) -> bool) { each(*self, blk) } + #[inline(always)] pure fn size_hint(&self) -> Option { Some(len(*self)) } } From 788de758e39f0ba1281c6244c10ce5701c436c33 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sat, 9 Mar 2013 16:41:43 -0500 Subject: [PATCH 10/43] vec: cleanup --- src/libcore/vec.rs | 437 ++++++++++++++++++++++----------------------- 1 file changed, 218 insertions(+), 219 deletions(-) diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 6bcf396a15045..655db1c83d063 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -53,7 +53,7 @@ pub pure fn is_empty(v: &[const T]) -> bool { /// Returns true if two vectors have the same length pub pure fn same_length(xs: &[const T], ys: &[const U]) -> bool { - len(xs) == len(ys) + xs.len() == ys.len() } /** @@ -136,7 +136,7 @@ pub pure fn from_fn(n_elts: uint, op: iter::InitOp) -> ~[T] { } } raw::set_len(&mut v, n_elts); - return v; + v } } @@ -158,7 +158,7 @@ pub pure fn from_slice(t: &[T]) -> ~[T] { pub pure fn with_capacity(capacity: uint) -> ~[T] { let mut vec = ~[]; unsafe { reserve(&mut vec, capacity); } - return vec; + vec } /** @@ -257,8 +257,8 @@ pub pure fn last_opt(v: &r/[T]) -> Option<&r/T> { /// Return a slice that points into another slice. #[inline(always)] pub pure fn slice(v: &r/[T], start: uint, end: uint) -> &r/[T] { - fail_unless!((start <= end)); - fail_unless!((end <= len(v))); + fail_unless!(start <= end); + fail_unless!(end <= len(v)); do as_imm_buf(v) |p, _len| { unsafe { ::cast::reinterpret_cast( @@ -274,8 +274,8 @@ pub pure fn mut_slice(v: &r/mut [T], start: uint, end: uint) -> &r/mut [T] { - fail_unless!((start <= end)); - fail_unless!((end <= len(v))); + fail_unless!(start <= end); + fail_unless!(end <= v.len()); do as_mut_buf(v) |p, _len| { unsafe { ::cast::reinterpret_cast( @@ -291,8 +291,8 @@ pub pure fn const_slice(v: &r/[const T], start: uint, end: uint) -> &r/[const T] { - fail_unless!((start <= end)); - fail_unless!((end <= len(v))); + fail_unless!(start <= end); + fail_unless!(end <= len(v)); do as_const_buf(v) |p, _len| { unsafe { ::cast::reinterpret_cast( @@ -371,7 +371,7 @@ pub fn rsplit(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { } result.push(slice(v, 0u, end).to_vec()); reverse(result); - return result; + result } /** @@ -496,7 +496,7 @@ pub fn shift(v: &mut ~[T]) -> T { let vp = ptr::mut_offset(vp, next_ln - 1); *vp <-> work_elt; - return work_elt; + work_elt } } @@ -584,7 +584,7 @@ pub fn swap_remove(v: &mut ~[T], index: uint) -> T { if index < ln - 1 { v[index] <-> v[ln - 1]; } - vec::pop(v) + v.pop() } /// Append an element to a vector @@ -650,7 +650,7 @@ pub fn push_all_move(v: &mut ~[T], mut rhs: ~[T]) { /// Shorten a vector, dropping excess elements. pub fn truncate(v: &mut ~[T], newlen: uint) { do as_mut_buf(*v) |p, oldlen| { - fail_unless!((newlen <= oldlen)); + fail_unless!(newlen <= oldlen); unsafe { // This loop is optimized out for non-drop types. for uint::range(newlen, oldlen) |i| { @@ -973,7 +973,7 @@ pub pure fn foldl(z: T, v: &[U], p: fn(t: T, u: &U) -> T) -> T { accum = p(accum, &v[i]); i += 1; } - return accum; + accum } /** @@ -1000,7 +1000,7 @@ pub pure fn foldr(v: &[T], z: U, p: fn(t: &T, u: U) -> U) -> U { for rev_each(v) |elt| { accum = p(elt, accum); } - return accum; + accum } /** @@ -1010,7 +1010,7 @@ pub pure fn foldr(v: &[T], z: U, p: fn(t: &T, u: U) -> U) -> U { */ pub pure fn any(v: &[T], f: fn(t: &T) -> bool) -> bool { for each(v) |elem| { if f(elem) { return true; } } - return false; + false } /** @@ -1027,7 +1027,7 @@ pub pure fn any2(v0: &[T], v1: &[U], if f(&v0[i], &v1[i]) { return true; }; i += 1u; } - return false; + false } /** @@ -1037,7 +1037,7 @@ pub pure fn any2(v0: &[T], v1: &[U], */ pub pure fn all(v: &[T], f: fn(t: &T) -> bool) -> bool { for each(v) |elem| { if !f(elem) { return false; } } - return true; + true } /** @@ -1047,7 +1047,7 @@ pub pure fn all(v: &[T], f: fn(t: &T) -> bool) -> bool { */ pub pure fn alli(v: &[T], f: fn(uint, t: &T) -> bool) -> bool { for eachi(v) |i, elem| { if !f(i, elem) { return false; } } - return true; + true } /** @@ -1061,20 +1061,20 @@ pub pure fn all2(v0: &[T], v1: &[U], if v0_len != len(v1) { return false; } let mut i = 0u; while i < v0_len { if !f(&v0[i], &v1[i]) { return false; }; i += 1u; } - return true; + true } /// Return true if a vector contains an element with the given value pub pure fn contains(v: &[T], x: &T) -> bool { for each(v) |elt| { if *x == *elt { return true; } } - return false; + false } /// Returns the number of elements that are equal to a given value pub pure fn count(v: &[T], x: &T) -> uint { let mut cnt = 0u; for each(v) |elt| { if *x == *elt { cnt += 1u; } } - return cnt; + cnt } /** @@ -1152,7 +1152,7 @@ pub pure fn position_between(v: &[T], start: uint, end: uint, fail_unless!(end <= len(v)); let mut i = start; while i < end { if f(&v[i]) { return Some::(i); } i += 1u; } - return None; + None } /// Find the last index containing a matching value @@ -1188,7 +1188,7 @@ pub pure fn rposition_between(v: &[T], start: uint, end: uint, if f(&v[i - 1u]) { return Some::(i - 1u); } i -= 1u; } - return None; + None } // FIXME: if issue #586 gets implemented, could have a postcondition @@ -1207,7 +1207,7 @@ pure fn unzip_slice(v: &[(T, U)]) -> (~[T], ~[U]) { us.push(u); } } - return (ts, us); + (ts, us) } /** @@ -1478,7 +1478,7 @@ pub pure fn windowed(nn: uint, xx: &[TT]) -> ~[~[TT]] { let mut ww = ~[]; fail_unless!(1u <= nn); for vec::eachi (xx) |ii, _x| { - let len = vec::len(xx); + let len = xx.len(); if ii+nn <= len { unsafe { ww.push(slice(xx, ii, ii+nn).to_vec()); @@ -1551,7 +1551,7 @@ pure fn eq(a: &[T], b: &[T]) -> bool { i += 1; } - return true; + true } #[cfg(notest)] @@ -1631,7 +1631,7 @@ pure fn lt(a: &[T], b: &[T]) -> bool { i += 1; } - return a_len < b_len; + a_len < b_len } pure fn le(a: &[T], b: &[T]) -> bool { !lt(b, a) } @@ -2114,21 +2114,21 @@ pub mod raw { #[inline(always)] pub unsafe fn to_ptr(v: &[T]) -> *T { let repr: **SliceRepr = ::cast::transmute(&v); - return ::cast::reinterpret_cast(&addr_of(&((**repr).data))); + ::cast::reinterpret_cast(&addr_of(&((**repr).data))) } /** see `to_ptr()` */ #[inline(always)] pub unsafe fn to_const_ptr(v: &[const T]) -> *const T { let repr: **SliceRepr = ::cast::transmute(&v); - return ::cast::reinterpret_cast(&addr_of(&((**repr).data))); + ::cast::reinterpret_cast(&addr_of(&((**repr).data))) } /** see `to_ptr()` */ #[inline(always)] pub unsafe fn to_mut_ptr(v: &mut [T]) -> *mut T { let repr: **SliceRepr = ::cast::transmute(&v); - return ::cast::reinterpret_cast(&addr_of(&((**repr).data))); + ::cast::reinterpret_cast(&addr_of(&((**repr).data))) } /** @@ -2165,7 +2165,7 @@ pub mod raw { let mut box2 = None; box2 <-> box; intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), - option::unwrap(box2)); + box2.unwrap()); } } @@ -2210,14 +2210,13 @@ pub mod raw { pub mod bytes { use libc; use uint; - use vec::len; use vec::raw; use vec; /// Bytewise string comparison pub pure fn memcmp(a: &~[u8], b: &~[u8]) -> int { - let a_len = len(*a); - let b_len = len(*b); + let a_len = a.len(); + let b_len = b.len(); let n = uint::min(a_len, b_len) as libc::size_t; let r = unsafe { libc::memcmp(raw::to_ptr(*a) as *libc::c_void, @@ -2273,7 +2272,7 @@ impl iter::BaseIter for &self/[A] { #[inline(always)] pure fn each(&self, blk: fn(v: &'self A) -> bool) { each(*self, blk) } #[inline(always)] - pure fn size_hint(&self) -> Option { Some(len(*self)) } + pure fn size_hint(&self) -> Option { Some(self.len()) } } // FIXME(#4148): This should be redundant @@ -2281,7 +2280,7 @@ impl iter::BaseIter for ~[A] { #[inline(always)] pure fn each(&self, blk: fn(v: &'self A) -> bool) { each(*self, blk) } #[inline(always)] - pure fn size_hint(&self) -> Option { Some(len(*self)) } + pure fn size_hint(&self) -> Option { Some(self.len()) } } // FIXME(#4148): This should be redundant @@ -2289,7 +2288,7 @@ impl iter::BaseIter for @[A] { #[inline(always)] pure fn each(&self, blk: fn(v: &'self A) -> bool) { each(*self, blk) } #[inline(always)] - pure fn size_hint(&self) -> Option { Some(len(*self)) } + pure fn size_hint(&self) -> Option { Some(self.len()) } } impl iter::ExtendedIter for &self/[A] { @@ -2477,25 +2476,25 @@ mod tests { use vec::*; use cmp::*; - fn square(n: uint) -> uint { return n * n; } + fn square(n: uint) -> uint { n * n } - fn square_ref(n: &uint) -> uint { return square(*n); } + fn square_ref(n: &uint) -> uint { square(*n) } - pure fn is_three(n: &uint) -> bool { return *n == 3u; } + pure fn is_three(n: &uint) -> bool { *n == 3u } - pure fn is_odd(n: &uint) -> bool { return *n % 2u == 1u; } + pure fn is_odd(n: &uint) -> bool { *n % 2u == 1u } - pure fn is_equal(x: &uint, y:&uint) -> bool { return *x == *y; } + pure fn is_equal(x: &uint, y:&uint) -> bool { *x == *y } fn square_if_odd_r(n: &uint) -> Option { - return if *n % 2u == 1u { Some(*n * *n) } else { None }; + if *n % 2u == 1u { Some(*n * *n) } else { None } } fn square_if_odd_v(n: uint) -> Option { - return if n % 2u == 1u { Some(n * n) } else { None }; + if n % 2u == 1u { Some(n * n) } else { None } } - fn add(x: uint, y: &uint) -> uint { return x + *y; } + fn add(x: uint, y: &uint) -> uint { x + *y } #[test] fn test_unsafe_ptrs() { @@ -2504,21 +2503,21 @@ mod tests { let a = ~[1, 2, 3]; let mut ptr = raw::to_ptr(a); let b = from_buf(ptr, 3u); - fail_unless!((len(b) == 3u)); - fail_unless!((b[0] == 1)); - fail_unless!((b[1] == 2)); - fail_unless!((b[2] == 3)); + fail_unless!(b.len() == 3u); + fail_unless!(b[0] == 1); + fail_unless!(b[1] == 2); + fail_unless!(b[2] == 3); // Test on-heap copy-from-buf. let c = ~[1, 2, 3, 4, 5]; ptr = raw::to_ptr(c); let d = from_buf(ptr, 5u); - fail_unless!((len(d) == 5u)); - fail_unless!((d[0] == 1)); - fail_unless!((d[1] == 2)); - fail_unless!((d[2] == 3)); - fail_unless!((d[3] == 4)); - fail_unless!((d[4] == 5)); + fail_unless!(d.len() == 5u); + fail_unless!(d[0] == 1); + fail_unless!(d[1] == 2); + fail_unless!(d[2] == 3); + fail_unless!(d[3] == 4); + fail_unless!(d[4] == 5); } } @@ -2526,43 +2525,43 @@ mod tests { fn test_from_fn() { // Test on-stack from_fn. let mut v = from_fn(3u, square); - fail_unless!((len(v) == 3u)); - fail_unless!((v[0] == 0u)); - fail_unless!((v[1] == 1u)); - fail_unless!((v[2] == 4u)); + fail_unless!(v.len() == 3u); + fail_unless!(v[0] == 0u); + fail_unless!(v[1] == 1u); + fail_unless!(v[2] == 4u); // Test on-heap from_fn. v = from_fn(5u, square); - fail_unless!((len(v) == 5u)); - fail_unless!((v[0] == 0u)); - fail_unless!((v[1] == 1u)); - fail_unless!((v[2] == 4u)); - fail_unless!((v[3] == 9u)); - fail_unless!((v[4] == 16u)); + fail_unless!(v.len() == 5u); + fail_unless!(v[0] == 0u); + fail_unless!(v[1] == 1u); + fail_unless!(v[2] == 4u); + fail_unless!(v[3] == 9u); + fail_unless!(v[4] == 16u); } #[test] fn test_from_elem() { // Test on-stack from_elem. let mut v = from_elem(2u, 10u); - fail_unless!((len(v) == 2u)); - fail_unless!((v[0] == 10u)); - fail_unless!((v[1] == 10u)); + fail_unless!(v.len() == 2u); + fail_unless!(v[0] == 10u); + fail_unless!(v[1] == 10u); // Test on-heap from_elem. v = from_elem(6u, 20u); - fail_unless!((v[0] == 20u)); - fail_unless!((v[1] == 20u)); - fail_unless!((v[2] == 20u)); - fail_unless!((v[3] == 20u)); - fail_unless!((v[4] == 20u)); - fail_unless!((v[5] == 20u)); + fail_unless!(v[0] == 20u); + fail_unless!(v[1] == 20u); + fail_unless!(v[2] == 20u); + fail_unless!(v[3] == 20u); + fail_unless!(v[4] == 20u); + fail_unless!(v[5] == 20u); } #[test] fn test_is_empty() { - fail_unless!((is_empty::(~[]))); - fail_unless!((!is_empty(~[0]))); + fail_unless!(is_empty::(~[])); + fail_unless!(!is_empty(~[0])); } #[test] @@ -2571,10 +2570,10 @@ mod tests { let v0 : &[Z] = &[]; let v1 : &[Z] = &[[]]; let v2 : &[Z] = &[[], []]; - fail_unless!((sys::size_of::() == 0)); - fail_unless!((len(v0) == 0)); - fail_unless!((len(v1) == 1)); - fail_unless!((len(v2) == 2)); + fail_unless!(sys::size_of::() == 0); + fail_unless!(v0.len() == 0); + fail_unless!(v1.len() == 1); + fail_unless!(v2.len() == 2); } #[test] @@ -2696,36 +2695,36 @@ mod tests { fn test_slice() { // Test fixed length vector. let vec_fixed = [1, 2, 3, 4]; - let v_a = slice(vec_fixed, 1u, len(vec_fixed)).to_vec(); - fail_unless!((len(v_a) == 3u)); - fail_unless!((v_a[0] == 2)); - fail_unless!((v_a[1] == 3)); - fail_unless!((v_a[2] == 4)); + let v_a = slice(vec_fixed, 1u, vec_fixed.len()).to_vec(); + fail_unless!(v_a.len() == 3u); + fail_unless!(v_a[0] == 2); + fail_unless!(v_a[1] == 3); + fail_unless!(v_a[2] == 4); // Test on stack. let vec_stack = &[1, 2, 3]; let v_b = slice(vec_stack, 1u, 3u).to_vec(); - fail_unless!((len(v_b) == 2u)); - fail_unless!((v_b[0] == 2)); - fail_unless!((v_b[1] == 3)); + fail_unless!(v_b.len() == 2u); + fail_unless!(v_b[0] == 2); + fail_unless!(v_b[1] == 3); // Test on managed heap. let vec_managed = @[1, 2, 3, 4, 5]; let v_c = slice(vec_managed, 0u, 3u).to_vec(); - fail_unless!((len(v_c) == 3u)); - fail_unless!((v_c[0] == 1)); - fail_unless!((v_c[1] == 2)); - fail_unless!((v_c[2] == 3)); + fail_unless!(v_c.len() == 3u); + fail_unless!(v_c[0] == 1); + fail_unless!(v_c[1] == 2); + fail_unless!(v_c[2] == 3); // Test on exchange heap. let vec_unique = ~[1, 2, 3, 4, 5, 6]; let v_d = slice(vec_unique, 1u, 6u).to_vec(); - fail_unless!((len(v_d) == 5u)); - fail_unless!((v_d[0] == 2)); - fail_unless!((v_d[1] == 3)); - fail_unless!((v_d[2] == 4)); - fail_unless!((v_d[3] == 5)); - fail_unless!((v_d[4] == 6)); + fail_unless!(v_d.len() == 5u); + fail_unless!(v_d[0] == 2); + fail_unless!(v_d[1] == 3); + fail_unless!(v_d[2] == 4); + fail_unless!(v_d[3] == 5); + fail_unless!(v_d[4] == 6); } #[test] @@ -2733,27 +2732,27 @@ mod tests { // Test on-heap pop. let mut v = ~[1, 2, 3, 4, 5]; let e = v.pop(); - fail_unless!((len(v) == 4u)); - fail_unless!((v[0] == 1)); - fail_unless!((v[1] == 2)); - fail_unless!((v[2] == 3)); - fail_unless!((v[3] == 4)); - fail_unless!((e == 5)); + fail_unless!(v.len() == 4u); + fail_unless!(v[0] == 1); + fail_unless!(v[1] == 2); + fail_unless!(v[2] == 3); + fail_unless!(v[3] == 4); + fail_unless!(e == 5); } #[test] fn test_swap_remove() { let mut v = ~[1, 2, 3, 4, 5]; let mut e = v.swap_remove(0); - fail_unless!((len(v) == 4)); + fail_unless!(v.len() == 4); fail_unless!(e == 1); - fail_unless!((v[0] == 5)); + fail_unless!(v[0] == 5); e = v.swap_remove(3); - fail_unless!((len(v) == 3)); + fail_unless!(v.len() == 3); fail_unless!(e == 4); - fail_unless!((v[0] == 5)); - fail_unless!((v[1] == 2)); - fail_unless!((v[2] == 3)); + fail_unless!(v[0] == 5); + fail_unless!(v[1] == 2); + fail_unless!(v[2] == 3); } #[test] @@ -2762,11 +2761,11 @@ mod tests { let mut v = ~[::unstable::exclusive(()), ::unstable::exclusive(()), ::unstable::exclusive(())]; let mut _e = v.swap_remove(0); - fail_unless!((len(v) == 2)); + fail_unless!(v.len() == 2); _e = v.swap_remove(1); - fail_unless!((len(v) == 1)); + fail_unless!(v.len() == 1); _e = v.swap_remove(0); - fail_unless!((len(v) == 0)); + fail_unless!(v.len() == 0); } #[test] @@ -2774,14 +2773,14 @@ mod tests { // Test on-stack push(). let mut v = ~[]; v.push(1); - fail_unless!((len(v) == 1u)); - fail_unless!((v[0] == 1)); + fail_unless!(v.len() == 1u); + fail_unless!(v[0] == 1); // Test on-heap push(). v.push(2); - fail_unless!((len(v) == 2u)); - fail_unless!((v[0] == 1)); - fail_unless!((v[1] == 2)); + fail_unless!(v.len() == 2u); + fail_unless!(v[0] == 1); + fail_unless!(v[1] == 2); } #[test] @@ -2789,48 +2788,48 @@ mod tests { // Test on-stack grow(). let mut v = ~[]; v.grow(2u, &1); - fail_unless!((len(v) == 2u)); - fail_unless!((v[0] == 1)); - fail_unless!((v[1] == 1)); + fail_unless!(v.len() == 2u); + fail_unless!(v[0] == 1); + fail_unless!(v[1] == 1); // Test on-heap grow(). v.grow(3u, &2); - fail_unless!((len(v) == 5u)); - fail_unless!((v[0] == 1)); - fail_unless!((v[1] == 1)); - fail_unless!((v[2] == 2)); - fail_unless!((v[3] == 2)); - fail_unless!((v[4] == 2)); + fail_unless!(v.len() == 5u); + fail_unless!(v[0] == 1); + fail_unless!(v[1] == 1); + fail_unless!(v[2] == 2); + fail_unless!(v[3] == 2); + fail_unless!(v[4] == 2); } #[test] fn test_grow_fn() { let mut v = ~[]; v.grow_fn(3u, square); - fail_unless!((len(v) == 3u)); - fail_unless!((v[0] == 0u)); - fail_unless!((v[1] == 1u)); - fail_unless!((v[2] == 4u)); + fail_unless!(v.len() == 3u); + fail_unless!(v[0] == 0u); + fail_unless!(v[1] == 1u); + fail_unless!(v[2] == 4u); } #[test] fn test_grow_set() { let mut v = ~[1, 2, 3]; v.grow_set(4u, &4, 5); - fail_unless!((len(v) == 5u)); - fail_unless!((v[0] == 1)); - fail_unless!((v[1] == 2)); - fail_unless!((v[2] == 3)); - fail_unless!((v[3] == 4)); - fail_unless!((v[4] == 5)); + fail_unless!(v.len() == 5u); + fail_unless!(v[0] == 1); + fail_unless!(v[1] == 2); + fail_unless!(v[2] == 3); + fail_unless!(v[3] == 4); + fail_unless!(v[4] == 5); } #[test] fn test_truncate() { let mut v = ~[@6,@5,@4]; v.truncate(1); - fail_unless!((v.len() == 1)); - fail_unless!((*(v[0]) == 6)); + fail_unless!(v.len() == 1); + fail_unless!(*(v[0]) == 6); // If the unsafe block didn't drop things properly, we blow up here. } @@ -2838,7 +2837,7 @@ mod tests { fn test_clear() { let mut v = ~[@6,@5,@4]; v.clear(); - fail_unless!((v.len() == 0)); + fail_unless!(v.len() == 0); // If the unsafe block didn't drop things properly, we blow up here. } @@ -2847,7 +2846,7 @@ mod tests { fn case(a: ~[uint], b: ~[uint]) { let mut v = a; v.dedup(); - fail_unless!((v == b)); + fail_unless!(v == b); } case(~[], ~[]); case(~[1], ~[1]); @@ -2892,31 +2891,31 @@ mod tests { // Test on-stack map. let mut v = ~[1u, 2u, 3u]; let mut w = map(v, square_ref); - fail_unless!((len(w) == 3u)); - fail_unless!((w[0] == 1u)); - fail_unless!((w[1] == 4u)); - fail_unless!((w[2] == 9u)); + fail_unless!(w.len() == 3u); + fail_unless!(w[0] == 1u); + fail_unless!(w[1] == 4u); + fail_unless!(w[2] == 9u); // Test on-heap map. v = ~[1u, 2u, 3u, 4u, 5u]; w = map(v, square_ref); - fail_unless!((len(w) == 5u)); - fail_unless!((w[0] == 1u)); - fail_unless!((w[1] == 4u)); - fail_unless!((w[2] == 9u)); - fail_unless!((w[3] == 16u)); - fail_unless!((w[4] == 25u)); + fail_unless!(w.len() == 5u); + fail_unless!(w[0] == 1u); + fail_unless!(w[1] == 4u); + fail_unless!(w[2] == 9u); + fail_unless!(w[3] == 16u); + fail_unless!(w[4] == 25u); } #[test] fn test_map2() { - fn times(x: &int, y: &int) -> int { return *x * *y; } + fn times(x: &int, y: &int) -> int { *x * *y } let f = times; let v0 = ~[1, 2, 3, 4, 5]; let v1 = ~[5, 4, 3, 2, 1]; let u = map2::(v0, v1, f); let mut i = 0; - while i < 5 { fail_unless!((v0[i] * v1[i] == u[i])); i += 1; } + while i < 5 { fail_unless!(v0[i] * v1[i] == u[i]); i += 1; } } #[test] @@ -2924,26 +2923,26 @@ mod tests { // Test on-stack filter-map. let mut v = ~[1u, 2u, 3u]; let mut w = filter_mapped(v, square_if_odd_r); - fail_unless!((len(w) == 2u)); - fail_unless!((w[0] == 1u)); - fail_unless!((w[1] == 9u)); + fail_unless!(w.len() == 2u); + fail_unless!(w[0] == 1u); + fail_unless!(w[1] == 9u); // Test on-heap filter-map. v = ~[1u, 2u, 3u, 4u, 5u]; w = filter_mapped(v, square_if_odd_r); - fail_unless!((len(w) == 3u)); - fail_unless!((w[0] == 1u)); - fail_unless!((w[1] == 9u)); - fail_unless!((w[2] == 25u)); + fail_unless!(w.len() == 3u); + fail_unless!(w[0] == 1u); + fail_unless!(w[1] == 9u); + fail_unless!(w[2] == 25u); fn halve(i: &int) -> Option { if *i % 2 == 0 { - return option::Some::(*i / 2); + Some::(*i / 2) } else { - return option::None::; + None:: } } - fn halve_for_sure(i: &int) -> int { return *i / 2; } + fn halve_for_sure(i: &int) -> int { *i / 2 } let all_even: ~[int] = ~[0, 2, 8, 6]; let all_odd1: ~[int] = ~[1, 7, 3]; let all_odd2: ~[int] = ~[]; @@ -2951,9 +2950,9 @@ mod tests { let mix_dest: ~[int] = ~[1, 3, 0, 0]; fail_unless!(filter_mapped(all_even, halve) == map(all_even, halve_for_sure)); - fail_unless!((filter_mapped(all_odd1, halve) == ~[])); - fail_unless!((filter_mapped(all_odd2, halve) == ~[])); - fail_unless!((filter_mapped(mix, halve) == mix_dest)); + fail_unless!(filter_mapped(all_odd1, halve) == ~[]); + fail_unless!(filter_mapped(all_odd2, halve) == ~[]); + fail_unless!(filter_mapped(mix, halve) == mix_dest); } #[test] @@ -2961,26 +2960,26 @@ mod tests { // Test on-stack filter-map. let mut v = ~[1u, 2u, 3u]; let mut w = filter_map(v, square_if_odd_v); - fail_unless!((len(w) == 2u)); - fail_unless!((w[0] == 1u)); - fail_unless!((w[1] == 9u)); + fail_unless!(w.len() == 2u); + fail_unless!(w[0] == 1u); + fail_unless!(w[1] == 9u); // Test on-heap filter-map. v = ~[1u, 2u, 3u, 4u, 5u]; w = filter_map(v, square_if_odd_v); - fail_unless!((len(w) == 3u)); - fail_unless!((w[0] == 1u)); - fail_unless!((w[1] == 9u)); - fail_unless!((w[2] == 25u)); + fail_unless!(w.len() == 3u); + fail_unless!(w[0] == 1u); + fail_unless!(w[1] == 9u); + fail_unless!(w[2] == 25u); fn halve(i: int) -> Option { if i % 2 == 0 { - return option::Some::(i / 2); + Some::(i / 2) } else { - return option::None::; + None:: } } - fn halve_for_sure(i: &int) -> int { return *i / 2; } + fn halve_for_sure(i: &int) -> int { *i / 2 } let all_even: ~[int] = ~[0, 2, 8, 6]; let all_even0: ~[int] = copy all_even; let all_odd1: ~[int] = ~[1, 7, 3]; @@ -2989,9 +2988,9 @@ mod tests { let mix_dest: ~[int] = ~[1, 3, 0, 0]; fail_unless!(filter_map(all_even, halve) == map(all_even0, halve_for_sure)); - fail_unless!((filter_map(all_odd1, halve) == ~[])); - fail_unless!((filter_map(all_odd2, halve) == ~[])); - fail_unless!((filter_map(mix, halve) == mix_dest)); + fail_unless!(filter_map(all_odd1, halve) == ~[]); + fail_unless!(filter_map(all_odd2, halve) == ~[]); + fail_unless!(filter_map(mix, halve) == mix_dest); } #[test] @@ -3012,12 +3011,12 @@ mod tests { // Test on-stack fold. let mut v = ~[1u, 2u, 3u]; let mut sum = foldl(0u, v, add); - fail_unless!((sum == 6u)); + fail_unless!(sum == 6u); // Test on-heap fold. v = ~[1u, 2u, 3u, 4u, 5u]; sum = foldl(0u, v, add); - fail_unless!((sum == 15u)); + fail_unless!(sum == 15u); } #[test] @@ -3119,29 +3118,29 @@ mod tests { #[test] fn test_any_and_all() { - fail_unless!((any(~[1u, 2u, 3u], is_three))); - fail_unless!((!any(~[0u, 1u, 2u], is_three))); - fail_unless!((any(~[1u, 2u, 3u, 4u, 5u], is_three))); - fail_unless!((!any(~[1u, 2u, 4u, 5u, 6u], is_three))); + fail_unless!(any(~[1u, 2u, 3u], is_three)); + fail_unless!(!any(~[0u, 1u, 2u], is_three)); + fail_unless!(any(~[1u, 2u, 3u, 4u, 5u], is_three)); + fail_unless!(!any(~[1u, 2u, 4u, 5u, 6u], is_three)); - fail_unless!((all(~[3u, 3u, 3u], is_three))); - fail_unless!((!all(~[3u, 3u, 2u], is_three))); - fail_unless!((all(~[3u, 3u, 3u, 3u, 3u], is_three))); - fail_unless!((!all(~[3u, 3u, 0u, 1u, 2u], is_three))); + fail_unless!(all(~[3u, 3u, 3u], is_three)); + fail_unless!(!all(~[3u, 3u, 2u], is_three)); + fail_unless!(all(~[3u, 3u, 3u, 3u, 3u], is_three)); + fail_unless!(!all(~[3u, 3u, 0u, 1u, 2u], is_three)); } #[test] fn test_any2_and_all2() { - fail_unless!((any2(~[2u, 4u, 6u], ~[2u, 4u, 6u], is_equal))); - fail_unless!((any2(~[1u, 2u, 3u], ~[4u, 5u, 3u], is_equal))); - fail_unless!((!any2(~[1u, 2u, 3u], ~[4u, 5u, 6u], is_equal))); - fail_unless!((any2(~[2u, 4u, 6u], ~[2u, 4u], is_equal))); + fail_unless!(any2(~[2u, 4u, 6u], ~[2u, 4u, 6u], is_equal)); + fail_unless!(any2(~[1u, 2u, 3u], ~[4u, 5u, 3u], is_equal)); + fail_unless!(!any2(~[1u, 2u, 3u], ~[4u, 5u, 6u], is_equal)); + fail_unless!(any2(~[2u, 4u, 6u], ~[2u, 4u], is_equal)); - fail_unless!((all2(~[2u, 4u, 6u], ~[2u, 4u, 6u], is_equal))); - fail_unless!((!all2(~[1u, 2u, 3u], ~[4u, 5u, 3u], is_equal))); - fail_unless!((!all2(~[1u, 2u, 3u], ~[4u, 5u, 6u], is_equal))); - fail_unless!((!all2(~[2u, 4u, 6u], ~[2u, 4u], is_equal))); + fail_unless!(all2(~[2u, 4u, 6u], ~[2u, 4u, 6u], is_equal)); + fail_unless!(!all2(~[1u, 2u, 3u], ~[4u, 5u, 3u], is_equal)); + fail_unless!(!all2(~[1u, 2u, 3u], ~[4u, 5u, 6u], is_equal)); + fail_unless!(!all2(~[2u, 4u, 6u], ~[2u, 4u], is_equal)); } #[test] @@ -3151,15 +3150,15 @@ mod tests { let z1 = zip(v1, v2); - fail_unless!(((1, 4) == z1[0])); - fail_unless!(((2, 5) == z1[1])); - fail_unless!(((3, 6) == z1[2])); + fail_unless!((1, 4) == z1[0]); + fail_unless!((2, 5) == z1[1]); + fail_unless!((3, 6) == z1[2]); let (left, right) = unzip(z1); - fail_unless!(((1, 4) == (left[0], right[0]))); - fail_unless!(((2, 5) == (left[1], right[1]))); - fail_unless!(((3, 6) == (left[2], right[2]))); + fail_unless!((1, 4) == (left[0], right[0])); + fail_unless!((2, 5) == (left[1], right[1])); + fail_unless!((3, 6) == (left[2], right[2])); } #[test] @@ -3175,8 +3174,8 @@ mod tests { #[test] fn test_position() { - fn less_than_three(i: &int) -> bool { return *i < 3; } - fn is_eighteen(i: &int) -> bool { return *i == 18; } + fn less_than_three(i: &int) -> bool { *i < 3 } + fn is_eighteen(i: &int) -> bool { *i == 18 } fail_unless!(position(~[], less_than_three).is_none()); @@ -3336,20 +3335,20 @@ mod tests { #[test] fn reverse_and_reversed() { let mut v: ~[int] = ~[10, 20]; - fail_unless!((v[0] == 10)); - fail_unless!((v[1] == 20)); + fail_unless!(v[0] == 10); + fail_unless!(v[1] == 20); reverse(v); - fail_unless!((v[0] == 20)); - fail_unless!((v[1] == 10)); + fail_unless!(v[0] == 20); + fail_unless!(v[1] == 10); let v2 = reversed::(~[10, 20]); - fail_unless!((v2[0] == 20)); - fail_unless!((v2[1] == 10)); + fail_unless!(v2[0] == 20); + fail_unless!(v2[1] == 10); v[0] = 30; - fail_unless!((v2[0] == 20)); + fail_unless!(v2[0] == 20); // Make sure they work with 0-length vectors too. let v4 = reversed::(~[]); - fail_unless!((v4 == ~[])); + fail_unless!(v4 == ~[]); let mut v3: ~[int] = ~[]; reverse::(v3); } @@ -3357,8 +3356,8 @@ mod tests { #[test] fn reversed_mut() { let mut v2 = reversed::(~[10, 20]); - fail_unless!((v2[0] == 20)); - fail_unless!((v2[1] == 10)); + fail_unless!(v2[0] == 20); + fail_unless!(v2[1] == 10); } #[test] @@ -3530,9 +3529,9 @@ mod tests { fn test_view() { let v = ~[1, 2, 3, 4, 5]; let v = v.view(1u, 3u); - fail_unless!((len(v) == 2u)); - fail_unless!((v[0] == 2)); - fail_unless!((v[1] == 3)); + fail_unless!(v.len() == 2u); + fail_unless!(v[0] == 2); + fail_unless!(v[1] == 3); } From 7cbd4b20ee857cf383ef1c0d8b34727a433231a9 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 27 Feb 2013 19:41:02 -0500 Subject: [PATCH 11/43] Remove @ast::Region and replace with @ast::Lifetime. Modify pretty-printer to emit lifetimes and fix a few minor parser bugs that this uncovered. --- src/librustc/middle/region.rs | 46 ++--- src/librustc/middle/typeck/astconv.rs | 62 ++++--- src/librustc/middle/typeck/check/mod.rs | 10 +- src/libsyntax/ast.rs | 32 +--- src/libsyntax/ext/auto_encode.rs | 10 +- src/libsyntax/ext/deriving.rs | 5 +- src/libsyntax/parse/obsolete.rs | 6 + src/libsyntax/parse/parser.rs | 165 ++++++++---------- src/libsyntax/print/pprust.rs | 59 +++---- src/test/compile-fail/prim-with-args.rs | 24 +-- src/test/compile-fail/regions-in-consts.rs | 2 +- src/test/compile-fail/regions-in-enums.rs | 4 +- src/test/compile-fail/regions-in-structs.rs | 2 +- .../compile-fail/regions-infer-not-param.rs | 11 +- ...regions-infer-region-in-fn-but-not-type.rs | 2 +- 15 files changed, 195 insertions(+), 245 deletions(-) diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 12c08ffb43585..a96ed9b8fa6da 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -31,6 +31,7 @@ use std::oldmap::HashMap; use syntax::ast_map; use syntax::codemap::span; use syntax::print::pprust; +use syntax::parse::token::special_idents; use syntax::{ast, visit}; pub type parent = Option; @@ -546,29 +547,20 @@ pub impl DetermineRpCtxt { // with &self type, &self is also bound. We detect those last two // cases via flags (anon_implies_rp and self_implies_rp) that are // true when the anon or self region implies RP. - fn region_is_relevant(&self, r: @ast::region) -> bool { - match r.node { - ast::re_static => false, - ast::re_anon => self.anon_implies_rp, - ast::re_self => self.self_implies_rp, - ast::re_named(_) => false - } - } - - // For named types like Foo, if there is no explicit region - // parameter, then we will add the anonymous region, so there is - // a dependency if the anonymous region implies rp. - // - // If the region is explicitly specified, then we follows the - // normal rules. - fn opt_region_is_relevant(&self, - opt_r: Option<@ast::region>) - -> bool { - debug!("opt_region_is_relevant: %? (anon_implies_rp=%b)", - opt_r, self.anon_implies_rp); - match opt_r { - None => self.anon_implies_rp, - Some(r) => self.region_is_relevant(r) + fn region_is_relevant(&self, r: Option<@ast::Lifetime>) -> bool { + match r { + None => { + self.anon_implies_rp + } + Some(ref l) if l.ident == special_idents::static => { + false + } + Some(ref l) if l.ident == special_idents::self_ => { + self.self_implies_rp + } + Some(_) => { + false + } } } @@ -672,8 +664,8 @@ pub fn determine_rp_in_ty(ty: @ast::Ty, debug!("referenced fn type: %s", pprust::ty_to_str(ty, sess.intr())); match f.region { - Some(r) => { - if cx.region_is_relevant(r) { + Some(_) => { + if cx.region_is_relevant(f.region) { cx.add_rp(cx.item_id, cx.add_variance(rv_contravariant)) } @@ -699,7 +691,7 @@ pub fn determine_rp_in_ty(ty: @ast::Ty, match cx.def_map.find(&id) { Some(ast::def_ty(did)) | Some(ast::def_struct(did)) => { if did.crate == ast::local_crate { - if cx.opt_region_is_relevant(path.rp) { + if cx.region_is_relevant(path.rp) { cx.add_dep(did.node); } } else { @@ -709,7 +701,7 @@ pub fn determine_rp_in_ty(ty: @ast::Ty, Some(variance) => { debug!("reference to external, rp'd type %s", pprust::ty_to_str(ty, sess.intr())); - if cx.opt_region_is_relevant(path.rp) { + if cx.region_is_relevant(path.rp) { cx.add_rp(cx.item_id, cx.add_variance(variance)) } } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 0b6c07832f634..8152200bf0476 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -65,7 +65,8 @@ use core::result; use core::vec; use syntax::ast; use syntax::codemap::span; -use syntax::print::pprust::{region_to_str, path_to_str}; +use syntax::print::pprust::{lifetime_to_str, path_to_str}; +use syntax::parse::token::special_idents; use util::common::indenter; pub trait AstConv { @@ -79,7 +80,7 @@ pub trait AstConv { pub fn get_region_reporting_err( tcx: ty::ctxt, span: span, - a_r: Option<@ast::region>, + a_r: Option<@ast::Lifetime>, res: Result) -> ty::Region { match res { @@ -87,13 +88,8 @@ pub fn get_region_reporting_err( result::Err(ref e) => { let descr = match a_r { None => ~"anonymous lifetime", - Some(a) if a.node == ast::re_anon => { - ~"anonymous lifetime" - } - Some(a) => { - fmt!("lifetime %s", - region_to_str(a, tcx.sess.intr())) - } + Some(a) => fmt!("lifetime %s", + lifetime_to_str(a, tcx.sess.intr())) }; tcx.sess.span_err( span, @@ -105,19 +101,28 @@ pub fn get_region_reporting_err( } pub fn ast_region_to_region( - self: &AC, - rscope: &RS, - span: span, - a_r: @ast::region) - -> ty::Region { - let res = match a_r.node { - ast::re_static => Ok(ty::re_static), - ast::re_anon => rscope.anon_region(span), - ast::re_self => rscope.self_region(span), - ast::re_named(id) => rscope.named_region(span, id) + self: &AC, + rscope: &RS, + default_span: span, + opt_lifetime: Option<@ast::Lifetime>) -> ty::Region +{ + let (span, res) = match opt_lifetime { + None => { + (default_span, rscope.anon_region(default_span)) + } + Some(ref lifetime) if lifetime.ident == special_idents::static => { + (lifetime.span, Ok(ty::re_static)) + } + Some(ref lifetime) if lifetime.ident == special_idents::self_ => { + (lifetime.span, rscope.self_region(lifetime.span)) + } + Some(ref lifetime) => { + (lifetime.span, rscope.named_region(lifetime.span, + lifetime.ident)) + } }; - get_region_reporting_err(self.tcx(), span, Some(a_r), res) + get_region_reporting_err(self.tcx(), span, opt_lifetime, res) } pub fn ast_path_to_substs_and_ty( @@ -156,8 +161,8 @@ pub fn ast_path_to_substs_and_ty( let r = get_region_reporting_err(self.tcx(), path.span, None, res); Some(r) } - (Some(_), Some(r)) => { - Some(ast_region_to_region(self, rscope, path.span, r)) + (Some(_), Some(_)) => { + Some(ast_region_to_region(self, rscope, path.span, path.rp)) } }; @@ -504,7 +509,7 @@ pub fn ty_of_closure( sigil: ast::Sigil, purity: ast::purity, onceness: ast::Onceness, - opt_region: Option<@ast::region>, + opt_lifetime: Option<@ast::Lifetime>, decl: &ast::fn_decl, expected_tys: Option, span: span) @@ -514,9 +519,9 @@ pub fn ty_of_closure( // resolve the function bound region in the original region // scope `rscope`, not the scope of the function parameters - let bound_region = match opt_region { - Some(region) => { - ast_region_to_region(self, rscope, span, region) + let bound_region = match opt_lifetime { + Some(_) => { + ast_region_to_region(self, rscope, span, opt_lifetime) } None => { match sigil { @@ -526,9 +531,8 @@ pub fn ty_of_closure( ty::re_static } ast::BorrowedSigil => { - // &fn() defaults to an anonymous region: - let r_result = rscope.anon_region(span); - get_region_reporting_err(self.tcx(), span, None, r_result) + // &fn() defaults as normal for an omitted lifetime: + ast_region_to_region(self, rscope, span, opt_lifetime) } } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 6efa62c55cc24..0798e2b7afe6e 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -2950,19 +2950,19 @@ pub fn instantiate_path(fcx: @mut FnCtxt, // determine the region bound, using the value given by the user // (if any) and otherwise using a fresh region variable let self_r = match pth.rp { - Some(r) => { + Some(_) => { // user supplied a lifetime parameter... match tpt.region_param { - None => { + None => { // ...but the type is not lifetime parameterized! fcx.ccx.tcx.sess.span_err (span, ~"this item is not region-parameterized"); None } - Some(_) => { - Some(ast_region_to_region(fcx, fcx, span, r)) + Some(_) => { // ...and the type is lifetime parameterized, ok. + Some(ast_region_to_region(fcx, fcx, span, pth.rp)) } } } - None => { + None => { // no lifetime parameter supplied, insert default fcx.region_var_if_parameterized( tpt.region_param, span, region_lb) } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a6ccd69dd0655..3782208eb851c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -116,7 +116,7 @@ pub struct path { span: span, global: bool, idents: ~[ident], - rp: Option<@region>, + rp: Option<@Lifetime>, types: ~[@Ty], } @@ -374,10 +374,10 @@ impl ToStr for Sigil { #[deriving_eq] pub enum vstore { // FIXME (#3469): Change uint to @expr (actually only constant exprs) - vstore_fixed(Option), // [1,2,3,4] - vstore_uniq, // ~[1,2,3,4] - vstore_box, // @[1,2,3,4] - vstore_slice(@region) // &[1,2,3,4](foo)? + vstore_fixed(Option), // [1,2,3,4] + vstore_uniq, // ~[1,2,3,4] + vstore_box, // @[1,2,3,4] + vstore_slice(Option<@Lifetime>) // &'foo? [1,2,3,4] } #[auto_encode] @@ -857,24 +857,6 @@ pub enum prim_ty { ty_bool, } -#[auto_encode] -#[auto_decode] -#[deriving_eq] -pub struct region { - id: node_id, - node: region_, -} - -#[auto_encode] -#[auto_decode] -#[deriving_eq] -pub enum region_ { - re_anon, - re_static, - re_self, - re_named(ident) -} - #[auto_encode] #[auto_decode] #[deriving_eq] @@ -903,7 +885,7 @@ impl to_bytes::IterBytes for Onceness { #[deriving_eq] pub struct TyClosure { sigil: Sigil, - region: Option<@region>, + region: Option<@Lifetime>, purity: purity, onceness: Onceness, decl: fn_decl @@ -929,7 +911,7 @@ pub enum ty_ { ty_vec(mt), ty_fixed_length_vec(mt, uint), ty_ptr(mt), - ty_rptr(@region, mt), + ty_rptr(Option<@Lifetime>, mt), ty_closure(@TyClosure), ty_bare_fn(@TyBareFn), ty_tup(~[@Ty]), diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index 644afaff37c5c..ecb5be6cc3c61 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -594,10 +594,7 @@ fn mk_ser_method( let ty_s = @ast::Ty { id: cx.next_id(), node: ast::ty_rptr( - @ast::region { - id: cx.next_id(), - node: ast::re_anon, - }, + None, ast::mt { ty: cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[]), mutbl: ast::m_imm @@ -658,10 +655,7 @@ fn mk_deser_method( let ty_d = @ast::Ty { id: cx.next_id(), node: ast::ty_rptr( - @ast::region { - id: cx.next_id(), - node: ast::re_anon, - }, + None, ast::mt { ty: cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[]), mutbl: ast::m_imm diff --git a/src/libsyntax/ext/deriving.rs b/src/libsyntax/ext/deriving.rs index a1514bc3eabdb..efea962a0892d 100644 --- a/src/libsyntax/ext/deriving.rs +++ b/src/libsyntax/ext/deriving.rs @@ -19,7 +19,7 @@ use ast::{enum_variant_kind, expr, expr_match, ident, impure_fn, item, item_}; use ast::{item_enum, item_impl, item_struct, Generics}; use ast::{m_imm, meta_item, method}; use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn}; -use ast::{re_anon, stmt, struct_def, struct_variant_kind}; +use ast::{stmt, struct_def, struct_variant_kind}; use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam}; use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant}; use ext::base::ext_ctxt; @@ -147,9 +147,8 @@ fn create_eq_method(cx: ext_ctxt, span, type_ident, generics); - let arg_region = @ast::region { id: cx.next_id(), node: re_anon }; let arg_type = ty_rptr( - arg_region, + None, ast::mt { ty: arg_path_type, mutbl: m_imm } ); let arg_type = @ast::Ty { diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 6f2d2c554aa93..97ff175da07fe 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -52,6 +52,7 @@ pub enum ObsoleteSyntax { ObsoleteRecordType, ObsoleteRecordPattern, ObsoleteAssertion, + ObsoletePostFnTySigil, } impl to_bytes::IterBytes for ObsoleteSyntax { @@ -160,6 +161,11 @@ pub impl Parser { "assertion", "use `fail_unless!()` instead" ), + ObsoletePostFnTySigil => ( + "fn sigil in postfix position", + "Rather than `fn@`, `fn~`, or `fn&`, \ + write `@fn`, `~fn`, and `&fn` respectively" + ), }; self.report(sp, kind, kind_str, desc); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 384cf4f0e9517..adcaa006247fa 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -14,7 +14,7 @@ use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil, RustAbi}; use ast::{CallSugar, NoSugar, DoSugar, ForSugar}; use ast::{TyBareFn, TyClosure}; use ast::{RegionTyParamBound, TraitTyParamBound}; -use ast::{provided, public, pure_fn, purity, re_static}; +use ast::{provided, public, pure_fn, purity}; use ast::{_mod, add, arg, arm, attribute, bind_by_ref, bind_infer}; use ast::{bind_by_copy, bitand, bitor, bitxor, blk}; use ast::{blk_check_mode, box, by_copy, by_ref, by_val}; @@ -40,9 +40,9 @@ use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, local, m_const}; use ast::{m_imm, m_mutbl, mac_, mac_invoc_tt, matcher, match_nonterminal}; use ast::{match_seq, match_tok, method, mode, module_ns, mt, mul, mutability}; use ast::{named_field, neg, node_id, noreturn, not, pat, pat_box, pat_enum}; -use ast::{pat_ident, pat_lit, pat_range, pat_region, pat_struct, pat_tup}; -use ast::{pat_uniq, pat_wild, path, private}; -use ast::{re_self, re_anon, re_named, region, rem, required}; +use ast::{pat_ident, pat_lit, pat_range, pat_region, pat_struct}; +use ast::{pat_tup, pat_uniq, pat_wild, path, private}; +use ast::{rem, required}; use ast::{ret_style, return_val, self_ty, shl, shr, stmt, stmt_decl}; use ast::{stmt_expr, stmt_semi, stmt_mac, struct_def, struct_field}; use ast::{struct_immutable, struct_mutable, struct_variant_kind, subtract}; @@ -76,7 +76,7 @@ use parse::obsolete::{ObsoleteUnsafeBlock, ObsoleteImplSyntax}; use parse::obsolete::{ObsoleteTraitBoundSeparator, ObsoleteMutOwnedPointer}; use parse::obsolete::{ObsoleteMutVector, ObsoleteTraitImplVisibility}; use parse::obsolete::{ObsoleteRecordType, ObsoleteRecordPattern}; -use parse::obsolete::{ObsoleteAssertion}; +use parse::obsolete::{ObsoleteAssertion, ObsoletePostFnTySigil}; use parse::prec::{as_prec, token_to_binop}; use parse::token::{can_begin_expr, is_ident, is_ident_or_path}; use parse::token::{is_plain_ident, INTERPOLATED, special_idents}; @@ -363,12 +363,13 @@ pub impl Parser { }); } - fn parse_ty_closure(&self, pre_sigil: Option, - pre_region_name: Option) -> ty_ + fn parse_ty_closure(&self, + sigil: ast::Sigil, + region: Option<@ast::Lifetime>) -> ty_ { /* - (&|~|@) [r/] [pure|unsafe] [once] fn <'lt> (S) -> T + (&|~|@) ['r] [pure|unsafe] [once] fn <'lt> (S) -> T ^~~~~~^ ^~~^ ^~~~~~~~~~~~^ ^~~~~^ ^~~~^ ^~^ ^ | | | | | | | | | | | | | Return type @@ -388,13 +389,10 @@ pub impl Parser { let onceness = parse_onceness(self); self.expect_keyword(&~"fn"); - let sigil = match pre_sigil { None => BorrowedSigil, Some(p) => p }; - - let region = if pre_region_name.is_some() { - Some(self.region_from_name(pre_region_name)) - } else { - None - }; + if self.parse_fn_ty_sigil().is_some() { + self.obsolete(*self.span, + ObsoletePostFnTySigil); + } return ty_closure(@TyClosure { sigil: sigil, @@ -432,7 +430,7 @@ pub impl Parser { */ if self.eat(&token::LT) { let _lifetimes = self.parse_lifetimes(); - self.expect(&token::GT); + self.expect_gt(); } let inputs = self.parse_unspanned_seq( &token::LPAREN, @@ -575,38 +573,6 @@ pub impl Parser { } } - fn region_from_name(&self, s: Option) -> @region { - let r = match s { - Some(id) if id == special_idents::static => ast::re_static, - Some(id) if id == special_idents::self_ => re_self, - Some(id) => re_named(id), - None => re_anon - }; - - @ast::region { id: self.get_id(), node: r } - } - - // Parses something like "&x" - fn parse_region(&self) -> @region { - self.expect(&token::BINOP(token::AND)); - - match *self.token { - token::IDENT(sid, _) => { - self.bump(); - self.region_from_name(Some(sid)) - } - _ => { - self.region_from_name(None) - } - } - } - - fn region_from_lifetime(&self, l: &ast::Lifetime) -> @region { - // eventually `ast::region` should go away in favor of - // `ast::Lifetime`. For now we convert between them. - self.region_from_name(Some(l.ident)) - } - fn parse_ty(&self, colons_before_params: bool) -> @Ty { maybe_whole!(self, nt_ty); @@ -681,7 +647,8 @@ pub impl Parser { } else if self.eat_keyword(&~"extern") { self.parse_ty_bare_fn() } else if self.token_is_closure_keyword(© *self.token) { - self.parse_ty_closure(None, None) + // self.warn(fmt!("Old-school closure keyword")); + self.parse_ty_closure(ast::BorrowedSigil, None) } else if *self.token == token::MOD_SEP || is_ident_or_path(&*self.token) { let path = self.parse_path_with_tps(colons_before_params); @@ -701,20 +668,20 @@ pub impl Parser { { // @'foo fn() or @foo/fn() or @fn() are parsed directly as fn types: match *self.token { - token::LIFETIME(rname) => { + token::LIFETIME(*) => { + let lifetime = @self.parse_lifetime(); self.bump(); - return self.parse_ty_closure(Some(sigil), Some(rname)); + return self.parse_ty_closure(sigil, Some(lifetime)); } - token::IDENT(rname, _) => { + token::IDENT(*) => { if self.look_ahead(1u) == token::BINOP(token::SLASH) && self.token_is_closure_keyword(&self.look_ahead(2u)) { - self.bump(); - self.bump(); - return self.parse_ty_closure(Some(sigil), Some(rname)); + let lifetime = @self.parse_lifetime(); + return self.parse_ty_closure(sigil, Some(lifetime)); } else if self.token_is_closure_keyword(© *self.token) { - return self.parse_ty_closure(Some(sigil), None); + return self.parse_ty_closure(sigil, None); } } _ => {} @@ -735,31 +702,14 @@ pub impl Parser { fn parse_borrowed_pointee(&self) -> ty_ { // look for `&'lt` or `&foo/` and interpret `foo` as the region name: - let rname = match *self.token { - token::LIFETIME(sid) => { - self.bump(); - Some(sid) - } - - token::IDENT(sid, _) => { - if self.look_ahead(1u) == token::BINOP(token::SLASH) { - self.bump(); self.bump(); - Some(sid) - } else { - None - } - } - - _ => { None } - }; + let opt_lifetime = self.parse_opt_lifetime(); if self.token_is_closure_keyword(© *self.token) { - return self.parse_ty_closure(Some(BorrowedSigil), rname); + return self.parse_ty_closure(BorrowedSigil, opt_lifetime); } - let r = self.region_from_name(rname); let mt = self.parse_mt(); - return ty_rptr(r, mt); + return ty_rptr(opt_lifetime, mt); } fn parse_arg_mode(&self) -> mode { @@ -939,19 +889,27 @@ pub impl Parser { return path; } - // Parse the region parameter, if any, which will + // Parse the (obsolete) trailing region parameter, if any, which will // be written "foo/&x" let rp_slash = { - // Hack: avoid parsing vstores like /@ and /~. This is painful - // because the notation for region bounds and the notation for - // vstores is... um... the same. I guess that's my fault. This - // is still not ideal as for &str we end up parsing more than we - // ought to and have to sort it out later. if *self.token == token::BINOP(token::SLASH) - && self.look_ahead(1u) == token::BINOP(token::AND) { - - self.expect(&token::BINOP(token::SLASH)); - Some(self.parse_region()) + && self.look_ahead(1u) == token::BINOP(token::AND) + { + self.bump(); self.bump(); + match *self.token { + token::IDENT(sid, _) => { + let span = copy self.span; + self.bump(); + Some(@ast::Lifetime { + id: self.get_id(), + span: *span, + ident: sid + }) + } + _ => { + self.fatal(fmt!("Expected a lifetime name")); + } + } } else { None } @@ -967,7 +925,7 @@ pub impl Parser { if v.len() == 0 { None } else if v.len() == 1 { - Some(self.region_from_lifetime(v.get(0))) + Some(@*v.get(0)) } else { self.fatal(fmt!("Expected at most one \ lifetime name (for now)")); @@ -981,16 +939,26 @@ pub impl Parser { .. copy *path } } - fn parse_opt_lifetime(&self) -> Option { + fn parse_opt_lifetime(&self) -> Option<@ast::Lifetime> { /*! * * Parses 0 or 1 lifetime. */ match *self.token { - token::LIFETIME(_) => { - Some(self.parse_lifetime()) + token::LIFETIME(*) => { + Some(@self.parse_lifetime()) + } + + // Also accept the (obsolete) syntax `foo/` + token::IDENT(*) => { + if self.look_ahead(1u) == token::BINOP(token::SLASH) { + Some(@self.parse_lifetime()) + } else { + None + } } + _ => { None } @@ -1005,13 +973,27 @@ pub impl Parser { match *self.token { token::LIFETIME(i) => { + let span = copy self.span; + self.bump(); + return ast::Lifetime { + id: self.get_id(), + span: *span, + ident: i + }; + } + + // Also accept the (obsolete) syntax `foo/` + token::IDENT(i, _) => { + let span = copy self.span; self.bump(); + self.expect(&token::BINOP(token::SLASH)); return ast::Lifetime { id: self.get_id(), - span: *self.span, + span: *span, ident: i }; } + _ => { self.fatal(fmt!("Expected a lifetime name")); } @@ -1041,6 +1023,7 @@ pub impl Parser { match *self.token { token::COMMA => { self.bump();} token::GT => { return res; } + token::BINOP(token::SHR) => { return res; } _ => { self.fatal(~"expected `,` or `>` after lifetime name"); } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index c68341c20fa4c..3744b7a8f6c03 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -146,8 +146,8 @@ pub fn expr_to_str(e: @ast::expr, intr: @ident_interner) -> ~str { to_str(e, print_expr, intr) } -pub fn region_to_str(e: @ast::region, intr: @ident_interner) -> ~str { - to_str(e, |s, e| print_region(s, ~"&", e, ~""), intr) +pub fn lifetime_to_str(e: &ast::Lifetime, intr: @ident_interner) -> ~str { + to_str(e, print_lifetime, intr) } pub fn tt_to_str(tt: ast::token_tree, intr: @ident_interner) -> ~str { @@ -355,23 +355,11 @@ pub fn print_foreign_mod(s: @ps, nmod: ast::foreign_mod, for nmod.items.each |item| { print_foreign_item(s, *item); } } -pub fn print_region(s: @ps, prefix: ~str, region: @ast::region, sep: ~str) { - word(s.s, prefix); - match region.node { - ast::re_anon => { - return; - } - ast::re_static => { - word_space(s, ~"static") - } - ast::re_self => { - word_space(s, ~"self") - } - ast::re_named(name) => { - print_ident(s, name); - } +pub fn print_opt_lifetime(s: @ps, lifetime: Option<@ast::Lifetime>) { + for lifetime.each |l| { + print_lifetime(s, *l); + nbsp(s); } - word(s.s, sep); } pub fn print_type(s: @ps, &&ty: @ast::Ty) { @@ -397,8 +385,9 @@ pub fn print_type_ex(s: @ps, &&ty: @ast::Ty, print_colons: bool) { word(s.s, ~"]"); } ast::ty_ptr(mt) => { word(s.s, ~"*"); print_mt(s, mt); } - ast::ty_rptr(region, mt) => { - print_region(s, ~"&", region, ~"/"); + ast::ty_rptr(lifetime, mt) => { + word(s.s, ~"&"); + print_opt_lifetime(s, lifetime); print_mt(s, mt); } ast::ty_tup(elts) => { @@ -1048,7 +1037,10 @@ pub fn print_vstore(s: @ps, t: ast::vstore) { ast::vstore_fixed(None) => word(s.s, ~"_"), ast::vstore_uniq => word(s.s, ~"~"), ast::vstore_box => word(s.s, ~"@"), - ast::vstore_slice(r) => print_region(s, ~"&", r, ~"/") + ast::vstore_slice(r) => { + word(s.s, ~"&"); + print_opt_lifetime(s, r); + } } } @@ -1501,17 +1493,18 @@ pub fn print_path(s: @ps, &&path: @ast::path, colons_before_params: bool) { if path.rp.is_some() || !path.types.is_empty() { if colons_before_params { word(s.s, ~"::"); } - match path.rp { - None => { /* ok */ } - Some(r) => { - word(s.s, ~"/"); - print_region(s, ~"&", r, ~""); - } - } - - if !path.types.is_empty() { + if path.rp.is_some() || !path.types.is_empty() { word(s.s, ~"<"); + + for path.rp.each |r| { + print_lifetime(s, *r); + if !path.types.is_empty() { + word_space(s, ~","); + } + } + commasep(s, inconsistent, path.types, print_type); + word(s.s, ~">"); } } @@ -1749,7 +1742,7 @@ pub fn print_bounds(s: @ps, bounds: @OptVec) { } } -pub fn print_lifetime(s: @ps, lifetime: &ast::Lifetime) { +pub fn print_lifetime(s: @ps, &&lifetime: &ast::Lifetime) { word(s.s, ~"'"); print_ident(s, lifetime.ident); } @@ -1908,7 +1901,7 @@ pub fn print_arg(s: @ps, input: ast::arg) { pub fn print_ty_fn(s: @ps, opt_abi: Option, opt_sigil: Option, - opt_region: Option<@ast::region>, + opt_region: Option<@ast::Lifetime>, purity: ast::purity, onceness: ast::Onceness, decl: &ast::fn_decl, id: Option, @@ -1921,7 +1914,7 @@ pub fn print_ty_fn(s: @ps, print_self_ty_if_static(s, opt_self_ty); print_opt_abi(s, opt_abi); print_opt_sigil(s, opt_sigil); - for opt_region.each |r| { print_region(s, ~"", *r, ~"/"); } + print_opt_lifetime(s, opt_region); print_purity(s, purity); print_onceness(s, onceness); word(s.s, ~"fn"); diff --git a/src/test/compile-fail/prim-with-args.rs b/src/test/compile-fail/prim-with-args.rs index be57f88fd0a98..40d5a44124177 100644 --- a/src/test/compile-fail/prim-with-args.rs +++ b/src/test/compile-fail/prim-with-args.rs @@ -23,17 +23,17 @@ let x: u64; //~ ERROR type parameters are not allowed on this type let x: float; //~ ERROR type parameters are not allowed on this type let x: char; //~ ERROR type parameters are not allowed on this type -let x: int/&; //~ ERROR region parameters are not allowed on this type -let x: i8/&; //~ ERROR region parameters are not allowed on this type -let x: i16/&; //~ ERROR region parameters are not allowed on this type -let x: i32/&; //~ ERROR region parameters are not allowed on this type -let x: i64/&; //~ ERROR region parameters are not allowed on this type -let x: uint/&; //~ ERROR region parameters are not allowed on this type -let x: u8/&; //~ ERROR region parameters are not allowed on this type -let x: u16/&; //~ ERROR region parameters are not allowed on this type -let x: u32/&; //~ ERROR region parameters are not allowed on this type -let x: u64/&; //~ ERROR region parameters are not allowed on this type -let x: float/&; //~ ERROR region parameters are not allowed on this type -let x: char/&; //~ ERROR region parameters are not allowed on this type +let x: int<'static>; //~ ERROR region parameters are not allowed on this type +let x: i8<'static>; //~ ERROR region parameters are not allowed on this type +let x: i16<'static>; //~ ERROR region parameters are not allowed on this type +let x: i32<'static>; //~ ERROR region parameters are not allowed on this type +let x: i64<'static>; //~ ERROR region parameters are not allowed on this type +let x: uint<'static>; //~ ERROR region parameters are not allowed on this type +let x: u8<'static>; //~ ERROR region parameters are not allowed on this type +let x: u16<'static>; //~ ERROR region parameters are not allowed on this type +let x: u32<'static>; //~ ERROR region parameters are not allowed on this type +let x: u64<'static>; //~ ERROR region parameters are not allowed on this type +let x: float<'static>; //~ ERROR region parameters are not allowed on this type +let x: char<'static>; //~ ERROR region parameters are not allowed on this type } diff --git a/src/test/compile-fail/regions-in-consts.rs b/src/test/compile-fail/regions-in-consts.rs index 19dea9a57ee49..2ba27e888cbe0 100644 --- a/src/test/compile-fail/regions-in-consts.rs +++ b/src/test/compile-fail/regions-in-consts.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const c_x: &'blk int = &22; //~ ERROR Illegal lifetime &blk: only 'static is allowed here +const c_x: &'blk int = &22; //~ ERROR Illegal lifetime 'blk: only 'static is allowed here const c_y: &int = &22; //~ ERROR Illegal anonymous lifetime: only 'static is allowed here const c_z: &'static int = &22; diff --git a/src/test/compile-fail/regions-in-enums.rs b/src/test/compile-fail/regions-in-enums.rs index 5c2269977d194..0adfaccdc0174 100644 --- a/src/test/compile-fail/regions-in-enums.rs +++ b/src/test/compile-fail/regions-in-enums.rs @@ -10,7 +10,7 @@ enum yes0<'lt> { // This will eventually be legal (and in fact the only way): - X3(&'lt uint) //~ ERROR Illegal lifetime <: only 'self is allowed allowed as part of a type declaration + X3(&'lt uint) //~ ERROR Illegal lifetime 'lt: only 'self is allowed allowed as part of a type declaration } enum yes1 { @@ -18,7 +18,7 @@ enum yes1 { } enum yes2 { - X5(&'foo uint) //~ ERROR Illegal lifetime &foo: only 'self is allowed allowed as part of a type declaration + X5(&'foo uint) //~ ERROR Illegal lifetime 'foo: only 'self is allowed allowed as part of a type declaration } fn main() {} diff --git a/src/test/compile-fail/regions-in-structs.rs b/src/test/compile-fail/regions-in-structs.rs index 10d7a921ed031..b425a40114a3d 100644 --- a/src/test/compile-fail/regions-in-structs.rs +++ b/src/test/compile-fail/regions-in-structs.rs @@ -17,7 +17,7 @@ struct yes1<'self> { } struct yes2<'self> { - x: &'foo uint, //~ ERROR Illegal lifetime &foo: only 'self is allowed allowed as part of a type declaration + x: &'foo uint, //~ ERROR Illegal lifetime 'foo: only 'self is allowed allowed as part of a type declaration } fn main() {} diff --git a/src/test/compile-fail/regions-infer-not-param.rs b/src/test/compile-fail/regions-infer-not-param.rs index b5f8d99829870..a0ecb08a08957 100644 --- a/src/test/compile-fail/regions-infer-not-param.rs +++ b/src/test/compile-fail/regions-infer-not-param.rs @@ -13,19 +13,16 @@ struct direct<'self> { } struct indirect1 { + // Here the lifetime parameter of direct is bound by the fn() g: @fn(direct) } -struct indirect2 { - g: @fn(direct/&) -} - -struct indirect3 { +struct indirect2<'self> { + // But here it is set to 'self g: @fn(direct<'self>) } fn take_direct(p: direct) -> direct { p } //~ ERROR mismatched types fn take_indirect1(p: indirect1) -> indirect1 { p } -fn take_indirect2(p: indirect2) -> indirect2 { p } -fn take_indirect3(p: indirect3) -> indirect3 { p } //~ ERROR mismatched types +fn take_indirect2(p: indirect2) -> indirect2 { p } //~ ERROR mismatched types fn main() {} diff --git a/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs b/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs index 11414a1110847..fe37d8990985d 100644 --- a/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs +++ b/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs @@ -13,7 +13,7 @@ // contains region pointers enum foo = ~fn(x: &int); -fn take_foo(x: foo/&) {} //~ ERROR no region bound is allowed on `foo` +fn take_foo(x: foo<'static>) {} //~ ERROR no region bound is allowed on `foo` fn main() { } From 80c71c839acde882e53ee9505a05b81e4af33ab7 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Fri, 8 Mar 2013 20:05:20 -0500 Subject: [PATCH 12/43] add a TotalOrd impl for the unit type --- src/libcore/nil.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libcore/nil.rs b/src/libcore/nil.rs index cf2af7e38cc6b..742e5a047d6ca 100644 --- a/src/libcore/nil.rs +++ b/src/libcore/nil.rs @@ -15,7 +15,7 @@ Functions for the unit type. */ #[cfg(notest)] -use cmp::{Eq, Ord}; +use cmp::{Eq, Ord, TotalOrd, Ordering, Equal}; #[cfg(notest)] impl Eq for () { @@ -37,3 +37,8 @@ impl Ord for () { pure fn gt(&self, _other: &()) -> bool { false } } +#[cfg(notest)] +impl TotalOrd for () { + #[inline(always)] + pure fn cmp(&self, _other: &()) -> Ordering { Equal } +} From 62aa8d7de96bc6439d14db3197313604292aa314 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 8 Mar 2013 17:48:11 -0500 Subject: [PATCH 13/43] Simplify the interface to check_fn by pulling some of the madness out to its callers --- src/librustc/middle/typeck/check/mod.rs | 95 +++++++++++++++---------- 1 file changed, 56 insertions(+), 39 deletions(-) diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 0798e2b7afe6e..cdc1f258cb544 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -162,7 +162,17 @@ pub struct inherited { adjustments: HashMap } -pub enum FnKind { ForLoop, DoBlock, Vanilla } +pub enum FnKind { + // This is a for-closure. The ty::t is the return type of the + // enclosing function. + ForLoop(ty::t), + + // A do-closure. + DoBlock, + + // A normal closure or fn item. + Vanilla +} pub struct FnCtxt { // var_bindings, locals and next_var_id are shared @@ -250,8 +260,14 @@ pub fn check_bare_fn(ccx: @mut CrateCtxt, let fty = ty::node_id_to_type(ccx.tcx, id); match ty::get(fty).sty { ty::ty_bare_fn(ref fn_ty) => { - check_fn(ccx, self_info, fn_ty.purity, None, - &fn_ty.sig, decl, body, Vanilla, None) + let fcx = + check_fn(ccx, self_info, fn_ty.purity, + &fn_ty.sig, decl, body, Vanilla, + @Nil, blank_inherited(ccx));; + + vtable::resolve_in_block(fcx, body); + regionck::regionck_fn(fcx, body); + writeback::resolve_type_vars_in_fn(fcx, decl, body, self_info); } _ => ccx.tcx.sess.impossible_case(body.span, "check_bare_fn: function type expected") @@ -261,16 +277,26 @@ pub fn check_bare_fn(ccx: @mut CrateCtxt, pub fn check_fn(ccx: @mut CrateCtxt, +self_info: Option, purity: ast::purity, - sigil: Option, fn_sig: &ty::FnSig, decl: &ast::fn_decl, body: &ast::blk, fn_kind: FnKind, - old_fcx: Option<@mut FnCtxt>) { + inherited_isr: isr_alist, + inherited: @inherited) -> @mut FnCtxt +{ + /*! + * + * Helper used by check_bare_fn and check_expr_fn. Does the + * grungy work of checking a function body and returns the + * function context used for that purpose, since in the case of a + * fn item there is still a bit more to do. + * + * - ... + * - inherited_isr: regions in scope from the enclosing fn (if any) + * - inherited: other fields inherited from the enclosing fn (if any) + */ + let tcx = ccx.tcx; - let indirect_ret = match fn_kind { - ForLoop => true, _ => false - }; // ______________________________________________________________________ // First, we have to replace any bound regions in the fn and self @@ -278,9 +304,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, // the node_id of the body block. let (isr, self_info, fn_sig) = { - let old_isr = option::map_default(&old_fcx, @Nil, - |fcx| fcx.in_scope_regions); - replace_bound_regions_in_fn_sig(tcx, old_isr, self_info, fn_sig, + replace_bound_regions_in_fn_sig(tcx, inherited_isr, self_info, fn_sig, |br| ty::re_free(body.node.id, br)) }; @@ -296,23 +320,13 @@ pub fn check_fn(ccx: @mut CrateCtxt, // Create the function context. This is either derived from scratch or, // in the case of function expressions, based on the outer context. let fcx: @mut FnCtxt = { - let (purity, inherited) = match old_fcx { - None => (purity, blank_inherited(ccx)), - Some(fcx) => { - (ty::determine_inherited_purity(fcx.purity, purity, - sigil.get()), - fcx.inh) - } + // In a for-loop, you have an 'indirect return' because return + // does not return out of the directly enclosing fn + let indirect_ret_ty = match fn_kind { + ForLoop(t) => Some(t), + DoBlock | Vanilla => None }; - let indirect_ret_ty = if indirect_ret { - let ofcx = old_fcx.get(); - match ofcx.indirect_ret_ty { - Some(t) => Some(t), - None => Some(ofcx.ret_ty) - } - } else { None }; - @mut FnCtxt { self_info: self_info, ret_ty: ret_ty, @@ -370,15 +384,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, fcx.write_ty(input.id, *arg); } - // If we don't have any enclosing function scope, it is time to - // force any remaining type vars to be resolved. - // If we have an enclosing function scope, our type variables will be - // resolved when the enclosing scope finishes up. - if old_fcx.is_none() { - vtable::resolve_in_block(fcx, body); - regionck::regionck_fn(fcx, body); - writeback::resolve_type_vars_in_fn(fcx, decl, body, self_info); - } + return fcx; fn gather_locals(fcx: @mut FnCtxt, decl: &ast::fn_decl, @@ -903,7 +909,7 @@ pub impl FnCtxt { a: ty::t, err: &ty::type_err) { match self.fn_kind { - ForLoop if !ty::type_is_bool(e) && !ty::type_is_nil(a) => + ForLoop(_) if !ty::type_is_bool(e) && !ty::type_is_nil(a) => self.tcx().sess.span_err(sp, fmt!("A for-loop body must \ return (), but it returns %s here. \ Perhaps you meant to write a `do`-block?", @@ -1667,10 +1673,15 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_ty(expr.id, fty); + let inherited_purity = + ty::determine_inherited_purity(fcx.purity, purity, + fn_ty.sigil); + // We inherit the same self info as the enclosing scope, // since the function we're checking might capture `self` - check_fn(fcx.ccx, fcx.self_info, fn_ty.purity, Some(fn_ty.sigil), - &fn_ty.sig, decl, body, fn_kind, Some(fcx)); + check_fn(fcx.ccx, fcx.self_info, inherited_purity, + &fn_ty.sig, decl, body, fn_kind, + fcx.in_scope_regions, fcx.inh); } @@ -2080,7 +2091,13 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, // derived errors. If we passed in ForLoop in the // error case, we'd potentially emit a spurious error // message because of the indirect_ret_ty. - let fn_kind = if err_happened {Vanilla} else {ForLoop}; + let fn_kind = if err_happened { + Vanilla + } else { + let indirect_ret_ty = + fcx.indirect_ret_ty.get_or_default(fcx.ret_ty); + ForLoop(indirect_ret_ty) + }; check_expr_fn(fcx, loop_body, None, decl, body, fn_kind, Some(inner_ty)); demand::suptype(fcx, loop_body.span, From a36386210293cf12f771adb6bc775a45cab6b4da Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Sun, 10 Mar 2013 13:27:11 -0400 Subject: [PATCH 14/43] Fix formatting and errors in std::getopts example. There were three issues effecting the example in the getopts rustdoc: 1. The blockquote was incorrectly formatted. Fixed by switching to using an explicit markdown code section with ```. 2. The `fail fail_str(f)` would not compile. Fixed by using `fail!()` instead of `fail`. 3. The line `matches.free[0]` produced a compile error about moving from an immutable vector. Fix by using `copy`. --- src/libstd/getopts.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs index 2090a3728db52..d3f1ed72edceb 100644 --- a/src/libstd/getopts.rs +++ b/src/libstd/getopts.rs @@ -1,4 +1,4 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// Copyright 2011-2013 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -29,8 +29,10 @@ * The following example shows simple command line parsing for an application * that requires an input file to be specified, accepts an optional output * file name following -o, and accepts both -h and --help as optional flags. - * extern mod std; - * use std::getopts::*; + * + * ``` + * extern mod std; + * use std::getopts::*; * * fn do_work(in: &str, out: Option<~str>) { * io::println(in); @@ -58,7 +60,7 @@ * ]; * let matches = match getopts(vec::tail(args), opts) { * result::Ok(m) => { m } - * result::Err(f) => { fail fail_str(f) } + * result::Err(f) => { fail!(fail_str(f)) } * }; * if opt_present(&matches, "h") || opt_present(&matches, "help") { * print_usage(program, opts); @@ -66,13 +68,14 @@ * } * let output = opt_maybe_str(&matches, "o"); * let input: &str = if !matches.free.is_empty() { - * matches.free[0] + * copy matches.free[0] * } else { * print_usage(program, opts); * return; * }; * do_work(input, output); * } + * ``` */ use core::cmp::Eq; From 13e58597a18d3d4a696bdd84750839655580ea55 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Sun, 10 Mar 2013 20:47:28 -0400 Subject: [PATCH 15/43] Correct copyright year to be 2012-2013. Previous year range of 2011-2013 was based on file creation date. The check_license python script, however, only accepts copyrights starting in 2012 or later. --- src/libstd/getopts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs index d3f1ed72edceb..eed00ccacffcc 100644 --- a/src/libstd/getopts.rs +++ b/src/libstd/getopts.rs @@ -1,4 +1,4 @@ -// Copyright 2011-2013 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. // From e6b5e00ea215c64731360b45d5867ee0332a93c0 Mon Sep 17 00:00:00 2001 From: Jed Davis Date: Sun, 10 Mar 2013 22:58:44 -0700 Subject: [PATCH 16/43] Simplify struct representation. Out goes the extra layer of struct wrapping; the destructedness flag is added to the end of the struct. This means that, if the struct previously had alignment padding at the end, the flag will live there instead of increasing the struct size. --- src/librustc/middle/trans/adt.rs | 79 +++++++++++++------------------- 1 file changed, 31 insertions(+), 48 deletions(-) diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index e39de62cd297c..d816aefeb2fd8 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -81,8 +81,14 @@ pub enum Repr { Unit(int), /// C-like enums; basically an int. CEnum(int, int), // discriminant range - /// Single-case variants, and structs/tuples/records. - Univariant(Struct, Destructor), + /** + * Single-case variants, and structs/tuples/records. + * + * Structs with destructors need a dynamic destroyedness flag to + * avoid running the destructor too many times; this is included + * in the `Struct` if present. + */ + Univariant(Struct, bool), /** * General-case enums: discriminant as int, followed by fields. * The fields start immediately after the discriminant, meaning @@ -92,18 +98,6 @@ pub enum Repr { General(~[Struct]) } -/** - * Structs without destructors have historically had an extra layer of - * LLVM-struct to make accessing them work the same as structs with - * destructors. This could probably be flattened to a boolean now - * that this module exists. - */ -enum Destructor { - StructWithDtor, - StructWithoutDtor, - NonStruct -} - /// For structs, and struct-like parts of anything fancier. struct Struct { size: u64, @@ -129,14 +123,17 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> @Repr { } let repr = @match ty::get(t).sty { ty::ty_tup(ref elems) => { - Univariant(mk_struct(cx, *elems), NonStruct) + Univariant(mk_struct(cx, *elems), false) } ty::ty_struct(def_id, ref substs) => { let fields = ty::lookup_struct_fields(cx.tcx, def_id); - let dt = ty::ty_dtor(cx.tcx, def_id).is_present(); - Univariant(mk_struct(cx, fields.map(|field| { + let ftys = do fields.map |field| { ty::lookup_field_type(cx.tcx, def_id, field.id, substs) - })), if dt { StructWithDtor } else { StructWithoutDtor }) + }; + let dtor = ty::ty_dtor(cx.tcx, def_id).is_present(); + let ftys = + if dtor { ftys + [ty::mk_bool(cx.tcx)] } else { ftys }; + Univariant(mk_struct(cx, ftys), dtor) } ty::ty_enum(def_id, ref substs) => { struct Case { discr: int, tys: ~[ty::t] }; @@ -156,7 +153,7 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> @Repr { } else if cases.len() == 1 { // Equivalent to a struct/tuple/newtype. fail_unless!(cases[0].discr == 0); - Univariant(mk_struct(cx, cases[0].tys), NonStruct) + Univariant(mk_struct(cx, cases[0].tys), false) } else if cases.all(|c| c.tys.len() == 0) { // All bodies empty -> intlike let discrs = cases.map(|c| c.discr); @@ -206,16 +203,11 @@ fn generic_fields_of(cx: @CrateContext, r: &Repr, sizing: bool) match *r { Unit(*) => ~[], CEnum(*) => ~[T_enum_discrim(cx)], - Univariant(ref st, dt) => { - let f = if sizing { + Univariant(ref st, _dtor) => { + if sizing { st.fields.map(|&ty| type_of::sizing_type_of(cx, ty)) } else { st.fields.map(|&ty| type_of::type_of(cx, ty)) - }; - match dt { - NonStruct => f, - StructWithoutDtor => ~[T_struct(f)], - StructWithDtor => ~[T_struct(f), T_i8()] } } General(ref sts) => { @@ -308,9 +300,10 @@ pub fn trans_start_init(bcx: block, r: &Repr, val: ValueRef, discr: int) { fail_unless!(min <= discr && discr <= max); Store(bcx, C_int(bcx.ccx(), discr), GEPi(bcx, val, [0, 0])) } - Univariant(_, StructWithDtor) => { + Univariant(ref st, true) => { fail_unless!(discr == 0); - Store(bcx, C_u8(1), GEPi(bcx, val, [0, 1])) + Store(bcx, C_bool(true), + GEPi(bcx, val, [0, st.fields.len() - 1])) } Univariant(*) => { fail_unless!(discr == 0); @@ -328,7 +321,10 @@ pub fn trans_start_init(bcx: block, r: &Repr, val: ValueRef, discr: int) { pub fn num_args(r: &Repr, discr: int) -> uint { match *r { Unit(*) | CEnum(*) => 0, - Univariant(ref st, _) => { fail_unless!(discr == 0); st.fields.len() } + Univariant(ref st, dtor) => { + fail_unless!(discr == 0); + st.fields.len() - (if dtor { 1 } else { 0 }) + } General(ref cases) => cases[discr as uint].fields.len() } } @@ -343,12 +339,8 @@ pub fn trans_field_ptr(bcx: block, r: &Repr, val: ValueRef, discr: int, Unit(*) | CEnum(*) => { bcx.ccx().sess.bug(~"element access in C-like enum") } - Univariant(ref st, dt) => { + Univariant(ref st, _dtor) => { fail_unless!(discr == 0); - let val = match dt { - NonStruct => val, - StructWithDtor | StructWithoutDtor => GEPi(bcx, val, [0, 0]) - }; struct_field_ptr(bcx, st, val, ix, false) } General(ref cases) => { @@ -376,7 +368,7 @@ fn struct_field_ptr(bcx: block, st: &Struct, val: ValueRef, ix: uint, /// Access the struct drop flag, if present. pub fn trans_drop_flag_ptr(bcx: block, r: &Repr, val: ValueRef) -> ValueRef { match *r { - Univariant(_, StructWithDtor) => GEPi(bcx, val, [0, 1]), + Univariant(ref st, true) => GEPi(bcx, val, [0, st.fields.len() - 1]), _ => bcx.ccx().sess.bug(~"tried to get drop flag of non-droppable \ type") } @@ -415,15 +407,9 @@ pub fn trans_const(ccx: @CrateContext, r: &Repr, discr: int, fail_unless!(min <= discr && discr <= max); C_int(ccx, discr) } - Univariant(ref st, dt) => { + Univariant(ref st, _dro) => { fail_unless!(discr == 0); - let s = C_struct(build_const_struct(ccx, st, vals)); - match dt { - NonStruct => s, - // The actual destructor flag doesn't need to be present. - // But add an extra struct layer for compatibility. - StructWithDtor | StructWithoutDtor => C_struct(~[s]) - } + C_struct(build_const_struct(ccx, st, vals)) } General(ref cases) => { let case = &cases[discr as uint]; @@ -508,9 +494,7 @@ pub fn const_get_field(ccx: @CrateContext, r: &Repr, val: ValueRef, match *r { Unit(*) | CEnum(*) => ccx.sess.bug(~"element access in C-like enum \ const"), - Univariant(_, NonStruct) => const_struct_field(ccx, val, ix), - Univariant(*) => const_struct_field(ccx, const_get_elt(ccx, val, - [0]), ix), + Univariant(*) => const_struct_field(ccx, val, ix), General(*) => const_struct_field(ccx, const_get_elt(ccx, val, [1, 0]), ix) } @@ -542,8 +526,7 @@ fn const_struct_field(ccx: @CrateContext, val: ValueRef, ix: uint) /// Is it safe to bitcast a value to the one field of its one variant? pub fn is_newtypeish(r: &Repr) -> bool { match *r { - Univariant(ref st, StructWithoutDtor) - | Univariant(ref st, NonStruct) => st.fields.len() == 1, + Univariant(ref st, false) => st.fields.len() == 1, _ => false } } From 9eaa608b041165df6ddfc064561f31315c5cb21b Mon Sep 17 00:00:00 2001 From: Jed Davis Date: Sun, 10 Mar 2013 23:16:08 -0700 Subject: [PATCH 17/43] Get rid of the `Unit` enum representation. The only thing we really lose is that C-like enums with one variant and a non-zero discriminant now take up space, but I do not think this is a common usage. As previously noted, that was mostly there for transitional compatibility with the pre-adt.rs codebase. --- src/librustc/middle/trans/adt.rs | 40 ++++++++------------------------ 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index d816aefeb2fd8..66a32335020ac 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -71,14 +71,6 @@ use util::ppaux::ty_to_str; /// Representations. pub enum Repr { - /** - * `Unit` exists only so that an enum with a single C-like variant - * can occupy no space, for ABI compatibility with rustc from - * before (and during) the creation of this module. It may not be - * worth keeping around; `CEnum` and `Univariant` cover it - * overwise. - */ - Unit(int), /// C-like enums; basically an int. CEnum(int, int), // discriminant range /** @@ -146,18 +138,15 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> @Repr { }; if cases.len() == 0 { // Uninhabitable; represent as unit - Unit(0) - } else if cases.len() == 1 && cases[0].tys.len() == 0 { - // `()`-like; see comment on definition of `Unit`. - Unit(cases[0].discr) - } else if cases.len() == 1 { - // Equivalent to a struct/tuple/newtype. - fail_unless!(cases[0].discr == 0); - Univariant(mk_struct(cx, cases[0].tys), false) + Univariant(mk_struct(cx, ~[]), false) } else if cases.all(|c| c.tys.len() == 0) { // All bodies empty -> intlike let discrs = cases.map(|c| c.discr); CEnum(discrs.min(), discrs.max()) + } else if cases.len() == 1 { + // Equivalent to a struct/tuple/newtype. + fail_unless!(cases[0].discr == 0); + Univariant(mk_struct(cx, cases[0].tys), false) } else { // The general case. Since there's at least one // non-empty body, explicit discriminants should have @@ -201,7 +190,6 @@ pub fn sizing_fields_of(cx: @CrateContext, r: &Repr) -> ~[TypeRef] { fn generic_fields_of(cx: @CrateContext, r: &Repr, sizing: bool) -> ~[TypeRef] { match *r { - Unit(*) => ~[], CEnum(*) => ~[T_enum_discrim(cx)], Univariant(ref st, _dtor) => { if sizing { @@ -229,7 +217,7 @@ pub fn trans_switch(bcx: block, r: &Repr, scrutinee: ValueRef) CEnum(*) | General(*) => { (_match::switch, Some(trans_get_discr(bcx, r, scrutinee))) } - Unit(*) | Univariant(*) => { + Univariant(*) => { (_match::single, None) } } @@ -239,7 +227,6 @@ pub fn trans_switch(bcx: block, r: &Repr, scrutinee: ValueRef) pub fn trans_get_discr(bcx: block, r: &Repr, scrutinee: ValueRef) -> ValueRef { match *r { - Unit(the_disc) => C_int(bcx.ccx(), the_disc), CEnum(min, max) => load_discr(bcx, scrutinee, min, max), Univariant(*) => C_int(bcx.ccx(), 0), General(ref cases) => load_discr(bcx, scrutinee, 0, @@ -277,7 +264,7 @@ pub fn trans_case(bcx: block, r: &Repr, discr: int) -> _match::opt_result { CEnum(*) => { _match::single_result(rslt(bcx, C_int(bcx.ccx(), discr))) } - Unit(*) | Univariant(*)=> { + Univariant(*)=> { bcx.ccx().sess.bug(~"no cases for univariants or structs") } General(*) => { @@ -293,9 +280,6 @@ pub fn trans_case(bcx: block, r: &Repr, discr: int) -> _match::opt_result { */ pub fn trans_start_init(bcx: block, r: &Repr, val: ValueRef, discr: int) { match *r { - Unit(the_discr) => { - fail_unless!(discr == the_discr); - } CEnum(min, max) => { fail_unless!(min <= discr && discr <= max); Store(bcx, C_int(bcx.ccx(), discr), GEPi(bcx, val, [0, 0])) @@ -320,7 +304,7 @@ pub fn trans_start_init(bcx: block, r: &Repr, val: ValueRef, discr: int) { */ pub fn num_args(r: &Repr, discr: int) -> uint { match *r { - Unit(*) | CEnum(*) => 0, + CEnum(*) => 0, Univariant(ref st, dtor) => { fail_unless!(discr == 0); st.fields.len() - (if dtor { 1 } else { 0 }) @@ -336,7 +320,7 @@ pub fn trans_field_ptr(bcx: block, r: &Repr, val: ValueRef, discr: int, // decide to do some kind of cdr-coding-like non-unique repr // someday), it will need to return a possibly-new bcx as well. match *r { - Unit(*) | CEnum(*) => { + CEnum(*) => { bcx.ccx().sess.bug(~"element access in C-like enum") } Univariant(ref st, _dtor) => { @@ -399,9 +383,6 @@ pub fn trans_drop_flag_ptr(bcx: block, r: &Repr, val: ValueRef) -> ValueRef { pub fn trans_const(ccx: @CrateContext, r: &Repr, discr: int, vals: &[ValueRef]) -> ValueRef { match *r { - Unit(*) => { - C_struct(~[]) - } CEnum(min, max) => { fail_unless!(vals.len() == 0); fail_unless!(min <= discr && discr <= max); @@ -475,7 +456,6 @@ fn roundup(x: u64, a: u64) -> u64 { ((x + (a - 1)) / a) * a } pub fn const_get_discrim(ccx: @CrateContext, r: &Repr, val: ValueRef) -> int { match *r { - Unit(discr) => discr, CEnum(*) => const_to_int(val) as int, Univariant(*) => 0, General(*) => const_to_int(const_get_elt(ccx, val, [0])) as int, @@ -492,7 +472,7 @@ pub fn const_get_discrim(ccx: @CrateContext, r: &Repr, val: ValueRef) pub fn const_get_field(ccx: @CrateContext, r: &Repr, val: ValueRef, _discr: int, ix: uint) -> ValueRef { match *r { - Unit(*) | CEnum(*) => ccx.sess.bug(~"element access in C-like enum \ + CEnum(*) => ccx.sess.bug(~"element access in C-like enum \ const"), Univariant(*) => const_struct_field(ccx, val, ix), General(*) => const_struct_field(ccx, const_get_elt(ccx, val, From 9e85589ad3ba61169cd7722520981c1bebb5b542 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Wed, 27 Feb 2013 03:58:46 +0900 Subject: [PATCH 18/43] Implement vector destructuring from tail --- src/librustc/middle/borrowck/gather_loans.rs | 24 ++--- src/librustc/middle/check_match.rs | 56 +++++++----- src/librustc/middle/mem_categorization.rs | 17 ++-- src/librustc/middle/trans/_match.rs | 88 ++++++++++++------- src/librustc/middle/typeck/check/_match.rs | 16 ++-- src/librustc/middle/typeck/check/regionck.rs | 10 +-- src/libsyntax/ast.rs | 4 +- src/libsyntax/ast_util.rs | 11 ++- src/libsyntax/fold.rs | 7 +- src/libsyntax/parse/parser.rs | 40 +++++---- src/libsyntax/print/pprust.rs | 16 ++-- src/libsyntax/visit.rs | 9 +- src/test/compile-fail/alt-vec-invalid-2.rs | 6 -- src/test/compile-fail/alt-vec-invalid.rs | 2 +- .../borrowck-vec-pattern-element-loan.rs | 27 ++++-- src/test/run-pass/vec-matching-fold.rs | 33 +++++++ src/test/run-pass/vec-matching.rs | 34 ++----- 17 files changed, 241 insertions(+), 159 deletions(-) delete mode 100644 src/test/compile-fail/alt-vec-invalid-2.rs create mode 100644 src/test/run-pass/vec-matching-fold.rs diff --git a/src/librustc/middle/borrowck/gather_loans.rs b/src/librustc/middle/borrowck/gather_loans.rs index 94c266ab44fcb..6e998864def57 100644 --- a/src/librustc/middle/borrowck/gather_loans.rs +++ b/src/librustc/middle/borrowck/gather_loans.rs @@ -617,17 +617,17 @@ pub impl GatherLoanCtxt { } } - ast::pat_vec(_, Some(tail_pat)) => { - // The `tail_pat` here creates a slice into the + ast::pat_vec(_, Some(slice_pat), _) => { + // The `slice_pat` here creates a slice into the // original vector. This is effectively a borrow of // the elements of the vector being matched. - let tail_ty = self.tcx().ty(tail_pat); - let (tail_mutbl, tail_r) = - self.vec_slice_info(tail_pat, tail_ty); + let slice_ty = self.tcx().ty(slice_pat); + let (slice_mutbl, slice_r) = + self.vec_slice_info(slice_pat, slice_ty); let mcx = self.bccx.mc_ctxt(); - let cmt_index = mcx.cat_index(tail_pat, cmt); - self.guarantee_valid(cmt_index, tail_mutbl, tail_r); + let cmt_index = mcx.cat_index(slice_pat, cmt); + self.guarantee_valid(cmt_index, slice_mutbl, slice_r); } _ => {} @@ -637,7 +637,7 @@ pub impl GatherLoanCtxt { fn vec_slice_info(@mut self, pat: @ast::pat, - tail_ty: ty::t) -> (ast::mutability, ty::Region) { + slice_ty: ty::t) -> (ast::mutability, ty::Region) { /*! * * In a pattern like [a, b, ..c], normally `c` has slice type, @@ -646,9 +646,9 @@ pub impl GatherLoanCtxt { * to recurse through rptrs. */ - match ty::get(tail_ty).sty { - ty::ty_evec(tail_mt, ty::vstore_slice(tail_r)) => { - (tail_mt.mutbl, tail_r) + match ty::get(slice_ty).sty { + ty::ty_evec(slice_mt, ty::vstore_slice(slice_r)) => { + (slice_mt.mutbl, slice_r) } ty::ty_rptr(_, ref mt) => { @@ -658,7 +658,7 @@ pub impl GatherLoanCtxt { _ => { self.tcx().sess.span_bug( pat.span, - fmt!("Type of tail pattern is not a slice")); + fmt!("Type of slice pattern is not a slice")); } } } diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index a60b0332b8fb4..a7fb1506d181b 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -244,7 +244,9 @@ pub fn is_useful(cx: @MatchCheckCtxt, m: &matrix, v: &[@pat]) -> useful { ty::ty_unboxed_vec(*) | ty::ty_evec(*) => { let max_len = do m.foldr(0) |r, max_len| { match /*bad*/copy r[0].node { - pat_vec(elems, _) => uint::max(elems.len(), max_len), + pat_vec(before, _, after) => { + uint::max(before.len() + after.len(), max_len) + } _ => max_len } }; @@ -322,10 +324,10 @@ pub fn pat_ctor_id(cx: @MatchCheckCtxt, p: @pat) -> Option { pat_box(_) | pat_uniq(_) | pat_tup(_) | pat_region(*) => { Some(single) } - pat_vec(elems, tail) => { - match tail { + pat_vec(before, slice, after) => { + match slice { Some(_) => None, - None => Some(vec(elems.len())) + None => Some(vec(before.len() + after.len())) } } } @@ -393,22 +395,22 @@ pub fn missing_ctor(cx: @MatchCheckCtxt, } ty::ty_unboxed_vec(*) | ty::ty_evec(*) => { - // Find the lengths and tails of all vector patterns. + // Find the lengths and slices of all vector patterns. let vec_pat_lens = do m.filter_mapped |r| { match r[0].node { - pat_vec(ref elems, ref tail) => { - Some((elems.len(), tail.is_some())) + pat_vec(ref before, ref slice, ref after) => { + Some((before.len() + after.len(), slice.is_some())) } _ => None } }; // Sort them by length such that for patterns of the same length, - // those with a destructured tail come first. + // those with a destructured slice come first. let mut sorted_vec_lens = sort::merge_sort(vec_pat_lens, - |&(len1, tail1), &(len2, tail2)| { + |&(len1, slice1), &(len2, slice2)| { if len1 == len2 { - tail1 > tail2 + slice1 > slice2 } else { len1 <= len2 } @@ -416,24 +418,24 @@ pub fn missing_ctor(cx: @MatchCheckCtxt, ); vec::dedup(&mut sorted_vec_lens); - let mut found_tail = false; + let mut found_slice = false; let mut next = 0; let mut missing = None; - for sorted_vec_lens.each |&(length, tail)| { + for sorted_vec_lens.each |&(length, slice)| { if length != next { missing = Some(next); break; } - if tail { - found_tail = true; + if slice { + found_slice = true; break; } next += 1; } // We found patterns of all lengths within <0, next), yet there was no - // pattern with a tail - therefore, we report vec(next) as missing. - if !found_tail { + // pattern with a slice - therefore, we report vec(next) as missing. + if !found_slice { missing = Some(next); } match missing { @@ -621,19 +623,25 @@ pub fn specialize(cx: @MatchCheckCtxt, compare_const_vals(c_hi, v_hi) <= 0; if match_ { Some(vec::from_slice(r.tail())) } else { None } } - pat_vec(elems, tail) => { + pat_vec(before, slice, after) => { match ctor_id { vec(_) => { - let num_elements = elems.len(); - if num_elements < arity && tail.is_some() { + let num_elements = before.len() + after.len(); + if num_elements < arity && slice.is_some() { Some(vec::append( - vec::append(elems, vec::from_elem( - arity - num_elements, wild() - )), - vec::from_slice(r.tail()) + vec::concat(&[ + before, + vec::from_elem( + arity - num_elements, wild()), + after + ]), + r.tail() )) } else if num_elements == arity { - Some(vec::append(elems, r.tail())) + Some(vec::append( + vec::append(before, after), + r.tail() + )) } else { None } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 00cab7961cada..85ff970be1cac 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -963,16 +963,19 @@ pub impl mem_categorization_ctxt { self.cat_pattern(subcmt, subpat, op); } - ast::pat_vec(ref pats, opt_tail_pat) => { - for pats.each |pat| { + ast::pat_vec(ref before, slice, ref after) => { + for before.each |pat| { let elt_cmt = self.cat_index(*pat, cmt); self.cat_pattern(elt_cmt, *pat, op); } - - for opt_tail_pat.each |tail_pat| { - let tail_ty = self.tcx.ty(*tail_pat); - let tail_cmt = self.cat_rvalue(*tail_pat, tail_ty); - self.cat_pattern(tail_cmt, *tail_pat, op); + for slice.each |slice_pat| { + let slice_ty = self.tcx.ty(*slice_pat); + let slice_cmt = self.cat_rvalue(*slice_pat, slice_ty); + self.cat_pattern(slice_cmt, *slice_pat, op); + } + for after.each |pat| { + let elt_cmt = self.cat_index(*pat, cmt); + self.cat_pattern(elt_cmt, *pat, op); } } diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 8411064c57aef..d4a7c104500ba 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -190,7 +190,7 @@ pub enum Opt { var(/* disr val */int, @adt::Repr), range(@ast::expr, @ast::expr), vec_len_eq(uint), - vec_len_ge(uint) + vec_len_ge(uint, /* slice */uint) } pub fn opt_eq(tcx: ty::ctxt, a: &Opt, b: &Opt) -> bool { @@ -235,7 +235,7 @@ pub fn opt_eq(tcx: ty::ctxt, a: &Opt, b: &Opt) -> bool { } (&var(a, _), &var(b, _)) => a == b, (&vec_len_eq(a), &vec_len_eq(b)) => a == b, - (&vec_len_ge(a), &vec_len_ge(b)) => a == b, + (&vec_len_ge(a, _), &vec_len_ge(b, _)) => a == b, _ => false } } @@ -273,7 +273,7 @@ pub fn trans_opt(bcx: block, o: &Opt) -> opt_result { vec_len_eq(n) => { return single_result(rslt(bcx, C_int(ccx, n as int))); } - vec_len_ge(n) => { + vec_len_ge(n, _) => { return lower_bound(rslt(bcx, C_int(ccx, n as int))); } } @@ -565,18 +565,22 @@ pub fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint, None } } - ast::pat_vec(elems, tail) => { - match tail { + ast::pat_vec(before, slice, after) => { + match slice { Some(_) => { - if opt_eq(tcx, &vec_len_ge(elems.len()), opt) { - Some(vec::append_one(elems, tail.get())) + let n = before.len() + after.len(); + let i = before.len(); + if opt_eq(tcx, &vec_len_ge(n, i), opt) { + Some(vec::concat( + &[before, ~[slice.get()], after])) } else { None } } None => { - if opt_eq(tcx, &vec_len_eq(elems.len()), opt) { - Some(copy elems) + let n = before.len(); + if opt_eq(tcx, &vec_len_eq(n), opt) { + Some(copy before) } else { None } @@ -807,10 +811,11 @@ pub fn get_options(bcx: block, m: &[@Match], col: uint) -> ~[Opt] { ast::pat_range(l1, l2) => { add_to_set(ccx.tcx, &mut found, range(l1, l2)); } - ast::pat_vec(elems, tail) => { - let opt = match tail { - None => vec_len_eq(elems.len()), - Some(_) => vec_len_ge(elems.len()) + ast::pat_vec(before, slice, after) => { + let opt = match slice { + None => vec_len_eq(before.len()), + Some(_) => vec_len_ge(before.len() + after.len(), + before.len()) }; add_to_set(ccx.tcx, &mut found, opt); } @@ -841,8 +846,9 @@ pub fn extract_variant_args(bcx: block, pub fn extract_vec_elems(bcx: block, pat_id: ast::node_id, elem_count: uint, - tail: bool, - val: ValueRef) + slice: Option, + val: ValueRef, + count: ValueRef) -> ExtractedBlock { let _icx = bcx.insn_ctxt("match::extract_vec_elems"); let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id)); @@ -850,26 +856,39 @@ pub fn extract_vec_elems(bcx: block, let (base, len) = tvec::get_base_and_len(bcx, unboxed, vt.vec_ty); let mut elems = do vec::from_fn(elem_count) |i| { - GEPi(bcx, base, ~[i]) + match slice { + None => GEPi(bcx, base, ~[i]), + Some(n) if i < n => GEPi(bcx, base, ~[i]), + Some(n) if i > n => { + InBoundsGEP(bcx, base, ~[ + Sub(bcx, count, + C_int(bcx.ccx(), (elem_count - i) as int))]) + } + _ => unsafe { llvm::LLVMGetUndef(vt.llunit_ty) } + } }; - if tail { - let tail_offset = Mul(bcx, vt.llunit_size, - C_int(bcx.ccx(), elem_count as int) + if slice.is_some() { + let n = slice.get(); + let slice_offset = Mul(bcx, vt.llunit_size, + C_int(bcx.ccx(), n as int) + ); + let slice_begin = tvec::pointer_add(bcx, base, slice_offset); + let slice_len_offset = Mul(bcx, vt.llunit_size, + C_int(bcx.ccx(), (elem_count - 1u) as int) ); - let tail_begin = tvec::pointer_add(bcx, base, tail_offset); - let tail_len = Sub(bcx, len, tail_offset); - let tail_ty = ty::mk_evec(bcx.tcx(), + let slice_len = Sub(bcx, len, slice_len_offset); + let slice_ty = ty::mk_evec(bcx.tcx(), ty::mt {ty: vt.unit_ty, mutbl: ast::m_imm}, ty::vstore_slice(ty::re_static) ); - let scratch = scratch_datum(bcx, tail_ty, false); - Store(bcx, tail_begin, + let scratch = scratch_datum(bcx, slice_ty, false); + Store(bcx, slice_begin, GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]) ); - Store(bcx, tail_len, + Store(bcx, slice_len, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len]) ); - elems.push(scratch.val); + elems[n] = scratch.val; scratch.add_clean(bcx); } @@ -1367,7 +1386,7 @@ pub fn compile_submatch(bcx: block, test_val = Load(bcx, val); kind = compare; }, - vec_len_eq(_) | vec_len_ge(_) => { + vec_len_eq(*) | vec_len_ge(*) => { let vt = tvec::vec_types(bcx, node_id_type(bcx, pat_id)); let unboxed = load_if_immediate(bcx, val, vt.vec_ty); let (_, len) = tvec::get_base_and_len( @@ -1511,12 +1530,17 @@ pub fn compile_submatch(bcx: block, unpacked = argvals; opt_cx = new_bcx; } - vec_len_eq(n) | vec_len_ge(n) => { - let tail = match *opt { - vec_len_ge(_) => true, - _ => false + vec_len_eq(n) | vec_len_ge(n, _) => { + let n = match *opt { + vec_len_ge(*) => n + 1u, + _ => n + }; + let slice = match *opt { + vec_len_ge(_, i) => Some(i), + _ => None }; - let args = extract_vec_elems(opt_cx, pat_id, n, tail, val); + let args = extract_vec_elems(opt_cx, pat_id, n, slice, + val, test_val); size = args.vals.len(); unpacked = /*bad*/copy args.vals; opt_cx = args.bcx; diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 1da4cbe7c91cc..4b7def26fd559 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -509,7 +509,7 @@ pub fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) { } } } - ast::pat_vec(elts, tail) => { + ast::pat_vec(before, slice, after) => { let default_region_var = fcx.infcx().next_region_var_with_lb( pat.span, pcx.block_region @@ -538,21 +538,23 @@ pub fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) { ); } }; - for elts.each |elt| { + for before.each |elt| { check_pat(pcx, *elt, elt_type.ty); } - fcx.write_ty(pat.id, expected); - - match tail { - Some(tail_pat) => { + match slice { + Some(slice_pat) => { let slice_ty = ty::mk_evec(tcx, ty::mt {ty: elt_type.ty, mutbl: elt_type.mutbl}, ty::vstore_slice(region_var) ); - check_pat(pcx, tail_pat, slice_ty); + check_pat(pcx, slice_pat, slice_ty); } None => () } + for after.each |elt| { + check_pat(pcx, *elt, elt_type.ty); + } + fcx.write_ty(pat.id, expected); } } } diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 818a444a4f38c..55d027549e30c 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -896,7 +896,7 @@ pub mod guarantor { } ast::pat_lit(*) => {} ast::pat_range(*) => {} - ast::pat_vec(ref ps, ref opt_tail_pat) => { + ast::pat_vec(ref before, ref slice, ref after) => { let vec_ty = rcx.resolve_node_type(pat.id); if !ty::type_contains_err(vec_ty) { let vstore = ty::ty_vstore(vec_ty); @@ -906,11 +906,11 @@ pub mod guarantor { ty::vstore_box => None }; - link_ref_bindings_in_pats(rcx, ps, guarantor1); - - for opt_tail_pat.each |p| { - link_ref_bindings_in_pat(rcx, *p, guarantor); + link_ref_bindings_in_pats(rcx, before, guarantor1); + for slice.each |&p| { + link_ref_bindings_in_pat(rcx, p, guarantor); } + link_ref_bindings_in_pats(rcx, after, guarantor1); } } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 3782208eb851c..f3e73823f69b3 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -309,7 +309,9 @@ pub enum pat_ { pat_region(@pat), // borrowed pointer pattern pat_lit(@expr), pat_range(@expr, @expr), - pat_vec(~[@pat], Option<@pat>) + // [a, b, ..i, y, z] is represented as + // pat_vec(~[a, b], Some(i), ~[y, z]) + pat_vec(~[@pat], Option<@pat>, ~[@pat]) } #[auto_encode] diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 686ae3900ff43..7b0e72e6e956e 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -533,12 +533,15 @@ pub fn walk_pat(pat: @pat, it: fn(@pat)) { pat_box(s) | pat_uniq(s) | pat_region(s) => { walk_pat(s, it) } - pat_vec(ref elts, ref tail) => { - for elts.each |p| { + pat_vec(ref before, ref slice, ref after) => { + for before.each |p| { walk_pat(*p, it) } - for tail.each |tail| { - walk_pat(*tail, it) + for slice.each |p| { + walk_pat(*p, it) + } + for after.each |p| { + walk_pat(*p, it) } } pat_wild | pat_lit(_) | pat_range(_, _) | pat_ident(_, _, _) | diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index b8371c9e8d962..2a5fe7887704d 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -416,10 +416,11 @@ pub fn noop_fold_pat(p: &pat_, fld: @ast_fold) -> pat_ { pat_range(e1, e2) => { pat_range(fld.fold_expr(e1), fld.fold_expr(e2)) }, - pat_vec(ref elts, ref tail) => { + pat_vec(ref before, ref slice, ref after) => { pat_vec( - elts.map(|x| fld.fold_pat(*x)), - tail.map(|tail| fld.fold_pat(*tail)) + before.map(|x| fld.fold_pat(*x)), + slice.map(|x| fld.fold_pat(*x)), + after.map(|x| fld.fold_pat(*x)) ) } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index adcaa006247fa..38cd09abad42b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2024,23 +2024,28 @@ pub impl Parser { fn parse_pat_vec_elements( &self, refutable: bool - ) -> (~[@pat], Option<@pat>) { - let mut elements = ~[]; - let mut tail = None; + ) -> (~[@pat], Option<@pat>, ~[@pat]) { + let mut before = ~[]; + let mut slice = None; + let mut after = ~[]; let mut first = true; + let mut before_slice = true; while *self.token != token::RBRACKET { if first { first = false; } else { self.expect(&token::COMMA); } - let mut is_tail = false; - if *self.token == token::DOTDOT { - self.bump(); - is_tail = true; + let mut is_slice = false; + if before_slice { + if *self.token == token::DOTDOT { + self.bump(); + is_slice = true; + before_slice = false; + } } let subpat = self.parse_pat(refutable); - if is_tail { + if is_slice { match subpat { @ast::pat { node: pat_wild, _ } => (), @ast::pat { node: pat_ident(_, _, _), _ } => (), @@ -2048,13 +2053,17 @@ pub impl Parser { span, ~"expected an identifier or `_`" ) } - tail = Some(subpat); - break; + slice = Some(subpat); + } else { + if before_slice { + before.push(subpat); + } else { + after.push(subpat); + } } - - elements.push(subpat); } - return (elements, tail); + + (before, slice, after) } fn parse_pat_fields(&self, refutable: bool) -> (~[ast::field_pat], bool) { @@ -2208,10 +2217,11 @@ pub impl Parser { } token::LBRACKET => { self.bump(); - let (elements, tail) = self.parse_pat_vec_elements(refutable); + let (before, slice, after) = + self.parse_pat_vec_elements(refutable); hi = self.span.hi; self.expect(&token::RBRACKET); - pat = ast::pat_vec(elements, tail); + pat = ast::pat_vec(before, slice, after); } copy tok => { if !is_ident_or_path(&tok) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 3744b7a8f6c03..c81c1c8bd0e1a 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1609,13 +1609,19 @@ pub fn print_pat(s: @ps, &&pat: @ast::pat, refutable: bool) { word(s.s, ~".."); print_expr(s, end); } - ast::pat_vec(elts, tail) => { + ast::pat_vec(before, slice, after) => { word(s.s, ~"["); - commasep(s, inconsistent, elts, |s, p| print_pat(s, p, refutable)); - for tail.each |tail| { - if vec::len(elts) != 0u { word_space(s, ~","); } + do commasep(s, inconsistent, before) |s, p| { + print_pat(s, p, refutable); + } + for slice.each |&p| { + if !before.is_empty() { word_space(s, ~","); } word(s.s, ~".."); - print_pat(s, *tail, refutable); + print_pat(s, p, refutable); + if !after.is_empty() { word_space(s, ~","); } + } + do commasep(s, inconsistent, after) |s, p| { + print_pat(s, p, refutable); } word(s.s, ~"]"); } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 6048256b90bfe..f04894729bd0c 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -287,11 +287,14 @@ pub fn visit_pat(p: @pat, e: E, v: vt) { (v.visit_expr)(e2, e, v); } pat_wild => (), - pat_vec(ref elts, ref tail) => { - for elts.each |elt| { + pat_vec(ref before, ref slice, ref after) => { + for before.each |elt| { + (v.visit_pat)(*elt, e, v); + } + for slice.each |elt| { (v.visit_pat)(*elt, e, v); } - for tail.each |tail| { + for after.each |tail| { (v.visit_pat)(*tail, e, v); } } diff --git a/src/test/compile-fail/alt-vec-invalid-2.rs b/src/test/compile-fail/alt-vec-invalid-2.rs deleted file mode 100644 index 4174120b291c6..0000000000000 --- a/src/test/compile-fail/alt-vec-invalid-2.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - match ~[] { - [_, ..tail, _] => {}, //~ ERROR: expected `]` but found `,` - _ => () - } -} diff --git a/src/test/compile-fail/alt-vec-invalid.rs b/src/test/compile-fail/alt-vec-invalid.rs index b35731c2e4acd..2cf2d5b93b056 100644 --- a/src/test/compile-fail/alt-vec-invalid.rs +++ b/src/test/compile-fail/alt-vec-invalid.rs @@ -1,7 +1,7 @@ fn main() { let a = ~[]; match a { - [1, ..tail, ..tail] => {}, //~ ERROR: expected `]` but found `,` + [1, ..tail, ..tail] => {}, //~ ERROR: unexpected token: `..` _ => () } } diff --git a/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs b/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs index cec81d8a6ef5b..c8a0dbedd5d95 100644 --- a/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs +++ b/src/test/compile-fail/borrowck-vec-pattern-element-loan.rs @@ -1,15 +1,28 @@ fn a() -> &[int] { let vec = [1, 2, 3, 4]; let tail = match vec { //~ ERROR illegal borrow - [_a, ..tail] => tail, - _ => fail!(~"foo") + [_, ..tail] => tail, + _ => fail!(~"a") }; tail } -fn main() { - let tail = a(); - for tail.each |n| { - io::println(fmt!("%d", *n)); - } +fn b() -> &[int] { + let vec = [1, 2, 3, 4]; + let init = match vec { //~ ERROR illegal borrow + [..init, _] => init, + _ => fail!(~"b") + }; + init } + +fn c() -> &[int] { + let vec = [1, 2, 3, 4]; + let slice = match vec { //~ ERROR illegal borrow + [_, ..slice, _] => slice, + _ => fail!(~"c") + }; + slice +} + +fn main() {} diff --git a/src/test/run-pass/vec-matching-fold.rs b/src/test/run-pass/vec-matching-fold.rs new file mode 100644 index 0000000000000..1df90bf681cfb --- /dev/null +++ b/src/test/run-pass/vec-matching-fold.rs @@ -0,0 +1,33 @@ +fn foldl( + values: &[T], + initial: U, + function: &fn(partial: U, element: &T) -> U +) -> U { + match values { + [head, ..tail] => + foldl(tail, function(initial, &head), function), + [] => copy initial + } +} + +fn foldr( + values: &[T], + initial: U, + function: &fn(element: &T, partial: U) -> U +) -> U { + match values { + [..head, tail] => + foldr(head, function(&tail, initial), function), + [] => copy initial + } +} + +pub fn main() { + let x = [1, 2, 3, 4, 5]; + + let product = foldl(x, 1, |a, b| a * *b); + fail_unless!(product == 120); + + let sum = foldr(x, 0, |a, b| *a + b); + fail_unless!(sum == 15); +} diff --git a/src/test/run-pass/vec-matching.rs b/src/test/run-pass/vec-matching.rs index 1cbd0d78c021d..e1243e18f5ffb 100644 --- a/src/test/run-pass/vec-matching.rs +++ b/src/test/run-pass/vec-matching.rs @@ -1,33 +1,13 @@ -fn foldl( - values: &[T], - initial: U, - function: &fn(partial: U, element: &T) -> U -) -> U { - match values { - [head, ..tail] => - foldl(tail, function(initial, &head), function), - _ => copy initial - } -} - pub fn main() { - let x = [1, 2, 3, 4, 5]; + let x = [1]; match x { - [a, b, c, d, e, f] => { - ::core::util::unreachable(); - } - [a, b, c, d, e] => { + [_, _, _, _, _, .._] => ::core::util::unreachable(), + [.._, _, _, _, _] => ::core::util::unreachable(), + [_, .._, _, _] => ::core::util::unreachable(), + [_, _] => ::core::util::unreachable(), + [a] => { fail_unless!(a == 1); - fail_unless!(b == 2); - fail_unless!(c == 3); - fail_unless!(d == 4); - fail_unless!(e == 5); - } - _ => { - ::core::util::unreachable(); } + [] => ::core::util::unreachable() } - - let product = foldl(x, 1, |a, b| a * *b); - fail_unless!(product == 120); } From 070137ce905d0177e8d112385f1d8dc7b2407006 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Mon, 11 Mar 2013 19:53:41 +0900 Subject: [PATCH 19/43] Add one more test for vector destructuring --- src/test/run-pass/vec-matching.rs | 43 ++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/test/run-pass/vec-matching.rs b/src/test/run-pass/vec-matching.rs index e1243e18f5ffb..1402dd18fc72d 100644 --- a/src/test/run-pass/vec-matching.rs +++ b/src/test/run-pass/vec-matching.rs @@ -1,4 +1,4 @@ -pub fn main() { +fn a() { let x = [1]; match x { [_, _, _, _, _, .._] => ::core::util::unreachable(), @@ -11,3 +11,44 @@ pub fn main() { [] => ::core::util::unreachable() } } + +fn b() { + let x = [1, 2, 3]; + match x { + [a, b, ..c] => { + fail_unless!(a == 1); + fail_unless!(b == 2); + fail_unless!(c == &[3]); + } + _ => fail!() + } + match x { + [..a, b, c] => { + fail_unless!(a == &[1]); + fail_unless!(b == 2); + fail_unless!(c == 3); + } + _ => fail!() + } + match x { + [a, ..b, c] => { + fail_unless!(a == 1); + fail_unless!(b == &[2]); + fail_unless!(c == 3); + } + _ => fail!() + } + match x { + [a, b, c] => { + fail_unless!(a == 1); + fail_unless!(b == 2); + fail_unless!(c == 3); + } + _ => fail!() + } +} + +pub fn main() { + a(); + b(); +} From d18f7854578e8c2e1d7dce90db6e3b5cf9befba9 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 7 Mar 2013 14:38:38 -0800 Subject: [PATCH 20/43] librustc: Replace all uses of `fn()` with `&fn()`. rs=defun --- src/compiletest/header.rs | 2 +- src/compiletest/runtest.rs | 2 +- src/libcore/at_vec.rs | 6 +- src/libcore/bool.rs | 2 +- src/libcore/cell.rs | 2 +- src/libcore/cleanup.rs | 2 +- src/libcore/container.rs | 12 +- src/libcore/dlist.rs | 2 +- src/libcore/either.rs | 6 +- src/libcore/hashmap.rs | 24 +- src/libcore/io.rs | 30 +-- src/libcore/iter.rs | 52 ++-- src/libcore/num/int-template.rs | 8 +- src/libcore/num/uint-template.rs | 8 +- src/libcore/num/uint-template/uint.rs | 4 +- src/libcore/option.rs | 30 +-- src/libcore/os.rs | 12 +- src/libcore/pipes.rs | 2 +- src/libcore/ptr.rs | 2 +- src/libcore/reflect.rs | 2 +- src/libcore/repr.rs | 4 +- src/libcore/result.rs | 32 +-- src/libcore/run.rs | 8 +- src/libcore/stackwalk.rs | 4 +- src/libcore/str.rs | 94 ++++---- src/libcore/sys.rs | 4 +- src/libcore/task/local_data.rs | 2 +- src/libcore/task/local_data_priv.rs | 2 +- src/libcore/task/mod.rs | 8 +- src/libcore/task/spawn.rs | 12 +- src/libcore/trie.rs | 24 +- src/libcore/unstable.rs | 6 +- src/libcore/vec.rs | 226 +++++++++--------- src/libfuzzer/fuzzer.rc | 2 +- src/librustc/back/link.rs | 2 +- src/librustc/driver/driver.rs | 2 +- src/librustc/driver/session.rs | 2 +- src/librustc/metadata/csearch.rs | 2 +- src/librustc/metadata/cstore.rs | 2 +- src/librustc/metadata/decoder.rs | 10 +- src/librustc/metadata/encoder.rs | 2 +- src/librustc/metadata/tydecode.rs | 2 +- src/librustc/metadata/tyencode.rs | 2 +- src/librustc/middle/astencode.rs | 4 +- src/librustc/middle/borrowck/mod.rs | 2 +- src/librustc/middle/kind.rs | 2 +- src/librustc/middle/lint.rs | 2 +- src/librustc/middle/liveness.rs | 13 +- src/librustc/middle/mem_categorization.rs | 2 +- src/librustc/middle/pat_util.rs | 2 +- src/librustc/middle/resolve.rs | 8 +- src/librustc/middle/trans/base.rs | 20 +- src/librustc/middle/trans/cabi.rs | 2 +- src/librustc/middle/trans/cabi_x86_64.rs | 2 +- src/librustc/middle/trans/callee.rs | 2 +- src/librustc/middle/trans/datum.rs | 2 +- src/librustc/middle/trans/debuginfo.rs | 2 +- src/librustc/middle/trans/expr.rs | 2 +- src/librustc/middle/ty.rs | 36 +-- src/librustc/middle/typeck/astconv.rs | 4 +- src/librustc/middle/typeck/check/demand.rs | 2 +- src/librustc/middle/typeck/check/mod.rs | 4 +- .../middle/typeck/check/regionmanip.rs | 6 +- src/librustc/middle/typeck/infer/glb.rs | 2 +- src/librustc/middle/typeck/infer/mod.rs | 16 +- .../middle/typeck/infer/region_inference.rs | 30 +-- src/librustc/middle/typeck/mod.rs | 2 +- src/librustc/util/common.rs | 2 +- src/librustdoc/rustdoc.rc | 2 +- src/librusti/rusti.rc | 2 +- src/librustpkg/util.rs | 2 +- src/libstd/arc.rs | 16 +- src/libstd/arena.rs | 6 +- src/libstd/bitv.rs | 30 +-- src/libstd/ebml.rs | 70 +++--- src/libstd/fun_treemap.rs | 2 +- src/libstd/json.rs | 86 +++---- src/libstd/list.rs | 8 +- src/libstd/md4.rs | 2 +- src/libstd/oldmap.rs | 14 +- src/libstd/prettyprint.rs | 30 +-- src/libstd/priority_queue.rs | 2 +- src/libstd/rope.rs | 10 +- src/libstd/semver.rs | 2 +- src/libstd/serialize.rs | 64 ++--- src/libstd/smallintmap.rs | 12 +- src/libstd/sync.rs | 32 +-- src/libstd/treemap.rs | 32 +-- src/libstd/workcache.rs | 2 +- src/libsyntax/ast_map.rs | 2 +- src/libsyntax/ast_util.rs | 2 +- src/libsyntax/diagnostic.rs | 2 +- src/libsyntax/ext/auto_encode.rs | 32 +-- src/libsyntax/ext/pipes/proto.rs | 2 +- src/libsyntax/opt_vec.rs | 20 +- src/libsyntax/parse/common.rs | 12 +- src/libsyntax/parse/mod.rs | 2 +- src/libsyntax/parse/parser.rs | 6 +- src/libsyntax/print/pprust.rs | 4 +- src/test/auxiliary/cci_impl_lib.rs | 4 +- src/test/auxiliary/cci_iter_lib.rs | 2 +- src/test/auxiliary/cci_no_inline_lib.rs | 2 +- src/test/bench/core-map.rs | 2 +- src/test/bench/core-set.rs | 6 +- src/test/bench/core-std.rs | 2 +- src/test/bench/pingpong.rs | 4 +- src/test/bench/shootout-k-nucleotide-pipes.rs | 2 +- src/test/compile-fail/arg-style-mismatch.rs | 2 +- src/test/compile-fail/bad-for-loop.rs | 2 +- src/test/compile-fail/block-coerce-no.rs | 6 +- .../compile-fail/borrowck-assign-comp-idx.rs | 2 +- .../compile-fail/borrowck-autoref-3261.rs | 2 +- .../borrowck-insert-during-each.rs | 2 +- src/test/compile-fail/borrowck-lend-flow.rs | 2 +- .../borrowck-loan-blocks-move-cc.rs | 2 +- .../borrowck-loan-blocks-mut-uniq.rs | 2 +- src/test/compile-fail/borrowck-loan-rcvr.rs | 4 +- .../compile-fail/borrowck-loan-vec-content.rs | 4 +- src/test/compile-fail/closure-that-fails.rs | 2 +- .../compile-fail/extern-wrong-value-type.rs | 2 +- src/test/compile-fail/fn-variance-1.rs | 2 +- .../compile-fail/immut-function-arguments.rs | 2 +- src/test/compile-fail/issue-2149.rs | 4 +- src/test/compile-fail/issue-2817-2.rs | 2 +- .../liveness-closure-require-ret.rs | 2 +- src/test/compile-fail/missing-do.rs | 2 +- src/test/compile-fail/mode-inference-fail.rs | 4 +- src/test/compile-fail/pure-higher-order.rs | 6 +- src/test/compile-fail/purity-infer-fail.rs | 2 +- src/test/compile-fail/qquote-1.rs | 2 +- src/test/compile-fail/qquote-2.rs | 2 +- .../compile-fail/regions-creating-enums.rs | 2 +- .../compile-fail/regions-escape-bound-fn-2.rs | 2 +- .../compile-fail/regions-escape-bound-fn.rs | 2 +- .../regions-escape-via-trait-or-not.rs | 2 +- .../regions-infer-borrow-scope-within-loop.rs | 2 +- src/test/compile-fail/regions-infer-call-3.rs | 2 +- .../compile-fail/regions-ret-borrowed-1.rs | 2 +- src/test/compile-fail/regions-ret-borrowed.rs | 2 +- src/test/compile-fail/regions-scoping.rs | 2 +- .../compile-fail/type-arg-out-of-scope.rs | 2 +- src/test/run-fail/unwind-iter.rs | 2 +- src/test/run-fail/unwind-iter2.rs | 2 +- src/test/run-pass-fulldeps/qquote.rs | 2 +- src/test/run-pass/alt-phi.rs | 2 +- src/test/run-pass/assignability-trait.rs | 6 +- src/test/run-pass/autobind.rs | 4 +- .../block-arg-can-be-followed-by-block-arg.rs | 2 +- src/test/run-pass/block-arg-used-as-any.rs | 2 +- src/test/run-pass/block-explicit-types.rs | 2 +- src/test/run-pass/block-fn-coerce.rs | 2 +- src/test/run-pass/block-iter-1.rs | 2 +- src/test/run-pass/block-iter-2.rs | 2 +- .../borrowck-borrow-from-expr-block.rs | 2 +- src/test/run-pass/borrowck-mut-uniq.rs | 2 +- .../borrowck-preserve-box-in-field.rs | 2 +- .../run-pass/borrowck-preserve-box-in-uniq.rs | 2 +- src/test/run-pass/borrowck-preserve-box.rs | 2 +- .../run-pass/borrowck-preserve-expl-deref.rs | 2 +- .../class-impl-parameterized-trait.rs | 6 +- .../class-impl-very-parameterized-trait.rs | 6 +- .../run-pass/class-trait-bounded-param.rs | 4 +- src/test/run-pass/closure-inference.rs | 2 +- src/test/run-pass/do-for-empty-args.rs | 2 +- src/test/run-pass/do-pure.rs | 2 +- .../run-pass/fn-assign-managed-to-bare-1.rs | 2 +- src/test/run-pass/fn-bare-coerce-to-block.rs | 2 +- src/test/run-pass/fn-pattern-expected-type.rs | 2 +- src/test/run-pass/foreach-nested.rs | 2 +- src/test/run-pass/foreach-put-structured.rs | 2 +- .../run-pass/foreach-simple-outer-slot.rs | 2 +- src/test/run-pass/issue-1458.rs | 2 +- src/test/run-pass/issue-2185.rs | 6 +- src/test/run-pass/issue-2487-a.rs | 2 +- src/test/run-pass/issue-2611.rs | 4 +- src/test/run-pass/issue-3874.rs | 2 +- src/test/run-pass/issue-868.rs | 2 +- src/test/run-pass/issue-912.rs | 2 +- src/test/run-pass/iter-range.rs | 2 +- src/test/run-pass/last-use-in-block.rs | 6 +- src/test/run-pass/monad.rs | 8 +- src/test/run-pass/mut-function-arguments.rs | 2 +- src/test/run-pass/newlambdas.rs | 2 +- src/test/run-pass/non-legacy-modes.rs | 2 +- src/test/run-pass/pipe-bank-proto.rs | 2 +- src/test/run-pass/purity-infer.rs | 2 +- src/test/run-pass/reflect-visit-data.rs | 6 +- src/test/run-pass/regions-fn-subtyping-2.rs | 4 +- src/test/run-pass/regions-infer-call-2.rs | 2 +- src/test/run-pass/regions-params.rs | 2 +- src/test/run-pass/ret-break-cont-in-block.rs | 2 +- src/test/run-pass/sendfn-is-a-block.rs | 2 +- src/test/run-pass/static-impl.rs | 12 +- src/test/run-pass/static-method-test.rs | 10 +- src/test/run-pass/task-killjoin-rsrc.rs | 2 +- src/test/run-pass/trait-generic.rs | 4 +- src/test/run-pass/type-params-in-for-each.rs | 2 +- src/test/run-pass/unnamed_argument_mode.rs | 2 +- 198 files changed, 813 insertions(+), 812 deletions(-) diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index daa3036687c44..7d0a4d7dcc805 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -103,7 +103,7 @@ pub fn is_test_ignored(config: config, testfile: &Path) -> bool { } } -fn iter_header(testfile: &Path, it: fn(~str) -> bool) -> bool { +fn iter_header(testfile: &Path, it: &fn(~str) -> bool) -> bool { let rdr = io::file_reader(testfile).get(); while !rdr.eof() { let ln = rdr.read_line(); diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index e0db543250d66..f95a530831b93 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -530,7 +530,7 @@ fn compose_and_run(config: config, testfile: &Path, } fn make_compile_args(config: config, props: TestProps, extras: ~[~str], - xform: fn(config, (&Path)) -> Path, + xform: &fn(config, (&Path)) -> Path, testfile: &Path) -> ProcArgs { let prog = config.rustc_path; let mut args = ~[testfile.to_str(), diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs index 7a2a15a5421dc..fa19e24aa0830 100644 --- a/src/libcore/at_vec.rs +++ b/src/libcore/at_vec.rs @@ -61,7 +61,7 @@ pub pure fn capacity(v: @[const T]) -> uint { */ #[inline(always)] pub pure fn build_sized(size: uint, - builder: &fn(push: pure fn(v: A))) -> @[A] { + builder: &fn(push: &pure fn(v: A))) -> @[A] { let mut vec: @[const A] = @[]; unsafe { raw::reserve(&mut vec, size); } builder(|+x| unsafe { raw::push(&mut vec, x) }); @@ -79,7 +79,7 @@ pub pure fn build_sized(size: uint, * onto the vector being constructed. */ #[inline(always)] -pub pure fn build(builder: &fn(push: pure fn(v: A))) -> @[A] { +pub pure fn build(builder: &fn(push: &pure fn(v: A))) -> @[A] { build_sized(4, builder) } @@ -97,7 +97,7 @@ pub pure fn build(builder: &fn(push: pure fn(v: A))) -> @[A] { */ #[inline(always)] pub pure fn build_sized_opt(size: Option, - builder: &fn(push: pure fn(v: A))) -> @[A] { + builder: &fn(push: &pure fn(v: A))) -> @[A] { build_sized(size.get_or_default(4), builder) } diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs index 13b8d0fc907fd..512855d8f86c0 100644 --- a/src/libcore/bool.rs +++ b/src/libcore/bool.rs @@ -67,7 +67,7 @@ pub pure fn to_str(v: bool) -> ~str { if v { ~"true" } else { ~"false" } } * Iterates over all truth values by passing them to `blk` in an unspecified * order */ -pub fn all_values(blk: fn(v: bool)) { +pub fn all_values(blk: &fn(v: bool)) { blk(true); blk(false); } diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 8df0037b2afe3..91a4ded60efd6 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -54,7 +54,7 @@ pub impl Cell { } // Calls a closure with a reference to the value. - fn with_ref(&self, op: fn(v: &T) -> R) -> R { + fn with_ref(&self, op: &fn(v: &T) -> R) -> R { let v = self.take(); let r = op(&v); self.put_back(v); diff --git a/src/libcore/cleanup.rs b/src/libcore/cleanup.rs index bf1ea5f1150a7..faa6db45df2f6 100644 --- a/src/libcore/cleanup.rs +++ b/src/libcore/cleanup.rs @@ -124,7 +124,7 @@ struct AnnihilateStats { n_bytes_freed: uint } -unsafe fn each_live_alloc(f: fn(box: *mut BoxRepr, uniq: bool) -> bool) { +unsafe fn each_live_alloc(f: &fn(box: *mut BoxRepr, uniq: bool) -> bool) { use managed; let task: *Task = transmute(rustrt::rust_get_task()); diff --git a/src/libcore/container.rs b/src/libcore/container.rs index 36424d1bfaaa3..4f1f6004aad77 100644 --- a/src/libcore/container.rs +++ b/src/libcore/container.rs @@ -30,10 +30,10 @@ pub trait Map: Mutable { pure fn contains_key(&self, key: &K) -> bool; /// Visit all keys - pure fn each_key(&self, f: fn(&K) -> bool); + pure fn each_key(&self, f: &fn(&K) -> bool); /// Visit all values - pure fn each_value(&self, f: fn(&V) -> bool); + pure fn each_value(&self, f: &fn(&V) -> bool); /// Return the value corresponding to the key in the map pure fn find(&self, key: &K) -> Option<&self/V>; @@ -71,14 +71,14 @@ pub trait Set: Mutable { pure fn is_superset(&self, other: &Self) -> bool; /// Visit the values representing the difference - pure fn difference(&self, other: &Self, f: fn(&T) -> bool); + pure fn difference(&self, other: &Self, f: &fn(&T) -> bool); /// Visit the values representing the symmetric difference - pure fn symmetric_difference(&self, other: &Self, f: fn(&T) -> bool); + pure fn symmetric_difference(&self, other: &Self, f: &fn(&T) -> bool); /// Visit the values representing the intersection - pure fn intersection(&self, other: &Self, f: fn(&T) -> bool); + pure fn intersection(&self, other: &Self, f: &fn(&T) -> bool); /// Visit the values representing the union - pure fn union(&self, other: &Self, f: fn(&T) -> bool); + pure fn union(&self, other: &Self, f: &fn(&T) -> bool); } diff --git a/src/libcore/dlist.rs b/src/libcore/dlist.rs index 9cb872a0542a1..fd3ba2e6f451f 100644 --- a/src/libcore/dlist.rs +++ b/src/libcore/dlist.rs @@ -399,7 +399,7 @@ pub impl DList { } /// Iterate over nodes. - pure fn each_node(@mut self, f: fn(@mut DListNode) -> bool) { + pure fn each_node(@mut self, f: &fn(@mut DListNode) -> bool) { let mut link = self.peek_n(); while link.is_some() { let nobe = link.get(); diff --git a/src/libcore/either.rs b/src/libcore/either.rs index e26f94261f9f9..e4b7bbbd99e87 100644 --- a/src/libcore/either.rs +++ b/src/libcore/either.rs @@ -24,8 +24,8 @@ pub enum Either { } #[inline(always)] -pub fn either(f_left: fn(&T) -> V, - f_right: fn(&U) -> V, value: &Either) -> V { +pub fn either(f_left: &fn(&T) -> V, + f_right: &fn(&U) -> V, value: &Either) -> V { /*! * Applies a function based on the given either value * @@ -148,7 +148,7 @@ pub pure fn unwrap_right(eith: Either) -> U { pub impl Either { #[inline(always)] - fn either(&self, f_left: fn(&T) -> V, f_right: fn(&U) -> V) -> V { + fn either(&self, f_left: &fn(&T) -> V, f_right: &fn(&U) -> V) -> V { either(f_left, f_right, self) } diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index 783f96d9b9e81..6f63cdbabb57d 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -86,7 +86,7 @@ pub mod linear { #[inline(always)] pure fn bucket_sequence(&self, hash: uint, - op: fn(uint) -> bool) -> uint { + op: &fn(uint) -> bool) -> uint { let start_idx = self.to_bucket(hash); let len_buckets = self.buckets.len(); let mut idx = start_idx; @@ -263,7 +263,7 @@ pub mod linear { } fn search(&self, hash: uint, - op: fn(x: &Option>) -> bool) { + op: &fn(x: &Option>) -> bool) { let _ = self.bucket_sequence(hash, |i| op(&self.buckets[i])); } } @@ -272,7 +272,7 @@ pub mod linear { BaseIter<(&self/K, &self/V)> for LinearMap { /// Visit all key-value pairs - pure fn each(&self, blk: fn(&(&self/K, &self/V)) -> bool) { + pure fn each(&self, blk: &fn(&(&self/K, &self/V)) -> bool) { for uint::range(0, self.buckets.len()) |i| { let mut broke = false; do self.buckets[i].map |bucket| { @@ -315,12 +315,12 @@ pub mod linear { } /// Visit all keys - pure fn each_key(&self, blk: fn(k: &K) -> bool) { + pure fn each_key(&self, blk: &fn(k: &K) -> bool) { self.each(|&(k, _)| blk(k)) } /// Visit all values - pure fn each_value(&self, blk: fn(v: &V) -> bool) { + pure fn each_value(&self, blk: &fn(v: &V) -> bool) { self.each(|&(_, v)| blk(v)) } @@ -428,7 +428,7 @@ pub mod linear { /// Return the value corresponding to the key in the map, or create, /// insert, and return a new value if it doesn't exist. - fn find_or_insert_with(&mut self, k: K, f: fn(&K) -> V) -> &self/V { + fn find_or_insert_with(&mut self, k: K, f: &fn(&K) -> V) -> &self/V { if self.size >= self.resize_at { // n.b.: We could also do this after searching, so // that we do not resize if this call to insert is @@ -457,7 +457,7 @@ pub mod linear { } } - fn consume(&mut self, f: fn(K, V)) { + fn consume(&mut self, f: &fn(K, V)) { let mut buckets = ~[]; self.buckets <-> buckets; self.size = 0; @@ -526,7 +526,7 @@ pub mod linear { impl BaseIter for LinearSet { /// Visit all values in order - pure fn each(&self, f: fn(&T) -> bool) { self.map.each_key(f) } + pure fn each(&self, f: &fn(&T) -> bool) { self.map.each_key(f) } pure fn size_hint(&self) -> Option { Some(self.len()) } } @@ -583,7 +583,7 @@ pub mod linear { } /// Visit the values representing the difference - pure fn difference(&self, other: &LinearSet, f: fn(&T) -> bool) { + pure fn difference(&self, other: &LinearSet, f: &fn(&T) -> bool) { for self.each |v| { if !other.contains(v) { if !f(v) { return } @@ -593,13 +593,13 @@ pub mod linear { /// Visit the values representing the symmetric difference pure fn symmetric_difference(&self, other: &LinearSet, - f: fn(&T) -> bool) { + f: &fn(&T) -> bool) { self.difference(other, f); other.difference(self, f); } /// Visit the values representing the intersection - pure fn intersection(&self, other: &LinearSet, f: fn(&T) -> bool) { + pure fn intersection(&self, other: &LinearSet, f: &fn(&T) -> bool) { for self.each |v| { if other.contains(v) { if !f(v) { return } @@ -608,7 +608,7 @@ pub mod linear { } /// Visit the values representing the union - pure fn union(&self, other: &LinearSet, f: fn(&T) -> bool) { + pure fn union(&self, other: &LinearSet, f: &fn(&T) -> bool) { for self.each |v| { if !f(v) { return } } diff --git a/src/libcore/io.rs b/src/libcore/io.rs index 4634eb8793d95..b04bb15f5e30b 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -118,13 +118,13 @@ pub trait ReaderUtil { fn read_whole_stream(&self) -> ~[u8]; /// Iterate over every byte until the iterator breaks or EOF. - fn each_byte(&self, it: fn(int) -> bool); + fn each_byte(&self, it: &fn(int) -> bool); /// Iterate over every char until the iterator breaks or EOF. - fn each_char(&self, it: fn(char) -> bool); + fn each_char(&self, it: &fn(char) -> bool); /// Iterate over every line until the iterator breaks or EOF. - fn each_line(&self, it: fn(&str) -> bool); + fn each_line(&self, it: &fn(&str) -> bool); /// Read n (between 1 and 8) little-endian unsigned integer bytes. fn read_le_uint_n(&self, nbytes: uint) -> u64; @@ -315,19 +315,19 @@ impl ReaderUtil for T { bytes } - fn each_byte(&self, it: fn(int) -> bool) { + fn each_byte(&self, it: &fn(int) -> bool) { while !self.eof() { if !it(self.read_byte()) { break; } } } - fn each_char(&self, it: fn(char) -> bool) { + fn each_char(&self, it: &fn(char) -> bool) { while !self.eof() { if !it(self.read_char()) { break; } } } - fn each_line(&self, it: fn(s: &str) -> bool) { + fn each_line(&self, it: &fn(s: &str) -> bool) { while !self.eof() { if !it(self.read_line()) { break; } } @@ -618,11 +618,11 @@ impl Reader for BytesReader/&self { fn tell(&self) -> uint { self.pos } } -pub pure fn with_bytes_reader(bytes: &[u8], f: fn(@Reader) -> t) -> t { +pub pure fn with_bytes_reader(bytes: &[u8], f: &fn(@Reader) -> t) -> t { f(@BytesReader { bytes: bytes, pos: 0u } as @Reader) } -pub pure fn with_str_reader(s: &str, f: fn(@Reader) -> T) -> T { +pub pure fn with_str_reader(s: &str, f: &fn(@Reader) -> T) -> T { str::byte_slice(s, |bytes| with_bytes_reader(bytes, f)) } @@ -819,7 +819,7 @@ pub fn mk_file_writer(path: &Path, flags: &[FileFlag]) } pub fn u64_to_le_bytes(n: u64, size: uint, - f: fn(v: &[u8]) -> T) -> T { + f: &fn(v: &[u8]) -> T) -> T { fail_unless!(size <= 8u); match size { 1u => f(&[n as u8]), @@ -851,7 +851,7 @@ pub fn u64_to_le_bytes(n: u64, size: uint, } pub fn u64_to_be_bytes(n: u64, size: uint, - f: fn(v: &[u8]) -> T) -> T { + f: &fn(v: &[u8]) -> T) -> T { fail_unless!(size <= 8u); match size { 1u => f(&[n as u8]), @@ -1142,14 +1142,14 @@ pub pure fn BytesWriter() -> BytesWriter { BytesWriter { bytes: ~[], mut pos: 0u } } -pub pure fn with_bytes_writer(f: fn(Writer)) -> ~[u8] { +pub pure fn with_bytes_writer(f: &fn(Writer)) -> ~[u8] { let wr = @BytesWriter(); f(wr as Writer); let @BytesWriter{bytes, _} = wr; return bytes; } -pub pure fn with_str_writer(f: fn(Writer)) -> ~str { +pub pure fn with_str_writer(f: &fn(Writer)) -> ~str { let mut v = with_bytes_writer(f); // FIXME (#3758): This should not be needed. @@ -1251,7 +1251,7 @@ pub mod fsync { // FIXME (#2004) find better way to create resources within lifetime of // outer res pub fn FILE_res_sync(file: &FILERes, opt_level: Option, - blk: fn(v: Res<*libc::FILE>)) { + blk: &fn(v: Res<*libc::FILE>)) { unsafe { blk(Res(Arg { val: file.f, opt_level: opt_level, @@ -1266,7 +1266,7 @@ pub mod fsync { // fsync fd after executing blk pub fn fd_res_sync(fd: &FdRes, opt_level: Option, - blk: fn(v: Res)) { + blk: &fn(v: Res)) { blk(Res(Arg { val: fd.fd, opt_level: opt_level, fsync_fn: |fd, l| os::fsync_fd(fd, l) as int @@ -1278,7 +1278,7 @@ pub mod fsync { // Call o.fsync after executing blk pub fn obj_sync(o: FSyncable, opt_level: Option, - blk: fn(v: Res)) { + blk: &fn(v: Res)) { blk(Res(Arg { val: o, opt_level: opt_level, fsync_fn: |o, l| o.fsync(l) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index c92f747fc9872..8931b4088263e 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -23,22 +23,22 @@ use vec; pub type InitOp = &self/fn(uint) -> T; pub trait BaseIter { - pure fn each(&self, blk: fn(v: &A) -> bool); + pure fn each(&self, blk: &fn(v: &A) -> bool); pure fn size_hint(&self) -> Option; } pub trait ReverseIter: BaseIter { - pure fn each_reverse(&self, blk: fn(&A) -> bool); + pure fn each_reverse(&self, blk: &fn(&A) -> bool); } pub trait ExtendedIter { - pure fn eachi(&self, blk: fn(uint, v: &A) -> bool); - pure fn all(&self, blk: fn(&A) -> bool) -> bool; - pure fn any(&self, blk: fn(&A) -> bool) -> bool; - pure fn foldl(&self, b0: B, blk: fn(&B, &A) -> B) -> B; - pure fn position(&self, f: fn(&A) -> bool) -> Option; - pure fn map_to_vec(&self, op: fn(&A) -> B) -> ~[B]; - pure fn flat_map_to_vec>(&self, op: fn(&A) -> IB) + pure fn eachi(&self, blk: &fn(uint, v: &A) -> bool); + pure fn all(&self, blk: &fn(&A) -> bool) -> bool; + pure fn any(&self, blk: &fn(&A) -> bool) -> bool; + pure fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B; + pure fn position(&self, f: &fn(&A) -> bool) -> Option; + pure fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B]; + pure fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B]; } @@ -48,13 +48,13 @@ pub trait EqIter { } pub trait Times { - pure fn times(&self, it: fn() -> bool); + pure fn times(&self, it: &fn() -> bool); } pub trait CopyableIter { - pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A]; + pure fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A]; pure fn to_vec(&self) -> ~[A]; - pure fn find(&self, p: fn(&A) -> bool) -> Option; + pure fn find(&self, p: &fn(&A) -> bool) -> Option; } pub trait CopyableOrderedIter { @@ -86,12 +86,12 @@ pub trait Buildable { * onto the sequence being constructed. */ static pure fn build_sized(size: uint, - builder: fn(push: pure fn(A))) -> Self; + builder: &fn(push: &pure fn(A))) -> Self; } #[inline(always)] pub pure fn eachi>(self: &IA, - blk: fn(uint, &A) -> bool) { + blk: &fn(uint, &A) -> bool) { let mut i = 0; for self.each |a| { if !blk(i, a) { break; } @@ -101,7 +101,7 @@ pub pure fn eachi>(self: &IA, #[inline(always)] pub pure fn all>(self: &IA, - blk: fn(&A) -> bool) -> bool { + blk: &fn(&A) -> bool) -> bool { for self.each |a| { if !blk(a) { return false; } } @@ -110,7 +110,7 @@ pub pure fn all>(self: &IA, #[inline(always)] pub pure fn any>(self: &IA, - blk: fn(&A) -> bool) -> bool { + blk: &fn(&A) -> bool) -> bool { for self.each |a| { if blk(a) { return true; } } @@ -119,7 +119,7 @@ pub pure fn any>(self: &IA, #[inline(always)] pub pure fn filter_to_vec>( - self: &IA, prd: fn(&A) -> bool) -> ~[A] { + self: &IA, prd: &fn(&A) -> bool) -> ~[A] { do vec::build_sized_opt(self.size_hint()) |push| { for self.each |a| { if prd(a) { push(*a); } @@ -129,7 +129,7 @@ pub pure fn filter_to_vec>( #[inline(always)] pub pure fn map_to_vec>(self: &IA, - op: fn(&A) -> B) + op: &fn(&A) -> B) -> ~[B] { do vec::build_sized_opt(self.size_hint()) |push| { for self.each |a| { @@ -140,7 +140,7 @@ pub pure fn map_to_vec>(self: &IA, #[inline(always)] pub pure fn flat_map_to_vec,IB:BaseIter>( - self: &IA, op: fn(&A) -> IB) -> ~[B] { + self: &IA, op: &fn(&A) -> IB) -> ~[B] { do vec::build |push| { for self.each |a| { for op(a).each |&b| { @@ -152,7 +152,7 @@ pub pure fn flat_map_to_vec,IB:BaseIter>( #[inline(always)] pub pure fn foldl>(self: &IA, b0: B, - blk: fn(&B, &A) -> B) + blk: &fn(&B, &A) -> B) -> B { let mut b = b0; for self.each |a| { @@ -186,7 +186,7 @@ pub pure fn count>(self: &IA, x: &A) -> uint { } #[inline(always)] -pub pure fn position>(self: &IA, f: fn(&A) -> bool) +pub pure fn position>(self: &IA, f: &fn(&A) -> bool) -> Option { let mut i = 0; @@ -202,7 +202,7 @@ pub pure fn position>(self: &IA, f: fn(&A) -> bool) // it would have to be implemented with foldr, which is too inefficient. #[inline(always)] -pub pure fn repeat(times: uint, blk: fn() -> bool) { +pub pure fn repeat(times: uint, blk: &fn() -> bool) { let mut i = 0; while i < times { if !blk() { break } @@ -242,7 +242,7 @@ pub pure fn max>(self: &IA) -> A { #[inline(always)] pub pure fn find>(self: &IA, - f: fn(&A) -> bool) -> Option { + f: &fn(&A) -> bool) -> Option { for self.each |i| { if f(i) { return Some(*i) } } @@ -262,7 +262,7 @@ pub pure fn find>(self: &IA, * onto the sequence being constructed. */ #[inline(always)] -pub pure fn build>(builder: fn(push: pure fn(A))) +pub pure fn build>(builder: &fn(push: &pure fn(A))) -> B { Buildable::build_sized(4, builder) } @@ -283,7 +283,7 @@ pub pure fn build>(builder: fn(push: pure fn(A))) #[inline(always)] pub pure fn build_sized_opt>( size: Option, - builder: fn(push: pure fn(A))) -> B { + builder: &fn(push: &pure fn(A))) -> B { Buildable::build_sized(size.get_or_default(4), builder) } @@ -292,7 +292,7 @@ pub pure fn build_sized_opt>( /// Applies a function to each element of an iterable and returns the results. #[inline(always)] -pub fn map,U,BU: Buildable>(v: &IT, f: fn(&T) -> U) +pub fn map,U,BU: Buildable>(v: &IT, f: &fn(&T) -> U) -> BU { do build_sized_opt(v.size_hint()) |push| { for v.each() |elem| { diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs index 2f59b4c50de04..cef8542823a67 100644 --- a/src/libcore/num/int-template.rs +++ b/src/libcore/num/int-template.rs @@ -100,7 +100,7 @@ pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T } */ #[inline(always)] /// Iterate over the range [`start`,`start`+`step`..`stop`) -pub pure fn range_step(start: T, stop: T, step: T, it: fn(T) -> bool) { +pub pure fn range_step(start: T, stop: T, step: T, it: &fn(T) -> bool) { let mut i = start; if step == 0 { fail!(~"range_step called with step == 0"); @@ -119,13 +119,13 @@ pub pure fn range_step(start: T, stop: T, step: T, it: fn(T) -> bool) { #[inline(always)] /// Iterate over the range [`lo`..`hi`) -pub pure fn range(lo: T, hi: T, it: fn(T) -> bool) { +pub pure fn range(lo: T, hi: T, it: &fn(T) -> bool) { range_step(lo, hi, 1 as T, it); } #[inline(always)] /// Iterate over the range [`hi`..`lo`) -pub pure fn range_rev(hi: T, lo: T, it: fn(T) -> bool) { +pub pure fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) { range_step(hi, lo, -1 as T, it); } @@ -237,7 +237,7 @@ impl FromStrRadix for T { /// Convert to a string as a byte slice in a given base. #[inline(always)] -pub pure fn to_str_bytes(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U { +pub pure fn to_str_bytes(n: T, radix: uint, f: &fn(v: &[u8]) -> U) -> U { let (buf, _) = strconv::to_str_bytes_common(&n, radix, false, strconv::SignNeg, strconv::DigAll); f(buf) diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs index 11bd7dbfd3ad9..9a141bfd34161 100644 --- a/src/libcore/num/uint-template.rs +++ b/src/libcore/num/uint-template.rs @@ -67,7 +67,7 @@ pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T } * Iterate over the range [`start`,`start`+`step`..`stop`) * */ -pub pure fn range_step(start: T, stop: T, step: T_SIGNED, it: fn(T) -> bool) { +pub pure fn range_step(start: T, stop: T, step: T_SIGNED, it: &fn(T) -> bool) { let mut i = start; if step == 0 { fail!(~"range_step called with step == 0"); @@ -88,13 +88,13 @@ pub pure fn range_step(start: T, stop: T, step: T_SIGNED, it: fn(T) -> bool) { #[inline(always)] /// Iterate over the range [`lo`..`hi`) -pub pure fn range(lo: T, hi: T, it: fn(T) -> bool) { +pub pure fn range(lo: T, hi: T, it: &fn(T) -> bool) { range_step(lo, hi, 1 as T_SIGNED, it); } #[inline(always)] /// Iterate over the range [`hi`..`lo`) -pub pure fn range_rev(hi: T, lo: T, it: fn(T) -> bool) { +pub pure fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) { range_step(hi, lo, -1 as T_SIGNED, it); } @@ -200,7 +200,7 @@ impl FromStrRadix for T { /// Convert to a string as a byte slice in a given base. #[inline(always)] -pub pure fn to_str_bytes(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U { +pub pure fn to_str_bytes(n: T, radix: uint, f: &fn(v: &[u8]) -> U) -> U { let (buf, _) = strconv::to_str_bytes_common(&n, radix, false, strconv::SignNeg, strconv::DigAll); f(buf) diff --git a/src/libcore/num/uint-template/uint.rs b/src/libcore/num/uint-template/uint.rs index 6814b0e754199..f73ff4442ceee 100644 --- a/src/libcore/num/uint-template/uint.rs +++ b/src/libcore/num/uint-template/uint.rs @@ -101,7 +101,7 @@ pub mod inst { * `true` If execution proceeded correctly, `false` if it was interrupted, * that is if `it` returned `false` at any point. */ - pub pure fn iterate(lo: uint, hi: uint, it: fn(uint) -> bool) -> bool { + pub pure fn iterate(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool { let mut i = lo; while i < hi { if (!it(i)) { return false; } @@ -122,7 +122,7 @@ pub mod inst { * use with integer literals of inferred integer-type as * the self-value (eg. `for 100.times { ... }`). */ - pure fn times(&self, it: fn() -> bool) { + pure fn times(&self, it: &fn() -> bool) { let mut i = *self; while i > 0 { if !it() { break } diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 7b0e4d07b53b8..e0393fdf5e35a 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -131,7 +131,7 @@ pub pure fn get_ref(opt: &r/Option) -> &r/T { } #[inline(always)] -pub pure fn map(opt: &r/Option, f: fn(x: &r/T) -> U) -> Option { +pub pure fn map(opt: &r/Option, f: &fn(x: &r/T) -> U) -> Option { //! Maps a `some` value by reference from one type to another match *opt { Some(ref x) => Some(f(x)), None => None } @@ -139,7 +139,7 @@ pub pure fn map(opt: &r/Option, f: fn(x: &r/T) -> U) -> Option { #[inline(always)] pub pure fn map_consume(opt: Option, - f: fn(v: T) -> U) -> Option { + f: &fn(v: T) -> U) -> Option { /*! * As `map`, but consumes the option and gives `f` ownership to avoid * copying. @@ -149,7 +149,7 @@ pub pure fn map_consume(opt: Option, #[inline(always)] pub pure fn chain(opt: Option, - f: fn(t: T) -> Option) -> Option { + f: &fn(t: T) -> Option) -> Option { /*! * Update an optional value by optionally running its content through a * function that returns an option. @@ -163,7 +163,7 @@ pub pure fn chain(opt: Option, #[inline(always)] pub pure fn chain_ref(opt: &Option, - f: fn(x: &T) -> Option) -> Option { + f: &fn(x: &T) -> Option) -> Option { /*! * Update an optional value by optionally running its content by reference * through a function that returns an option. @@ -184,7 +184,7 @@ pub pure fn or(opta: Option, optb: Option) -> Option { } #[inline(always)] -pub pure fn while_some(x: Option, blk: fn(v: T) -> Option) { +pub pure fn while_some(x: Option, blk: &fn(v: T) -> Option) { //! Applies a function zero or more times until the result is none. let mut opt = x; @@ -223,7 +223,7 @@ pub pure fn get_or_default(opt: Option, def: T) -> T { #[inline(always)] pub pure fn map_default(opt: &r/Option, def: U, - f: fn(&r/T) -> U) -> U { + f: &fn(&r/T) -> U) -> U { //! Applies a function to the contained value or returns a default match *opt { None => def, Some(ref t) => f(t) } @@ -279,7 +279,7 @@ pub pure fn expect(opt: Option, reason: &str) -> T { impl BaseIter for Option { /// Performs an operation on the contained value by reference #[inline(always)] - pure fn each(&self, f: fn(x: &self/T) -> bool) { + pure fn each(&self, f: &fn(x: &self/T) -> bool) { match *self { None => (), Some(ref t) => { f(t); } } } @@ -303,43 +303,43 @@ pub impl Option { * through a function that returns an option. */ #[inline(always)] - pure fn chain_ref(&self, f: fn(x: &T) -> Option) -> Option { + pure fn chain_ref(&self, f: &fn(x: &T) -> Option) -> Option { chain_ref(self, f) } /// Maps a `some` value from one type to another by reference #[inline(always)] - pure fn map(&self, f: fn(&self/T) -> U) -> Option { map(self, f) } + pure fn map(&self, f: &fn(&self/T) -> U) -> Option { map(self, f) } /// As `map`, but consumes the option and gives `f` ownership to avoid /// copying. #[inline(always)] - pure fn map_consume(self, f: fn(v: T) -> U) -> Option { + pure fn map_consume(self, f: &fn(v: T) -> U) -> Option { map_consume(self, f) } /// Applies a function to the contained value or returns a default #[inline(always)] - pure fn map_default(&self, def: U, f: fn(&self/T) -> U) -> U { + pure fn map_default(&self, def: U, f: &fn(&self/T) -> U) -> U { map_default(self, def, f) } /// As `map_default`, but consumes the option and gives `f` /// ownership to avoid copying. #[inline(always)] - pure fn map_consume_default(self, def: U, f: fn(v: T) -> U) -> U { + pure fn map_consume_default(self, def: U, f: &fn(v: T) -> U) -> U { match self { None => def, Some(v) => f(v) } } /// Apply a function to the contained value or do nothing - fn mutate(&mut self, f: fn(T) -> T) { + fn mutate(&mut self, f: &fn(T) -> T) { if self.is_some() { *self = Some(f(self.swap_unwrap())); } } /// Apply a function to the contained value or set it to a default - fn mutate_default(&mut self, def: T, f: fn(T) -> T) { + fn mutate_default(&mut self, def: T, f: &fn(T) -> T) { if self.is_some() { *self = Some(f(self.swap_unwrap())); } else { @@ -420,7 +420,7 @@ pub impl Option { /// Applies a function zero or more times until the result is none. #[inline(always)] - pure fn while_some(self, blk: fn(v: T) -> Option) { + pure fn while_some(self, blk: &fn(v: T) -> Option) { while_some(self, blk) } } diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 5c73e45364be7..ba16c14a85add 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -75,11 +75,11 @@ pub fn getcwd() -> Path { } } -pub fn as_c_charp(s: &str, f: fn(*c_char) -> T) -> T { +pub fn as_c_charp(s: &str, f: &fn(*c_char) -> T) -> T { str::as_c_str(s, |b| f(b as *c_char)) } -pub fn fill_charp_buf(f: fn(*mut c_char, size_t) -> bool) +pub fn fill_charp_buf(f: &fn(*mut c_char, size_t) -> bool) -> Option<~str> { let mut buf = vec::from_elem(TMPBUF_SZ, 0u8 as c_char); do vec::as_mut_buf(buf) |b, sz| { @@ -103,7 +103,7 @@ pub mod win32 { use os::TMPBUF_SZ; use libc::types::os::arch::extra::DWORD; - pub fn fill_utf16_buf_and_decode(f: fn(*mut u16, DWORD) -> DWORD) + pub fn fill_utf16_buf_and_decode(f: &fn(*mut u16, DWORD) -> DWORD) -> Option<~str> { unsafe { let mut n = TMPBUF_SZ as DWORD; @@ -133,7 +133,7 @@ pub mod win32 { } } - pub fn as_utf16_p(s: &str, f: fn(*u16) -> T) -> T { + pub fn as_utf16_p(s: &str, f: &fn(*u16) -> T) -> T { let mut t = str::to_utf16(s); // Null terminate before passing on. t += ~[0u16]; @@ -518,11 +518,11 @@ pub fn tmpdir() -> Path { } } /// Recursively walk a directory structure -pub fn walk_dir(p: &Path, f: fn(&Path) -> bool) { +pub fn walk_dir(p: &Path, f: &fn(&Path) -> bool) { walk_dir_(p, f); - fn walk_dir_(p: &Path, f: fn(&Path) -> bool) -> bool { + fn walk_dir_(p: &Path, f: &fn(&Path) -> bool) -> bool { let mut keepgoing = true; do list_dir(p).each |q| { let path = &p.push(*q); diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index afb7aef25a3a0..fd823e9dda0d7 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -246,7 +246,7 @@ pub fn packet() -> *Packet { #[doc(hidden)] pub fn entangle_buffer( buffer: ~Buffer, - init: fn(*libc::c_void, x: &T) -> *Packet) + init: &fn(*libc::c_void, x: &T) -> *Packet) -> (SendPacketBuffered, RecvPacketBuffered) { let p = init(unsafe { reinterpret_cast(&buffer) }, &buffer.data); diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index ebf41dc48f405..b66c1c4696fcf 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -82,7 +82,7 @@ pub unsafe fn buf_len(buf: **T) -> uint { /// Return the first offset `i` such that `f(buf[i]) == true`. #[inline(always)] -pub unsafe fn position(buf: *T, f: fn(&T) -> bool) -> uint { +pub unsafe fn position(buf: *T, f: &fn(&T) -> bool) -> uint { let mut i = 0; loop { if f(&(*offset(buf, i))) { return i; } diff --git a/src/libcore/reflect.rs b/src/libcore/reflect.rs index f29447ef53e33..30c46cd3e35d1 100644 --- a/src/libcore/reflect.rs +++ b/src/libcore/reflect.rs @@ -26,7 +26,7 @@ use vec; * then build a MovePtrAdaptor wrapped around your struct. */ pub trait MovePtr { - fn move_ptr(&self, adjustment: fn(*c_void) -> *c_void); + fn move_ptr(&self, adjustment: &fn(*c_void) -> *c_void); fn push_ptr(&self); fn pop_ptr(&self); } diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs index e9122754eb42a..ad85c5e5ceff4 100644 --- a/src/libcore/repr.rs +++ b/src/libcore/repr.rs @@ -159,7 +159,7 @@ pub fn ReprVisitor(ptr: *c_void, writer: @Writer) -> ReprVisitor { impl MovePtr for ReprVisitor { #[inline(always)] - fn move_ptr(&self, adjustment: fn(*c_void) -> *c_void) { + fn move_ptr(&self, adjustment: &fn(*c_void) -> *c_void) { self.ptr = adjustment(self.ptr); } fn push_ptr(&self) { @@ -175,7 +175,7 @@ pub impl ReprVisitor { // Various helpers for the TyVisitor impl #[inline(always)] - fn get(&self, f: fn(&T)) -> bool { + fn get(&self, f: &fn(&T)) -> bool { unsafe { f(transmute::<*c_void,&T>(copy self.ptr)); } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index dd9b55e672580..e3fd279a99609 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -122,7 +122,7 @@ pub pure fn to_either(res: &Result) * } */ #[inline(always)] -pub pure fn chain(res: Result, op: fn(T) +pub pure fn chain(res: Result, op: &fn(T) -> Result) -> Result { match res { Ok(t) => op(t), @@ -141,7 +141,7 @@ pub pure fn chain(res: Result, op: fn(T) #[inline(always)] pub pure fn chain_err( res: Result, - op: fn(t: V) -> Result) + op: &fn(t: V) -> Result) -> Result { match res { Ok(t) => Ok(t), @@ -164,7 +164,7 @@ pub pure fn chain_err( * } */ #[inline(always)] -pub pure fn iter(res: &Result, f: fn(&T)) { +pub pure fn iter(res: &Result, f: &fn(&T)) { match *res { Ok(ref t) => f(t), Err(_) => () @@ -180,7 +180,7 @@ pub pure fn iter(res: &Result, f: fn(&T)) { * handling an error. */ #[inline(always)] -pub pure fn iter_err(res: &Result, f: fn(&E)) { +pub pure fn iter_err(res: &Result, f: &fn(&E)) { match *res { Ok(_) => (), Err(ref e) => f(e) @@ -202,7 +202,7 @@ pub pure fn iter_err(res: &Result, f: fn(&E)) { * } */ #[inline(always)] -pub pure fn map(res: &Result, op: fn(&T) -> U) +pub pure fn map(res: &Result, op: &fn(&T) -> U) -> Result { match *res { Ok(ref t) => Ok(op(t)), @@ -219,7 +219,7 @@ pub pure fn map(res: &Result, op: fn(&T) -> U) * successful result while handling an error. */ #[inline(always)] -pub pure fn map_err(res: &Result, op: fn(&E) -> F) +pub pure fn map_err(res: &Result, op: &fn(&E) -> F) -> Result { match *res { Ok(copy t) => Ok(t), @@ -238,10 +238,10 @@ pub impl Result { pure fn is_err(&self) -> bool { is_err(self) } #[inline(always)] - pure fn iter(&self, f: fn(&T)) { iter(self, f) } + pure fn iter(&self, f: &fn(&T)) { iter(self, f) } #[inline(always)] - pure fn iter_err(&self, f: fn(&E)) { iter_err(self, f) } + pure fn iter_err(&self, f: &fn(&E)) { iter_err(self, f) } #[inline(always)] pure fn unwrap(self) -> T { unwrap(self) } @@ -250,12 +250,12 @@ pub impl Result { pure fn unwrap_err(self) -> E { unwrap_err(self) } #[inline(always)] - pure fn chain(self, op: fn(T) -> Result) -> Result { + pure fn chain(self, op: &fn(T) -> Result) -> Result { chain(self, op) } #[inline(always)] - pure fn chain_err(self, op: fn(E) -> Result) -> Result { + pure fn chain_err(self, op: &fn(E) -> Result) -> Result { chain_err(self, op) } } @@ -265,7 +265,7 @@ pub impl Result { pure fn get(&self) -> T { get(self) } #[inline(always)] - pure fn map_err(&self, op: fn(&E) -> F) -> Result { + pure fn map_err(&self, op: &fn(&E) -> F) -> Result { map_err(self, op) } } @@ -275,7 +275,7 @@ pub impl Result { pure fn get_err(&self) -> E { get_err(self) } #[inline(always)] - pure fn map(&self, op: fn(&T) -> U) -> Result { + pure fn map(&self, op: &fn(&T) -> U) -> Result { map(self, op) } } @@ -299,7 +299,7 @@ pub impl Result { */ #[inline(always)] pub fn map_vec( - ts: &[T], op: fn(&T) -> Result) -> Result<~[V],U> { + ts: &[T], op: &fn(&T) -> Result) -> Result<~[V],U> { let mut vs: ~[V] = vec::with_capacity(vec::len(ts)); for vec::each(ts) |t| { @@ -313,7 +313,7 @@ pub fn map_vec( #[inline(always)] pub fn map_opt( - o_t: &Option, op: fn(&T) -> Result) -> Result,U> { + o_t: &Option, op: &fn(&T) -> Result) -> Result,U> { match *o_t { None => Ok(None), @@ -335,7 +335,7 @@ pub fn map_opt( */ #[inline(always)] pub fn map_vec2(ss: &[S], ts: &[T], - op: fn(&S,&T) -> Result) -> Result<~[V],U> { + op: &fn(&S,&T) -> Result) -> Result<~[V],U> { fail_unless!(vec::same_length(ss, ts)); let n = vec::len(ts); @@ -358,7 +358,7 @@ pub fn map_vec2(ss: &[S], ts: &[T], */ #[inline(always)] pub fn iter_vec2(ss: &[S], ts: &[T], - op: fn(&S,&T) -> Result<(),U>) -> Result<(),U> { + op: &fn(&S,&T) -> Result<(),U>) -> Result<(),U> { fail_unless!(vec::same_length(ss, ts)); let n = vec::len(ts); diff --git a/src/libcore/run.rs b/src/libcore/run.rs index bebcc909dc658..a9d96d891c944 100644 --- a/src/libcore/run.rs +++ b/src/libcore/run.rs @@ -102,7 +102,7 @@ pub fn spawn_process(prog: &str, args: &[~str], } fn with_argv(prog: &str, args: &[~str], - cb: fn(**libc::c_char) -> T) -> T { + cb: &fn(**libc::c_char) -> T) -> T { let mut argptrs = str::as_c_str(prog, |b| ~[b]); let mut tmps = ~[]; for vec::each(args) |arg| { @@ -116,7 +116,7 @@ fn with_argv(prog: &str, args: &[~str], #[cfg(unix)] fn with_envp(env: &Option<~[(~str,~str)]>, - cb: fn(*c_void) -> T) -> T { + cb: &fn(*c_void) -> T) -> T { // On posixy systems we can pass a char** for envp, which is // a null-terminated array of "k=v\n" strings. match *env { @@ -141,7 +141,7 @@ fn with_envp(env: &Option<~[(~str,~str)]>, #[cfg(windows)] fn with_envp(env: &Option<~[(~str,~str)]>, - cb: fn(*c_void) -> T) -> T { + cb: &fn(*c_void) -> T) -> T { // On win32 we pass an "environment block" which is not a char**, but // rather a concatenation of null-terminated k=v\0 sequences, with a final // \0 to terminate. @@ -165,7 +165,7 @@ fn with_envp(env: &Option<~[(~str,~str)]>, } fn with_dirp(d: &Option<~str>, - cb: fn(*libc::c_char) -> T) -> T { + cb: &fn(*libc::c_char) -> T) -> T { match *d { Some(ref dir) => str::as_c_str(*dir, cb), None => cb(ptr::null()) diff --git a/src/libcore/stackwalk.rs b/src/libcore/stackwalk.rs index 107e52b245e37..955e486649b99 100644 --- a/src/libcore/stackwalk.rs +++ b/src/libcore/stackwalk.rs @@ -24,7 +24,7 @@ pub fn Frame(fp: *Word) -> Frame { } } -pub fn walk_stack(visit: fn(Frame) -> bool) { +pub fn walk_stack(visit: &fn(Frame) -> bool) { debug!("beginning stack walk"); @@ -80,7 +80,7 @@ fn breakpoint() { } } -fn frame_address(f: fn(++x: *u8)) { +fn frame_address(f: &fn(++x: *u8)) { unsafe { rusti::frame_address(f) } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 6a0673878e0e2..415c12e33a8a8 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -382,7 +382,7 @@ pub pure fn to_bytes(s: &str) -> ~[u8] { /// Work with the string as a byte slice, not including trailing null. #[inline(always)] -pub pure fn byte_slice(s: &str, f: fn(v: &[u8]) -> T) -> T { +pub pure fn byte_slice(s: &str, f: &fn(v: &[u8]) -> T) -> T { do as_buf(s) |p,n| { unsafe { vec::raw::buf_as_slice(p, n-1u, f) } } @@ -483,7 +483,7 @@ pure fn split_char_inner(s: &str, sep: char, count: uint, allow_empty: bool) /// Splits a string into substrings using a character function -pub pure fn split(s: &str, sepfn: fn(char) -> bool) -> ~[~str] { +pub pure fn split(s: &str, sepfn: &fn(char) -> bool) -> ~[~str] { split_inner(s, sepfn, len(s), true) } @@ -491,16 +491,16 @@ pub pure fn split(s: &str, sepfn: fn(char) -> bool) -> ~[~str] { * Splits a string into substrings using a character function, cutting at * most `count` times. */ -pub pure fn splitn(s: &str, sepfn: fn(char) -> bool, count: uint) -> ~[~str] { +pub pure fn splitn(s: &str, sepfn: &fn(char) -> bool, count: uint) -> ~[~str] { split_inner(s, sepfn, count, true) } /// Like `split`, but omits empty strings from the returned vector -pub pure fn split_nonempty(s: &str, sepfn: fn(char) -> bool) -> ~[~str] { +pub pure fn split_nonempty(s: &str, sepfn: &fn(char) -> bool) -> ~[~str] { split_inner(s, sepfn, len(s), false) } -pure fn split_inner(s: &str, sepfn: fn(cc: char) -> bool, count: uint, +pure fn split_inner(s: &str, sepfn: &fn(cc: char) -> bool, count: uint, allow_empty: bool) -> ~[~str] { let l = len(s); let mut result = ~[], i = 0u, start = 0u, done = 0u; @@ -526,7 +526,7 @@ pure fn split_inner(s: &str, sepfn: fn(cc: char) -> bool, count: uint, } // See Issue #1932 for why this is a naive search -pure fn iter_matches(s: &a/str, sep: &b/str, f: fn(uint, uint)) { +pure fn iter_matches(s: &a/str, sep: &b/str, f: &fn(uint, uint)) { let sep_len = len(sep), l = len(s); fail_unless!(sep_len > 0u); let mut i = 0u, match_start = 0u, match_i = 0u; @@ -553,7 +553,7 @@ pure fn iter_matches(s: &a/str, sep: &b/str, f: fn(uint, uint)) { } } -pure fn iter_between_matches(s: &a/str, sep: &b/str, f: fn(uint, uint)) { +pure fn iter_between_matches(s: &a/str, sep: &b/str, f: &fn(uint, uint)) { let mut last_end = 0u; do iter_matches(s, sep) |from, to| { f(last_end, from); @@ -912,7 +912,7 @@ Section: Iterating through strings * Return true if a predicate matches all characters or if the string * contains no characters */ -pub pure fn all(s: &str, it: fn(char) -> bool) -> bool { +pub pure fn all(s: &str, it: &fn(char) -> bool) -> bool { all_between(s, 0u, len(s), it) } @@ -920,12 +920,12 @@ pub pure fn all(s: &str, it: fn(char) -> bool) -> bool { * Return true if a predicate matches any character (and false if it * matches none or there are no characters) */ -pub pure fn any(ss: &str, pred: fn(char) -> bool) -> bool { +pub pure fn any(ss: &str, pred: &fn(char) -> bool) -> bool { !all(ss, |cc| !pred(cc)) } /// Apply a function to each character -pub pure fn map(ss: &str, ff: fn(char) -> char) -> ~str { +pub pure fn map(ss: &str, ff: &fn(char) -> char) -> ~str { let mut result = ~""; unsafe { reserve(&mut result, len(ss)); @@ -937,7 +937,7 @@ pub pure fn map(ss: &str, ff: fn(char) -> char) -> ~str { } /// Iterate over the bytes in a string -pub pure fn bytes_each(ss: &str, it: fn(u8) -> bool) { +pub pure fn bytes_each(ss: &str, it: &fn(u8) -> bool) { let mut pos = 0u; let len = len(ss); @@ -949,13 +949,13 @@ pub pure fn bytes_each(ss: &str, it: fn(u8) -> bool) { /// Iterate over the bytes in a string #[inline(always)] -pub pure fn each(s: &str, it: fn(u8) -> bool) { +pub pure fn each(s: &str, it: &fn(u8) -> bool) { eachi(s, |_i, b| it(b) ) } /// Iterate over the bytes in a string, with indices #[inline(always)] -pub pure fn eachi(s: &str, it: fn(uint, u8) -> bool) { +pub pure fn eachi(s: &str, it: &fn(uint, u8) -> bool) { let mut i = 0u, l = len(s); while (i < l) { if !it(i, s[i]) { break; } @@ -965,13 +965,13 @@ pub pure fn eachi(s: &str, it: fn(uint, u8) -> bool) { /// Iterates over the chars in a string #[inline(always)] -pub pure fn each_char(s: &str, it: fn(char) -> bool) { +pub pure fn each_char(s: &str, it: &fn(char) -> bool) { each_chari(s, |_i, c| it(c)) } /// Iterates over the chars in a string, with indices #[inline(always)] -pub pure fn each_chari(s: &str, it: fn(uint, char) -> bool) { +pub pure fn each_chari(s: &str, it: &fn(uint, char) -> bool) { let mut pos = 0u, ch_pos = 0u; let len = len(s); while pos < len { @@ -983,7 +983,7 @@ pub pure fn each_chari(s: &str, it: fn(uint, char) -> bool) { } /// Iterate over the characters in a string -pub pure fn chars_each(s: &str, it: fn(char) -> bool) { +pub pure fn chars_each(s: &str, it: &fn(char) -> bool) { let mut pos = 0u; let len = len(s); while (pos < len) { @@ -994,7 +994,7 @@ pub pure fn chars_each(s: &str, it: fn(char) -> bool) { } /// Apply a function to each substring after splitting by character -pub pure fn split_char_each(ss: &str, cc: char, ff: fn(v: &str) -> bool) { +pub pure fn split_char_each(ss: &str, cc: char, ff: &fn(v: &str) -> bool) { vec::each(split_char(ss, cc), |s| ff(*s)) } @@ -1003,19 +1003,19 @@ pub pure fn split_char_each(ss: &str, cc: char, ff: fn(v: &str) -> bool) { * `count` times */ pub pure fn splitn_char_each(ss: &str, sep: char, count: uint, - ff: fn(v: &str) -> bool) { + ff: &fn(v: &str) -> bool) { vec::each(splitn_char(ss, sep, count), |s| ff(*s)) } /// Apply a function to each word -pub pure fn words_each(ss: &str, ff: fn(v: &str) -> bool) { +pub pure fn words_each(ss: &str, ff: &fn(v: &str) -> bool) { vec::each(words(ss), |s| ff(*s)) } /** * Apply a function to each line (by '\n') */ -pub pure fn lines_each(ss: &str, ff: fn(v: &str) -> bool) { +pub pure fn lines_each(ss: &str, ff: &fn(v: &str) -> bool) { vec::each(lines(ss), |s| ff(*s)) } @@ -1195,7 +1195,7 @@ pub pure fn rfind_char_between(s: &str, c: char, start: uint, end: uint) * An `option` containing the byte index of the first matching character * or `none` if there is no match */ -pub pure fn find(s: &str, f: fn(char) -> bool) -> Option { +pub pure fn find(s: &str, f: &fn(char) -> bool) -> Option { find_between(s, 0u, len(s), f) } @@ -1219,7 +1219,7 @@ pub pure fn find(s: &str, f: fn(char) -> bool) -> Option { * `start` must be less than or equal to `len(s)`. `start` must be the * index of a character boundary, as defined by `is_char_boundary`. */ -pub pure fn find_from(s: &str, start: uint, f: fn(char) +pub pure fn find_from(s: &str, start: uint, f: &fn(char) -> bool) -> Option { find_between(s, start, len(s), f) } @@ -1246,7 +1246,7 @@ pub pure fn find_from(s: &str, start: uint, f: fn(char) * or equal to `len(s)`. `start` must be the index of a character * boundary, as defined by `is_char_boundary`. */ -pub pure fn find_between(s: &str, start: uint, end: uint, f: fn(char) -> bool) +pub pure fn find_between(s: &str, start: uint, end: uint, f: &fn(char) -> bool) -> Option { fail_unless!(start <= end); fail_unless!(end <= len(s)); @@ -1274,7 +1274,7 @@ pub pure fn find_between(s: &str, start: uint, end: uint, f: fn(char) -> bool) * An option containing the byte index of the last matching character * or `none` if there is no match */ -pub pure fn rfind(s: &str, f: fn(char) -> bool) -> Option { +pub pure fn rfind(s: &str, f: &fn(char) -> bool) -> Option { rfind_between(s, len(s), 0u, f) } @@ -1298,7 +1298,7 @@ pub pure fn rfind(s: &str, f: fn(char) -> bool) -> Option { * `start` must be less than or equal to `len(s)', `start` must be the * index of a character boundary, as defined by `is_char_boundary` */ -pub pure fn rfind_from(s: &str, start: uint, f: fn(char) -> bool) +pub pure fn rfind_from(s: &str, start: uint, f: &fn(char) -> bool) -> Option { rfind_between(s, start, 0u, f) } @@ -1326,7 +1326,7 @@ pub pure fn rfind_from(s: &str, start: uint, f: fn(char) -> bool) * boundary, as defined by `is_char_boundary` */ pub pure fn rfind_between(s: &str, start: uint, end: uint, - f: fn(char) -> bool) + f: &fn(char) -> bool) -> Option { fail_unless!(start >= end); fail_unless!(start <= len(s)); @@ -1589,7 +1589,7 @@ pub pure fn to_utf16(s: &str) -> ~[u16] { u } -pub pure fn utf16_chars(v: &[u16], f: fn(char)) { +pub pure fn utf16_chars(v: &[u16], f: &fn(char)) { let len = vec::len(v); let mut i = 0u; while (i < len && v[i] != 0u16) { @@ -1815,7 +1815,7 @@ pure fn char_range_at_reverse(ss: &str, start: uint) -> CharRange { * that is if `it` returned `false` at any point. */ pub pure fn all_between(s: &str, start: uint, end: uint, - it: fn(char) -> bool) -> bool { + it: &fn(char) -> bool) -> bool { fail_unless!(is_char_boundary(s, start)); let mut i = start; while i < end { @@ -1848,7 +1848,7 @@ pub pure fn all_between(s: &str, start: uint, end: uint, * `true` if `it` returns `true` for any character */ pub pure fn any_between(s: &str, start: uint, end: uint, - it: fn(char) -> bool) -> bool { + it: &fn(char) -> bool) -> bool { !all_between(s, start, end, |c| !it(c)) } @@ -1886,7 +1886,7 @@ pub const nan_buf: [u8*3] = ['N' as u8, 'a' as u8, 'N' as u8]; * let i = str::as_bytes("Hello World") { |bytes| vec::len(bytes) }; * ~~~ */ -pub pure fn as_bytes(s: &const ~str, f: fn(&~[u8]) -> T) -> T { +pub pure fn as_bytes(s: &const ~str, f: &fn(&~[u8]) -> T) -> T { unsafe { let v: *~[u8] = cast::transmute(copy s); f(&*v) @@ -1921,7 +1921,7 @@ pub pure fn as_bytes_slice(s: &a/str) -> &a/[u8] { * let s = str::as_c_str("PATH", { |path| libc::getenv(path) }); * ~~~ */ -pub pure fn as_c_str(s: &str, f: fn(*libc::c_char) -> T) -> T { +pub pure fn as_c_str(s: &str, f: &fn(*libc::c_char) -> T) -> T { do as_buf(s) |buf, len| { // NB: len includes the trailing null. fail_unless!(len > 0); @@ -1943,7 +1943,7 @@ pub pure fn as_c_str(s: &str, f: fn(*libc::c_char) -> T) -> T { * to full strings, or suffixes of them. */ #[inline(always)] -pub pure fn as_buf(s: &str, f: fn(*u8, uint) -> T) -> T { +pub pure fn as_buf(s: &str, f: &fn(*u8, uint) -> T) -> T { unsafe { let v : *(*u8,uint) = ::cast::reinterpret_cast(&ptr::addr_of(&s)); let (buf,len) = *v; @@ -2088,7 +2088,7 @@ pub mod raw { /// Form a slice from a *u8 buffer of the given length without copying. pub unsafe fn buf_as_slice(buf: *u8, len: uint, - f: fn(v: &str) -> T) -> T { + f: &fn(v: &str) -> T) -> T { let v = (buf, len + 1); fail_unless!(is_utf8(::cast::reinterpret_cast(&v))); f(::cast::transmute(v)) @@ -2238,21 +2238,21 @@ pub mod traits { pub mod traits {} pub trait StrSlice { - pure fn all(&self, it: fn(char) -> bool) -> bool; - pure fn any(&self, it: fn(char) -> bool) -> bool; + pure fn all(&self, it: &fn(char) -> bool) -> bool; + pure fn any(&self, it: &fn(char) -> bool) -> bool; pure fn contains(&self, needle: &a/str) -> bool; pure fn contains_char(&self, needle: char) -> bool; - pure fn each(&self, it: fn(u8) -> bool); - pure fn eachi(&self, it: fn(uint, u8) -> bool); - pure fn each_char(&self, it: fn(char) -> bool); - pure fn each_chari(&self, it: fn(uint, char) -> bool); + pure fn each(&self, it: &fn(u8) -> bool); + pure fn eachi(&self, it: &fn(uint, u8) -> bool); + pure fn each_char(&self, it: &fn(char) -> bool); + pure fn each_chari(&self, it: &fn(uint, char) -> bool); pure fn ends_with(&self, needle: &str) -> bool; pure fn is_empty(&self) -> bool; pure fn is_whitespace(&self) -> bool; pure fn is_alphanumeric(&self) -> bool; pure fn len(&self) -> uint; pure fn slice(&self, begin: uint, end: uint) -> ~str; - pure fn split(&self, sepfn: fn(char) -> bool) -> ~[~str]; + pure fn split(&self, sepfn: &fn(char) -> bool) -> ~[~str]; pure fn split_char(&self, sep: char) -> ~[~str]; pure fn split_str(&self, sep: &a/str) -> ~[~str]; pure fn starts_with(&self, needle: &a/str) -> bool; @@ -2276,13 +2276,13 @@ impl StrSlice for &self/str { * contains no characters */ #[inline] - pure fn all(&self, it: fn(char) -> bool) -> bool { all(*self, it) } + pure fn all(&self, it: &fn(char) -> bool) -> bool { all(*self, it) } /** * Return true if a predicate matches any character (and false if it * matches none or there are no characters) */ #[inline] - pure fn any(&self, it: fn(char) -> bool) -> bool { any(*self, it) } + pure fn any(&self, it: &fn(char) -> bool) -> bool { any(*self, it) } /// Returns true if one string contains another #[inline] pure fn contains(&self, needle: &a/str) -> bool { @@ -2295,16 +2295,16 @@ impl StrSlice for &self/str { } /// Iterate over the bytes in a string #[inline] - pure fn each(&self, it: fn(u8) -> bool) { each(*self, it) } + pure fn each(&self, it: &fn(u8) -> bool) { each(*self, it) } /// Iterate over the bytes in a string, with indices #[inline] - pure fn eachi(&self, it: fn(uint, u8) -> bool) { eachi(*self, it) } + pure fn eachi(&self, it: &fn(uint, u8) -> bool) { eachi(*self, it) } /// Iterate over the chars in a string #[inline] - pure fn each_char(&self, it: fn(char) -> bool) { each_char(*self, it) } + pure fn each_char(&self, it: &fn(char) -> bool) { each_char(*self, it) } /// Iterate over the chars in a string, with indices #[inline] - pure fn each_chari(&self, it: fn(uint, char) -> bool) { + pure fn each_chari(&self, it: &fn(uint, char) -> bool) { each_chari(*self, it) } /// Returns true if one string ends with another @@ -2345,7 +2345,7 @@ impl StrSlice for &self/str { } /// Splits a string into substrings using a character function #[inline] - pure fn split(&self, sepfn: fn(char) -> bool) -> ~[~str] { + pure fn split(&self, sepfn: &fn(char) -> bool) -> ~[~str] { split(*self, sepfn) } /** diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs index d4db61f4519c3..179a33ae43ea3 100644 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@ -227,7 +227,7 @@ pub mod tests { pub fn synthesize_closure() { unsafe { let x = 10; - let f: fn(int) -> int = |y| x + y; + let f: &fn(int) -> int = |y| x + y; fail_unless!(f(20) == 30); @@ -241,7 +241,7 @@ pub mod tests { env: environment }; - let new_f: fn(int) -> int = cast::transmute(new_closure); + let new_f: &fn(int) -> int = cast::transmute(new_closure); fail_unless!(new_f(20) == 30); } } diff --git a/src/libcore/task/local_data.rs b/src/libcore/task/local_data.rs index 72c328d4613bc..690b3aedc5a49 100644 --- a/src/libcore/task/local_data.rs +++ b/src/libcore/task/local_data.rs @@ -79,7 +79,7 @@ pub unsafe fn local_data_set( */ pub unsafe fn local_data_modify( key: LocalDataKey, - modify_fn: fn(Option<@T>) -> Option<@T>) { + modify_fn: &fn(Option<@T>) -> Option<@T>) { local_modify(rt::rust_get_task(), key, modify_fn) } diff --git a/src/libcore/task/local_data_priv.rs b/src/libcore/task/local_data_priv.rs index f035916f59423..bb05520e1a363 100644 --- a/src/libcore/task/local_data_priv.rs +++ b/src/libcore/task/local_data_priv.rs @@ -176,7 +176,7 @@ pub unsafe fn local_set( pub unsafe fn local_modify( task: *rust_task, key: LocalDataKey, - modify_fn: fn(Option<@T>) -> Option<@T>) { + modify_fn: &fn(Option<@T>) -> Option<@T>) { // Could be more efficient by doing the lookup work, but this is easy. let newdata = modify_fn(local_pop(task, key)); diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs index 065feaebb5169..31c44531efec0 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -295,7 +295,7 @@ pub impl TaskBuilder { * # Failure * Fails if a future_result was already set for this task. */ - fn future_result(&self, blk: fn(v: Port)) -> TaskBuilder { + fn future_result(&self, blk: &fn(v: Port)) -> TaskBuilder { // FIXME (#3725): Once linked failure and notification are // handled in the library, I can imagine implementing this by just // registering an arbitrary number of task::on_exit handlers and @@ -572,7 +572,7 @@ pub fn get_scheduler() -> Scheduler { * } * ~~~ */ -pub unsafe fn unkillable(f: fn() -> U) -> U { +pub unsafe fn unkillable(f: &fn() -> U) -> U { struct AllowFailure { t: *rust_task, drop { @@ -597,7 +597,7 @@ pub unsafe fn unkillable(f: fn() -> U) -> U { } /// The inverse of unkillable. Only ever to be used nested in unkillable(). -pub unsafe fn rekillable(f: fn() -> U) -> U { +pub unsafe fn rekillable(f: &fn() -> U) -> U { struct DisallowFailure { t: *rust_task, drop { @@ -625,7 +625,7 @@ pub unsafe fn rekillable(f: fn() -> U) -> U { * A stronger version of unkillable that also inhibits scheduling operations. * For use with exclusive ARCs, which use pthread mutexes directly. */ -pub unsafe fn atomically(f: fn() -> U) -> U { +pub unsafe fn atomically(f: &fn() -> U) -> U { struct DeferInterrupts { t: *rust_task, drop { diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index 7b7ec769fa9a7..617149f7fd57d 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -108,7 +108,7 @@ fn taskset_remove(tasks: &mut TaskSet, task: *rust_task) { let was_present = tasks.remove(&task); fail_unless!(was_present); } -pub fn taskset_each(tasks: &TaskSet, blk: fn(v: *rust_task) -> bool) { +pub fn taskset_each(tasks: &TaskSet, blk: &fn(v: *rust_task) -> bool) { tasks.each(|k| blk(*k)) } @@ -155,13 +155,13 @@ enum AncestorList = Option>; // Accessors for taskgroup arcs and ancestor arcs that wrap the unsafety. #[inline(always)] -fn access_group(x: &TaskGroupArc, blk: fn(TaskGroupInner) -> U) -> U { +fn access_group(x: &TaskGroupArc, blk: &fn(TaskGroupInner) -> U) -> U { unsafe { x.with(blk) } } #[inline(always)] fn access_ancestors(x: &unstable::Exclusive, - blk: fn(x: &mut AncestorNode) -> U) -> U { + blk: &fn(x: &mut AncestorNode) -> U) -> U { unsafe { x.with(blk) } } @@ -175,7 +175,7 @@ fn access_ancestors(x: &unstable::Exclusive, // allocations. Once that bug is fixed, changing the sigil should suffice. fn each_ancestor(list: &mut AncestorList, bail_opt: Option<@fn(TaskGroupInner)>, - forward_blk: fn(TaskGroupInner) -> bool) + forward_blk: &fn(TaskGroupInner) -> bool) -> bool { // "Kickoff" call - there was no last generation. return !coalesce(list, bail_opt, forward_blk, uint::max_value); @@ -184,7 +184,7 @@ fn each_ancestor(list: &mut AncestorList, // whether or not unwinding is needed (i.e., !successful iteration). fn coalesce(list: &mut AncestorList, bail_opt: Option<@fn(TaskGroupInner)>, - forward_blk: fn(TaskGroupInner) -> bool, + forward_blk: &fn(TaskGroupInner) -> bool, last_generation: uint) -> bool { // Need to swap the list out to use it, to appease borrowck. let tmp_list = util::replace(&mut *list, AncestorList(None)); @@ -288,7 +288,7 @@ fn each_ancestor(list: &mut AncestorList, // Wrapper around exclusive::with that appeases borrowck. fn with_parent_tg(parent_group: &mut Option, - blk: fn(TaskGroupInner) -> U) -> U { + blk: &fn(TaskGroupInner) -> U) -> U { // If this trips, more likely the problem is 'blk' failed inside. let tmp_arc = option::swap_unwrap(&mut *parent_group); let result = do access_group(&tmp_arc) |tg_opt| { blk(tg_opt) }; diff --git a/src/libcore/trie.rs b/src/libcore/trie.rs index 395772df57179..4bd751adc3c5e 100644 --- a/src/libcore/trie.rs +++ b/src/libcore/trie.rs @@ -32,7 +32,7 @@ pub struct TrieMap { impl BaseIter<(uint, &'self T)> for TrieMap { /// Visit all key-value pairs in order #[inline(always)] - pure fn each(&self, f: fn(&(uint, &self/T)) -> bool) { + pure fn each(&self, f: &fn(&(uint, &self/T)) -> bool) { self.root.each(f); } #[inline(always)] @@ -42,7 +42,7 @@ impl BaseIter<(uint, &'self T)> for TrieMap { impl ReverseIter<(uint, &'self T)> for TrieMap { /// Visit all key-value pairs in reverse order #[inline(always)] - pure fn each_reverse(&self, f: fn(&(uint, &self/T)) -> bool) { + pure fn each_reverse(&self, f: &fn(&(uint, &self/T)) -> bool) { self.root.each_reverse(f); } } @@ -75,13 +75,13 @@ impl Map for TrieMap { /// Visit all keys in order #[inline(always)] - pure fn each_key(&self, f: fn(&uint) -> bool) { + pure fn each_key(&self, f: &fn(&uint) -> bool) { self.each(|&(k, _)| f(&k)) } /// Visit all values in order #[inline(always)] - pure fn each_value(&self, f: fn(&T) -> bool) { self.each(|&(_, v)| f(v)) } + pure fn each_value(&self, f: &fn(&T) -> bool) { self.each(|&(_, v)| f(v)) } /// Return the value corresponding to the key in the map #[inline(hint)] @@ -138,18 +138,18 @@ impl TrieMap { impl TrieMap { /// Visit all keys in reverse order #[inline(always)] - pure fn each_key_reverse(&self, f: fn(&uint) -> bool) { + pure fn each_key_reverse(&self, f: &fn(&uint) -> bool) { self.each_reverse(|&(k, _)| f(&k)) } /// Visit all values in reverse order #[inline(always)] - pure fn each_value_reverse(&self, f: fn(&T) -> bool) { + pure fn each_value_reverse(&self, f: &fn(&T) -> bool) { self.each_reverse(|&(_, v)| f(v)) } /// Iterate over the map and mutate the contained values - fn mutate_values(&mut self, f: fn(uint, &mut T) -> bool) { + fn mutate_values(&mut self, f: &fn(uint, &mut T) -> bool) { self.root.mutate_values(f); } } @@ -160,13 +160,13 @@ pub struct TrieSet { impl BaseIter for TrieSet { /// Visit all values in order - pure fn each(&self, f: fn(&uint) -> bool) { self.map.each_key(f) } + pure fn each(&self, f: &fn(&uint) -> bool) { self.map.each_key(f) } pure fn size_hint(&self) -> Option { Some(self.len()) } } impl ReverseIter for TrieSet { /// Visit all values in reverse order - pure fn each_reverse(&self, f: fn(&uint) -> bool) { + pure fn each_reverse(&self, f: &fn(&uint) -> bool) { self.map.each_key_reverse(f) } } @@ -223,7 +223,7 @@ impl TrieNode { } impl TrieNode { - pure fn each(&self, f: fn(&(uint, &self/T)) -> bool) -> bool { + pure fn each(&self, f: &fn(&(uint, &self/T)) -> bool) -> bool { for uint::range(0, self.children.len()) |idx| { match self.children[idx] { Internal(ref x) => if !x.each(f) { return false }, @@ -234,7 +234,7 @@ impl TrieNode { true } - pure fn each_reverse(&self, f: fn(&(uint, &self/T)) -> bool) -> bool { + pure fn each_reverse(&self, f: &fn(&(uint, &self/T)) -> bool) -> bool { for uint::range_rev(self.children.len(), 0) |idx| { match self.children[idx - 1] { Internal(ref x) => if !x.each_reverse(f) { return false }, @@ -245,7 +245,7 @@ impl TrieNode { true } - fn mutate_values(&mut self, f: fn(uint, &mut T) -> bool) -> bool { + fn mutate_values(&mut self, f: &fn(uint, &mut T) -> bool) -> bool { for vec::each_mut(self.children) |child| { match *child { Internal(ref mut x) => if !x.mutate_values(f) { diff --git a/src/libcore/unstable.rs b/src/libcore/unstable.rs index 96cd732d815d5..4f45535d0f856 100644 --- a/src/libcore/unstable.rs +++ b/src/libcore/unstable.rs @@ -232,7 +232,7 @@ fn LittleLock() -> LittleLock { pub impl LittleLock { #[inline(always)] - unsafe fn lock(&self, f: fn() -> T) -> T { + unsafe fn lock(&self, f: &fn() -> T) -> T { struct Unlock { l: rust_little_lock, drop { @@ -284,7 +284,7 @@ pub impl Exclusive { // accessing the provided condition variable) are prohibited while inside // the exclusive. Supporting that is a work in progress. #[inline(always)] - unsafe fn with(&self, f: fn(x: &mut T) -> U) -> U { + unsafe fn with(&self, f: &fn(x: &mut T) -> U) -> U { unsafe { let rec = get_shared_mutable_state(&self.x); do (*rec).lock.lock { @@ -301,7 +301,7 @@ pub impl Exclusive { } #[inline(always)] - unsafe fn with_imm(&self, f: fn(x: &T) -> U) -> U { + unsafe fn with_imm(&self, f: &fn(x: &T) -> U) -> U { do self.with |x| { f(cast::transmute_immut(x)) } diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 655db1c83d063..aed98f3573e71 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -175,7 +175,7 @@ pub pure fn with_capacity(capacity: uint) -> ~[T] { */ #[inline(always)] pub pure fn build_sized(size: uint, - builder: fn(push: pure fn(v: A))) -> ~[A] { + builder: &fn(push: &pure fn(v: A))) -> ~[A] { let mut vec = with_capacity(size); builder(|x| unsafe { vec.push(x) }); vec @@ -192,7 +192,7 @@ pub pure fn build_sized(size: uint, * onto the vector being constructed. */ #[inline(always)] -pub pure fn build(builder: fn(push: pure fn(v: A))) -> ~[A] { +pub pure fn build(builder: &fn(push: &pure fn(v: A))) -> ~[A] { build_sized(4, builder) } @@ -210,7 +210,7 @@ pub pure fn build(builder: fn(push: pure fn(v: A))) -> ~[A] { */ #[inline(always)] pub pure fn build_sized_opt(size: Option, - builder: fn(push: pure fn(v: A))) -> ~[A] { + builder: &fn(push: &pure fn(v: A))) -> ~[A] { build_sized(size.get_or_default(4), builder) } @@ -305,7 +305,7 @@ pub pure fn const_slice(v: &r/[const T], /// Copies /// Split the vector `v` by applying each element against the predicate `f`. -pub fn split(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { +pub fn split(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); if (ln == 0u) { return ~[] } @@ -328,7 +328,7 @@ pub fn split(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { * Split the vector `v` by applying each element against the predicate `f` up * to `n` times. */ -pub fn splitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { +pub fn splitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); if (ln == 0u) { return ~[] } @@ -354,7 +354,7 @@ pub fn splitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { * Reverse split the vector `v` by applying each element against the predicate * `f`. */ -pub fn rsplit(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { +pub fn rsplit(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); if (ln == 0) { return ~[] } @@ -378,7 +378,7 @@ pub fn rsplit(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { * Reverse split the vector `v` by applying each element against the predicate * `f` up to `n times. */ -pub fn rsplitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { +pub fn rsplitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); if (ln == 0u) { return ~[] } @@ -405,7 +405,7 @@ pub fn rsplitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { * Partitions a vector into two new vectors: those that satisfies the * predicate, and those that do not. */ -pub fn partition(v: ~[T], f: fn(&T) -> bool) -> (~[T], ~[T]) { +pub fn partition(v: ~[T], f: &fn(&T) -> bool) -> (~[T], ~[T]) { let mut lefts = ~[]; let mut rights = ~[]; @@ -426,7 +426,7 @@ pub fn partition(v: ~[T], f: fn(&T) -> bool) -> (~[T], ~[T]) { * Partitions a vector into two new vectors: those that satisfies the * predicate, and those that do not. */ -pub pure fn partitioned(v: &[T], f: fn(&T) -> bool) -> (~[T], ~[T]) { +pub pure fn partitioned(v: &[T], f: &fn(&T) -> bool) -> (~[T], ~[T]) { let mut lefts = ~[]; let mut rights = ~[]; @@ -535,7 +535,7 @@ pub fn remove(v: &mut ~[T], i: uint) -> T { v.pop() } -pub fn consume(mut v: ~[T], f: fn(uint, v: T)) { +pub fn consume(mut v: ~[T], f: &fn(uint, v: T)) { unsafe { do as_mut_buf(v) |p, ln| { for uint::range(0, ln) |i| { @@ -780,7 +780,7 @@ pub fn grow_set(v: &mut ~[T], index: uint, initval: &T, val: T) { // Functional utilities /// Apply a function to each element of a vector and return the results -pub pure fn map(v: &[T], f: fn(t: &T) -> U) -> ~[U] { +pub pure fn map(v: &[T], f: &fn(t: &T) -> U) -> ~[U] { let mut result = with_capacity(len(v)); for each(v) |elem| { unsafe { @@ -790,7 +790,7 @@ pub pure fn map(v: &[T], f: fn(t: &T) -> U) -> ~[U] { result } -pub fn map_consume(v: ~[T], f: fn(v: T) -> U) -> ~[U] { +pub fn map_consume(v: ~[T], f: &fn(v: T) -> U) -> ~[U] { let mut result = ~[]; do consume(v) |_i, x| { result.push(f(x)); @@ -799,7 +799,7 @@ pub fn map_consume(v: ~[T], f: fn(v: T) -> U) -> ~[U] { } /// Apply a function to each element of a vector and return the results -pub pure fn mapi(v: &[T], f: fn(uint, t: &T) -> U) -> ~[U] { +pub pure fn mapi(v: &[T], f: &fn(uint, t: &T) -> U) -> ~[U] { let mut i = 0; do map(v) |e| { i += 1; @@ -811,7 +811,7 @@ pub pure fn mapi(v: &[T], f: fn(uint, t: &T) -> U) -> ~[U] { * Apply a function to each element of a vector and return a concatenation * of each result vector */ -pub pure fn flat_map(v: &[T], f: fn(t: &T) -> ~[U]) -> ~[U] { +pub pure fn flat_map(v: &[T], f: &fn(t: &T) -> ~[U]) -> ~[U] { let mut result = ~[]; for each(v) |elem| { unsafe{ result.push_all_move(f(elem)); } } result @@ -819,7 +819,7 @@ pub pure fn flat_map(v: &[T], f: fn(t: &T) -> ~[U]) -> ~[U] { /// Apply a function to each pair of elements and return the results pub pure fn map2(v0: &[T], v1: &[U], - f: fn(t: &T, v: &U) -> V) -> ~[V] { + f: &fn(t: &T, v: &U) -> V) -> ~[V] { let v0_len = len(v0); if v0_len != len(v1) { fail!(); } let mut u: ~[V] = ~[]; @@ -833,7 +833,7 @@ pub pure fn map2(v0: &[T], v1: &[U], pub fn filter_map( v: ~[T], - f: fn(t: T) -> Option) -> ~[U] + f: &fn(t: T) -> Option) -> ~[U] { /*! * @@ -854,7 +854,7 @@ pub fn filter_map( pub pure fn filter_mapped( v: &[T], - f: fn(t: &T) -> Option) -> ~[U] + f: &fn(t: &T) -> Option) -> ~[U] { /*! * @@ -879,7 +879,7 @@ pub pure fn filter_mapped( * Apply function `f` to each element of `v` and return a vector containing * only those elements for which `f` returned true. */ -pub fn filter(v: ~[T], f: fn(t: &T) -> bool) -> ~[T] { +pub fn filter(v: ~[T], f: &fn(t: &T) -> bool) -> ~[T] { let mut result = ~[]; // FIXME (#4355 maybe): using v.consume here crashes // do v.consume |_, elem| { @@ -896,7 +896,7 @@ pub fn filter(v: ~[T], f: fn(t: &T) -> bool) -> ~[T] { * Apply function `f` to each element of `v` and return a vector containing * only those elements for which `f` returned true. */ -pub pure fn filtered(v: &[T], f: fn(t: &T) -> bool) -> ~[T] { +pub pure fn filtered(v: &[T], f: &fn(t: &T) -> bool) -> ~[T] { let mut result = ~[]; for each(v) |elem| { if f(elem) { unsafe { result.push(*elem); } } @@ -907,7 +907,7 @@ pub pure fn filtered(v: &[T], f: fn(t: &T) -> bool) -> ~[T] { /** * Like `filter()`, but in place. Preserves order of `v`. Linear time. */ -pub fn retain(v: &mut ~[T], f: pure fn(t: &T) -> bool) { +pub fn retain(v: &mut ~[T], f: &pure fn(t: &T) -> bool) { let len = v.len(); let mut deleted: uint = 0; @@ -963,7 +963,7 @@ pub pure fn connect(v: &[~[T]], sep: &T) -> ~[T] { * ~~~ * */ -pub pure fn foldl(z: T, v: &[U], p: fn(t: T, u: &U) -> T) -> T { +pub pure fn foldl(z: T, v: &[U], p: &fn(t: T, u: &U) -> T) -> T { let mut accum = z; let mut i = 0; let l = v.len(); @@ -995,7 +995,7 @@ pub pure fn foldl(z: T, v: &[U], p: fn(t: T, u: &U) -> T) -> T { * ~~~ * */ -pub pure fn foldr(v: &[T], z: U, p: fn(t: &T, u: U) -> U) -> U { +pub pure fn foldr(v: &[T], z: U, p: &fn(t: &T, u: U) -> U) -> U { let mut accum = z; for rev_each(v) |elt| { accum = p(elt, accum); @@ -1008,7 +1008,7 @@ pub pure fn foldr(v: &[T], z: U, p: fn(t: &T, u: U) -> U) -> U { * * If the vector contains no elements then false is returned. */ -pub pure fn any(v: &[T], f: fn(t: &T) -> bool) -> bool { +pub pure fn any(v: &[T], f: &fn(t: &T) -> bool) -> bool { for each(v) |elem| { if f(elem) { return true; } } false } @@ -1019,7 +1019,7 @@ pub pure fn any(v: &[T], f: fn(t: &T) -> bool) -> bool { * If the vectors contains no elements then false is returned. */ pub pure fn any2(v0: &[T], v1: &[U], - f: fn(a: &T, b: &U) -> bool) -> bool { + f: &fn(a: &T, b: &U) -> bool) -> bool { let v0_len = len(v0); let v1_len = len(v1); let mut i = 0u; @@ -1035,7 +1035,7 @@ pub pure fn any2(v0: &[T], v1: &[U], * * If the vector contains no elements then true is returned. */ -pub pure fn all(v: &[T], f: fn(t: &T) -> bool) -> bool { +pub pure fn all(v: &[T], f: &fn(t: &T) -> bool) -> bool { for each(v) |elem| { if !f(elem) { return false; } } true } @@ -1045,7 +1045,7 @@ pub pure fn all(v: &[T], f: fn(t: &T) -> bool) -> bool { * * If the vector contains no elements then true is returned. */ -pub pure fn alli(v: &[T], f: fn(uint, t: &T) -> bool) -> bool { +pub pure fn alli(v: &[T], f: &fn(uint, t: &T) -> bool) -> bool { for eachi(v) |i, elem| { if !f(i, elem) { return false; } } true } @@ -1056,7 +1056,7 @@ pub pure fn alli(v: &[T], f: fn(uint, t: &T) -> bool) -> bool { * If the vectors are not the same size then false is returned. */ pub pure fn all2(v0: &[T], v1: &[U], - f: fn(t: &T, u: &U) -> bool) -> bool { + f: &fn(t: &T, u: &U) -> bool) -> bool { let v0_len = len(v0); if v0_len != len(v1) { return false; } let mut i = 0u; @@ -1084,7 +1084,7 @@ pub pure fn count(v: &[T], x: &T) -> uint { * When function `f` returns true then an option containing the element * is returned. If `f` matches no elements then none is returned. */ -pub pure fn find(v: &[T], f: fn(t: &T) -> bool) -> Option { +pub pure fn find(v: &[T], f: &fn(t: &T) -> bool) -> Option { find_between(v, 0u, len(v), f) } @@ -1096,7 +1096,7 @@ pub pure fn find(v: &[T], f: fn(t: &T) -> bool) -> Option { * the element is returned. If `f` matches no elements then none is returned. */ pub pure fn find_between(v: &[T], start: uint, end: uint, - f: fn(t: &T) -> bool) -> Option { + f: &fn(t: &T) -> bool) -> Option { position_between(v, start, end, f).map(|i| v[*i]) } @@ -1107,7 +1107,7 @@ pub pure fn find_between(v: &[T], start: uint, end: uint, * `f` returns true then an option containing the element is returned. If `f` * matches no elements then none is returned. */ -pub pure fn rfind(v: &[T], f: fn(t: &T) -> bool) -> Option { +pub pure fn rfind(v: &[T], f: &fn(t: &T) -> bool) -> Option { rfind_between(v, 0u, len(v), f) } @@ -1119,7 +1119,7 @@ pub pure fn rfind(v: &[T], f: fn(t: &T) -> bool) -> Option { * the element is returned. If `f` matches no elements then none is return. */ pub pure fn rfind_between(v: &[T], start: uint, end: uint, - f: fn(t: &T) -> bool) -> Option { + f: &fn(t: &T) -> bool) -> Option { rposition_between(v, start, end, f).map(|i| v[*i]) } @@ -1135,7 +1135,7 @@ pub pure fn position_elem(v: &[T], x: &T) -> Option { * then an option containing the index is returned. If `f` matches no elements * then none is returned. */ -pub pure fn position(v: &[T], f: fn(t: &T) -> bool) -> Option { +pub pure fn position(v: &[T], f: &fn(t: &T) -> bool) -> Option { position_between(v, 0u, len(v), f) } @@ -1147,7 +1147,7 @@ pub pure fn position(v: &[T], f: fn(t: &T) -> bool) -> Option { * the index is returned. If `f` matches no elements then none is returned. */ pub pure fn position_between(v: &[T], start: uint, end: uint, - f: fn(t: &T) -> bool) -> Option { + f: &fn(t: &T) -> bool) -> Option { fail_unless!(start <= end); fail_unless!(end <= len(v)); let mut i = start; @@ -1167,7 +1167,7 @@ pure fn rposition_elem(v: &[T], x: &T) -> Option { * `f` returns true then an option containing the index is returned. If `f` * matches no elements then none is returned. */ -pub pure fn rposition(v: &[T], f: fn(t: &T) -> bool) -> Option { +pub pure fn rposition(v: &[T], f: &fn(t: &T) -> bool) -> Option { rposition_between(v, 0u, len(v), f) } @@ -1180,7 +1180,7 @@ pub pure fn rposition(v: &[T], f: fn(t: &T) -> bool) -> Option { * returned. */ pub pure fn rposition_between(v: &[T], start: uint, end: uint, - f: fn(t: &T) -> bool) -> Option { + f: &fn(t: &T) -> bool) -> Option { fail_unless!(start <= end); fail_unless!(end <= len(v)); let mut i = end; @@ -1334,7 +1334,7 @@ pub pure fn reversed(v: &[const T]) -> ~[T] { * ~~~ */ #[inline(always)] -pub pure fn each(v: &r/[T], f: fn(&r/T) -> bool) { +pub pure fn each(v: &r/[T], f: &fn(&r/T) -> bool) { // ^^^^ // NB---this CANNOT be &[const T]! The reason // is that you are passing it to `f()` using @@ -1358,7 +1358,7 @@ pub pure fn each(v: &r/[T], f: fn(&r/T) -> bool) { /// a vector with mutable contents and you would like /// to mutate the contents as you iterate. #[inline(always)] -pub fn each_mut(v: &mut [T], f: fn(elem: &mut T) -> bool) { +pub fn each_mut(v: &mut [T], f: &fn(elem: &mut T) -> bool) { let mut i = 0; let n = v.len(); while i < n { @@ -1372,7 +1372,7 @@ pub fn each_mut(v: &mut [T], f: fn(elem: &mut T) -> bool) { /// Like `each()`, but for the case where you have a vector that *may or may /// not* have mutable contents. #[inline(always)] -pub pure fn each_const(v: &[const T], f: fn(elem: &const T) -> bool) { +pub pure fn each_const(v: &[const T], f: &fn(elem: &const T) -> bool) { let mut i = 0; let n = v.len(); while i < n { @@ -1389,7 +1389,7 @@ pub pure fn each_const(v: &[const T], f: fn(elem: &const T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pub pure fn eachi(v: &r/[T], f: fn(uint, v: &r/T) -> bool) { +pub pure fn eachi(v: &r/[T], f: &fn(uint, v: &r/T) -> bool) { let mut i = 0; for each(v) |p| { if !f(i, p) { return; } @@ -1403,7 +1403,7 @@ pub pure fn eachi(v: &r/[T], f: fn(uint, v: &r/T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pub pure fn rev_each(v: &r/[T], blk: fn(v: &r/T) -> bool) { +pub pure fn rev_each(v: &r/[T], blk: &fn(v: &r/T) -> bool) { rev_eachi(v, |_i, v| blk(v)) } @@ -1413,7 +1413,7 @@ pub pure fn rev_each(v: &r/[T], blk: fn(v: &r/T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pub pure fn rev_eachi(v: &r/[T], blk: fn(i: uint, v: &r/T) -> bool) { +pub pure fn rev_eachi(v: &r/[T], blk: &fn(i: uint, v: &r/T) -> bool) { let mut i = v.len(); while i > 0 { i -= 1; @@ -1431,7 +1431,7 @@ pub pure fn rev_eachi(v: &r/[T], blk: fn(i: uint, v: &r/T) -> bool) { * Both vectors must have the same length */ #[inline] -pub pure fn each2(v1: &[U], v2: &[T], f: fn(u: &U, t: &T) -> bool) { +pub pure fn each2(v1: &[U], v2: &[T], f: &fn(u: &U, t: &T) -> bool) { fail_unless!(len(v1) == len(v2)); for uint::range(0u, len(v1)) |i| { if !f(&v1[i], &v2[i]) { @@ -1450,7 +1450,7 @@ pub pure fn each2(v1: &[U], v2: &[T], f: fn(u: &U, t: &T) -> bool) { * The total number of permutations produced is `len(v)!`. If `v` contains * repeated elements, then some permutations are repeated. */ -pub pure fn each_permutation(v: &[T], put: fn(ts: &[T]) -> bool) { +pub pure fn each_permutation(v: &[T], put: &fn(ts: &[T]) -> bool) { let ln = len(v); if ln <= 1 { put(v); @@ -1497,7 +1497,7 @@ pub pure fn windowed(nn: uint, xx: &[TT]) -> ~[~[TT]] { #[inline(always)] pub pure fn as_imm_buf(s: &[T], /* NB---this CANNOT be const, see below */ - f: fn(*T, uint) -> U) -> U { + f: &fn(*T, uint) -> U) -> U { // NB---Do not change the type of s to `&[const T]`. This is // unsound. The reason is that we are going to create immutable pointers @@ -1516,7 +1516,7 @@ pub pure fn as_imm_buf(s: &[T], /// Similar to `as_imm_buf` but passing a `*const T` #[inline(always)] pub pure fn as_const_buf(s: &[const T], - f: fn(*const T, uint) -> U) -> U { + f: &fn(*const T, uint) -> U) -> U { unsafe { let v : *(*const T,uint) = @@ -1529,7 +1529,7 @@ pub pure fn as_const_buf(s: &[const T], /// Similar to `as_imm_buf` but passing a `*mut T` #[inline(always)] pub pure fn as_mut_buf(s: &mut [T], - f: fn(*mut T, uint) -> U) -> U { + f: &fn(*mut T, uint) -> U) -> U { unsafe { let v : *(*mut T,uint) = @@ -1721,13 +1721,13 @@ pub trait ImmutableVector { pure fn initn(&self, n: uint) -> &self/[T]; pure fn last(&self) -> &self/T; pure fn last_opt(&self) -> Option<&self/T>; - pure fn foldr(&self, z: U, p: fn(t: &T, u: U) -> U) -> U; - pure fn map(&self, f: fn(t: &T) -> U) -> ~[U]; - pure fn mapi(&self, f: fn(uint, t: &T) -> U) -> ~[U]; - fn map_r(&self, f: fn(x: &T) -> U) -> ~[U]; - pure fn alli(&self, f: fn(uint, t: &T) -> bool) -> bool; - pure fn flat_map(&self, f: fn(t: &T) -> ~[U]) -> ~[U]; - pure fn filter_mapped(&self, f: fn(t: &T) -> Option) -> ~[U]; + pure fn foldr(&self, z: U, p: &fn(t: &T, u: U) -> U) -> U; + pure fn map(&self, f: &fn(t: &T) -> U) -> ~[U]; + pure fn mapi(&self, f: &fn(uint, t: &T) -> U) -> ~[U]; + fn map_r(&self, f: &fn(x: &T) -> U) -> ~[U]; + pure fn alli(&self, f: &fn(uint, t: &T) -> bool) -> bool; + pure fn flat_map(&self, f: &fn(t: &T) -> ~[U]) -> ~[U]; + pure fn filter_mapped(&self, f: &fn(t: &T) -> Option) -> ~[U]; } /// Extension methods for vectors @@ -1772,24 +1772,24 @@ impl ImmutableVector for &self/[T] { /// Reduce a vector from right to left #[inline] - pure fn foldr(&self, z: U, p: fn(t: &T, u: U) -> U) -> U { + pure fn foldr(&self, z: U, p: &fn(t: &T, u: U) -> U) -> U { foldr(*self, z, p) } /// Apply a function to each element of a vector and return the results #[inline] - pure fn map(&self, f: fn(t: &T) -> U) -> ~[U] { map(*self, f) } + pure fn map(&self, f: &fn(t: &T) -> U) -> ~[U] { map(*self, f) } /** * Apply a function to the index and value of each element in the vector * and return the results */ - pure fn mapi(&self, f: fn(uint, t: &T) -> U) -> ~[U] { + pure fn mapi(&self, f: &fn(uint, t: &T) -> U) -> ~[U] { mapi(*self, f) } #[inline] - fn map_r(&self, f: fn(x: &T) -> U) -> ~[U] { + fn map_r(&self, f: &fn(x: &T) -> U) -> ~[U] { let mut r = ~[]; let mut i = 0; while i < self.len() { @@ -1804,7 +1804,7 @@ impl ImmutableVector for &self/[T] { * * If the vector is empty, true is returned. */ - pure fn alli(&self, f: fn(uint, t: &T) -> bool) -> bool { + pure fn alli(&self, f: &fn(uint, t: &T) -> bool) -> bool { alli(*self, f) } /** @@ -1812,7 +1812,7 @@ impl ImmutableVector for &self/[T] { * of each result vector */ #[inline] - pure fn flat_map(&self, f: fn(t: &T) -> ~[U]) -> ~[U] { + pure fn flat_map(&self, f: &fn(t: &T) -> ~[U]) -> ~[U] { flat_map(*self, f) } /** @@ -1822,15 +1822,15 @@ impl ImmutableVector for &self/[T] { * the resulting vector. */ #[inline] - pure fn filter_mapped(&self, f: fn(t: &T) -> Option) -> ~[U] { + pure fn filter_mapped(&self, f: &fn(t: &T) -> Option) -> ~[U] { filter_mapped(*self, f) } } pub trait ImmutableEqVector { - pure fn position(&self, f: fn(t: &T) -> bool) -> Option; + pure fn position(&self, f: &fn(t: &T) -> bool) -> Option; pure fn position_elem(&self, t: &T) -> Option; - pure fn rposition(&self, f: fn(t: &T) -> bool) -> Option; + pure fn rposition(&self, f: &fn(t: &T) -> bool) -> Option; pure fn rposition_elem(&self, t: &T) -> Option; } @@ -1843,7 +1843,7 @@ impl ImmutableEqVector for &self/[T] { * elements then none is returned. */ #[inline] - pure fn position(&self, f: fn(t: &T) -> bool) -> Option { + pure fn position(&self, f: &fn(t: &T) -> bool) -> Option { position(*self, f) } @@ -1861,7 +1861,7 @@ impl ImmutableEqVector for &self/[T] { * returned. If `f` matches no elements then none is returned. */ #[inline] - pure fn rposition(&self, f: fn(t: &T) -> bool) -> Option { + pure fn rposition(&self, f: &fn(t: &T) -> bool) -> Option { rposition(*self, f) } @@ -1873,9 +1873,9 @@ impl ImmutableEqVector for &self/[T] { } pub trait ImmutableCopyableVector { - pure fn filtered(&self, f: fn(&T) -> bool) -> ~[T]; - pure fn rfind(&self, f: fn(t: &T) -> bool) -> Option; - pure fn partitioned(&self, f: fn(&T) -> bool) -> (~[T], ~[T]); + pure fn filtered(&self, f: &fn(&T) -> bool) -> ~[T]; + pure fn rfind(&self, f: &fn(t: &T) -> bool) -> Option; + pure fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]); } /// Extension methods for vectors @@ -1888,7 +1888,7 @@ impl ImmutableCopyableVector for &self/[T] { * containing only those elements for which `f` returned true. */ #[inline] - pure fn filtered(&self, f: fn(t: &T) -> bool) -> ~[T] { + pure fn filtered(&self, f: &fn(t: &T) -> bool) -> ~[T] { filtered(*self, f) } @@ -1900,7 +1900,7 @@ impl ImmutableCopyableVector for &self/[T] { * returned. If `f` matches no elements then none is returned. */ #[inline] - pure fn rfind(&self, f: fn(t: &T) -> bool) -> Option { + pure fn rfind(&self, f: &fn(t: &T) -> bool) -> Option { rfind(*self, f) } @@ -1909,7 +1909,7 @@ impl ImmutableCopyableVector for &self/[T] { * those that do not. */ #[inline] - pure fn partitioned(&self, f: fn(&T) -> bool) -> (~[T], ~[T]) { + pure fn partitioned(&self, f: &fn(&T) -> bool) -> (~[T], ~[T]) { partitioned(*self, f) } } @@ -1924,10 +1924,10 @@ pub trait OwnedVector { fn remove(&mut self, i: uint) -> T; fn swap_remove(&mut self, index: uint) -> T; fn truncate(&mut self, newlen: uint); - fn retain(&mut self, f: pure fn(t: &T) -> bool); - fn consume(self, f: fn(uint, v: T)); - fn filter(self, f: fn(t: &T) -> bool) -> ~[T]; - fn partition(self, f: pure fn(&T) -> bool) -> (~[T], ~[T]); + fn retain(&mut self, f: &pure fn(t: &T) -> bool); + fn consume(self, f: &fn(uint, v: T)); + fn filter(self, f: &fn(t: &T) -> bool) -> ~[T]; + fn partition(self, f: &pure fn(&T) -> bool) -> (~[T], ~[T]); fn grow_fn(&mut self, n: uint, op: iter::InitOp); } @@ -1978,17 +1978,17 @@ impl OwnedVector for ~[T] { } #[inline] - fn retain(&mut self, f: pure fn(t: &T) -> bool) { + fn retain(&mut self, f: &pure fn(t: &T) -> bool) { retain(self, f); } #[inline] - fn consume(self, f: fn(uint, v: T)) { + fn consume(self, f: &fn(uint, v: T)) { consume(self, f) } #[inline] - fn filter(self, f: fn(&T) -> bool) -> ~[T] { + fn filter(self, f: &fn(&T) -> bool) -> ~[T] { filter(self, f) } @@ -1997,7 +1997,7 @@ impl OwnedVector for ~[T] { * those that do not. */ #[inline] - fn partition(self, f: fn(&T) -> bool) -> (~[T], ~[T]) { + fn partition(self, f: &fn(&T) -> bool) -> (~[T], ~[T]) { partition(self, f) } @@ -2138,7 +2138,7 @@ pub mod raw { #[inline(always)] pub unsafe fn buf_as_slice(p: *T, len: uint, - f: fn(v: &[T]) -> U) -> U { + f: &fn(v: &[T]) -> U) -> U { let pair = (p, len * sys::nonzero_size_of::()); let v : *(&blk/[T]) = ::cast::reinterpret_cast(&addr_of(&pair)); @@ -2270,7 +2270,9 @@ pub mod bytes { impl iter::BaseIter for &self/[A] { #[inline(always)] - pure fn each(&self, blk: fn(v: &'self A) -> bool) { each(*self, blk) } + pub pure fn each(&self, blk: &fn(v: &'self A) -> bool) { + each(*self, blk) + } #[inline(always)] pure fn size_hint(&self) -> Option { Some(self.len()) } } @@ -2278,7 +2280,7 @@ impl iter::BaseIter for &self/[A] { // FIXME(#4148): This should be redundant impl iter::BaseIter for ~[A] { #[inline(always)] - pure fn each(&self, blk: fn(v: &'self A) -> bool) { each(*self, blk) } + pure fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) } #[inline(always)] pure fn size_hint(&self) -> Option { Some(self.len()) } } @@ -2286,31 +2288,31 @@ impl iter::BaseIter for ~[A] { // FIXME(#4148): This should be redundant impl iter::BaseIter for @[A] { #[inline(always)] - pure fn each(&self, blk: fn(v: &'self A) -> bool) { each(*self, blk) } + pure fn each(&self, blk: &fn(v: &'self A) -> bool) { each(*self, blk) } #[inline(always)] pure fn size_hint(&self) -> Option { Some(self.len()) } } impl iter::ExtendedIter for &self/[A] { - pub pure fn eachi(&self, blk: fn(uint, v: &A) -> bool) { + pub pure fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { iter::eachi(self, blk) } - pub pure fn all(&self, blk: fn(&A) -> bool) -> bool { + pub pure fn all(&self, blk: &fn(&A) -> bool) -> bool { iter::all(self, blk) } - pub pure fn any(&self, blk: fn(&A) -> bool) -> bool { + pub pure fn any(&self, blk: &fn(&A) -> bool) -> bool { iter::any(self, blk) } - pub pure fn foldl(&self, b0: B, blk: fn(&B, &A) -> B) -> B { + pub pure fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { iter::foldl(self, b0, blk) } - pub pure fn position(&self, f: fn(&A) -> bool) -> Option { + pub pure fn position(&self, f: &fn(&A) -> bool) -> Option { iter::position(self, f) } - pure fn map_to_vec(&self, op: fn(&A) -> B) -> ~[B] { + pure fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { iter::map_to_vec(self, op) } - pure fn flat_map_to_vec>(&self, op: fn(&A) -> IB) + pure fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B] { iter::flat_map_to_vec(self, op) } @@ -2318,25 +2320,25 @@ impl iter::ExtendedIter for &self/[A] { // FIXME(#4148): This should be redundant impl iter::ExtendedIter for ~[A] { - pub pure fn eachi(&self, blk: fn(uint, v: &A) -> bool) { + pub pure fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { iter::eachi(self, blk) } - pub pure fn all(&self, blk: fn(&A) -> bool) -> bool { + pub pure fn all(&self, blk: &fn(&A) -> bool) -> bool { iter::all(self, blk) } - pub pure fn any(&self, blk: fn(&A) -> bool) -> bool { + pub pure fn any(&self, blk: &fn(&A) -> bool) -> bool { iter::any(self, blk) } - pub pure fn foldl(&self, b0: B, blk: fn(&B, &A) -> B) -> B { + pub pure fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { iter::foldl(self, b0, blk) } - pub pure fn position(&self, f: fn(&A) -> bool) -> Option { + pub pure fn position(&self, f: &fn(&A) -> bool) -> Option { iter::position(self, f) } - pure fn map_to_vec(&self, op: fn(&A) -> B) -> ~[B] { + pure fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { iter::map_to_vec(self, op) } - pure fn flat_map_to_vec>(&self, op: fn(&A) -> IB) + pure fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B] { iter::flat_map_to_vec(self, op) } @@ -2344,25 +2346,25 @@ impl iter::ExtendedIter for ~[A] { // FIXME(#4148): This should be redundant impl iter::ExtendedIter for @[A] { - pub pure fn eachi(&self, blk: fn(uint, v: &A) -> bool) { + pub pure fn eachi(&self, blk: &fn(uint, v: &A) -> bool) { iter::eachi(self, blk) } - pub pure fn all(&self, blk: fn(&A) -> bool) -> bool { + pub pure fn all(&self, blk: &fn(&A) -> bool) -> bool { iter::all(self, blk) } - pub pure fn any(&self, blk: fn(&A) -> bool) -> bool { + pub pure fn any(&self, blk: &fn(&A) -> bool) -> bool { iter::any(self, blk) } - pub pure fn foldl(&self, b0: B, blk: fn(&B, &A) -> B) -> B { + pub pure fn foldl(&self, b0: B, blk: &fn(&B, &A) -> B) -> B { iter::foldl(self, b0, blk) } - pub pure fn position(&self, f: fn(&A) -> bool) -> Option { + pub pure fn position(&self, f: &fn(&A) -> bool) -> Option { iter::position(self, f) } - pure fn map_to_vec(&self, op: fn(&A) -> B) -> ~[B] { + pure fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { iter::map_to_vec(self, op) } - pure fn flat_map_to_vec>(&self, op: fn(&A) -> IB) + pure fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B] { iter::flat_map_to_vec(self, op) } @@ -2386,33 +2388,33 @@ impl iter::EqIter for @[A] { } impl iter::CopyableIter for &self/[A] { - pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { + pure fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) } pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) } - pub pure fn find(&self, f: fn(&A) -> bool) -> Option { + pub pure fn find(&self, f: &fn(&A) -> bool) -> Option { iter::find(self, f) } } // FIXME(#4148): This should be redundant impl iter::CopyableIter for ~[A] { - pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { + pure fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) } pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) } - pub pure fn find(&self, f: fn(&A) -> bool) -> Option { + pub pure fn find(&self, f: &fn(&A) -> bool) -> Option { iter::find(self, f) } } // FIXME(#4148): This should be redundant impl iter::CopyableIter for @[A] { - pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { + pure fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) } pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) } - pub pure fn find(&self, f: fn(&A) -> bool) -> Option { + pub pure fn find(&self, f: &fn(&A) -> bool) -> Option { iter::find(self, f) } } @@ -2435,7 +2437,7 @@ impl iter::CopyableOrderedIter for @[A] { } impl iter::CopyableNonstrictIter for &self/[A] { - pure fn each_val(&const self, f: fn(A) -> bool) { + pure fn each_val(&const self, f: &fn(A) -> bool) { let mut i = 0; while i < self.len() { if !f(copy self[i]) { break; } @@ -2446,7 +2448,7 @@ impl iter::CopyableNonstrictIter for &self/[A] { // FIXME(#4148): This should be redundant impl iter::CopyableNonstrictIter for ~[A] { - pure fn each_val(&const self, f: fn(A) -> bool) { + pure fn each_val(&const self, f: &fn(A) -> bool) { let mut i = 0; while i < self.len() { if !f(copy self[i]) { break; } @@ -2457,7 +2459,7 @@ impl iter::CopyableNonstrictIter for ~[A] { // FIXME(#4148): This should be redundant impl iter::CopyableNonstrictIter for @[A] { - pure fn each_val(&const self, f: fn(A) -> bool) { + pure fn each_val(&const self, f: &fn(A) -> bool) { let mut i = 0; while i < self.len() { if !f(copy self[i]) { break; } diff --git a/src/libfuzzer/fuzzer.rc b/src/libfuzzer/fuzzer.rc index f21029a8a4f0f..90ada832327f4 100644 --- a/src/libfuzzer/fuzzer.rc +++ b/src/libfuzzer/fuzzer.rc @@ -247,7 +247,7 @@ pub fn replace_ty_in_crate(crate: ast::crate, i: uint, newty: ast::Ty, *crate2 } -pub fn under(n: uint, it: fn(uint)) { +pub fn under(n: uint, it: &fn(uint)) { let mut i: uint = 0u; while i < n { it(i); i += 1u; } } diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index eaac7dd1a0b54..fec3f77668137 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -153,7 +153,7 @@ pub mod jit { code: entry, env: ptr::null() }; - let func: fn(++argv: ~[~str]) = cast::transmute(closure); + let func: &fn(++argv: ~[~str]) = cast::transmute(closure); func(~[/*bad*/copy sess.opts.binary]); } diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index e7e29ec6c72d5..2b61c9480457d 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -164,7 +164,7 @@ pub fn parse_input(sess: Session, +cfg: ast::crate_cfg, input: input) } } -pub fn time(do_it: bool, what: ~str, thunk: fn() -> T) -> T { +pub fn time(do_it: bool, what: ~str, thunk: &fn() -> T) -> T { if !do_it { return thunk(); } let start = std::time::precise_time_s(); let rv = thunk(); diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 52426401d7927..d2d0ceff6331d 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -306,7 +306,7 @@ pub fn basic_options() -> @options { // Seems out of place, but it uses session, so I'm putting it here pub fn expect(sess: Session, opt: Option, - msg: fn() -> ~str) + msg: &fn() -> ~str) -> T { diagnostic::expect(sess.diagnostic(), opt, msg) } diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 00cb977b50c83..47ee477210b78 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -155,7 +155,7 @@ pub fn get_static_methods_if_impl(cstore: @mut cstore::CStore, pub fn get_item_attrs(cstore: @mut cstore::CStore, def_id: ast::def_id, - f: fn(~[@ast::meta_item])) { + f: &fn(~[@ast::meta_item])) { let cdata = cstore::get_crate_data(cstore, def_id.crate); decoder::get_item_attrs(cdata, def_id.node, f) } diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 2f82d99420c1a..0909a4437369d 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -88,7 +88,7 @@ pub fn have_crate_data(cstore: @mut CStore, cnum: ast::crate_num) -> bool { } pub fn iter_crate_data(cstore: @mut CStore, - i: fn(ast::crate_num, @crate_metadata)) { + i: &fn(ast::crate_num, @crate_metadata)) { let metas = cstore.metas; for metas.each |&k, &v| { i(k, v); diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 4fe708d1020cd..2643012d30ae2 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -48,7 +48,7 @@ type cmd = @crate_metadata; // what crate that's in and give us a def_id that makes sense for the current // build. -fn lookup_hash(d: ebml::Doc, eq_fn: fn(x:&[u8]) -> bool, hash: uint) -> +fn lookup_hash(d: ebml::Doc, eq_fn: &fn(x:&[u8]) -> bool, hash: uint) -> Option { let index = reader::get_doc(d, tag_index); let table = reader::get_doc(index, tag_index_table); @@ -193,7 +193,7 @@ fn item_def_id(d: ebml::Doc, cdata: cmd) -> ast::def_id { |d| parse_def_id(d))); } -fn each_reexport(d: ebml::Doc, f: fn(ebml::Doc) -> bool) { +fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) { for reader::tagged_docs(d, tag_items_data_item_reexport) |reexport_doc| { if !f(reexport_doc) { return; @@ -451,7 +451,7 @@ pub fn each_lang_item(cdata: cmd, f: &fn(ast::node_id, uint) -> bool) { /// Iterates over all the paths in the given crate. pub fn each_path(intr: @ident_interner, cdata: cmd, get_crate_data: GetCrateDataCb, - f: fn(&str, def_like) -> bool) { + f: &fn(&str, def_like) -> bool) { let root = reader::Doc(cdata.data); let items = reader::get_doc(root, tag_items); let items_data = reader::get_doc(items, tag_items_data); @@ -855,7 +855,7 @@ pub fn get_static_methods_if_impl(intr: @ident_interner, pub fn get_item_attrs(cdata: cmd, node_id: ast::node_id, - f: fn(~[@ast::meta_item])) { + f: &fn(~[@ast::meta_item])) { let item = lookup_item(node_id, cdata.data); for reader::tagged_docs(item, tag_attributes) |attributes| { @@ -1093,7 +1093,7 @@ pub fn get_crate_vers(data: @~[u8]) -> @~str { fn iter_crate_items(intr: @ident_interner, cdata: cmd, get_crate_data: GetCrateDataCb, - proc: fn(path: &str, ast::def_id)) { + proc: &fn(path: &str, ast::def_id)) { for each_path(intr, cdata, get_crate_data) |path_string, def_like| { match def_like { dl_impl(*) | dl_field => {} diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 414aa035b5497..fc42ac2ffedb9 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1054,7 +1054,7 @@ fn create_index(index: ~[entry]) -> } fn encode_index(ebml_w: writer::Encoder, buckets: ~[@~[entry]], - write_fn: fn(io::Writer, T)) { + write_fn: &fn(io::Writer, T)) { let writer = ebml_w.writer; ebml_w.start_tag(tag_index); let mut bucket_locs: ~[uint] = ~[]; diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 08b9facf48613..63b14cc51be1c 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -217,7 +217,7 @@ fn parse_region(st: @mut PState) -> ty::Region { } } -fn parse_opt(st: @mut PState, f: fn() -> T) -> Option { +fn parse_opt(st: @mut PState, f: &fn() -> T) -> Option { match next(st) { 'n' => None, 's' => Some(f()), diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index caad6335ce512..b9cb0b1d4b5a3 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -122,7 +122,7 @@ fn enc_mt(w: io::Writer, cx: @ctxt, mt: ty::mt) { enc_ty(w, cx, mt.ty); } -fn enc_opt(w: io::Writer, t: Option, enc_f: fn(T)) { +fn enc_opt(w: io::Writer, t: Option, enc_f: &fn(T)) { match &t { &None => w.write_char('n'), &Some(ref v) => { diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 48fddec00797a..c1a8f79b9b131 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -795,12 +795,12 @@ impl ebml_writer_helpers for writer::Encoder { } trait write_tag_and_id { - fn tag(&self, tag_id: c::astencode_tag, f: fn()); + fn tag(&self, tag_id: c::astencode_tag, f: &fn()); fn id(&self, id: ast::node_id); } impl write_tag_and_id for writer::Encoder { - fn tag(&self, tag_id: c::astencode_tag, f: fn()) { + fn tag(&self, tag_id: c::astencode_tag, f: &fn()) { do self.wr_tag(tag_id as uint) { f() } } diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 5462ec87014e2..3e63707162417 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -510,7 +510,7 @@ pub impl BorrowckCtxt { method_map: self.method_map} } - fn cat_pattern(&self, cmt: cmt, pat: @ast::pat, op: fn(cmt, @ast::pat)) { + fn cat_pattern(&self, cmt: cmt, pat: @ast::pat, op: &fn(cmt, @ast::pat)) { let mc = self.mc_ctxt(); mc.cat_pattern(cmt, pat, op); } diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 84de194915ad0..48d136ce65f36 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -95,7 +95,7 @@ type check_fn = @fn(Context, @freevar_entry); // Yields the appropriate function to check the kind of closed over // variables. `id` is the node_id for some expression that creates the // closure. -fn with_appropriate_checker(cx: Context, id: node_id, b: fn(check_fn)) { +fn with_appropriate_checker(cx: Context, id: node_id, b: &fn(check_fn)) { fn check_for_uniq(cx: Context, fv: @freevar_entry) { // all captured data must be owned, regardless of whether it is // moved in or copied in. diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 2bd08f109812f..5ff731a27f030 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -342,7 +342,7 @@ pub impl Context { * current lint context, call the provided function, then reset the * lints in effect to their previous state. */ - fn with_lint_attrs(&self, attrs: ~[ast::attribute], f: fn(Context)) { + fn with_lint_attrs(&self, attrs: ~[ast::attribute], f: &fn(Context)) { let mut new_ctxt = *self; let mut triples = ~[]; diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 068327dc74167..1bde1e85843fe 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -735,7 +735,7 @@ pub impl Liveness { } } - fn pat_bindings(&self, pat: @pat, f: fn(LiveNode, Variable, span)) { + fn pat_bindings(&self, pat: @pat, f: &fn(LiveNode, Variable, span)) { let def_map = self.tcx.def_map; do pat_util::pat_bindings(def_map, pat) |_bm, p_id, sp, _n| { let ln = self.live_node(p_id, sp); @@ -745,7 +745,7 @@ pub impl Liveness { } fn arm_pats_bindings(&self, - pats: &[@pat], f: fn(LiveNode, Variable, span)) { + pats: &[@pat], f: &fn(LiveNode, Variable, span)) { // only consider the first pattern; any later patterns must have // the same bindings, and we also consider the first pattern to be // the "authoratative" set of ids @@ -809,15 +809,14 @@ pub impl Liveness { self.assigned_on_entry(copy self.successors[*ln], var) } - fn indices(&self, ln: LiveNode, op: fn(uint)) { + fn indices(&self, ln: LiveNode, op: &fn(uint)) { let node_base_idx = self.idx(ln, Variable(0)); for uint::range(0, self.ir.num_vars) |var_idx| { op(node_base_idx + var_idx) } } - fn indices2(&self, ln: LiveNode, succ_ln: LiveNode, - op: fn(uint, uint)) { + fn indices2(&self, ln: LiveNode, succ_ln: LiveNode, op: &fn(uint, uint)) { let node_base_idx = self.idx(ln, Variable(0u)); let succ_base_idx = self.idx(succ_ln, Variable(0u)); for uint::range(0u, self.ir.num_vars) |var_idx| { @@ -827,7 +826,7 @@ pub impl Liveness { fn write_vars(&self, wr: io::Writer, ln: LiveNode, - test: fn(uint) -> LiveNode) { + test: &fn(uint) -> LiveNode) { let node_base_idx = self.idx(ln, Variable(0)); for uint::range(0, self.ir.num_vars) |var_idx| { let idx = node_base_idx + var_idx; @@ -1510,7 +1509,7 @@ pub impl Liveness { fn with_loop_nodes(&self, loop_node_id: node_id, break_ln: LiveNode, cont_ln: LiveNode, - f: fn() -> R) -> R { + f: &fn() -> R) -> R { debug!("with_loop_nodes: %d %u", loop_node_id, *break_ln); self.loop_scope.push(loop_node_id); self.break_ln.insert(loop_node_id, break_ln); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 85ff970be1cac..9e0ecb5a21859 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -856,7 +856,7 @@ pub impl mem_categorization_ctxt { fn cat_pattern(&self, cmt: cmt, pat: @ast::pat, - op: fn(cmt, @ast::pat)) + op: &fn(cmt, @ast::pat)) { // Here, `cmt` is the categorization for the value being // matched and pat is the pattern it is being matched against. diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index 77ad7df531978..4522977a4ab12 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -72,7 +72,7 @@ pub fn pat_is_binding_or_wild(dm: resolve::DefMap, pat: @pat) -> bool { } pub fn pat_bindings(dm: resolve::DefMap, pat: @pat, - it: fn(binding_mode, node_id, span, @path)) { + it: &fn(binding_mode, node_id, span, @path)) { do walk_pat(pat) |p| { match p.node { pat_ident(binding_mode, pth, _) if pat_is_binding(dm, p) => { diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index d1e35f7a19df2..7ac559161af4f 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -3241,7 +3241,7 @@ pub impl Resolver { // generate a fake "implementation scope" containing all the // implementations thus found, for compatibility with old resolve pass. - fn with_scope(@mut self, name: Option, f: fn()) { + fn with_scope(@mut self, name: Option, f: &fn()) { let orig_module = self.current_module; // Move down in the graph. @@ -3661,7 +3661,7 @@ pub impl Resolver { fn with_type_parameter_rib(@mut self, type_parameters: TypeParameters, - f: fn()) { + f: &fn()) { match type_parameters { HasTypeParameters(generics, node_id, initial_index, rib_kind) => { @@ -3702,13 +3702,13 @@ pub impl Resolver { } } - fn with_label_rib(@mut self, f: fn()) { + fn with_label_rib(@mut self, f: &fn()) { self.label_ribs.push(@Rib(NormalRibKind)); f(); self.label_ribs.pop(); } - fn with_constant_rib(@mut self, f: fn()) { + fn with_constant_rib(@mut self, f: &fn()) { self.value_ribs.push(@Rib(ConstantItemRibKind)); f(); self.value_ribs.pop(); diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 7af1fcc7e779b..d4ed0004c8f9b 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -728,8 +728,8 @@ pub fn cast_shift_const_rhs(op: ast::binop, pub fn cast_shift_rhs(op: ast::binop, lhs: ValueRef, rhs: ValueRef, - trunc: fn(ValueRef, TypeRef) -> ValueRef, - zext: fn(ValueRef, TypeRef) -> ValueRef) + trunc: &fn(ValueRef, TypeRef) -> ValueRef, + zext: &fn(ValueRef, TypeRef) -> ValueRef) -> ValueRef { // Shifts may have any size int on the rhs unsafe { @@ -863,7 +863,7 @@ pub fn have_cached_lpad(bcx: block) -> bool { return res; } -pub fn in_lpad_scope_cx(bcx: block, f: fn(+si: &mut scope_info)) { +pub fn in_lpad_scope_cx(bcx: block, f: &fn(+si: &mut scope_info)) { let mut bcx = bcx; loop { { @@ -1326,7 +1326,7 @@ pub fn leave_block(bcx: block, out_of: block) -> block { pub fn with_scope(bcx: block, opt_node_info: Option, +name: ~str, - f: fn(block) -> block) -> block { + f: &fn(block) -> block) -> block { let _icx = bcx.insn_ctxt("with_scope"); debug!("with_scope(bcx=%s, opt_node_info=%?, name=%s)", @@ -1341,7 +1341,7 @@ pub fn with_scope(bcx: block, pub fn with_scope_result(bcx: block, opt_node_info: Option, +name: ~str, - f: fn(block) -> Result) -> Result { + f: &fn(block) -> Result) -> Result { let _icx = bcx.insn_ctxt("with_scope_result"); let scope_cx = scope_block(bcx, opt_node_info, name); Br(bcx, scope_cx.llbb); @@ -1350,7 +1350,7 @@ pub fn with_scope_result(bcx: block, } pub fn with_scope_datumblock(bcx: block, opt_node_info: Option, - +name: ~str, f: fn(block) -> datum::DatumBlock) + +name: ~str, f: &fn(block) -> datum::DatumBlock) -> datum::DatumBlock { use middle::trans::datum::DatumBlock; @@ -1361,7 +1361,7 @@ pub fn with_scope_datumblock(bcx: block, opt_node_info: Option, DatumBlock {bcx: leave_block(bcx, scope_cx), datum: datum} } -pub fn block_locals(b: &ast::blk, it: fn(@ast::local)) { +pub fn block_locals(b: &ast::blk, it: &fn(@ast::local)) { for vec::each(b.node.stmts) |s| { match s.node { ast::stmt_decl(d, _) => { @@ -1401,7 +1401,7 @@ pub fn alloc_local(cx: block, local: @ast::local) -> block { } -pub fn with_cond(bcx: block, val: ValueRef, f: fn(block) -> block) -> block { +pub fn with_cond(bcx: block, val: ValueRef, f: &fn(block) -> block) -> block { let _icx = bcx.insn_ctxt("with_cond"); let next_cx = base::sub_block(bcx, ~"next"); let cond_cx = base::sub_block(bcx, ~"cond"); @@ -1742,8 +1742,8 @@ pub fn trans_closure(ccx: @CrateContext, param_substs: Option<@param_substs>, id: ast::node_id, impl_id: Option, - maybe_load_env: fn(fn_ctxt), - finish: fn(block)) { + maybe_load_env: &fn(fn_ctxt), + finish: &fn(block)) { ccx.stats.n_closures += 1; let _icx = ccx.insn_ctxt("trans_closure"); set_uwtable(llfndecl); diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs index 1d7314f751870..7e159ef606242 100644 --- a/src/librustc/middle/trans/cabi.rs +++ b/src/librustc/middle/trans/cabi.rs @@ -37,7 +37,7 @@ pub struct FnType { } pub impl FnType { - fn decl_fn(&self, decl: fn(fnty: TypeRef) -> ValueRef) -> ValueRef { + fn decl_fn(&self, decl: &fn(fnty: TypeRef) -> ValueRef) -> ValueRef { let atys = vec::map(self.arg_tys, |t| t.ty); let rty = self.ret_ty.ty; let fnty = T_fn(atys, rty); diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index 54b10e2ad5c62..d5877ec563123 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -346,7 +346,7 @@ fn x86_64_tys(atys: &[TypeRef], } fn x86_64_ty(ty: TypeRef, - is_mem_cls: fn(cls: &[x86_64_reg_class]) -> bool, + is_mem_cls: &fn(cls: &[x86_64_reg_class]) -> bool, attr: Attribute) -> (LLVMType, Option) { let mut cast = false; let mut ty_attr = option::None; diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index d4ff0d74a47b7..9e38252dc9a8a 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -438,7 +438,7 @@ pub fn trans_call_inner( call_info: Option, fn_expr_ty: ty::t, ret_ty: ty::t, - get_callee: fn(block) -> Callee, + get_callee: &fn(block) -> Callee, args: CallArgs, dest: expr::Dest, autoref_arg: AutorefArg) -> block { diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 556c15c446d2f..11d3e1552028f 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -515,7 +515,7 @@ pub impl Datum { fn get_element(&self, bcx: block, ty: ty::t, source: DatumCleanup, - gep: fn(ValueRef) -> ValueRef) -> Datum { + gep: &fn(ValueRef) -> ValueRef) -> Datum { let base_val = self.to_ref_llval(bcx); Datum { val: gep(base_val), diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 02b68afff4a82..af54d4734314c 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -190,7 +190,7 @@ fn md_from_metadata(val: debug_metadata) -> T { fn cached_metadata(cache: metadata_cache, mdtag: int, - eq_fn: fn(md: T) -> bool) + eq_fn: &fn(md: T) -> bool) -> Option { unsafe { if cache.contains_key(&mdtag) { diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index b7942fa66dbbd..e38b0be7bccba 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1135,7 +1135,7 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum { pub fn with_field_tys(tcx: ty::ctxt, ty: ty::t, node_id_opt: Option, - op: fn(int, (&[ty::field])) -> R) -> R { + op: &fn(int, (&[ty::field])) -> R) -> R { match ty::get(ty).sty { ty::ty_struct(did, ref substs) => { op(0, struct_mutable_fields(tcx, did, substs)) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 978b1ed16d841..5552364df239d 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1138,11 +1138,11 @@ pub fn encl_region(cx: ctxt, id: ast::node_id) -> ty::Region { } } -pub fn walk_ty(ty: t, f: fn(t)) { +pub fn walk_ty(ty: t, f: &fn(t)) { maybe_walk_ty(ty, |t| { f(t); true }); } -pub fn maybe_walk_ty(ty: t, f: fn(t) -> bool) { +pub fn maybe_walk_ty(ty: t, f: &fn(t) -> bool) { if !f(ty) { return; } match /*bad*/copy get(ty).sty { ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) | @@ -1170,11 +1170,11 @@ pub fn maybe_walk_ty(ty: t, f: fn(t) -> bool) { } } -pub fn fold_sty_to_ty(tcx: ty::ctxt, sty: &sty, foldop: fn(t) -> t) -> t { +pub fn fold_sty_to_ty(tcx: ty::ctxt, sty: &sty, foldop: &fn(t) -> t) -> t { mk_t(tcx, fold_sty(sty, foldop)) } -pub fn fold_sig(sig: &FnSig, fldop: fn(t) -> t) -> FnSig { +pub fn fold_sig(sig: &FnSig, fldop: &fn(t) -> t) -> FnSig { let args = do sig.inputs.map |arg| { arg { mode: arg.mode, ty: fldop(arg.ty) } }; @@ -1185,8 +1185,8 @@ pub fn fold_sig(sig: &FnSig, fldop: fn(t) -> t) -> FnSig { } } -fn fold_sty(sty: &sty, fldop: fn(t) -> t) -> sty { - fn fold_substs(substs: &substs, fldop: fn(t) -> t) -> substs { +fn fold_sty(sty: &sty, fldop: &fn(t) -> t) -> sty { + fn fold_substs(substs: &substs, fldop: &fn(t) -> t) -> substs { substs {self_r: substs.self_r, self_ty: substs.self_ty.map(|t| fldop(*t)), tps: substs.tps.map(|t| fldop(*t))} @@ -1241,7 +1241,7 @@ fn fold_sty(sty: &sty, fldop: fn(t) -> t) -> sty { } // Folds types from the bottom up. -pub fn fold_ty(cx: ctxt, t0: t, fldop: fn(t) -> t) -> t { +pub fn fold_ty(cx: ctxt, t0: t, fldop: &fn(t) -> t) -> t { let sty = fold_sty(&get(t0).sty, |t| fold_ty(cx, fldop(t), fldop)); fldop(mk_t(cx, sty)) } @@ -1249,8 +1249,8 @@ pub fn fold_ty(cx: ctxt, t0: t, fldop: fn(t) -> t) -> t { pub fn walk_regions_and_ty( cx: ctxt, ty: t, - walkr: fn(r: Region), - walkt: fn(t: t) -> bool) { + walkr: &fn(r: Region), + walkt: &fn(t: t) -> bool) { if (walkt(ty)) { fold_regions_and_ty( @@ -1264,14 +1264,14 @@ pub fn walk_regions_and_ty( pub fn fold_regions_and_ty( cx: ctxt, ty: t, - fldr: fn(r: Region) -> Region, - fldfnt: fn(t: t) -> t, - fldt: fn(t: t) -> t) -> t { + fldr: &fn(r: Region) -> Region, + fldfnt: &fn(t: t) -> t, + fldt: &fn(t: t) -> t) -> t { fn fold_substs( substs: &substs, - fldr: fn(r: Region) -> Region, - fldt: fn(t: t) -> t) + fldr: &fn(r: Region) -> Region, + fldt: &fn(t: t) -> t) -> substs { substs { self_r: substs.self_r.map(|r| fldr(*r)), @@ -1325,9 +1325,9 @@ pub fn fold_regions_and_ty( pub fn fold_regions( cx: ctxt, ty: t, - fldr: fn(r: Region, in_fn: bool) -> Region) -> t { + fldr: &fn(r: Region, in_fn: bool) -> Region) -> t { fn do_fold(cx: ctxt, ty: t, in_fn: bool, - fldr: fn(Region, bool) -> Region) -> t { + fldr: &fn(Region, bool) -> Region) -> t { debug!("do_fold(ty=%s, in_fn=%b)", ty_to_str(cx, ty), in_fn); if !type_has_regions(ty) { return ty; } fold_regions_and_ty( @@ -2274,7 +2274,7 @@ pub fn is_instantiable(cx: ctxt, r_ty: t) -> bool { pub fn type_structurally_contains(cx: ctxt, ty: t, - test: fn(x: &sty) -> bool) + test: &fn(x: &sty) -> bool) -> bool { let sty = &get(ty).sty; debug!("type_structurally_contains: %s", @@ -4008,7 +4008,7 @@ pub fn struct_fields(cx: ctxt, fn struct_item_fields(cx:ctxt, did: ast::def_id, substs: &substs, - frob_mutability: fn(struct_mutability) -> mutability) + frob_mutability: &fn(struct_mutability) -> mutability) -> ~[field] { do lookup_struct_fields(cx, did).map |f| { // consider all instance vars mut, because the diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 8152200bf0476..6c27decc28345 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -36,7 +36,7 @@ * scopes and (b) the default region may change. To understand case (a), * consider something like: * - * type foo = { x: &a.int, y: fn(&a.int) } + * type foo = { x: &a.int, y: &fn(&a.int) } * * The type of `x` is an error because there is no region `a` in scope. * In the type of `y`, however, region `a` is considered a bound region @@ -224,7 +224,7 @@ pub fn ast_ty_to_ty( rscope: &RS, a_seq_ty: ast::mt, vst: ty::vstore, - constr: fn(ty::mt) -> ty::t) -> ty::t + constr: &fn(ty::mt) -> ty::t) -> ty::t { let tcx = self.tcx(); diff --git a/src/librustc/middle/typeck/check/demand.rs b/src/librustc/middle/typeck/check/demand.rs index a3fac8b4e1cde..1bb71c156c3dc 100644 --- a/src/librustc/middle/typeck/check/demand.rs +++ b/src/librustc/middle/typeck/check/demand.rs @@ -33,7 +33,7 @@ pub fn subtype(fcx: @mut FnCtxt, sp: span, expected: ty::t, actual: ty::t) { pub fn suptype_with_fn(fcx: @mut FnCtxt, sp: span, b_is_expected: bool, ty_a: ty::t, ty_b: ty::t, - handle_err: fn(span, ty::t, ty::t, &ty::type_err)) { + handle_err: &fn(span, ty::t, ty::t, &ty::type_err)) { // n.b.: order of actual, expected is reversed match infer::mk_subty(fcx.infcx(), b_is_expected, sp, ty_b, ty_a) { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index cdc1f258cb544..f3804934186d4 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1142,7 +1142,7 @@ pub fn break_here() { pub fn check_expr_with_unifier(fcx: @mut FnCtxt, expr: @ast::expr, expected: Option, - unifier: fn()) -> bool { + unifier: &fn()) -> bool { debug!(">> typechecking %s", fcx.expr_to_str(expr)); // A generic function to factor out common logic from call and @@ -1602,7 +1602,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, // returns `none`. fn unpack_expected(fcx: @mut FnCtxt, expected: Option, - unpack: fn(&ty::sty) -> Option) + unpack: &fn(&ty::sty) -> Option) -> Option { match expected { Some(t) => { diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index a5c64e7c8736b..98f49e48c0849 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -30,7 +30,7 @@ pub fn replace_bound_regions_in_fn_sig( isr: isr_alist, self_info: Option, fn_sig: &ty::FnSig, - mapf: fn(ty::bound_region) -> ty::Region) -> + mapf: &fn(ty::bound_region) -> ty::Region) -> (isr_alist, Option, ty::FnSig) { // Take self_info apart; the self_ty part is the only one we want // to update here. @@ -96,7 +96,7 @@ pub fn replace_bound_regions_in_fn_sig( tcx: ty::ctxt, isr: isr_alist, tys: ~[ty::t], - to_r: fn(ty::bound_region) -> ty::Region) -> isr_alist { + to_r: &fn(ty::bound_region) -> ty::Region) -> isr_alist { // Takes `isr` (described above), `to_r` (described above), // and `r`, a region. If `r` is anything other than a bound @@ -106,7 +106,7 @@ pub fn replace_bound_regions_in_fn_sig( // updated isr_alist that now contains a mapping from `r` to // the result of calling `to_r` on it. fn append_isr(isr: isr_alist, - to_r: fn(ty::bound_region) -> ty::Region, + to_r: &fn(ty::bound_region) -> ty::Region, r: ty::Region) -> isr_alist { match r { ty::re_free(_, _) | ty::re_static | ty::re_scope(_) | diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index dd9bf9cac64bf..49e5fe617627e 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -228,7 +228,7 @@ impl Combine for Glb { // NB---I do not believe this algorithm computes // (necessarily) the GLB. As written it can // spuriously fail. In particular, if there is a case - // like: fn(fn(&a)) and fn(fn(&b)), where a and b are + // like: &fn(fn(&a)) and fn(fn(&b)), where a and b are // free, it will return fn(&c) where c = GLB(a,b). If // however this GLB is not defined, then the result is // an error, even though something like diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index a334ba57e6e04..f68a0db63870b 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -481,12 +481,12 @@ fn resolve_borrowings(cx: @mut InferCtxt) { */ trait then { - fn then(&self, f: fn() -> Result) + fn then(&self, f: &fn() -> Result) -> Result; } impl then for ures { - fn then(&self, f: fn() -> Result) + fn then(&self, f: &fn() -> Result) -> Result { self.chain(|_i| f()) } @@ -506,11 +506,11 @@ impl ToUres for cres { } trait CresCompare { - fn compare(&self, t: T, f: fn() -> ty::type_err) -> cres; + fn compare(&self, t: T, f: &fn() -> ty::type_err) -> cres; } impl CresCompare for cres { - fn compare(&self, t: T, f: fn() -> ty::type_err) -> cres { + fn compare(&self, t: T, f: &fn() -> ty::type_err) -> cres { do self.chain |s| { if s == t { *self @@ -584,7 +584,7 @@ pub impl @mut InferCtxt { } /// Execute `f` and commit the bindings if successful - fn commit(&self, f: fn() -> Result) -> Result { + fn commit(&self, f: &fn() -> Result) -> Result { fail_unless!(!self.in_snapshot()); debug!("commit()"); @@ -599,7 +599,7 @@ pub impl @mut InferCtxt { } /// Execute `f`, unroll bindings on failure - fn try(&self, f: fn() -> Result) -> Result { + fn try(&self, f: &fn() -> Result) -> Result { debug!("try()"); do indent { let snapshot = self.start_snapshot(); @@ -613,7 +613,7 @@ pub impl @mut InferCtxt { } /// Execute `f` then unroll any bindings it creates - fn probe(&self, f: fn() -> Result) -> Result { + fn probe(&self, f: &fn() -> Result) -> Result { debug!("probe()"); do indent { let snapshot = self.start_snapshot(); @@ -706,7 +706,7 @@ pub impl @mut InferCtxt { } } - fn type_error_message(&self, sp: span, mk_msg: fn(~str) -> ~str, + fn type_error_message(&self, sp: span, mk_msg: &fn(~str) -> ~str, actual_ty: ty::t, err: Option<&ty::type_err>) { let actual_ty = self.resolve_type_vars_if_possible(actual_ty); diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index 35c901c7528de..cceef9fc0c301 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -153,7 +153,7 @@ The problem we are addressing is that there is a kind of subtyping between functions with bound region parameters. Consider, for example, whether the following relation holds: - fn(&a/int) <: fn(&b/int)? (Yes, a => b) + fn(&a/int) <: &fn(&b/int)? (Yes, a => b) The answer is that of course it does. These two types are basically the same, except that in one we used the name `a` and one we used @@ -170,7 +170,7 @@ Now let's consider two more function types. Here, we assume that the `self` lifetime is defined somewhere outside and hence is not a lifetime parameter bound by the function type (it "appears free"): - fn(&a/int) <: fn(&self/int)? (Yes, a => self) + fn(&a/int) <: &fn(&self/int)? (Yes, a => self) This subtyping relation does in fact hold. To see why, you have to consider what subtyping means. One way to look at `T1 <: T2` is to @@ -187,7 +187,7 @@ to the same thing: a function that accepts pointers with any lifetime So, what if we reverse the order of the two function types, like this: - fn(&self/int) <: fn(&a/int)? (No) + fn(&self/int) <: &fn(&a/int)? (No) Does the subtyping relationship still hold? The answer of course is no. In this case, the function accepts *only the lifetime `&self`*, @@ -196,8 +196,8 @@ accepted any lifetime. What about these two examples: - fn(&a/int, &b/int) <: fn(&a/int, &a/int)? (Yes) - fn(&a/int, &a/int) <: fn(&a/int, &b/int)? (No) + fn(&a/int, &b/int) <: &fn(&a/int, &a/int)? (Yes) + fn(&a/int, &a/int) <: &fn(&a/int, &b/int)? (No) Here, it is true that functions which take two pointers with any two lifetimes can be treated as if they only accepted two pointers with @@ -221,12 +221,12 @@ Let's walk through some examples and see how this algorithm plays out. We'll start with the first example, which was: - 1. fn(&a/T) <: fn(&b/T)? Yes: a -> b + 1. fn(&a/T) <: &fn(&b/T)? Yes: a -> b After steps 1 and 2 of the algorithm we will have replaced the types like so: - 1. fn(&A/T) <: fn(&x/T)? + 1. fn(&A/T) <: &fn(&x/T)? Here the upper case `&A` indicates a *region variable*, that is, a region whose value is being inferred by the system. I also replaced @@ -255,12 +255,12 @@ So far we have encountered no error, so the subtype check succeeds. Now let's look first at the third example, which was: - 3. fn(&self/T) <: fn(&b/T)? No! + 3. fn(&self/T) <: &fn(&b/T)? No! After steps 1 and 2 of the algorithm we will have replaced the types like so: - 3. fn(&self/T) <: fn(&x/T)? + 3. fn(&self/T) <: &fn(&x/T)? This looks pretty much the same as before, except that on the LHS `&self` was not bound, and hence was left as-is and not replaced with @@ -275,7 +275,7 @@ You may be wondering about that mysterious last step in the algorithm. So far it has not been relevant. The purpose of that last step is to catch something like *this*: - fn() -> fn(&a/T) <: fn() -> fn(&b/T)? No. + fn() -> fn(&a/T) <: &fn() -> fn(&b/T)? No. Here the function types are the same but for where the binding occurs. The subtype returns a function that expects a value in precisely one @@ -289,15 +289,15 @@ So let's step through what happens when we perform this subtype check. We first replace the bound regions in the subtype (the supertype has no bound regions). This gives us: - fn() -> fn(&A/T) <: fn() -> fn(&b/T)? + fn() -> fn(&A/T) <: &fn() -> fn(&b/T)? Now we compare the return types, which are covariant, and hence we have: - fn(&A/T) <: fn(&b/T)? + fn(&A/T) <: &fn(&b/T)? Here we skolemize the bound region in the supertype to yield: - fn(&A/T) <: fn(&x/T)? + fn(&A/T) <: &fn(&x/T)? And then proceed to compare the argument types: @@ -314,7 +314,7 @@ The difference between this example and the first one is that the variable `A` already existed at the point where the skolemization occurred. In the first example, you had two functions: - fn(&a/T) <: fn(&b/T) + fn(&a/T) <: &fn(&b/T) and hence `&A` and `&x` were created "together". In general, the intention of the skolemized names is that they are supposed to be @@ -1657,7 +1657,7 @@ pub impl RegionVarBindings { graph: &Graph, node_idx: RegionVid, dir: Direction, - op: fn(edge: &GraphEdge) -> bool) { + op: &fn(edge: &GraphEdge) -> bool) { let mut edge_idx = graph.nodes[*node_idx].head_edge[dir as uint]; while edge_idx != uint::max_value { let edge_ptr = &graph.edges[edge_idx]; diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 61f1ceeabaec5..abaf658a1a43e 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -225,7 +225,7 @@ pub fn require_same_types( span: span, t1: ty::t, t2: ty::t, - msg: fn() -> ~str) -> bool { + msg: &fn() -> ~str) -> bool { let l_tcx, l_infcx; match maybe_infcx { diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index d3ffd2deb8141..c7945f74f55a5 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -17,7 +17,7 @@ use syntax::visit; use core::str; use std::oldmap::HashMap; -pub fn indent(op: fn() -> R) -> R { +pub fn indent(op: &fn() -> R) -> R { // Use in conjunction with the log post-processor like `src/etc/indenter` // to make debug output more readable. debug!(">>"); diff --git a/src/librustdoc/rustdoc.rc b/src/librustdoc/rustdoc.rc index f17f7ffd9cf4a..f5cf98759b375 100644 --- a/src/librustdoc/rustdoc.rc +++ b/src/librustdoc/rustdoc.rc @@ -143,7 +143,7 @@ fn run(config: Config) { } } -pub fn time(what: ~str, f: fn() -> T) -> T { +pub fn time(what: ~str, f: &fn() -> T) -> T { let start = std::time::precise_time_s(); let rv = f(); let end = std::time::precise_time_s(); diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index 6674885a6e28a..0367a771ffbd1 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -59,7 +59,7 @@ enum CmdAction { /// A utility function that hands off a pretty printer to a callback. fn with_pp(intr: @token::ident_interner, - cb: fn(@pprust::ps, io::Writer)) -> ~str { + cb: &fn(@pprust::ps, io::Writer)) -> ~str { do io::with_str_writer |writer| { let pp = pprust::rust_printer(writer, intr); diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index b63a0a92e6c15..7d2b8eccd6c0e 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -260,7 +260,7 @@ pub fn hash(data: ~str) -> ~str { hasher.result_str() } -pub fn temp_change_dir(dir: &Path, cb: fn() -> T) { +pub fn temp_change_dir(dir: &Path, cb: &fn() -> T) { let cwd = os::getcwd(); os::change_dir(dir); diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index e7503f0082c2e..46e6980be581a 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -176,7 +176,7 @@ pub impl MutexARC { * blocked on the mutex) will also fail immediately. */ #[inline(always)] - unsafe fn access(&self, blk: fn(x: &mut T) -> U) -> U { + unsafe fn access(&self, blk: &fn(x: &mut T) -> U) -> U { unsafe { let state = get_shared_mutable_state(&self.x); // Borrowck would complain about this if the function were @@ -301,7 +301,7 @@ pub impl RWARC { * poison the ARC, so subsequent readers and writers will both also fail. */ #[inline(always)] - fn write(&self, blk: fn(x: &mut T) -> U) -> U { + fn write(&self, blk: &fn(x: &mut T) -> U) -> U { unsafe { let state = get_shared_mutable_state(&self.x); do (*borrow_rwlock(state)).write { @@ -313,7 +313,7 @@ pub impl RWARC { } /// As write(), but with a condvar, as sync::rwlock.write_cond(). #[inline(always)] - fn write_cond(&self, blk: fn(x: &x/mut T, c: &c/Condvar) -> U) -> U { + fn write_cond(&self, blk: &fn(x: &x/mut T, c: &c/Condvar) -> U) -> U { unsafe { let state = get_shared_mutable_state(&self.x); do (*borrow_rwlock(state)).write_cond |cond| { @@ -335,7 +335,7 @@ pub impl RWARC { * Failing will unlock the ARC while unwinding. However, unlike all other * access modes, this will not poison the ARC. */ - fn read(&self, blk: fn(x: &T) -> U) -> U { + fn read(&self, blk: &fn(x: &T) -> U) -> U { let state = unsafe { get_shared_immutable_state(&self.x) }; do (&state.lock).read { check_poison(false, state.failed); @@ -360,7 +360,7 @@ pub impl RWARC { * } * ~~~ */ - fn write_downgrade(&self, blk: fn(v: RWWriteMode) -> U) -> U { + fn write_downgrade(&self, blk: &fn(v: RWWriteMode) -> U) -> U { unsafe { let state = get_shared_mutable_state(&self.x); do (*borrow_rwlock(state)).write_downgrade |write_mode| { @@ -408,7 +408,7 @@ pub enum RWReadMode = (&self/T, sync::RWlockReadMode/&self); pub impl RWWriteMode/&self { /// Access the pre-downgrade RWARC in write mode. - fn write(&self, blk: fn(x: &mut T) -> U) -> U { + fn write(&self, blk: &fn(x: &mut T) -> U) -> U { match *self { RWWriteMode((ref data, ref token, _)) => { do token.write { @@ -418,7 +418,7 @@ pub impl RWWriteMode/&self { } } /// Access the pre-downgrade RWARC in write mode with a condvar. - fn write_cond(&self, blk: fn(x: &x/mut T, c: &c/Condvar) -> U) -> U { + fn write_cond(&self, blk: &fn(x: &x/mut T, c: &c/Condvar) -> U) -> U { match *self { RWWriteMode((ref data, ref token, ref poison)) => { do token.write_cond |cond| { @@ -438,7 +438,7 @@ pub impl RWWriteMode/&self { pub impl RWReadMode/&self { /// Access the post-downgrade rwlock in read mode. - fn read(&self, blk: fn(x: &T) -> U) -> U { + fn read(&self, blk: &fn(x: &T) -> U) -> U { match *self { RWReadMode((data, ref token)) => { do token.read { blk(data) } diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs index 9ed6d285ce687..695b3d01376c3 100644 --- a/src/libstd/arena.rs +++ b/src/libstd/arena.rs @@ -201,7 +201,7 @@ pub impl Arena { } #[inline(always)] - fn alloc_pod(&self, op: fn() -> T) -> &self/T { + fn alloc_pod(&self, op: &fn() -> T) -> &self/T { unsafe { let tydesc = sys::get_type_desc::(); let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align); @@ -246,7 +246,7 @@ pub impl Arena { } #[inline(always)] - fn alloc_nonpod(&self, op: fn() -> T) -> &self/T { + fn alloc_nonpod(&self, op: &fn() -> T) -> &self/T { unsafe { let tydesc = sys::get_type_desc::(); let (ty_ptr, ptr) = @@ -268,7 +268,7 @@ pub impl Arena { // The external interface #[inline(always)] - fn alloc(&self, op: fn() -> T) -> &self/T { + fn alloc(&self, op: &fn() -> T) -> &self/T { unsafe { if !rusti::needs_drop::() { self.alloc_pod(op) diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs index 55ec29d2337ca..8dbdb83698c6f 100644 --- a/src/libstd/bitv.rs +++ b/src/libstd/bitv.rs @@ -33,7 +33,7 @@ pub impl SmallBitv { #[inline(always)] fn bits_op(&mut self, right_bits: uint, nbits: uint, - f: fn(uint, uint) -> uint) -> bool { + f: &fn(uint, uint) -> uint) -> bool { let mask = small_mask(nbits); let old_b: uint = self.bits; let new_b = f(old_b, right_bits); @@ -130,7 +130,7 @@ pub impl BigBitv { #[inline(always)] fn process(&mut self, b: &BigBitv, nbits: uint, - op: fn(uint, uint) -> uint) -> bool { + op: &fn(uint, uint) -> uint) -> bool { let len = b.storage.len(); fail_unless!((self.storage.len() == len)); let mut changed = false; @@ -148,7 +148,7 @@ pub impl BigBitv { } #[inline(always)] - fn each_storage(&mut self, op: fn(v: &mut uint) -> bool) { + fn each_storage(&mut self, op: &fn(v: &mut uint) -> bool) { for uint::range(0, self.storage.len()) |i| { let mut w = self.storage[i]; let b = op(&mut w); @@ -392,7 +392,7 @@ pub impl Bitv { } #[inline(always)] - fn each(&self, f: fn(bool) -> bool) { + fn each(&self, f: &fn(bool) -> bool) { let mut i = 0; while i < self.nbits { if !f(self.get(i)) { break; } @@ -493,7 +493,7 @@ pub impl Bitv { true } - fn ones(&self, f: fn(uint) -> bool) { + fn ones(&self, f: &fn(uint) -> bool) { for uint::range(0, self.nbits) |i| { if self.get(i) { if !f(i) { break } @@ -546,7 +546,7 @@ pub fn from_bools(bools: &[bool]) -> Bitv { * Create a bitv of the specified length where the value at each * index is f(index). */ -pub fn from_fn(len: uint, f: fn(index: uint) -> bool) -> Bitv { +pub fn from_fn(len: uint, f: &fn(index: uint) -> bool) -> Bitv { let mut bitv = Bitv::new(len, false); for uint::range(0, len) |i| { bitv.set(i, f(i)); @@ -561,7 +561,7 @@ impl ops::Index for Bitv { } #[inline(always)] -pure fn iterate_bits(base: uint, bits: uint, f: fn(uint) -> bool) -> bool { +pure fn iterate_bits(base: uint, bits: uint, f: &fn(uint) -> bool) -> bool { if bits == 0 { return true; } @@ -622,7 +622,7 @@ pub impl BitvSet { } #[inline(always)] - priv fn other_op(&mut self, other: &BitvSet, f: fn(uint, uint) -> uint) { + priv fn other_op(&mut self, other: &BitvSet, f: &fn(uint, uint) -> uint) { fn nbits(mut w: uint) -> uint { let mut bits = 0; for uint::bits.times { @@ -669,7 +669,7 @@ pub impl BitvSet { impl BaseIter for BitvSet { pure fn size_hint(&self) -> Option { Some(self.len()) } - pure fn each(&self, blk: fn(v: &uint) -> bool) { + pure fn each(&self, blk: &fn(v: &uint) -> bool) { for self.bitv.storage.eachi |i, &w| { if !iterate_bits(i * uint::bits, w, |b| blk(&b)) { return; @@ -778,7 +778,7 @@ impl Set for BitvSet { other.is_subset(self) } - pure fn difference(&self, other: &BitvSet, f: fn(&uint) -> bool) { + pure fn difference(&self, other: &BitvSet, f: &fn(&uint) -> bool) { for self.each_common(other) |i, w1, w2| { if !iterate_bits(i, w1 & !w2, |b| f(&b)) { return; @@ -791,7 +791,7 @@ impl Set for BitvSet { } pure fn symmetric_difference(&self, other: &BitvSet, - f: fn(&uint) -> bool) { + f: &fn(&uint) -> bool) { for self.each_common(other) |i, w1, w2| { if !iterate_bits(i, w1 ^ w2, |b| f(&b)) { return; @@ -802,7 +802,7 @@ impl Set for BitvSet { ); } - pure fn intersection(&self, other: &BitvSet, f: fn(&uint) -> bool) { + pure fn intersection(&self, other: &BitvSet, f: &fn(&uint) -> bool) { for self.each_common(other) |i, w1, w2| { if !iterate_bits(i, w1 & w2, |b| f(&b)) { return; @@ -810,7 +810,7 @@ impl Set for BitvSet { } } - pure fn union(&self, other: &BitvSet, f: fn(&uint) -> bool) { + pure fn union(&self, other: &BitvSet, f: &fn(&uint) -> bool) { for self.each_common(other) |i, w1, w2| { if !iterate_bits(i, w1 | w2, |b| f(&b)) { return; @@ -828,7 +828,7 @@ priv impl BitvSet { /// w1, w2) where the bit location is the number of bits offset so far, /// and w1/w2 are the words coming from the two vectors self, other. pure fn each_common(&self, other: &BitvSet, - f: fn(uint, uint, uint) -> bool) { + f: &fn(uint, uint, uint) -> bool) { let min = uint::min(self.bitv.storage.len(), other.bitv.storage.len()); for self.bitv.storage.view(0, min).eachi |i, &w| { @@ -846,7 +846,7 @@ priv impl BitvSet { /// is true if the word comes from 'self', and false if it comes from /// 'other'. pure fn each_outlier(&self, other: &BitvSet, - f: fn(bool, uint, uint) -> bool) { + f: &fn(bool, uint, uint) -> bool) { let len1 = self.bitv.storage.len(); let len2 = other.bitv.storage.len(); let min = uint::min(len1, len2); diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index 44461ae06fff4..a55d4bc97ec56 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -142,7 +142,7 @@ pub mod reader { } } - pub fn docs(d: Doc, it: fn(uint, Doc) -> bool) { + pub fn docs(d: Doc, it: &fn(uint, Doc) -> bool) { let mut pos = d.start; while pos < d.end { let elt_tag = vuint_at(*d.data, pos); @@ -155,7 +155,7 @@ pub mod reader { } } - pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) { + pub fn tagged_docs(d: Doc, tg: uint, it: &fn(Doc) -> bool) { let mut pos = d.start; while pos < d.end { let elt_tag = vuint_at(*d.data, pos); @@ -175,7 +175,7 @@ pub mod reader { vec::slice::(*d.data, d.start, d.end).to_vec() } - pub fn with_doc_data(d: Doc, f: fn(x: &[u8]) -> T) -> T { + pub fn with_doc_data(d: Doc, f: &fn(x: &[u8]) -> T) -> T { f(vec::slice(*d.data, d.start, d.end)) } @@ -255,7 +255,7 @@ pub mod reader { r_doc } - fn push_doc(&self, d: Doc, f: fn() -> T) -> T { + fn push_doc(&self, d: Doc, f: &fn() -> T) -> T { let old_parent = self.parent; let old_pos = self.pos; self.parent = d; @@ -274,7 +274,7 @@ pub mod reader { } pub impl Decoder { - fn read_opaque(&self, op: fn(Doc) -> R) -> R { + fn read_opaque(&self, op: &fn(Doc) -> R) -> R { do self.push_doc(self.next_doc(EsOpaque)) { op(copy self.parent) } @@ -321,23 +321,23 @@ pub mod reader { fn read_managed_str(&self) -> @str { fail!(~"read_managed_str()"); } // Compound types: - fn read_owned(&self, f: fn() -> T) -> T { + fn read_owned(&self, f: &fn() -> T) -> T { debug!("read_owned()"); f() } - fn read_managed(&self, f: fn() -> T) -> T { + fn read_managed(&self, f: &fn() -> T) -> T { debug!("read_managed()"); f() } - fn read_enum(&self, name: &str, f: fn() -> T) -> T { + fn read_enum(&self, name: &str, f: &fn() -> T) -> T { debug!("read_enum(%s)", name); self._check_label(name); self.push_doc(self.next_doc(EsEnum), f) } - fn read_enum_variant(&self, f: fn(uint) -> T) -> T { + fn read_enum_variant(&self, f: &fn(uint) -> T) -> T { debug!("read_enum_variant()"); let idx = self._next_uint(EsEnumVid); debug!(" idx=%u", idx); @@ -346,12 +346,12 @@ pub mod reader { } } - fn read_enum_variant_arg(&self, idx: uint, f: fn() -> T) -> T { + fn read_enum_variant_arg(&self, idx: uint, f: &fn() -> T) -> T { debug!("read_enum_variant_arg(idx=%u)", idx); f() } - fn read_owned_vec(&self, f: fn(uint) -> T) -> T { + fn read_owned_vec(&self, f: &fn(uint) -> T) -> T { debug!("read_owned_vec()"); do self.push_doc(self.next_doc(EsVec)) { let len = self._next_uint(EsVecLen); @@ -360,7 +360,7 @@ pub mod reader { } } - fn read_managed_vec(&self, f: fn(uint) -> T) -> T { + fn read_managed_vec(&self, f: &fn(uint) -> T) -> T { debug!("read_managed_vec()"); do self.push_doc(self.next_doc(EsVec)) { let len = self._next_uint(EsVecLen); @@ -369,33 +369,33 @@ pub mod reader { } } - fn read_vec_elt(&self, idx: uint, f: fn() -> T) -> T { + fn read_vec_elt(&self, idx: uint, f: &fn() -> T) -> T { debug!("read_vec_elt(idx=%u)", idx); self.push_doc(self.next_doc(EsVecElt), f) } - fn read_rec(&self, f: fn() -> T) -> T { + fn read_rec(&self, f: &fn() -> T) -> T { debug!("read_rec()"); f() } - fn read_struct(&self, name: &str, _len: uint, f: fn() -> T) -> T { + fn read_struct(&self, name: &str, _len: uint, f: &fn() -> T) -> T { debug!("read_struct(name=%s)", name); f() } - fn read_field(&self, name: &str, idx: uint, f: fn() -> T) -> T { + fn read_field(&self, name: &str, idx: uint, f: &fn() -> T) -> T { debug!("read_field(name=%s, idx=%u)", name, idx); self._check_label(name); f() } - fn read_tup(&self, len: uint, f: fn() -> T) -> T { + fn read_tup(&self, len: uint, f: &fn() -> T) -> T { debug!("read_tup(len=%u)", len); f() } - fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T { + fn read_tup_elt(&self, idx: uint, f: &fn() -> T) -> T { debug!("read_tup_elt(idx=%u)", idx); f() } @@ -469,7 +469,7 @@ pub mod writer { debug!("End tag (size = %u)", size); } - fn wr_tag(&self, tag_id: uint, blk: fn()) { + fn wr_tag(&self, tag_id: uint, blk: &fn()) { self.start_tag(tag_id); blk(); self.end_tag(); @@ -566,7 +566,7 @@ pub mod writer { } pub impl Encoder { - fn emit_opaque(&self, f: fn()) { + fn emit_opaque(&self, f: &fn()) { do self.wr_tag(EsOpaque as uint) { f() } @@ -623,49 +623,49 @@ pub mod writer { self.emit_borrowed_str(v) } - fn emit_borrowed(&self, f: fn()) { f() } - fn emit_owned(&self, f: fn()) { f() } - fn emit_managed(&self, f: fn()) { f() } + fn emit_borrowed(&self, f: &fn()) { f() } + fn emit_owned(&self, f: &fn()) { f() } + fn emit_managed(&self, f: &fn()) { f() } - fn emit_enum(&self, name: &str, f: fn()) { + fn emit_enum(&self, name: &str, f: &fn()) { self._emit_label(name); self.wr_tag(EsEnum as uint, f) } fn emit_enum_variant(&self, _v_name: &str, v_id: uint, _cnt: uint, - f: fn()) { + f: &fn()) { self._emit_tagged_uint(EsEnumVid, v_id); self.wr_tag(EsEnumBody as uint, f) } - fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { f() } + fn emit_enum_variant_arg(&self, _idx: uint, f: &fn()) { f() } - fn emit_borrowed_vec(&self, len: uint, f: fn()) { + fn emit_borrowed_vec(&self, len: uint, f: &fn()) { do self.wr_tag(EsVec as uint) { self._emit_tagged_uint(EsVecLen, len); f() } } - fn emit_owned_vec(&self, len: uint, f: fn()) { + fn emit_owned_vec(&self, len: uint, f: &fn()) { self.emit_borrowed_vec(len, f) } - fn emit_managed_vec(&self, len: uint, f: fn()) { + fn emit_managed_vec(&self, len: uint, f: &fn()) { self.emit_borrowed_vec(len, f) } - fn emit_vec_elt(&self, _idx: uint, f: fn()) { + fn emit_vec_elt(&self, _idx: uint, f: &fn()) { self.wr_tag(EsVecElt as uint, f) } - fn emit_rec(&self, f: fn()) { f() } - fn emit_struct(&self, _name: &str, _len: uint, f: fn()) { f() } - fn emit_field(&self, name: &str, _idx: uint, f: fn()) { + fn emit_rec(&self, f: &fn()) { f() } + fn emit_struct(&self, _name: &str, _len: uint, f: &fn()) { f() } + fn emit_field(&self, name: &str, _idx: uint, f: &fn()) { self._emit_label(name); f() } - fn emit_tup(&self, _len: uint, f: fn()) { f() } - fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() } + fn emit_tup(&self, _len: uint, f: &fn()) { f() } + fn emit_tup_elt(&self, _idx: uint, f: &fn()) { f() } } } diff --git a/src/libstd/fun_treemap.rs b/src/libstd/fun_treemap.rs index 0729987958a06..735f86b34eca7 100644 --- a/src/libstd/fun_treemap.rs +++ b/src/libstd/fun_treemap.rs @@ -61,7 +61,7 @@ pub fn find(m: Treemap, k: K) -> Option { } /// Visit all pairs in the map in order. -pub fn traverse(m: Treemap, f: fn(&K, &V)) { +pub fn traverse(m: Treemap, f: &fn(&K, &V)) { match *m { Empty => (), /* diff --git a/src/libstd/json.rs b/src/libstd/json.rs index 9208d415971c6..8c6a870b98cd4 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -116,15 +116,15 @@ impl serialize::Encoder for Encoder { fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) } fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) } - fn emit_borrowed(&self, f: fn()) { f() } - fn emit_owned(&self, f: fn()) { f() } - fn emit_managed(&self, f: fn()) { f() } + fn emit_borrowed(&self, f: &fn()) { f() } + fn emit_owned(&self, f: &fn()) { f() } + fn emit_managed(&self, f: &fn()) { f() } - fn emit_enum(&self, _name: &str, f: fn()) { + fn emit_enum(&self, _name: &str, f: &fn()) { f() } - fn emit_enum_variant(&self, name: &str, _id: uint, _cnt: uint, f: fn()) { + fn emit_enum_variant(&self, name: &str, _id: uint, _cnt: uint, f: &fn()) { // encoding of enums is special-cased for Option. Specifically: // Some(34) => 34 // None => null @@ -160,49 +160,49 @@ impl serialize::Encoder for Encoder { } } - fn emit_enum_variant_arg(&self, idx: uint, f: fn()) { + fn emit_enum_variant_arg(&self, idx: uint, f: &fn()) { if (idx != 0) {self.wr.write_char(',');} f(); } - fn emit_borrowed_vec(&self, _len: uint, f: fn()) { + fn emit_borrowed_vec(&self, _len: uint, f: &fn()) { self.wr.write_char('['); f(); self.wr.write_char(']'); } - fn emit_owned_vec(&self, len: uint, f: fn()) { + fn emit_owned_vec(&self, len: uint, f: &fn()) { self.emit_borrowed_vec(len, f) } - fn emit_managed_vec(&self, len: uint, f: fn()) { + fn emit_managed_vec(&self, len: uint, f: &fn()) { self.emit_borrowed_vec(len, f) } - fn emit_vec_elt(&self, idx: uint, f: fn()) { + fn emit_vec_elt(&self, idx: uint, f: &fn()) { if idx != 0 { self.wr.write_char(','); } f() } - fn emit_rec(&self, f: fn()) { + fn emit_rec(&self, f: &fn()) { self.wr.write_char('{'); f(); self.wr.write_char('}'); } - fn emit_struct(&self, _name: &str, _len: uint, f: fn()) { + fn emit_struct(&self, _name: &str, _len: uint, f: &fn()) { self.wr.write_char('{'); f(); self.wr.write_char('}'); } - fn emit_field(&self, name: &str, idx: uint, f: fn()) { + fn emit_field(&self, name: &str, idx: uint, f: &fn()) { if idx != 0 { self.wr.write_char(','); } self.wr.write_str(escape_str(name)); self.wr.write_char(':'); f(); } - fn emit_tup(&self, len: uint, f: fn()) { + fn emit_tup(&self, len: uint, f: &fn()) { self.emit_borrowed_vec(len, f); } - fn emit_tup_elt(&self, idx: uint, f: fn()) { + fn emit_tup_elt(&self, idx: uint, f: &fn()) { self.emit_vec_elt(idx, f) } } @@ -251,39 +251,39 @@ impl serialize::Encoder for PrettyEncoder { fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) } fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) } - fn emit_borrowed(&self, f: fn()) { f() } - fn emit_owned(&self, f: fn()) { f() } - fn emit_managed(&self, f: fn()) { f() } + fn emit_borrowed(&self, f: &fn()) { f() } + fn emit_owned(&self, f: &fn()) { f() } + fn emit_managed(&self, f: &fn()) { f() } - fn emit_enum(&self, name: &str, f: fn()) { + fn emit_enum(&self, name: &str, f: &fn()) { if name != "option" { fail!(~"only supports option enum") } f() } - fn emit_enum_variant(&self, _name: &str, id: uint, _cnt: uint, f: fn()) { + fn emit_enum_variant(&self, _name: &str, id: uint, _cnt: uint, f: &fn()) { if id == 0 { self.emit_nil(); } else { f() } } - fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { + fn emit_enum_variant_arg(&self, _idx: uint, f: &fn()) { f() } - fn emit_borrowed_vec(&self, _len: uint, f: fn()) { + fn emit_borrowed_vec(&self, _len: uint, f: &fn()) { self.wr.write_char('['); self.indent += 2; f(); self.indent -= 2; self.wr.write_char(']'); } - fn emit_owned_vec(&self, len: uint, f: fn()) { + fn emit_owned_vec(&self, len: uint, f: &fn()) { self.emit_borrowed_vec(len, f) } - fn emit_managed_vec(&self, len: uint, f: fn()) { + fn emit_managed_vec(&self, len: uint, f: &fn()) { self.emit_borrowed_vec(len, f) } - fn emit_vec_elt(&self, idx: uint, f: fn()) { + fn emit_vec_elt(&self, idx: uint, f: &fn()) { if idx == 0 { self.wr.write_char('\n'); } else { @@ -293,17 +293,17 @@ impl serialize::Encoder for PrettyEncoder { f() } - fn emit_rec(&self, f: fn()) { + fn emit_rec(&self, f: &fn()) { self.wr.write_char('{'); self.indent += 2; f(); self.indent -= 2; self.wr.write_char('}'); } - fn emit_struct(&self, _name: &str, _len: uint, f: fn()) { + fn emit_struct(&self, _name: &str, _len: uint, f: &fn()) { self.emit_rec(f) } - fn emit_field(&self, name: &str, idx: uint, f: fn()) { + fn emit_field(&self, name: &str, idx: uint, f: &fn()) { if idx == 0 { self.wr.write_char('\n'); } else { @@ -314,10 +314,10 @@ impl serialize::Encoder for PrettyEncoder { self.wr.write_str(": "); f(); } - fn emit_tup(&self, sz: uint, f: fn()) { + fn emit_tup(&self, sz: uint, f: &fn()) { self.emit_borrowed_vec(sz, f); } - fn emit_tup_elt(&self, idx: uint, f: fn()) { + fn emit_tup_elt(&self, idx: uint, f: &fn()) { self.emit_vec_elt(idx, f) } } @@ -828,23 +828,23 @@ impl serialize::Decoder for Decoder/&self { } } - fn read_owned(&self, f: fn() -> T) -> T { + fn read_owned(&self, f: &fn() -> T) -> T { debug!("read_owned()"); f() } - fn read_managed(&self, f: fn() -> T) -> T { + fn read_managed(&self, f: &fn() -> T) -> T { debug!("read_managed()"); f() } - fn read_enum(&self, name: &str, f: fn() -> T) -> T { + fn read_enum(&self, name: &str, f: &fn() -> T) -> T { debug!("read_enum(%s)", name); if name != ~"option" { fail!(~"only supports the option enum") } f() } - fn read_enum_variant(&self, f: fn(uint) -> T) -> T { + fn read_enum_variant(&self, f: &fn(uint) -> T) -> T { debug!("read_enum_variant()"); let idx = match *self.peek() { Null => 0, @@ -853,13 +853,13 @@ impl serialize::Decoder for Decoder/&self { f(idx) } - fn read_enum_variant_arg(&self, idx: uint, f: fn() -> T) -> T { + fn read_enum_variant_arg(&self, idx: uint, f: &fn() -> T) -> T { debug!("read_enum_variant_arg(idx=%u)", idx); if idx != 0 { fail!(~"unknown index") } f() } - fn read_owned_vec(&self, f: fn(uint) -> T) -> T { + fn read_owned_vec(&self, f: &fn(uint) -> T) -> T { debug!("read_owned_vec()"); let len = match *self.peek() { List(ref list) => list.len(), @@ -870,7 +870,7 @@ impl serialize::Decoder for Decoder/&self { res } - fn read_managed_vec(&self, f: fn(uint) -> T) -> T { + fn read_managed_vec(&self, f: &fn(uint) -> T) -> T { debug!("read_owned_vec()"); let len = match *self.peek() { List(ref list) => list.len(), @@ -881,7 +881,7 @@ impl serialize::Decoder for Decoder/&self { res } - fn read_vec_elt(&self, idx: uint, f: fn() -> T) -> T { + fn read_vec_elt(&self, idx: uint, f: &fn() -> T) -> T { debug!("read_vec_elt(idx=%u)", idx); match *self.peek() { List(ref list) => { @@ -892,21 +892,21 @@ impl serialize::Decoder for Decoder/&self { } } - fn read_rec(&self, f: fn() -> T) -> T { + fn read_rec(&self, f: &fn() -> T) -> T { debug!("read_rec()"); let value = f(); self.pop(); value } - fn read_struct(&self, _name: &str, _len: uint, f: fn() -> T) -> T { + fn read_struct(&self, _name: &str, _len: uint, f: &fn() -> T) -> T { debug!("read_struct()"); let value = f(); self.pop(); value } - fn read_field(&self, name: &str, idx: uint, f: fn() -> T) -> T { + fn read_field(&self, name: &str, idx: uint, f: &fn() -> T) -> T { debug!("read_rec_field(%s, idx=%u)", name, idx); let top = self.peek(); match *top { @@ -929,14 +929,14 @@ impl serialize::Decoder for Decoder/&self { } } - fn read_tup(&self, len: uint, f: fn() -> T) -> T { + fn read_tup(&self, len: uint, f: &fn() -> T) -> T { debug!("read_tup(len=%u)", len); let value = f(); self.pop(); value } - fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T { + fn read_tup_elt(&self, idx: uint, f: &fn() -> T) -> T { debug!("read_tup_elt(idx=%u)", idx); match *self.peek() { List(ref list) => { diff --git a/src/libstd/list.rs b/src/libstd/list.rs index 5ab1722ae8399..3a0f299257e09 100644 --- a/src/libstd/list.rs +++ b/src/libstd/list.rs @@ -39,7 +39,7 @@ pub pure fn from_vec(v: &[T]) -> @List { * * z - The initial value * * f - The function to apply */ -pub fn foldl(z: T, ls: @List, f: fn(&T, &U) -> T) -> T { +pub fn foldl(z: T, ls: @List, f: &fn(&T, &U) -> T) -> T { let mut accum: T = z; do iter(ls) |elt| { accum = f(&accum, elt);} accum @@ -52,7 +52,7 @@ pub fn foldl(z: T, ls: @List, f: fn(&T, &U) -> T) -> T { * When function `f` returns true then an option containing the element * is returned. If `f` matches no elements then none is returned. */ -pub pure fn find(ls: @List, f: fn(&T) -> bool) -> Option { +pub pure fn find(ls: @List, f: &fn(&T) -> bool) -> Option { let mut ls = ls; loop { ls = match *ls { @@ -125,7 +125,7 @@ pure fn push(ll: &mut @list, vv: T) { */ /// Iterate over a list -pub pure fn iter(l: @List, f: fn(&T)) { +pub pure fn iter(l: @List, f: &fn(&T)) { let mut cur = l; loop { cur = match *cur { @@ -139,7 +139,7 @@ pub pure fn iter(l: @List, f: fn(&T)) { } /// Iterate over a list -pub pure fn each(l: @List, f: fn(&T) -> bool) { +pub pure fn each(l: @List, f: &fn(&T) -> bool) { let mut cur = l; loop { cur = match *cur { diff --git a/src/libstd/md4.rs b/src/libstd/md4.rs index eb4bd6fe23f47..df254543512b0 100644 --- a/src/libstd/md4.rs +++ b/src/libstd/md4.rs @@ -105,7 +105,7 @@ pub pure fn md4(msg: &[u8]) -> Quad { pub pure fn md4_str(msg: &[u8]) -> ~str { let Quad {a, b, c, d} = md4(msg); - pure fn app(a: u32, b: u32, c: u32, d: u32, f: fn(u32)) { + pure fn app(a: u32, b: u32, c: u32, d: u32, f: &fn(u32)) { f(a); f(b); f(c); f(d); } let mut result = ~""; diff --git a/src/libstd/oldmap.rs b/src/libstd/oldmap.rs index 0f6434f1b2ba5..18527cfece111 100644 --- a/src/libstd/oldmap.rs +++ b/src/libstd/oldmap.rs @@ -134,7 +134,7 @@ pub mod chained { } pub impl T { - pure fn each_entry(&self, blk: fn(@Entry) -> bool) { + pure fn each_entry(&self, blk: &fn(@Entry) -> bool) { // n.b. we can't use vec::iter() here because self.chains // is stored in a mutable location. let mut i = 0u, n = self.chains.len(); @@ -236,17 +236,17 @@ pub mod chained { } } - pure fn each(&self, blk: fn(key: &K, value: &V) -> bool) { + pure fn each(&self, blk: &fn(key: &K, value: &V) -> bool) { for self.each_entry |entry| { if !blk(&entry.key, &entry.value) { break; } } } - pure fn each_key(&self, blk: fn(key: &K) -> bool) { + pure fn each_key(&self, blk: &fn(key: &K) -> bool) { self.each(|k, _v| blk(k)) } - pure fn each_value(&self, blk: fn(value: &V) -> bool) { + pure fn each_value(&self, blk: &fn(value: &V) -> bool) { self.each(|_k, v| blk(v)) } } @@ -260,8 +260,8 @@ pub mod chained { } } - fn update_with_key(&self, key: K, newval: V, ff: fn(K, V, V) -> V) - -> bool { + fn update_with_key(&self, key: K, newval: V, ff: &fn(K, V, V) -> V) + -> bool { /* match self.find(key) { None => return self.insert(key, val), @@ -312,7 +312,7 @@ pub mod chained { } } - fn update(&self, key: K, newval: V, ff: fn(V, V) -> V) -> bool { + fn update(&self, key: K, newval: V, ff: &fn(V, V) -> V) -> bool { return self.update_with_key(key, newval, |_k, v, v1| ff(v,v1)); } diff --git a/src/libstd/prettyprint.rs b/src/libstd/prettyprint.rs index ed02ea87dac4a..d2d80eb7da803 100644 --- a/src/libstd/prettyprint.rs +++ b/src/libstd/prettyprint.rs @@ -98,87 +98,87 @@ impl serialize::Encoder for Serializer { self.wr.write_str(fmt!("@%?", v)); } - fn emit_borrowed(&self, f: fn()) { + fn emit_borrowed(&self, f: &fn()) { self.wr.write_str(~"&"); f(); } - fn emit_owned(&self, f: fn()) { + fn emit_owned(&self, f: &fn()) { self.wr.write_str(~"~"); f(); } - fn emit_managed(&self, f: fn()) { + fn emit_managed(&self, f: &fn()) { self.wr.write_str(~"@"); f(); } - fn emit_enum(&self, _name: &str, f: fn()) { + fn emit_enum(&self, _name: &str, f: &fn()) { f(); } fn emit_enum_variant(&self, v_name: &str, _v_id: uint, sz: uint, - f: fn()) { + f: &fn()) { self.wr.write_str(v_name); if sz > 0u { self.wr.write_str(~"("); } f(); if sz > 0u { self.wr.write_str(~")"); } } - fn emit_enum_variant_arg(&self, idx: uint, f: fn()) { + fn emit_enum_variant_arg(&self, idx: uint, f: &fn()) { if idx > 0u { self.wr.write_str(~", "); } f(); } - fn emit_borrowed_vec(&self, _len: uint, f: fn()) { + fn emit_borrowed_vec(&self, _len: uint, f: &fn()) { self.wr.write_str(~"&["); f(); self.wr.write_str(~"]"); } - fn emit_owned_vec(&self, _len: uint, f: fn()) { + fn emit_owned_vec(&self, _len: uint, f: &fn()) { self.wr.write_str(~"~["); f(); self.wr.write_str(~"]"); } - fn emit_managed_vec(&self, _len: uint, f: fn()) { + fn emit_managed_vec(&self, _len: uint, f: &fn()) { self.wr.write_str(~"@["); f(); self.wr.write_str(~"]"); } - fn emit_vec_elt(&self, idx: uint, f: fn()) { + fn emit_vec_elt(&self, idx: uint, f: &fn()) { if idx > 0u { self.wr.write_str(~", "); } f(); } - fn emit_rec(&self, f: fn()) { + fn emit_rec(&self, f: &fn()) { self.wr.write_str(~"{"); f(); self.wr.write_str(~"}"); } - fn emit_struct(&self, name: &str, _len: uint, f: fn()) { + fn emit_struct(&self, name: &str, _len: uint, f: &fn()) { self.wr.write_str(fmt!("%s {", name)); f(); self.wr.write_str(~"}"); } - fn emit_field(&self, name: &str, idx: uint, f: fn()) { + fn emit_field(&self, name: &str, idx: uint, f: &fn()) { if idx > 0u { self.wr.write_str(~", "); } self.wr.write_str(name); self.wr.write_str(~": "); f(); } - fn emit_tup(&self, _len: uint, f: fn()) { + fn emit_tup(&self, _len: uint, f: &fn()) { self.wr.write_str(~"("); f(); self.wr.write_str(~")"); } - fn emit_tup_elt(&self, idx: uint, f: fn()) { + fn emit_tup_elt(&self, idx: uint, f: &fn()) { if idx > 0u { self.wr.write_str(~", "); } f(); } diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs index 676bc68e4e513..31f29ce23f2cd 100644 --- a/src/libstd/priority_queue.rs +++ b/src/libstd/priority_queue.rs @@ -31,7 +31,7 @@ impl BaseIter for PriorityQueue { /// Visit all values in the underlying vector. /// /// The values are **not** visited in order. - pure fn each(&self, f: fn(&T) -> bool) { self.data.each(f) } + pure fn each(&self, f: &fn(&T) -> bool) { self.data.each(f) } pure fn size_hint(&self) -> Option { self.data.size_hint() } } diff --git a/src/libstd/rope.rs b/src/libstd/rope.rs index d511ac9744eb3..dd2f5b58fb96a 100644 --- a/src/libstd/rope.rs +++ b/src/libstd/rope.rs @@ -393,7 +393,7 @@ Section: Iterating * `true` If execution proceeded correctly, `false` if it was interrupted, * that is if `it` returned `false` at any point. */ -pub fn loop_chars(rope: Rope, it: fn(c: char) -> bool) -> bool { +pub fn loop_chars(rope: Rope, it: &fn(c: char) -> bool) -> bool { match (rope) { node::Empty => return true, node::Content(x) => return node::loop_chars(x, it) @@ -407,7 +407,7 @@ pub fn loop_chars(rope: Rope, it: fn(c: char) -> bool) -> bool { * * rope - A rope to traverse. It may be empty * * it - A block to execute with each consecutive character of the rope. */ -pub fn iter_chars(rope: Rope, it: fn(char)) { +pub fn iter_chars(rope: Rope, it: &fn(char)) { do loop_chars(rope) |x| { it(x); true @@ -436,7 +436,7 @@ pub fn iter_chars(rope: Rope, it: fn(char)) { * `true` If execution proceeded correctly, `false` if it was interrupted, * that is if `it` returned `false` at any point. */ -pub fn loop_leaves(rope: Rope, it: fn(node::Leaf) -> bool) -> bool{ +pub fn loop_leaves(rope: Rope, it: &fn(node::Leaf) -> bool) -> bool{ match (rope) { node::Empty => return true, node::Content(x) => return node::loop_leaves(x, it) @@ -1078,7 +1078,7 @@ pub mod node { return result; } - pub fn loop_chars(node: @Node, it: fn(c: char) -> bool) -> bool { + pub fn loop_chars(node: @Node, it: &fn(c: char) -> bool) -> bool { return loop_leaves(node,|leaf| { str::all_between(*leaf.content, leaf.byte_offset, @@ -1100,7 +1100,7 @@ pub mod node { * `true` If execution proceeded correctly, `false` if it was interrupted, * that is if `it` returned `false` at any point. */ - pub fn loop_leaves(node: @Node, it: fn(Leaf) -> bool) -> bool{ + pub fn loop_leaves(node: @Node, it: &fn(Leaf) -> bool) -> bool{ let mut current = node; loop { match (*current) { diff --git a/src/libstd/semver.rs b/src/libstd/semver.rs index bf4091e1e902d..7b8a06f1b93af 100644 --- a/src/libstd/semver.rs +++ b/src/libstd/semver.rs @@ -140,7 +140,7 @@ condition! { fn take_nonempty_prefix(rdr: io::Reader, ch: char, - pred: fn(char) -> bool) -> (~str, char) { + pred: &fn(char) -> bool) -> (~str, char) { let mut buf = ~""; let mut ch = ch; while pred(ch) { diff --git a/src/libstd/serialize.rs b/src/libstd/serialize.rs index 5bbd926ba6beb..0288155d29ebd 100644 --- a/src/libstd/serialize.rs +++ b/src/libstd/serialize.rs @@ -43,25 +43,25 @@ pub trait Encoder { fn emit_managed_str(&self, v: &str); // Compound types: - fn emit_borrowed(&self, f: fn()); - fn emit_owned(&self, f: fn()); - fn emit_managed(&self, f: fn()); + fn emit_borrowed(&self, f: &fn()); + fn emit_owned(&self, f: &fn()); + fn emit_managed(&self, f: &fn()); - fn emit_enum(&self, name: &str, f: fn()); - fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: fn()); - fn emit_enum_variant_arg(&self, idx: uint, f: fn()); + fn emit_enum(&self, name: &str, f: &fn()); + fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: &fn()); + fn emit_enum_variant_arg(&self, idx: uint, f: &fn()); - fn emit_borrowed_vec(&self, len: uint, f: fn()); - fn emit_owned_vec(&self, len: uint, f: fn()); - fn emit_managed_vec(&self, len: uint, f: fn()); - fn emit_vec_elt(&self, idx: uint, f: fn()); + fn emit_borrowed_vec(&self, len: uint, f: &fn()); + fn emit_owned_vec(&self, len: uint, f: &fn()); + fn emit_managed_vec(&self, len: uint, f: &fn()); + fn emit_vec_elt(&self, idx: uint, f: &fn()); - fn emit_rec(&self, f: fn()); - fn emit_struct(&self, name: &str, _len: uint, f: fn()); - fn emit_field(&self, f_name: &str, f_idx: uint, f: fn()); + fn emit_rec(&self, f: &fn()); + fn emit_struct(&self, name: &str, _len: uint, f: &fn()); + fn emit_field(&self, f_name: &str, f_idx: uint, f: &fn()); - fn emit_tup(&self, len: uint, f: fn()); - fn emit_tup_elt(&self, idx: uint, f: fn()); + fn emit_tup(&self, len: uint, f: &fn()); + fn emit_tup_elt(&self, idx: uint, f: &fn()); } pub trait Decoder { @@ -86,23 +86,23 @@ pub trait Decoder { fn read_managed_str(&self) -> @str; // Compound types: - fn read_enum(&self, name: &str, f: fn() -> T) -> T; - fn read_enum_variant(&self, f: fn(uint) -> T) -> T; - fn read_enum_variant_arg(&self, idx: uint, f: fn() -> T) -> T; + fn read_enum(&self, name: &str, f: &fn() -> T) -> T; + fn read_enum_variant(&self, f: &fn(uint) -> T) -> T; + fn read_enum_variant_arg(&self, idx: uint, f: &fn() -> T) -> T; - fn read_owned(&self, f: fn() -> T) -> T; - fn read_managed(&self, f: fn() -> T) -> T; + fn read_owned(&self, f: &fn() -> T) -> T; + fn read_managed(&self, f: &fn() -> T) -> T; - fn read_owned_vec(&self, f: fn(uint) -> T) -> T; - fn read_managed_vec(&self, f: fn(uint) -> T) -> T; - fn read_vec_elt(&self, idx: uint, f: fn() -> T) -> T; + fn read_owned_vec(&self, f: &fn(uint) -> T) -> T; + fn read_managed_vec(&self, f: &fn(uint) -> T) -> T; + fn read_vec_elt(&self, idx: uint, f: &fn() -> T) -> T; - fn read_rec(&self, f: fn() -> T) -> T; - fn read_struct(&self, name: &str, _len: uint, f: fn() -> T) -> T; - fn read_field(&self, name: &str, idx: uint, f: fn() -> T) -> T; + fn read_rec(&self, f: &fn() -> T) -> T; + fn read_struct(&self, name: &str, _len: uint, f: &fn() -> T) -> T; + fn read_field(&self, name: &str, idx: uint, f: &fn() -> T) -> T; - fn read_tup(&self, sz: uint, f: fn() -> T) -> T; - fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T; + fn read_tup(&self, sz: uint, f: &fn() -> T) -> T; + fn read_tup_elt(&self, idx: uint, f: &fn() -> T) -> T; } pub trait Encodable { @@ -547,11 +547,11 @@ impl< // In some cases, these should eventually be coded as traits. pub trait EncoderHelpers { - fn emit_from_vec(&self, v: &[T], f: fn(v: &T)); + fn emit_from_vec(&self, v: &[T], f: &fn(v: &T)); } impl EncoderHelpers for S { - fn emit_from_vec(&self, v: &[T], f: fn(v: &T)) { + fn emit_from_vec(&self, v: &[T], f: &fn(v: &T)) { do self.emit_owned_vec(v.len()) { for v.eachi |i, e| { do self.emit_vec_elt(i) { @@ -563,11 +563,11 @@ impl EncoderHelpers for S { } pub trait DecoderHelpers { - fn read_to_vec(&self, f: fn() -> T) -> ~[T]; + fn read_to_vec(&self, f: &fn() -> T) -> ~[T]; } impl DecoderHelpers for D { - fn read_to_vec(&self, f: fn() -> T) -> ~[T] { + fn read_to_vec(&self, f: &fn() -> T) -> ~[T] { do self.read_owned_vec |len| { do vec::from_fn(len) |i| { self.read_vec_elt(i, || f()) diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index 84600ac74eeb9..726e7c36abd1b 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -24,7 +24,7 @@ pub struct SmallIntMap { impl BaseIter<(uint, &self/V)> for SmallIntMap { /// Visit all key-value pairs in order - pure fn each(&self, it: fn(&(uint, &self/V)) -> bool) { + pure fn each(&self, it: &fn(&(uint, &self/V)) -> bool) { for uint::range(0, self.v.len()) |i| { match self.v[i] { Some(ref elt) => if !it(&(i, elt)) { break }, @@ -38,7 +38,7 @@ impl BaseIter<(uint, &self/V)> for SmallIntMap { impl ReverseIter<(uint, &self/V)> for SmallIntMap { /// Visit all key-value pairs in reverse order - pure fn each_reverse(&self, it: fn(&(uint, &self/V)) -> bool) { + pure fn each_reverse(&self, it: &fn(&(uint, &self/V)) -> bool) { for uint::range_rev(self.v.len(), 0) |i| { match self.v[i - 1] { Some(ref elt) => if !it(&(i - 1, elt)) { break }, @@ -76,12 +76,12 @@ impl Map for SmallIntMap { } /// Visit all keys in order - pure fn each_key(&self, blk: fn(key: &uint) -> bool) { + pure fn each_key(&self, blk: &fn(key: &uint) -> bool) { self.each(|&(k, _)| blk(&k)) } /// Visit all values in order - pure fn each_value(&self, blk: fn(value: &V) -> bool) { + pure fn each_value(&self, blk: &fn(value: &V) -> bool) { self.each(|&(_, v)| blk(v)) } @@ -133,7 +133,7 @@ pub impl SmallIntMap { pub impl SmallIntMap { fn update_with_key(&mut self, key: uint, val: V, - ff: fn(uint, V, V) -> V) -> bool { + ff: &fn(uint, V, V) -> V) -> bool { let new_val = match self.find(&key) { None => val, Some(orig) => ff(key, *orig, val) @@ -141,7 +141,7 @@ pub impl SmallIntMap { self.insert(key, new_val) } - fn update(&mut self, key: uint, newval: V, ff: fn(V, V) -> V) -> bool { + fn update(&mut self, key: uint, newval: V, ff: &fn(V, V) -> V) -> bool { self.update_with_key(key, newval, |_k, v, v1| ff(v,v1)) } } diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs index d143c665d8310..a68fe5f10a3c3 100644 --- a/src/libstd/sync.rs +++ b/src/libstd/sync.rs @@ -135,7 +135,7 @@ pub impl &self/Sem { // FIXME(#3154) move both copies of this into Sem, and unify the 2 structs #[doc(hidden)] pub impl &self/Sem<()> { - fn access(&self, blk: fn() -> U) -> U { + fn access(&self, blk: &fn() -> U) -> U { let mut release = None; unsafe { do task::unkillable { @@ -148,7 +148,7 @@ pub impl &self/Sem<()> { } #[doc(hidden)] pub impl &self/Sem<~[Waitqueue]> { - fn access(&self, blk: fn() -> U) -> U { + fn access(&self, blk: &fn() -> U) -> U { let mut release = None; unsafe { do task::unkillable { @@ -332,7 +332,7 @@ pub impl Condvar/&self { #[inline(always)] #[doc(hidden)] fn check_cvar_bounds(out_of_bounds: Option, id: uint, act: &str, - blk: fn() -> U) -> U { + blk: &fn() -> U) -> U { match out_of_bounds { Some(0) => fail!(fmt!("%s with illegal ID %u - this lock has no condvars!", @@ -347,7 +347,7 @@ fn check_cvar_bounds(out_of_bounds: Option, id: uint, act: &str, #[doc(hidden)] pub impl Sem<~[Waitqueue]> { // The only other place that condvars get built is rwlock_write_mode. - fn access_cond(&self, blk: fn(c: &Condvar) -> U) -> U { + fn access_cond(&self, blk: &fn(c: &Condvar) -> U) -> U { do self.access { blk(&Condvar { sem: self }) } } } @@ -385,7 +385,7 @@ pub impl Semaphore { fn release(&self) { (&self.sem).release() } /// Run a function with ownership of one of the semaphore's resources. - fn access(&self, blk: fn() -> U) -> U { (&self.sem).access(blk) } + fn access(&self, blk: &fn() -> U) -> U { (&self.sem).access(blk) } } /**************************************************************************** @@ -421,10 +421,10 @@ impl Clone for Mutex { pub impl Mutex { /// Run a function with ownership of the mutex. - fn lock(&self, blk: fn() -> U) -> U { (&self.sem).access(blk) } + fn lock(&self, blk: &fn() -> U) -> U { (&self.sem).access(blk) } /// Run a function with ownership of the mutex and a handle to a condvar. - fn lock_cond(&self, blk: fn(c: &Condvar) -> U) -> U { + fn lock_cond(&self, blk: &fn(c: &Condvar) -> U) -> U { (&self.sem).access_cond(blk) } } @@ -480,7 +480,7 @@ pub impl RWlock { * Run a function with the rwlock in read mode. Calls to 'read' from other * tasks may run concurrently with this one. */ - fn read(&self, blk: fn() -> U) -> U { + fn read(&self, blk: &fn() -> U) -> U { let mut release = None; unsafe { do task::unkillable { @@ -511,7 +511,7 @@ pub impl RWlock { * Run a function with the rwlock in write mode. No calls to 'read' or * 'write' from other tasks will run concurrently with this one. */ - fn write(&self, blk: fn() -> U) -> U { + fn write(&self, blk: &fn() -> U) -> U { unsafe { do task::unkillable { (&self.order_lock).acquire(); @@ -529,7 +529,7 @@ pub impl RWlock { * the waiting task is signalled. (Note: a writer that waited and then * was signalled might reacquire the lock before other waiting writers.) */ - fn write_cond(&self, blk: fn(c: &Condvar) -> U) -> U { + fn write_cond(&self, blk: &fn(c: &Condvar) -> U) -> U { // NB: You might think I should thread the order_lock into the cond // wait call, so that it gets waited on before access_lock gets // reacquired upon being woken up. However, (a) this would be not @@ -564,7 +564,7 @@ pub impl RWlock { * } * ~~~ */ - fn write_downgrade(&self, blk: fn(v: RWlockWriteMode) -> U) -> U { + fn write_downgrade(&self, blk: &fn(v: RWlockWriteMode) -> U) -> U { // Implementation slightly different from the slicker 'write's above. // The exit path is conditional on whether the caller downgrades. let mut _release = None; @@ -692,16 +692,16 @@ impl Drop for RWlockReadMode/&self { fn finalize(&self) {} } pub impl RWlockWriteMode/&self { /// Access the pre-downgrade rwlock in write mode. - fn write(&self, blk: fn() -> U) -> U { blk() } + fn write(&self, blk: &fn() -> U) -> U { blk() } /// Access the pre-downgrade rwlock in write mode with a condvar. - fn write_cond(&self, blk: fn(c: &Condvar) -> U) -> U { + fn write_cond(&self, blk: &fn(c: &Condvar) -> U) -> U { blk(&Condvar { sem: &self.lock.access_lock }) } } pub impl RWlockReadMode/&self { /// Access the post-downgrade rwlock in read mode. - fn read(&self, blk: fn() -> U) -> U { blk() } + fn read(&self, blk: &fn() -> U) -> U { blk() } } /**************************************************************************** @@ -1082,7 +1082,7 @@ mod tests { #[cfg(test)] pub enum RWlockMode { Read, Write, Downgrade, DowngradeRead } #[cfg(test)] - pub fn lock_rwlock_in_mode(x: &RWlock, mode: RWlockMode, blk: fn()) { + pub fn lock_rwlock_in_mode(x: &RWlock, mode: RWlockMode, blk: &fn()) { match mode { Read => x.read(blk), Write => x.write(blk), @@ -1239,7 +1239,7 @@ mod tests { dg1: bool, dg2: bool) { // Much like the mutex broadcast test. Downgrade-enabled. - fn lock_cond(x: &RWlock, downgrade: bool, blk: fn(c: &Condvar)) { + fn lock_cond(x: &RWlock, downgrade: bool, blk: &fn(c: &Condvar)) { if downgrade { do x.write_downgrade |mode| { (&mode).write_cond(blk) diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index f06f64dde010b..f053bcfd397ce 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -96,7 +96,7 @@ impl Ord for TreeMap { impl<'self, K: TotalOrd, V> BaseIter<(&'self K, &'self V)> for TreeMap { /// Visit all key-value pairs in order - pure fn each(&self, f: fn(&(&self/K, &self/V)) -> bool) { + pure fn each(&self, f: &fn(&(&self/K, &self/V)) -> bool) { each(&self.root, f) } pure fn size_hint(&self) -> Option { Some(self.len()) } @@ -107,7 +107,7 @@ impl<'self, K: TotalOrd, V> for TreeMap { /// Visit all key-value pairs in reverse order - pure fn each_reverse(&self, f: fn(&(&self/K, &self/V)) -> bool) { + pure fn each_reverse(&self, f: &fn(&(&self/K, &self/V)) -> bool) { each_reverse(&self.root, f); } } @@ -135,10 +135,10 @@ impl Map for TreeMap { } /// Visit all keys in order - pure fn each_key(&self, f: fn(&K) -> bool) { self.each(|&(k, _)| f(k)) } + pure fn each_key(&self, f: &fn(&K) -> bool) { self.each(|&(k, _)| f(k)) } /// Visit all values in order - pure fn each_value(&self, f: fn(&V) -> bool) { self.each(|&(_, v)| f(v)) } + pure fn each_value(&self, f: &fn(&V) -> bool) { self.each(|&(_, v)| f(v)) } /// Return the value corresponding to the key in the map pure fn find(&self, key: &K) -> Option<&self/V> { @@ -180,12 +180,12 @@ pub impl TreeMap { static pure fn new() -> TreeMap { TreeMap{root: None, length: 0} } /// Visit all keys in reverse order - pure fn each_key_reverse(&self, f: fn(&K) -> bool) { + pure fn each_key_reverse(&self, f: &fn(&K) -> bool) { self.each_reverse(|&(k, _)| f(k)) } /// Visit all values in reverse order - pure fn each_value_reverse(&self, f: fn(&V) -> bool) { + pure fn each_value_reverse(&self, f: &fn(&V) -> bool) { self.each_reverse(|&(_, v)| f(v)) } @@ -225,7 +225,7 @@ pub fn map_next(iter: &mut TreeMapIterator/&r) /// Advance the iterator through the map pub fn map_advance(iter: &mut TreeMapIterator/&r, - f: fn((&r/K, &r/V)) -> bool) { + f: &fn((&r/K, &r/V)) -> bool) { loop { match map_next(iter) { Some(x) => { @@ -242,13 +242,13 @@ pub struct TreeSet { impl BaseIter for TreeSet { /// Visit all values in order - pure fn each(&self, f: fn(&T) -> bool) { self.map.each_key(f) } + pure fn each(&self, f: &fn(&T) -> bool) { self.map.each_key(f) } pure fn size_hint(&self) -> Option { Some(self.len()) } } impl ReverseIter for TreeSet { /// Visit all values in reverse order - pure fn each_reverse(&self, f: fn(&T) -> bool) { + pure fn each_reverse(&self, f: &fn(&T) -> bool) { self.map.each_key_reverse(f) } } @@ -350,7 +350,7 @@ impl Set for TreeSet { } /// Visit the values (in-order) representing the difference - pure fn difference(&self, other: &TreeSet, f: fn(&T) -> bool) { + pure fn difference(&self, other: &TreeSet, f: &fn(&T) -> bool) { let mut x = self.iter(); let mut y = other.iter(); @@ -383,7 +383,7 @@ impl Set for TreeSet { /// Visit the values (in-order) representing the symmetric difference pure fn symmetric_difference(&self, other: &TreeSet, - f: fn(&T) -> bool) { + f: &fn(&T) -> bool) { let mut x = self.iter(); let mut y = other.iter(); @@ -422,7 +422,7 @@ impl Set for TreeSet { } /// Visit the values (in-order) representing the intersection - pure fn intersection(&self, other: &TreeSet, f: fn(&T) -> bool) { + pure fn intersection(&self, other: &TreeSet, f: &fn(&T) -> bool) { let mut x = self.iter(); let mut y = other.iter(); @@ -449,7 +449,7 @@ impl Set for TreeSet { } /// Visit the values (in-order) representing the union - pure fn union(&self, other: &TreeSet, f: fn(&T) -> bool) { + pure fn union(&self, other: &TreeSet, f: &fn(&T) -> bool) { let mut x = self.iter(); let mut y = other.iter(); @@ -508,7 +508,7 @@ pub fn set_next(iter: &mut TreeSetIterator/&r) -> Option<&r/T> { /// Advance the iterator through the set fn set_advance(iter: &mut TreeSetIterator/&r, - f: fn(&r/T) -> bool) { + f: &fn(&r/T) -> bool) { do map_advance(&mut iter.iter) |(k, _)| { f(k) } } @@ -530,7 +530,7 @@ pub impl TreeNode { } pure fn each(node: &r/Option<~TreeNode>, - f: fn(&(&r/K, &r/V)) -> bool) { + f: &fn(&(&r/K, &r/V)) -> bool) { for node.each |x| { each(&x.left, f); if f(&(&x.key, &x.value)) { each(&x.right, f) } @@ -538,7 +538,7 @@ pure fn each(node: &r/Option<~TreeNode>, } pure fn each_reverse(node: &r/Option<~TreeNode>, - f: fn(&(&r/K, &r/V)) -> bool) { + f: &fn(&(&r/K, &r/V)) -> bool) { for node.each |x| { each_reverse(&x.right, f); if f(&(&x.key, &x.value)) { each_reverse(&x.left, f) } diff --git a/src/libstd/workcache.rs b/src/libstd/workcache.rs index eac6e090f1f10..68a6f8effaa77 100644 --- a/src/libstd/workcache.rs +++ b/src/libstd/workcache.rs @@ -269,7 +269,7 @@ pub impl Context { Decodable>( // FIXME(#5121) @self, fn_name:&str, - blk: fn(@Mut)->Work) -> Work { + blk: &fn(@Mut)->Work) -> Work { let p = @Mut(Prep {ctxt: self, fn_name: fn_name.to_owned(), declared_inputs: LinearMap::new()}); diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 3001fe8069c93..a7d5c0ce75fa0 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -423,7 +423,7 @@ pub fn node_id_to_str(map: map, id: node_id, itr: @ident_interner) -> ~str { } pub fn node_item_query(items: map, id: node_id, - query: fn(@item) -> Result, + query: &fn(@item) -> Result, +error_msg: ~str) -> Result { match items.find(&id) { Some(node_item(it, _)) => query(it), diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 7b0e72e6e956e..35b188a248fd4 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -516,7 +516,7 @@ pub pure fn is_item_impl(item: @ast::item) -> bool { } } -pub fn walk_pat(pat: @pat, it: fn(@pat)) { +pub fn walk_pat(pat: @pat, it: &fn(@pat)) { it(pat); match pat.node { pat_ident(_, _, Some(p)) => walk_pat(p, it), diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 33e734fbd64cc..4e177fecec9e6 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -306,7 +306,7 @@ fn print_macro_backtrace(cm: @codemap::CodeMap, sp: span) { pub fn expect(diag: span_handler, opt: Option, - msg: fn() -> ~str) -> T { + msg: &fn() -> ~str) -> T { match opt { Some(ref t) => (*t), None => diag.handler().bug(msg()) diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index ecb5be6cc3c61..8aa03e14fa47f 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -432,7 +432,7 @@ fn mk_impl( ty_param: ast::TyParam, path: @ast::path, generics: &ast::Generics, - f: fn(@ast::Ty) -> @ast::method + f: &fn(@ast::Ty) -> @ast::method ) -> @ast::item { /*! * @@ -1256,51 +1256,51 @@ mod test { fn emit_owned_str(&self, +_v: &str) { self.add_unknown_to_log(); } fn emit_managed_str(&self, +_v: &str) { self.add_unknown_to_log(); } - fn emit_borrowed(&self, f: fn()) { self.add_unknown_to_log(); f() } - fn emit_owned(&self, f: fn()) { self.add_unknown_to_log(); f() } - fn emit_managed(&self, f: fn()) { self.add_unknown_to_log(); f() } + fn emit_borrowed(&self, f: &fn()) { self.add_unknown_to_log(); f() } + fn emit_owned(&self, f: &fn()) { self.add_unknown_to_log(); f() } + fn emit_managed(&self, f: &fn()) { self.add_unknown_to_log(); f() } - fn emit_enum(&self, name: &str, f: fn()) { + fn emit_enum(&self, name: &str, f: &fn()) { self.add_to_log(CallToEmitEnum(name.to_str())); f(); } fn emit_enum_variant(&self, name: &str, +id: uint, - +cnt: uint, f: fn()) { + +cnt: uint, f: &fn()) { self.add_to_log(CallToEmitEnumVariant (name.to_str(),id,cnt)); f(); } - fn emit_enum_variant_arg(&self, +idx: uint, f: fn()) { + fn emit_enum_variant_arg(&self, +idx: uint, f: &fn()) { self.add_to_log(CallToEmitEnumVariantArg (idx)); f(); } - fn emit_borrowed_vec(&self, +_len: uint, f: fn()) { + fn emit_borrowed_vec(&self, +_len: uint, f: &fn()) { self.add_unknown_to_log(); f(); } - fn emit_owned_vec(&self, +_len: uint, f: fn()) { + fn emit_owned_vec(&self, +_len: uint, f: &fn()) { self.add_unknown_to_log(); f(); } - fn emit_managed_vec(&self, +_len: uint, f: fn()) { + fn emit_managed_vec(&self, +_len: uint, f: &fn()) { self.add_unknown_to_log(); f(); } - fn emit_vec_elt(&self, +_idx: uint, f: fn()) { + fn emit_vec_elt(&self, +_idx: uint, f: &fn()) { self.add_unknown_to_log(); f(); } - fn emit_rec(&self, f: fn()) { + fn emit_rec(&self, f: &fn()) { self.add_unknown_to_log(); f(); } - fn emit_struct(&self, name: &str, +len: uint, f: fn()) { + fn emit_struct(&self, name: &str, +len: uint, f: &fn()) { self.add_to_log(CallToEmitStruct (name.to_str(),len)); f(); } - fn emit_field(&self, name: &str, +idx: uint, f: fn()) { + fn emit_field(&self, name: &str, +idx: uint, f: &fn()) { self.add_to_log(CallToEmitField (name.to_str(),idx)); f(); } - fn emit_tup(&self, +_len: uint, f: fn()) { + fn emit_tup(&self, +_len: uint, f: &fn()) { self.add_unknown_to_log(); f(); } - fn emit_tup_elt(&self, +_idx: uint, f: fn()) { + fn emit_tup_elt(&self, +_idx: uint, f: &fn()) { self.add_unknown_to_log(); f(); } } diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index 329b3f59b1e33..dc9abd536d11f 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -104,7 +104,7 @@ pub impl state_ { /// Iterate over the states that can be reached in one message /// from this state. - fn reachable(&self, f: fn(state) -> bool) { + fn reachable(&self, f: &fn(state) -> bool) { for self.messages.each |m| { match *m { message(_, _, _, _, Some(next_state { state: ref id, _ })) => { diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index 16db384bb062c..ba0c7a71b7c17 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -122,7 +122,7 @@ impl Eq for OptVec { } impl BaseIter for OptVec { - pure fn each(&self, blk: fn(v: &A) -> bool) { + pure fn each(&self, blk: &fn(v: &A) -> bool) { match *self { Empty => {} Vec(ref v) => v.each(blk) @@ -136,31 +136,31 @@ impl BaseIter for OptVec { impl iter::ExtendedIter for OptVec { #[inline(always)] - pure fn eachi(&self, blk: fn(+v: uint, v: &A) -> bool) { + pure fn eachi(&self, blk: &fn(+v: uint, v: &A) -> bool) { iter::eachi(self, blk) } #[inline(always)] - pure fn all(&self, blk: fn(&A) -> bool) -> bool { + pure fn all(&self, blk: &fn(&A) -> bool) -> bool { iter::all(self, blk) } #[inline(always)] - pure fn any(&self, blk: fn(&A) -> bool) -> bool { + pure fn any(&self, blk: &fn(&A) -> bool) -> bool { iter::any(self, blk) } #[inline(always)] - pure fn foldl(&self, +b0: B, blk: fn(&B, &A) -> B) -> B { + pure fn foldl(&self, +b0: B, blk: &fn(&B, &A) -> B) -> B { iter::foldl(self, b0, blk) } #[inline(always)] - pure fn position(&self, f: fn(&A) -> bool) -> Option { + pure fn position(&self, f: &fn(&A) -> bool) -> Option { iter::position(self, f) } #[inline(always)] - pure fn map_to_vec(&self, op: fn(&A) -> B) -> ~[B] { + pure fn map_to_vec(&self, op: &fn(&A) -> B) -> ~[B] { iter::map_to_vec(self, op) } #[inline(always)] - pure fn flat_map_to_vec>(&self, op: fn(&A) -> IB) + pure fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B] { iter::flat_map_to_vec(self, op) } @@ -176,13 +176,13 @@ impl iter::EqIter for OptVec { impl iter::CopyableIter for OptVec { #[inline(always)] - pure fn filter_to_vec(&self, pred: fn(&A) -> bool) -> ~[A] { + pure fn filter_to_vec(&self, pred: &fn(&A) -> bool) -> ~[A] { iter::filter_to_vec(self, pred) } #[inline(always)] pure fn to_vec(&self) -> ~[A] { iter::to_vec(self) } #[inline(always)] - pure fn find(&self, f: fn(&A) -> bool) -> Option { + pure fn find(&self, f: &fn(&A) -> bool) -> Option { iter::find(self, f) } } diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index 7af2204fafd09..c7b9a769293d6 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -248,7 +248,7 @@ pub impl Parser { fn parse_seq_to_before_gt( &self, sep: Option, - f: fn(&Parser) -> T + f: &fn(&Parser) -> T ) -> OptVec { let mut first = true; let mut v = opt_vec::Empty; @@ -269,7 +269,7 @@ pub impl Parser { fn parse_seq_to_gt( &self, sep: Option, - f: fn(&Parser) -> T + f: &fn(&Parser) -> T ) -> OptVec { let v = self.parse_seq_to_before_gt(sep, f); self.expect_gt(); @@ -283,7 +283,7 @@ pub impl Parser { &self, ket: &token::Token, sep: SeqSep, - f: fn(&Parser) -> T + f: &fn(&Parser) -> T ) -> ~[T] { let val = self.parse_seq_to_before_end(ket, sep, f); self.bump(); @@ -297,7 +297,7 @@ pub impl Parser { &self, ket: &token::Token, sep: SeqSep, - f: fn(&Parser) -> T + f: &fn(&Parser) -> T ) -> ~[T] { let mut first: bool = true; let mut v: ~[T] = ~[]; @@ -323,7 +323,7 @@ pub impl Parser { bra: &token::Token, ket: &token::Token, sep: SeqSep, - f: fn(&Parser) -> T + f: &fn(&Parser) -> T ) -> ~[T] { self.expect(bra); let result = self.parse_seq_to_before_end(ket, sep, f); @@ -338,7 +338,7 @@ pub impl Parser { bra: &token::Token, ket: &token::Token, sep: SeqSep, - f: fn(&Parser) -> T + f: &fn(&Parser) -> T ) -> spanned<~[T]> { let lo = self.span.lo; self.expect(bra); diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index a1fc7230dd1f0..fd84f8670686b 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -173,7 +173,7 @@ pub fn parse_tts_from_source_str( } pub fn parse_from_source_str( - f: fn (Parser) -> T, + f: &fn (Parser) -> T, name: ~str, ss: codemap::FileSubstr, source: @~str, +cfg: ast::crate_cfg, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 38cd09abad42b..92ff83a39756f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1829,7 +1829,7 @@ pub impl Parser { fn parse_sugary_call_expr(&self, keyword: ~str, sugar: CallSugar, - ctor: fn(+v: @expr) -> expr_) -> @expr { + ctor: &fn(+v: @expr) -> expr_) -> @expr { let lo = self.last_span; // Parse the callee `foo` in // for foo || { @@ -2769,7 +2769,7 @@ pub impl Parser { (lifetimes, opt_vec::take_vec(result)) } - fn parse_fn_decl(&self, parse_arg_fn: fn(&Parser) -> arg_or_capture_item) + fn parse_fn_decl(&self, parse_arg_fn: &fn(&Parser) -> arg_or_capture_item) -> fn_decl { let args_or_capture_items: ~[arg_or_capture_item] = @@ -2816,7 +2816,7 @@ pub impl Parser { fn(&Parser) -> arg_or_capture_item ) -> (self_ty, fn_decl) { fn maybe_parse_self_ty( - cnstr: fn(+v: mutability) -> ast::self_ty_, + cnstr: &fn(+v: mutability) -> ast::self_ty_, p: &Parser ) -> ast::self_ty_ { // We need to make sure it isn't a mode or a type diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index c81c1c8bd0e1a..e7e2435587ef1 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -314,8 +314,8 @@ pub fn commasep(s: @ps, b: breaks, elts: ~[IN], op: &fn(@ps, IN)) { } -pub fn commasep_cmnt(s: @ps, b: breaks, elts: ~[IN], op: fn(@ps, IN), - get_span: fn(IN) -> codemap::span) { +pub fn commasep_cmnt(s: @ps, b: breaks, elts: ~[IN], op: &fn(@ps, IN), + get_span: &fn(IN) -> codemap::span) { box(s, 0u, b); let len = vec::len::(elts); let mut i = 0u; diff --git a/src/test/auxiliary/cci_impl_lib.rs b/src/test/auxiliary/cci_impl_lib.rs index ab744d60ac228..b7149be00cca9 100644 --- a/src/test/auxiliary/cci_impl_lib.rs +++ b/src/test/auxiliary/cci_impl_lib.rs @@ -11,12 +11,12 @@ #[link(name="cci_impl_lib", vers="0.0")]; trait uint_helpers { - fn to(v: uint, f: fn(uint)); + fn to(v: uint, f: &fn(uint)); } impl uint_helpers for uint { #[inline] - fn to(v: uint, f: fn(uint)) { + fn to(v: uint, f: &fn(uint)) { let mut i = self; while i < v { f(i); diff --git a/src/test/auxiliary/cci_iter_lib.rs b/src/test/auxiliary/cci_iter_lib.rs index 6e2c36578ff1c..107f0ac32a4bf 100644 --- a/src/test/auxiliary/cci_iter_lib.rs +++ b/src/test/auxiliary/cci_iter_lib.rs @@ -12,7 +12,7 @@ #[legacy_modes]; #[inline] -pub fn iter(v: ~[T], f: fn(T)) { +pub fn iter(v: ~[T], f: &fn(T)) { let mut i = 0u; let n = vec::len(v); while i < n { diff --git a/src/test/auxiliary/cci_no_inline_lib.rs b/src/test/auxiliary/cci_no_inline_lib.rs index 0b0492f13b8c5..407f62adb0251 100644 --- a/src/test/auxiliary/cci_no_inline_lib.rs +++ b/src/test/auxiliary/cci_no_inline_lib.rs @@ -11,7 +11,7 @@ #[link(name="cci_no_inline_lib", vers="0.0")]; // same as cci_iter_lib, more-or-less, but not marked inline -pub fn iter(v: ~[uint], f: fn(uint)) { +pub fn iter(v: ~[uint], f: &fn(uint)) { let mut i = 0u; let n = vec::len(v); while i < n { diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs index a1896c660eb6f..c86d2fe4d9332 100644 --- a/src/test/bench/core-map.rs +++ b/src/test/bench/core-map.rs @@ -25,7 +25,7 @@ struct Results { } fn timed(result: &mut float, - op: fn()) { + op: &fn()) { let start = std::time::precise_time_s(); op(); let end = std::time::precise_time_s(); diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs index ab441277c62a3..adfde66e57a01 100644 --- a/src/test/bench/core-set.rs +++ b/src/test/bench/core-set.rs @@ -24,7 +24,7 @@ struct Results { delete_strings: float } -fn timed(result: &mut float, op: fn()) { +fn timed(result: &mut float, op: &fn()) { let start = std::time::precise_time_s(); op(); let end = std::time::precise_time_s(); @@ -33,7 +33,7 @@ fn timed(result: &mut float, op: fn()) { pub impl Results { fn bench_int>(&mut self, rng: @rand::Rng, num_keys: uint, - rand_cap: uint, f: fn() -> T) { + rand_cap: uint, f: &fn() -> T) { { let mut set = f(); do timed(&mut self.sequential_ints) { @@ -71,7 +71,7 @@ pub impl Results { } fn bench_str>(&mut self, rng: @rand::Rng, num_keys: uint, - f: fn() -> T) { + f: &fn() -> T) { { let mut set = f(); do timed(&mut self.sequential_strings) { diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index e026e78ffb81d..e8fb86fda7889 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -34,7 +34,7 @@ fn main() { bench!(vec_push_all); } -fn maybe_run_test(argv: &[~str], name: ~str, test: fn()) { +fn maybe_run_test(argv: &[~str], name: ~str, test: &fn()) { let mut run_test = false; if os::getenv(~"RUST_BENCH").is_some() { run_test = true } diff --git a/src/test/bench/pingpong.rs b/src/test/bench/pingpong.rs index f95bc3fc35a18..731605e82bd1f 100644 --- a/src/test/bench/pingpong.rs +++ b/src/test/bench/pingpong.rs @@ -71,7 +71,7 @@ macro_rules! follow ( ) fn switch(+endp: core::pipes::RecvPacketBuffered, - f: fn(+v: Option) -> U) -> U { + f: &fn(+v: Option) -> U) -> U { f(core::pipes::try_recv(endp)) } @@ -131,7 +131,7 @@ fn unbounded(count: uint) { } } -fn timeit(f: fn()) -> float { +fn timeit(f: &fn()) -> float { let start = precise_time_s(); f(); let stop = precise_time_s(); diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index 35c6694ee0c74..fc980e3d6db53 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -85,7 +85,7 @@ fn update_freq(mm: HashMap<~[u8], uint>, key: &[u8]) { // i.e., for "hello" and windows of size four, // run it("hell") and it("ello"), then return "llo" fn windows_with_carry(bb: &[u8], nn: uint, - it: fn(window: &[u8])) -> ~[u8] { + it: &fn(window: &[u8])) -> ~[u8] { let mut ii = 0u; let len = vec::len(bb); diff --git a/src/test/compile-fail/arg-style-mismatch.rs b/src/test/compile-fail/arg-style-mismatch.rs index f07a2be1edf66..2efc16de8307f 100644 --- a/src/test/compile-fail/arg-style-mismatch.rs +++ b/src/test/compile-fail/arg-style-mismatch.rs @@ -11,5 +11,5 @@ // error-pattern: mismatched types fn f(&&_x: int) {} -fn g(_a: fn(+v: int)) {} +fn g(_a: &fn(+v: int)) {} fn main() { g(f); } diff --git a/src/test/compile-fail/bad-for-loop.rs b/src/test/compile-fail/bad-for-loop.rs index bda463031fae9..8835c577fa8fd 100644 --- a/src/test/compile-fail/bad-for-loop.rs +++ b/src/test/compile-fail/bad-for-loop.rs @@ -9,6 +9,6 @@ // except according to those terms. fn main() { - fn baz(_x: fn(y: int) -> int) {} + fn baz(_x: &fn(y: int) -> int) {} for baz |_e| { } //~ ERROR A `for` loop iterator should expect a closure that returns `bool` } diff --git a/src/test/compile-fail/block-coerce-no.rs b/src/test/compile-fail/block-coerce-no.rs index af93b1891e840..980dc66b4af59 100644 --- a/src/test/compile-fail/block-coerce-no.rs +++ b/src/test/compile-fail/block-coerce-no.rs @@ -11,9 +11,9 @@ // Make sure that fn-to-block coercion isn't incorrectly lifted over // other tycons. -fn coerce(b: fn()) -> extern fn() { - fn lol(+f: extern fn(+v: fn()) -> extern fn(), - +g: fn()) -> extern fn() { return f(g); } +fn coerce(b: &fn()) -> extern fn() { + fn lol(+f: extern fn(+v: &fn()) -> extern fn(), + +g: &fn()) -> extern fn() { return f(g); } fn fn_id(+f: extern fn()) -> extern fn() { return f } return lol(fn_id, b); //~^ ERROR mismatched types diff --git a/src/test/compile-fail/borrowck-assign-comp-idx.rs b/src/test/compile-fail/borrowck-assign-comp-idx.rs index 9c175ed42b665..25b56abb5ba00 100644 --- a/src/test/compile-fail/borrowck-assign-comp-idx.rs +++ b/src/test/compile-fail/borrowck-assign-comp-idx.rs @@ -22,7 +22,7 @@ fn a() { p[0] = 5; //~ ERROR assigning to mutable vec content prohibited due to outstanding loan } -fn borrow(_x: &[int], _f: fn()) {} +fn borrow(_x: &[int], _f: &fn()) {} fn b() { // here we alias the mutable vector into an imm slice and try to diff --git a/src/test/compile-fail/borrowck-autoref-3261.rs b/src/test/compile-fail/borrowck-autoref-3261.rs index 7873adbf21d8e..237c1b8671352 100644 --- a/src/test/compile-fail/borrowck-autoref-3261.rs +++ b/src/test/compile-fail/borrowck-autoref-3261.rs @@ -10,7 +10,7 @@ enum X = Either<(uint,uint),extern fn()>; pub impl &'self X { - fn with(blk: fn(x: &Either<(uint,uint),extern fn()>)) { + fn with(blk: &fn(x: &Either<(uint,uint),extern fn()>)) { blk(&**self) } } diff --git a/src/test/compile-fail/borrowck-insert-during-each.rs b/src/test/compile-fail/borrowck-insert-during-each.rs index 476a790b85ede..788c5397e35d0 100644 --- a/src/test/compile-fail/borrowck-insert-during-each.rs +++ b/src/test/compile-fail/borrowck-insert-during-each.rs @@ -15,7 +15,7 @@ struct Foo { } pub impl Foo { - fn foo(&mut self, fun: fn(&int)) { + fn foo(&mut self, fun: &fn(&int)) { for self.n.each |f| { fun(f); } diff --git a/src/test/compile-fail/borrowck-lend-flow.rs b/src/test/compile-fail/borrowck-lend-flow.rs index 6ec7dd7330526..ed6446a6311b8 100644 --- a/src/test/compile-fail/borrowck-lend-flow.rs +++ b/src/test/compile-fail/borrowck-lend-flow.rs @@ -94,7 +94,7 @@ fn loop_in_block() { } fn at_most_once_block() { - fn at_most_once(f: fn()) { f() } + fn at_most_once(f: &fn()) { f() } // Here, the borrow check has no way of knowing that the block is // executed at most once. diff --git a/src/test/compile-fail/borrowck-loan-blocks-move-cc.rs b/src/test/compile-fail/borrowck-loan-blocks-move-cc.rs index aca63308d874e..784fce1300f76 100644 --- a/src/test/compile-fail/borrowck-loan-blocks-move-cc.rs +++ b/src/test/compile-fail/borrowck-loan-blocks-move-cc.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn borrow(v: &int, f: fn(x: &int)) { +fn borrow(v: &int, f: &fn(x: &int)) { f(v); } diff --git a/src/test/compile-fail/borrowck-loan-blocks-mut-uniq.rs b/src/test/compile-fail/borrowck-loan-blocks-mut-uniq.rs index e56a179e7741e..332ec3fe697d0 100644 --- a/src/test/compile-fail/borrowck-loan-blocks-mut-uniq.rs +++ b/src/test/compile-fail/borrowck-loan-blocks-mut-uniq.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn borrow(v: &int, f: fn(x: &int)) { +fn borrow(v: &int, f: &fn(x: &int)) { f(v); } diff --git a/src/test/compile-fail/borrowck-loan-rcvr.rs b/src/test/compile-fail/borrowck-loan-rcvr.rs index bd4428dc93064..85989bf9d2140 100644 --- a/src/test/compile-fail/borrowck-loan-rcvr.rs +++ b/src/test/compile-fail/borrowck-loan-rcvr.rs @@ -12,7 +12,7 @@ struct point { x: int, y: int } trait methods { fn impurem(); - fn blockm(f: fn()); + fn blockm(f: &fn()); pure fn purem(); } @@ -20,7 +20,7 @@ impl methods for point { fn impurem() { } - fn blockm(f: fn()) { f() } + fn blockm(f: &fn()) { f() } pure fn purem() { } diff --git a/src/test/compile-fail/borrowck-loan-vec-content.rs b/src/test/compile-fail/borrowck-loan-vec-content.rs index 8457fce255ea3..d27d690437aff 100644 --- a/src/test/compile-fail/borrowck-loan-vec-content.rs +++ b/src/test/compile-fail/borrowck-loan-vec-content.rs @@ -12,7 +12,7 @@ // (locally rooted) mutable, unique vector, and that we then prevent // modifications to the contents. -fn takes_imm_elt(_v: &int, f: fn()) { +fn takes_imm_elt(_v: &int, f: &fn()) { f(); } @@ -29,7 +29,7 @@ fn has_mut_vec_but_tries_to_change_it() { } } -fn takes_const_elt(_v: &const int, f: fn()) { +fn takes_const_elt(_v: &const int, f: &fn()) { f(); } diff --git a/src/test/compile-fail/closure-that-fails.rs b/src/test/compile-fail/closure-that-fails.rs index 66d4e601ec7b6..aad0e8bcbb6dd 100644 --- a/src/test/compile-fail/closure-that-fails.rs +++ b/src/test/compile-fail/closure-that-fails.rs @@ -1,4 +1,4 @@ -fn foo(f: fn() -> !) {} +fn foo(f: &fn() -> !) {} fn main() { // Type inference didn't use to be able to handle this: diff --git a/src/test/compile-fail/extern-wrong-value-type.rs b/src/test/compile-fail/extern-wrong-value-type.rs index 2462451c88a00..4daa7f71adf28 100644 --- a/src/test/compile-fail/extern-wrong-value-type.rs +++ b/src/test/compile-fail/extern-wrong-value-type.rs @@ -13,5 +13,5 @@ extern fn f() { fn main() { // extern functions are *u8 types - let _x: fn() = f; //~ ERROR mismatched types: expected `&fn()` but found `*u8` + let _x: &fn() = f; //~ ERROR mismatched types: expected `&fn()` but found `*u8` } diff --git a/src/test/compile-fail/fn-variance-1.rs b/src/test/compile-fail/fn-variance-1.rs index 5550eb4902e17..c5c29bd3ecfe7 100644 --- a/src/test/compile-fail/fn-variance-1.rs +++ b/src/test/compile-fail/fn-variance-1.rs @@ -14,7 +14,7 @@ fn takes_mut(&&x: @mut int) { } fn takes_const(&&x: @const int) { } fn takes_imm(&&x: @int) { } -fn apply(t: T, f: fn(T)) { +fn apply(t: T, f: &fn(T)) { f(t) } diff --git a/src/test/compile-fail/immut-function-arguments.rs b/src/test/compile-fail/immut-function-arguments.rs index e557eaba83474..2084729372d1d 100644 --- a/src/test/compile-fail/immut-function-arguments.rs +++ b/src/test/compile-fail/immut-function-arguments.rs @@ -13,7 +13,7 @@ fn f(y: ~int) { } fn g() { - let _frob: fn(~int) = |q| { *q = 2; }; //~ ERROR assigning to dereference of immutable ~ pointer + let _frob: &fn(~int) = |q| { *q = 2; }; //~ ERROR assigning to dereference of immutable ~ pointer } diff --git a/src/test/compile-fail/issue-2149.rs b/src/test/compile-fail/issue-2149.rs index 0880cabb2abf9..361a20ad45133 100644 --- a/src/test/compile-fail/issue-2149.rs +++ b/src/test/compile-fail/issue-2149.rs @@ -9,11 +9,11 @@ // except according to those terms. trait vec_monad { - fn bind(f: fn(A) -> ~[B]); + fn bind(f: &fn(A) -> ~[B]); } impl vec_monad for ~[A] { - fn bind(f: fn(A) -> ~[B]) { + fn bind(f: &fn(A) -> ~[B]) { let mut r = fail!(); for self.each |elt| { r += f(*elt); } //~^ WARNING unreachable expression diff --git a/src/test/compile-fail/issue-2817-2.rs b/src/test/compile-fail/issue-2817-2.rs index 890b984e42ef2..6084552f0ed6d 100644 --- a/src/test/compile-fail/issue-2817-2.rs +++ b/src/test/compile-fail/issue-2817-2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn not_bool(f: fn(int) -> ~str) {} +fn not_bool(f: &fn(int) -> ~str) {} fn main() { for uint::range(0, 100000) |_i| { //~ ERROR A for-loop body must return (), but diff --git a/src/test/compile-fail/liveness-closure-require-ret.rs b/src/test/compile-fail/liveness-closure-require-ret.rs index 742afd6d30ea9..b1fc6a870d086 100644 --- a/src/test/compile-fail/liveness-closure-require-ret.rs +++ b/src/test/compile-fail/liveness-closure-require-ret.rs @@ -8,5 +8,5 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn force(f: fn() -> int) -> int { f() } +fn force(f: &fn() -> int) -> int { f() } fn main() { log(debug, force(|| {})); } //~ ERROR mismatched types diff --git a/src/test/compile-fail/missing-do.rs b/src/test/compile-fail/missing-do.rs index fc4a4c11e7d27..974f30feb0651 100644 --- a/src/test/compile-fail/missing-do.rs +++ b/src/test/compile-fail/missing-do.rs @@ -10,7 +10,7 @@ // Regression test for issue #2783 -fn foo(f: fn()) { f() } +fn foo(f: &fn()) { f() } fn main() { ~"" || 42; //~ ERROR binary operation || cannot be applied to type `~str` diff --git a/src/test/compile-fail/mode-inference-fail.rs b/src/test/compile-fail/mode-inference-fail.rs index fd15321e1d02b..d9f6cf8b2d722 100644 --- a/src/test/compile-fail/mode-inference-fail.rs +++ b/src/test/compile-fail/mode-inference-fail.rs @@ -13,8 +13,8 @@ // In this test, the mode gets inferred to ++ due to the apply_int(), // but then we get a failure in the generic apply(). -fn apply(f: fn(A) -> A, a: A) -> A { f(a) } -fn apply_int(f: fn(int) -> int, a: int) -> int { f(a) } +fn apply(f: &fn(A) -> A, a: A) -> A { f(a) } +fn apply_int(f: &fn(int) -> int, a: int) -> int { f(a) } fn main() { let f = {|i| i}; diff --git a/src/test/compile-fail/pure-higher-order.rs b/src/test/compile-fail/pure-higher-order.rs index e5638e11ae918..6d262bc04e1e4 100644 --- a/src/test/compile-fail/pure-higher-order.rs +++ b/src/test/compile-fail/pure-higher-order.rs @@ -16,7 +16,7 @@ struct S<'self> { f: &'self fn(uint) } -pure fn range(from: uint, to: uint, f: fn(uint)) { +pure fn range(from: uint, to: uint, f: &fn(uint)) { let mut i = from; while i < to { f(i); // Note: legal to call argument, even if it is not pure. @@ -24,13 +24,13 @@ pure fn range(from: uint, to: uint, f: fn(uint)) { } } -pure fn range2(from: uint, to: uint, f: fn(uint)) { +pure fn range2(from: uint, to: uint, f: &fn(uint)) { do range(from, to) |i| { f(i*2u); } } -pure fn range3(from: uint, to: uint, f: fn(uint)) { +pure fn range3(from: uint, to: uint, f: &fn(uint)) { range(from, to, f) } diff --git a/src/test/compile-fail/purity-infer-fail.rs b/src/test/compile-fail/purity-infer-fail.rs index e5301c0693d52..3e5296530fa35 100644 --- a/src/test/compile-fail/purity-infer-fail.rs +++ b/src/test/compile-fail/purity-infer-fail.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn something(f: pure fn()) { f(); } +fn something(f: &pure fn()) { f(); } fn main() { let mut x = ~[]; diff --git a/src/test/compile-fail/qquote-1.rs b/src/test/compile-fail/qquote-1.rs index e4e61e438f938..eda207f711d68 100644 --- a/src/test/compile-fail/qquote-1.rs +++ b/src/test/compile-fail/qquote-1.rs @@ -62,7 +62,7 @@ fn main() { check_pp(expr3, pprust::print_expr, "2 - 23 + 7"); } -fn check_pp(expr: T, f: fn(pprust::ps, T), expect: str) { +fn check_pp(expr: T, f: &fn(pprust::ps, T), expect: str) { fail!(); } diff --git a/src/test/compile-fail/qquote-2.rs b/src/test/compile-fail/qquote-2.rs index abe62e15e1309..c669053400831 100644 --- a/src/test/compile-fail/qquote-2.rs +++ b/src/test/compile-fail/qquote-2.rs @@ -57,7 +57,7 @@ fn main() { check_pp(*stmt, pprust::print_stmt, ""); } -fn check_pp(expr: T, f: fn(pprust::ps, T), expect: str) { +fn check_pp(expr: T, f: &fn(pprust::ps, T), expect: str) { fail!(); } diff --git a/src/test/compile-fail/regions-creating-enums.rs b/src/test/compile-fail/regions-creating-enums.rs index 27fcd2338fa51..88f2eefd36905 100644 --- a/src/test/compile-fail/regions-creating-enums.rs +++ b/src/test/compile-fail/regions-creating-enums.rs @@ -29,7 +29,7 @@ fn compute(x: &ast) -> uint { } } -fn map_nums(x: &ast, f: fn(uint) -> uint) -> &ast { +fn map_nums(x: &ast, f: &fn(uint) -> uint) -> &ast { match *x { num(x) => { return &num(f(x)); //~ ERROR illegal borrow diff --git a/src/test/compile-fail/regions-escape-bound-fn-2.rs b/src/test/compile-fail/regions-escape-bound-fn-2.rs index 147a1bfa36d54..9cee55643f89c 100644 --- a/src/test/compile-fail/regions-escape-bound-fn-2.rs +++ b/src/test/compile-fail/regions-escape-bound-fn-2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn with_int(f: fn(x: &int)) { +fn with_int(f: &fn(x: &int)) { let x = 3; f(&x); } diff --git a/src/test/compile-fail/regions-escape-bound-fn.rs b/src/test/compile-fail/regions-escape-bound-fn.rs index 8cdfe69a2f3ba..c81ef77f497db 100644 --- a/src/test/compile-fail/regions-escape-bound-fn.rs +++ b/src/test/compile-fail/regions-escape-bound-fn.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn with_int(f: fn(x: &int)) { +fn with_int(f: &fn(x: &int)) { let x = 3; f(&x); } diff --git a/src/test/compile-fail/regions-escape-via-trait-or-not.rs b/src/test/compile-fail/regions-escape-via-trait-or-not.rs index 0a1e917c361af..767d7c9174dfa 100644 --- a/src/test/compile-fail/regions-escape-via-trait-or-not.rs +++ b/src/test/compile-fail/regions-escape-via-trait-or-not.rs @@ -18,7 +18,7 @@ impl deref for &'self int { } } -fn with(f: fn(x: &int) -> R) -> int { +fn with(f: &fn(x: &int) -> R) -> int { f(&3).get() } diff --git a/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs b/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs index 59329195b712c..ef8f6748d36af 100644 --- a/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs +++ b/src/test/compile-fail/regions-infer-borrow-scope-within-loop.rs @@ -10,7 +10,7 @@ fn borrow(x: &r/T) -> &r/T {x} -fn foo(cond: fn() -> bool, box: fn() -> @int) { +fn foo(cond: &fn() -> bool, box: &fn() -> @int) { let mut y: ∫ loop { let x = box(); diff --git a/src/test/compile-fail/regions-infer-call-3.rs b/src/test/compile-fail/regions-infer-call-3.rs index 762142993f9d9..49d3f6aee65c8 100644 --- a/src/test/compile-fail/regions-infer-call-3.rs +++ b/src/test/compile-fail/regions-infer-call-3.rs @@ -10,7 +10,7 @@ fn select(x: &r/int, y: &r/int) -> &r/int { x } -fn with(f: fn(x: &int) -> T) -> T { +fn with(f: &fn(x: &int) -> T) -> T { f(&20) } diff --git a/src/test/compile-fail/regions-ret-borrowed-1.rs b/src/test/compile-fail/regions-ret-borrowed-1.rs index 5e2f45293842c..ab6a37b58de6f 100644 --- a/src/test/compile-fail/regions-ret-borrowed-1.rs +++ b/src/test/compile-fail/regions-ret-borrowed-1.rs @@ -12,7 +12,7 @@ // some point regions-ret-borrowed reported an error but this file did // not, due to special hardcoding around the anonymous region. -fn with(f: fn(x: &a/int) -> R) -> R { +fn with(f: &fn(x: &a/int) -> R) -> R { f(&3) } diff --git a/src/test/compile-fail/regions-ret-borrowed.rs b/src/test/compile-fail/regions-ret-borrowed.rs index 52f9770250ee4..157b99de9e806 100644 --- a/src/test/compile-fail/regions-ret-borrowed.rs +++ b/src/test/compile-fail/regions-ret-borrowed.rs @@ -15,7 +15,7 @@ // used to successfully compile because we failed to account for the // fact that fn(x: &int) rebound the region &. -fn with(f: fn(x: &int) -> R) -> R { +fn with(f: &fn(x: &int) -> R) -> R { f(&3) } diff --git a/src/test/compile-fail/regions-scoping.rs b/src/test/compile-fail/regions-scoping.rs index 66f1007afcf97..e675d4d455f2c 100644 --- a/src/test/compile-fail/regions-scoping.rs +++ b/src/test/compile-fail/regions-scoping.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn with(t: T, f: fn(T)) { f(t) } +fn with(t: T, f: &fn(T)) { f(t) } fn nested<'x>(x: &'x int) { // (1) do with( diff --git a/src/test/compile-fail/type-arg-out-of-scope.rs b/src/test/compile-fail/type-arg-out-of-scope.rs index 4d3005a2a7410..07dc677c04763 100644 --- a/src/test/compile-fail/type-arg-out-of-scope.rs +++ b/src/test/compile-fail/type-arg-out-of-scope.rs @@ -10,6 +10,6 @@ // error-pattern:attempt to use a type argument out of scope fn foo(x: T) { - fn bar(f: fn(T) -> T) { } + fn bar(f: &fn(T) -> T) { } } fn main() { foo(1); } diff --git a/src/test/run-fail/unwind-iter.rs b/src/test/run-fail/unwind-iter.rs index 135c5eecc2e9b..1b28d2f6c6d63 100644 --- a/src/test/run-fail/unwind-iter.rs +++ b/src/test/run-fail/unwind-iter.rs @@ -10,7 +10,7 @@ // error-pattern:fail -fn x(it: fn(int)) { +fn x(it: &fn(int)) { fail!(); it(0); } diff --git a/src/test/run-fail/unwind-iter2.rs b/src/test/run-fail/unwind-iter2.rs index f17f9fb9154bb..286e5f4976430 100644 --- a/src/test/run-fail/unwind-iter2.rs +++ b/src/test/run-fail/unwind-iter2.rs @@ -10,7 +10,7 @@ // error-pattern:fail -fn x(it: fn(int)) { +fn x(it: &fn(int)) { let a = @0; it(1); } diff --git a/src/test/run-pass-fulldeps/qquote.rs b/src/test/run-pass-fulldeps/qquote.rs index 92f80a9aa0d9b..613480e3a63cd 100644 --- a/src/test/run-pass-fulldeps/qquote.rs +++ b/src/test/run-pass-fulldeps/qquote.rs @@ -75,7 +75,7 @@ fn main() { } fn check_pp(cx: fake_ext_ctxt, - expr: T, f: fn(pprust::ps, T), expect: ~str) { + expr: T, f: &fn(pprust::ps, T), expect: ~str) { let s = do io::with_str_writer |wr| { let pp = pprust::rust_printer(wr, cx.parse_sess().interner); f(pp, expr); diff --git a/src/test/run-pass/alt-phi.rs b/src/test/run-pass/alt-phi.rs index 3702db8327e0d..40d2158835002 100644 --- a/src/test/run-pass/alt-phi.rs +++ b/src/test/run-pass/alt-phi.rs @@ -12,7 +12,7 @@ enum thing { a, b, c, } -fn foo(it: fn(int)) { it(10); } +fn foo(it: &fn(int)) { it(10); } pub fn main() { let mut x = true; diff --git a/src/test/run-pass/assignability-trait.rs b/src/test/run-pass/assignability-trait.rs index 9f13147b276d1..ae046babfdf83 100644 --- a/src/test/run-pass/assignability-trait.rs +++ b/src/test/run-pass/assignability-trait.rs @@ -13,11 +13,11 @@ // it. trait iterable { - fn iterate(blk: fn(x: &A) -> bool); + fn iterate(blk: &fn(x: &A) -> bool); } impl iterable for &self/[A] { - fn iterate(f: fn(x: &A) -> bool) { + fn iterate(f: &fn(x: &A) -> bool) { for vec::each(self) |e| { if !f(e) { break; } } @@ -25,7 +25,7 @@ impl iterable for &self/[A] { } impl iterable for ~[A] { - fn iterate(f: fn(x: &A) -> bool) { + fn iterate(f: &fn(x: &A) -> bool) { for vec::each(self) |e| { if !f(e) { break; } } diff --git a/src/test/run-pass/autobind.rs b/src/test/run-pass/autobind.rs index 1ab760307b272..44688a8dfce96 100644 --- a/src/test/run-pass/autobind.rs +++ b/src/test/run-pass/autobind.rs @@ -10,10 +10,10 @@ fn f(x: ~[T]) -> T { return x[0]; } -fn g(act: fn(~[int]) -> int) -> int { return act(~[1, 2, 3]); } +fn g(act: &fn(~[int]) -> int) -> int { return act(~[1, 2, 3]); } pub fn main() { fail_unless!((g(f) == 1)); - let f1: fn(~[~str]) -> ~str = f; + let f1: &fn(~[~str]) -> ~str = f; fail_unless!((f1(~[~"x", ~"y", ~"z"]) == ~"x")); } diff --git a/src/test/run-pass/block-arg-can-be-followed-by-block-arg.rs b/src/test/run-pass/block-arg-can-be-followed-by-block-arg.rs index 94d568b71585d..b2e1bc515865a 100644 --- a/src/test/run-pass/block-arg-can-be-followed-by-block-arg.rs +++ b/src/test/run-pass/block-arg-can-be-followed-by-block-arg.rs @@ -9,7 +9,7 @@ // except according to those terms. pub fn main() { - fn f(i: fn() -> uint) -> uint { i() } + fn f(i: &fn() -> uint) -> uint { i() } let v = ~[-1f, 0f, 1f, 2f, 3f]; let z = do do vec::foldl(f, v) |x, _y| { x } { 22u }; fail_unless!(z == 22u); diff --git a/src/test/run-pass/block-arg-used-as-any.rs b/src/test/run-pass/block-arg-used-as-any.rs index 6d311a138288d..ae110a0477374 100644 --- a/src/test/run-pass/block-arg-used-as-any.rs +++ b/src/test/run-pass/block-arg-used-as-any.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn call_any(f: fn() -> uint) -> uint { +fn call_any(f: &fn() -> uint) -> uint { return f(); } diff --git a/src/test/run-pass/block-explicit-types.rs b/src/test/run-pass/block-explicit-types.rs index f6bbb94690f79..b24a655667a6b 100644 --- a/src/test/run-pass/block-explicit-types.rs +++ b/src/test/run-pass/block-explicit-types.rs @@ -9,6 +9,6 @@ // except according to those terms. pub fn main() { - fn as_buf(s: ~str, f: fn(~str) -> T) -> T { f(s) } + fn as_buf(s: ~str, f: &fn(~str) -> T) -> T { f(s) } as_buf(~"foo", |foo: ~str| -> () log(error, foo) ); } diff --git a/src/test/run-pass/block-fn-coerce.rs b/src/test/run-pass/block-fn-coerce.rs index 4593934d52300..dc8ad25e27606 100644 --- a/src/test/run-pass/block-fn-coerce.rs +++ b/src/test/run-pass/block-fn-coerce.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn force(f: fn() -> int) -> int { return f(); } +fn force(f: &fn() -> int) -> int { return f(); } pub fn main() { fn f() -> int { return 7; } fail_unless!((force(f) == 7)); diff --git a/src/test/run-pass/block-iter-1.rs b/src/test/run-pass/block-iter-1.rs index 571e67b4e5b85..d0a24f80c0b90 100644 --- a/src/test/run-pass/block-iter-1.rs +++ b/src/test/run-pass/block-iter-1.rs @@ -10,7 +10,7 @@ // xfail-fast -fn iter_vec(v: ~[T], f: fn(&T)) { for v.each |x| { f(x); } } +fn iter_vec(v: ~[T], f: &fn(&T)) { for v.each |x| { f(x); } } pub fn main() { let v = ~[1, 2, 3, 4, 5, 6, 7]; diff --git a/src/test/run-pass/block-iter-2.rs b/src/test/run-pass/block-iter-2.rs index 1ec5c781807fd..acffb6830dede 100644 --- a/src/test/run-pass/block-iter-2.rs +++ b/src/test/run-pass/block-iter-2.rs @@ -10,7 +10,7 @@ // xfail-fast -fn iter_vec(v: ~[T], f: fn(&T)) { for v.each |x| { f(x); } } +fn iter_vec(v: ~[T], f: &fn(&T)) { for v.each |x| { f(x); } } pub fn main() { let v = ~[1, 2, 3, 4, 5]; diff --git a/src/test/run-pass/borrowck-borrow-from-expr-block.rs b/src/test/run-pass/borrowck-borrow-from-expr-block.rs index f2bde5a9f4bd8..0422be9d333df 100644 --- a/src/test/run-pass/borrowck-borrow-from-expr-block.rs +++ b/src/test/run-pass/borrowck-borrow-from-expr-block.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn borrow(x: &int, f: fn(x: &int)) { +fn borrow(x: &int, f: &fn(x: &int)) { f(x) } diff --git a/src/test/run-pass/borrowck-mut-uniq.rs b/src/test/run-pass/borrowck-mut-uniq.rs index 2cd445ee7af8b..5f5b9c59d7680 100644 --- a/src/test/run-pass/borrowck-mut-uniq.rs +++ b/src/test/run-pass/borrowck-mut-uniq.rs @@ -18,7 +18,7 @@ fn add_int(x: &mut Ints, v: int) { x.values <-> values; } -fn iter_ints(x: &Ints, f: fn(x: &int) -> bool) { +fn iter_ints(x: &Ints, f: &fn(x: &int) -> bool) { let l = x.values.len(); uint::range(0, l, |i| f(&x.values[i])) } diff --git a/src/test/run-pass/borrowck-preserve-box-in-field.rs b/src/test/run-pass/borrowck-preserve-box-in-field.rs index 0b84ba4ff59fb..795b074e37c4f 100644 --- a/src/test/run-pass/borrowck-preserve-box-in-field.rs +++ b/src/test/run-pass/borrowck-preserve-box-in-field.rs @@ -10,7 +10,7 @@ // exec-env:RUST_POISON_ON_FREE=1 -fn borrow(x: &int, f: fn(x: &int)) { +fn borrow(x: &int, f: &fn(x: &int)) { let before = *x; f(x); let after = *x; diff --git a/src/test/run-pass/borrowck-preserve-box-in-uniq.rs b/src/test/run-pass/borrowck-preserve-box-in-uniq.rs index fedd8c42e8fc9..11ec78b681cbb 100644 --- a/src/test/run-pass/borrowck-preserve-box-in-uniq.rs +++ b/src/test/run-pass/borrowck-preserve-box-in-uniq.rs @@ -10,7 +10,7 @@ // exec-env:RUST_POISON_ON_FREE=1 -fn borrow(x: &int, f: fn(x: &int)) { +fn borrow(x: &int, f: &fn(x: &int)) { let before = *x; f(x); let after = *x; diff --git a/src/test/run-pass/borrowck-preserve-box.rs b/src/test/run-pass/borrowck-preserve-box.rs index ec9e82c7731fc..8d625476f57dc 100644 --- a/src/test/run-pass/borrowck-preserve-box.rs +++ b/src/test/run-pass/borrowck-preserve-box.rs @@ -10,7 +10,7 @@ // exec-env:RUST_POISON_ON_FREE=1 -fn borrow(x: &int, f: fn(x: &int)) { +fn borrow(x: &int, f: &fn(x: &int)) { let before = *x; f(x); let after = *x; diff --git a/src/test/run-pass/borrowck-preserve-expl-deref.rs b/src/test/run-pass/borrowck-preserve-expl-deref.rs index fd64507daa19e..fcb84eaaf00ab 100644 --- a/src/test/run-pass/borrowck-preserve-expl-deref.rs +++ b/src/test/run-pass/borrowck-preserve-expl-deref.rs @@ -10,7 +10,7 @@ // exec-env:RUST_POISON_ON_FREE=1 -fn borrow(x: &int, f: fn(x: &int)) { +fn borrow(x: &int, f: &fn(x: &int)) { let before = *x; f(x); let after = *x; diff --git a/src/test/run-pass/class-impl-parameterized-trait.rs b/src/test/run-pass/class-impl-parameterized-trait.rs index 15972d4bcd04d..87573b84dc885 100644 --- a/src/test/run-pass/class-impl-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-parameterized-trait.rs @@ -57,17 +57,17 @@ class cat : map { fn [](&&k:int) -> bool { k <= self.meows } fn find(&&k:int) -> Option { Some(self.get(k)) } fn remove(&&k:int) -> Option { self.meows -= k; Some(true) } - fn each(f: fn(&&int, &&bool) -> bool) { + fn each(f: &fn(&&int, &&bool) -> bool) { let mut n = int::abs(self.meows); while n > 0 { if !f(n, true) { break; } n -= 1; } } - fn each_key(&&f: fn(&&int) -> bool) { + fn each_key(&&f: &fn(&&int) -> bool) { for self.each |k, _v| { if !f(k) { break; } again;}; } - fn each_value(&&f: fn(&&bool) -> bool) { + fn each_value(&&f: &fn(&&bool) -> bool) { for self.each |_k, v| { if !f(v) { break; } again;}; } fn clear() { } diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs index b616937731091..6cb0749ddb57f 100644 --- a/src/test/run-pass/class-impl-very-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs @@ -50,7 +50,7 @@ pub impl cat { } impl BaseIter<(int, &'self T)> for cat { - pure fn each(&self, f: fn(&(int, &'self T)) -> bool) { + pure fn each(&self, f: &fn(&(int, &'self T)) -> bool) { let mut n = int::abs(self.meows); while n > 0 { if !f(&(n, &self.name)) { break; } @@ -73,11 +73,11 @@ impl Mutable for cat { impl Map for cat { pure fn contains_key(&self, k: &int) -> bool { *k <= self.meows } - pure fn each_key(&self, f: fn(v: &int) -> bool) { + pure fn each_key(&self, f: &fn(v: &int) -> bool) { for self.each |&(k, _)| { if !f(&k) { break; } loop;}; } - pure fn each_value(&self, f: fn(v: &T) -> bool) { + pure fn each_value(&self, f: &fn(v: &T) -> bool) { for self.each |&(_, v)| { if !f(v) { break; } loop;}; } diff --git a/src/test/run-pass/class-trait-bounded-param.rs b/src/test/run-pass/class-trait-bounded-param.rs index 294c7264c739e..e525312d6da5b 100644 --- a/src/test/run-pass/class-trait-bounded-param.rs +++ b/src/test/run-pass/class-trait-bounded-param.rs @@ -22,9 +22,9 @@ class keys> self.map = map; } - fn each(blk: fn(K) -> bool) { self.map.each(|k, _v| blk(k) ) } + fn each(blk: &fn(K) -> bool) { self.map.each(|k, _v| blk(k) ) } fn size_hint() -> Option { Some(self.map.size()) } - fn eachi(blk: fn(uint, K) -> bool) { iter::eachi(self, blk) } + fn eachi(blk: &fn(uint, K) -> bool) { iter::eachi(self, blk) } } pub fn main() { diff --git a/src/test/run-pass/closure-inference.rs b/src/test/run-pass/closure-inference.rs index 246450d2a075b..e61636a323a65 100644 --- a/src/test/run-pass/closure-inference.rs +++ b/src/test/run-pass/closure-inference.rs @@ -12,7 +12,7 @@ fn foo(i: int) -> int { i + 1 } -fn apply(f: fn(A) -> A, v: A) -> A { f(v) } +fn apply(f: &fn(A) -> A, v: A) -> A { f(v) } pub fn main() { let f = {|i| foo(i)}; diff --git a/src/test/run-pass/do-for-empty-args.rs b/src/test/run-pass/do-for-empty-args.rs index 2a7091cb16305..c86c1768111f7 100644 --- a/src/test/run-pass/do-for-empty-args.rs +++ b/src/test/run-pass/do-for-empty-args.rs @@ -11,7 +11,7 @@ // no-reformat // Testing various forms of `do` and `for` with empty arg lists -fn f(f: fn() -> bool) { +fn f(f: &fn() -> bool) { } pub fn main() { diff --git a/src/test/run-pass/do-pure.rs b/src/test/run-pass/do-pure.rs index b422f5819f09c..41686cf5b3736 100644 --- a/src/test/run-pass/do-pure.rs +++ b/src/test/run-pass/do-pure.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pure fn f(f: fn()) { +pure fn f(f: &fn()) { } pure fn g() { diff --git a/src/test/run-pass/fn-assign-managed-to-bare-1.rs b/src/test/run-pass/fn-assign-managed-to-bare-1.rs index a9bd5587de240..9ab6af0ac276e 100644 --- a/src/test/run-pass/fn-assign-managed-to-bare-1.rs +++ b/src/test/run-pass/fn-assign-managed-to-bare-1.rs @@ -15,6 +15,6 @@ fn add(n: int) -> @fn(int) -> int { pub fn main() { fail_unless!(add(3)(4) == 7); - let add3 : fn(int)->int = add(3); + let add3 : &fn(int)->int = add(3); fail_unless!(add3(4) == 7); } diff --git a/src/test/run-pass/fn-bare-coerce-to-block.rs b/src/test/run-pass/fn-bare-coerce-to-block.rs index a1ccb8b37eff9..db7604d11484d 100644 --- a/src/test/run-pass/fn-bare-coerce-to-block.rs +++ b/src/test/run-pass/fn-bare-coerce-to-block.rs @@ -10,7 +10,7 @@ fn bare() {} -fn likes_block(f: fn()) { f() } +fn likes_block(f: &fn()) { f() } pub fn main() { likes_block(bare); diff --git a/src/test/run-pass/fn-pattern-expected-type.rs b/src/test/run-pass/fn-pattern-expected-type.rs index 411eb5ffb0946..3f5d3818e1c12 100644 --- a/src/test/run-pass/fn-pattern-expected-type.rs +++ b/src/test/run-pass/fn-pattern-expected-type.rs @@ -9,7 +9,7 @@ // except according to those terms. pub fn main() { - let f: fn((int,int)) = |(x, y)| { + let f: &fn((int,int)) = |(x, y)| { fail_unless!(x == 1); fail_unless!(y == 2); }; diff --git a/src/test/run-pass/foreach-nested.rs b/src/test/run-pass/foreach-nested.rs index 8d705447531f9..a94131b36c051 100644 --- a/src/test/run-pass/foreach-nested.rs +++ b/src/test/run-pass/foreach-nested.rs @@ -12,7 +12,7 @@ // -*- rust -*- -fn two(it: fn(int)) { it(0); it(1); } +fn two(it: &fn(int)) { it(0); it(1); } pub fn main() { let mut a: ~[int] = ~[-1, -1, -1, -1]; diff --git a/src/test/run-pass/foreach-put-structured.rs b/src/test/run-pass/foreach-put-structured.rs index 8bbfe90ba0307..1a71cf52de259 100644 --- a/src/test/run-pass/foreach-put-structured.rs +++ b/src/test/run-pass/foreach-put-structured.rs @@ -10,7 +10,7 @@ -fn pairs(it: fn((int, int))) { +fn pairs(it: &fn((int, int))) { let mut i: int = 0; let mut j: int = 0; while i < 10 { it((i, j)); i += 1; j += i; } diff --git a/src/test/run-pass/foreach-simple-outer-slot.rs b/src/test/run-pass/foreach-simple-outer-slot.rs index 5245158525019..1c0b28982dbe1 100644 --- a/src/test/run-pass/foreach-simple-outer-slot.rs +++ b/src/test/run-pass/foreach-simple-outer-slot.rs @@ -20,7 +20,7 @@ pub fn main() { fail_unless!((sum == 45)); } -fn first_ten(it: fn(int)) { +fn first_ten(it: &fn(int)) { let mut i: int = 0; while i < 10 { debug!("first_ten"); it(i); i = i + 1; } } diff --git a/src/test/run-pass/issue-1458.rs b/src/test/run-pass/issue-1458.rs index 7ef47ed1dda93..76ec34330d4b8 100644 --- a/src/test/run-pass/issue-1458.rs +++ b/src/test/run-pass/issue-1458.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn plus_one(f: fn() -> int) -> int { +fn plus_one(f: &fn() -> int) -> int { return f() + 1; } diff --git a/src/test/run-pass/issue-2185.rs b/src/test/run-pass/issue-2185.rs index cd2273ab173fe..ac680d3d12e41 100644 --- a/src/test/run-pass/issue-2185.rs +++ b/src/test/run-pass/issue-2185.rs @@ -15,15 +15,15 @@ // warrant still having a test, so I inlined the old definitions. trait iterable { - fn iter(blk: fn(A)); + fn iter(blk: &fn(A)); } impl iterable for @fn(&fn(A)) { - fn iter(blk: fn(A)) { self(blk); } + fn iter(blk: &fn(A)) { self(blk); } } impl iterable for @fn(&fn(uint)) { - fn iter(blk: fn(&&v: uint)) { self( |i| blk(i) ) } + fn iter(blk: &fn(&&v: uint)) { self( |i| blk(i) ) } } fn filter>(self: IA, prd: @fn(A) -> bool, blk: &fn(A)) { diff --git a/src/test/run-pass/issue-2487-a.rs b/src/test/run-pass/issue-2487-a.rs index 33023db5323fc..138860ce72d1f 100644 --- a/src/test/run-pass/issue-2487-a.rs +++ b/src/test/run-pass/issue-2487-a.rs @@ -32,7 +32,7 @@ fn socket() -> socket { } } -fn closure(f: fn()) { f() } +fn closure(f: &fn()) { f() } fn setsockopt_bytes(_sock: int) { } diff --git a/src/test/run-pass/issue-2611.rs b/src/test/run-pass/issue-2611.rs index 83cedc0fe5024..af3e8e9c7a2b5 100644 --- a/src/test/run-pass/issue-2611.rs +++ b/src/test/run-pass/issue-2611.rs @@ -11,11 +11,11 @@ use core::iter::BaseIter; trait FlatMapToVec { - fn flat_map_to_vec>(&self, op: fn(&A) -> IB) -> ~[B]; + fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B]; } impl FlatMapToVec for ~[A] { - fn flat_map_to_vec>(&self, op: fn(&A) -> IB) -> ~[B] { + fn flat_map_to_vec>(&self, op: &fn(&A) -> IB) -> ~[B] { iter::flat_map_to_vec(self, op) } } diff --git a/src/test/run-pass/issue-3874.rs b/src/test/run-pass/issue-3874.rs index d709757adb02d..8d62da9efad42 100644 --- a/src/test/run-pass/issue-3874.rs +++ b/src/test/run-pass/issue-3874.rs @@ -11,7 +11,7 @@ // xfail-test enum PureCounter { PureCounter(uint) } -pure fn each(self: PureCounter, blk: fn(v: &uint)) { +pure fn each(self: PureCounter, blk: &fn(v: &uint)) { let PureCounter(ref x) = self; blk(x); } diff --git a/src/test/run-pass/issue-868.rs b/src/test/run-pass/issue-868.rs index 55c5dcb4e0768..16e8fa18c2a02 100644 --- a/src/test/run-pass/issue-868.rs +++ b/src/test/run-pass/issue-868.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f(g: fn() -> T) -> T { g() } +fn f(g: &fn() -> T) -> T { g() } pub fn main() { let _x = f( | | { 10 }); diff --git a/src/test/run-pass/issue-912.rs b/src/test/run-pass/issue-912.rs index dddcb8b957f6d..d2c51df2b8fb3 100644 --- a/src/test/run-pass/issue-912.rs +++ b/src/test/run-pass/issue-912.rs @@ -9,7 +9,7 @@ // except according to those terms. // xfail-test -fn find(_f: fn(@T) -> bool, _v: [@T]) {} +fn find(_f: &fn(@T) -> bool, _v: [@T]) {} pub fn main() { let x = 10, arr = []; diff --git a/src/test/run-pass/iter-range.rs b/src/test/run-pass/iter-range.rs index 5fdd60bedb366..0ec8eea52365f 100644 --- a/src/test/run-pass/iter-range.rs +++ b/src/test/run-pass/iter-range.rs @@ -10,7 +10,7 @@ -fn range(a: int, b: int, it: fn(int)) { +fn range(a: int, b: int, it: &fn(int)) { fail_unless!((a < b)); let mut i: int = a; while i < b { it(i); i += 1; } diff --git a/src/test/run-pass/last-use-in-block.rs b/src/test/run-pass/last-use-in-block.rs index e8083dd3f6b21..e2dbf7d29db19 100644 --- a/src/test/run-pass/last-use-in-block.rs +++ b/src/test/run-pass/last-use-in-block.rs @@ -10,7 +10,7 @@ // Issue #1818 -fn lp(s: ~str, f: fn(~str) -> T) -> T { +fn lp(s: ~str, f: &fn(~str) -> T) -> T { while false { let r = f(s); return (r); @@ -18,8 +18,8 @@ fn lp(s: ~str, f: fn(~str) -> T) -> T { fail!(); } -fn apply(s: ~str, f: fn(~str) -> T) -> T { - fn g(s: ~str, f: fn(~str) -> T) -> T {f(s)} +fn apply(s: ~str, f: &fn(~str) -> T) -> T { + fn g(s: ~str, f: &fn(~str) -> T) -> T {f(s)} g(s, |v| { let r = f(v); r }) } diff --git a/src/test/run-pass/monad.rs b/src/test/run-pass/monad.rs index 523348b4ffdea..b21b3b6c7fb26 100644 --- a/src/test/run-pass/monad.rs +++ b/src/test/run-pass/monad.rs @@ -11,11 +11,11 @@ // xfail-fast trait vec_monad { - fn bind(f: fn(&A) -> ~[B]) -> ~[B]; + fn bind(f: &fn(&A) -> ~[B]) -> ~[B]; } impl vec_monad for ~[A] { - fn bind(f: fn(&A) -> ~[B]) -> ~[B] { + fn bind(f: &fn(&A) -> ~[B]) -> ~[B] { let mut r = ~[]; for self.each |elt| { r += f(elt); } r @@ -23,11 +23,11 @@ impl vec_monad for ~[A] { } trait option_monad { - fn bind(f: fn(&A) -> Option) -> Option; + fn bind(f: &fn(&A) -> Option) -> Option; } impl option_monad for Option { - fn bind(f: fn(&A) -> Option) -> Option { + fn bind(f: &fn(&A) -> Option) -> Option { match self { Some(ref a) => { f(a) } None => { None } diff --git a/src/test/run-pass/mut-function-arguments.rs b/src/test/run-pass/mut-function-arguments.rs index a092e3bcc1889..f61ffc1bc3e00 100644 --- a/src/test/run-pass/mut-function-arguments.rs +++ b/src/test/run-pass/mut-function-arguments.rs @@ -14,7 +14,7 @@ fn f(mut y: ~int) { } fn g() { - let frob: fn(~int) = |mut q| { *q = 2; fail_unless!(*q == 2); }; + let frob: &fn(~int) = |mut q| { *q = 2; fail_unless!(*q == 2); }; let w = ~37; frob(w); diff --git a/src/test/run-pass/newlambdas.rs b/src/test/run-pass/newlambdas.rs index 267946e7b2e01..076e019bab46d 100644 --- a/src/test/run-pass/newlambdas.rs +++ b/src/test/run-pass/newlambdas.rs @@ -12,7 +12,7 @@ fn f(i: int, f: &fn(int) -> int) -> int { f(i) } -fn g(g: fn()) { } +fn g(g: &fn()) { } fn ff() -> @fn(int) -> int { return |x| x + 1; diff --git a/src/test/run-pass/non-legacy-modes.rs b/src/test/run-pass/non-legacy-modes.rs index 6260de64cd839..330a9b9de7b8f 100644 --- a/src/test/run-pass/non-legacy-modes.rs +++ b/src/test/run-pass/non-legacy-modes.rs @@ -12,7 +12,7 @@ struct X { repr: int } -fn apply(x: T, f: fn(T)) { +fn apply(x: T, f: &fn(T)) { f(x); } diff --git a/src/test/run-pass/pipe-bank-proto.rs b/src/test/run-pass/pipe-bank-proto.rs index b74c70d3ea716..20daa894bc128 100644 --- a/src/test/run-pass/pipe-bank-proto.rs +++ b/src/test/run-pass/pipe-bank-proto.rs @@ -49,7 +49,7 @@ macro_rules! move_it ( ) fn switch(+endp: pipes::RecvPacket, - f: fn(+v: Option) -> U) -> U { + f: &fn(+v: Option) -> U) -> U { f(pipes::try_recv(endp)) } diff --git a/src/test/run-pass/purity-infer.rs b/src/test/run-pass/purity-infer.rs index 9aba504695579..d546909de8e1e 100644 --- a/src/test/run-pass/purity-infer.rs +++ b/src/test/run-pass/purity-infer.rs @@ -9,7 +9,7 @@ // except according to those terms. -fn something(f: pure fn()) { f(); } +fn something(f: &pure fn()) { f(); } pub fn main() { something(|| log(error, "hi!") ); } diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index 029dc37cfb2ee..90aaafd247ba6 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -19,7 +19,7 @@ use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor}; /// Trait for visitor that wishes to reflect on data. trait movable_ptr { - fn move_ptr(adjustment: fn(*c_void) -> *c_void); + fn move_ptr(adjustment: &fn(*c_void) -> *c_void); } /// Helper function for alignment calculation. @@ -479,7 +479,7 @@ struct Stuff { } pub impl my_visitor { - fn get(f: fn(T)) { + fn get(f: &fn(T)) { unsafe { f(*(self.ptr1 as *T)); } @@ -498,7 +498,7 @@ pub impl my_visitor { struct Inner { inner: V } impl movable_ptr for my_visitor { - fn move_ptr(adjustment: fn(*c_void) -> *c_void) { + fn move_ptr(adjustment: &fn(*c_void) -> *c_void) { self.ptr1 = adjustment(self.ptr1); self.ptr2 = adjustment(self.ptr2); } diff --git a/src/test/run-pass/regions-fn-subtyping-2.rs b/src/test/run-pass/regions-fn-subtyping-2.rs index ad9ede07f779b..a995b3d969352 100644 --- a/src/test/run-pass/regions-fn-subtyping-2.rs +++ b/src/test/run-pass/regions-fn-subtyping-2.rs @@ -15,13 +15,13 @@ // Here, `f` is a function that takes a pointer `x` and a function // `g`, where `g` requires its argument `y` to be in the same region // that `x` is in. -fn has_same_region(f: fn(x: &a.int, g: fn(y: &a.int))) { +fn has_same_region(f: &fn(x: &a.int, g: &fn(y: &a.int))) { // `f` should be the type that `wants_same_region` wants, but // right now the compiler complains that it isn't. wants_same_region(f); } -fn wants_same_region(_f: fn(x: &b.int, g: fn(y: &b.int))) { +fn wants_same_region(_f: &fn(x: &b.int, g: &fn(y: &b.int))) { } pub fn main() { diff --git a/src/test/run-pass/regions-infer-call-2.rs b/src/test/run-pass/regions-infer-call-2.rs index eba9bb592bb65..dc38a7baacd21 100644 --- a/src/test/run-pass/regions-infer-call-2.rs +++ b/src/test/run-pass/regions-infer-call-2.rs @@ -10,7 +10,7 @@ fn takes_two(x: &int, y: &int) -> int { *x + *y } -fn with(f: fn(x: &int) -> T) -> T { +fn with(f: &fn(x: &int) -> T) -> T { f(&20) } diff --git a/src/test/run-pass/regions-params.rs b/src/test/run-pass/regions-params.rs index 500ce356018c0..0049653dea9d3 100644 --- a/src/test/run-pass/regions-params.rs +++ b/src/test/run-pass/regions-params.rs @@ -12,7 +12,7 @@ fn region_identity(x: &r/uint) -> &r/uint { x } -fn apply(t: T, f: fn(T) -> T) -> T { f(t) } +fn apply(t: T, f: &fn(T) -> T) -> T { f(t) } fn parameterized(x: &uint) -> uint { let z = apply(x, ({|y| diff --git a/src/test/run-pass/ret-break-cont-in-block.rs b/src/test/run-pass/ret-break-cont-in-block.rs index da2aa2b8cd4b3..6fe7575884249 100644 --- a/src/test/run-pass/ret-break-cont-in-block.rs +++ b/src/test/run-pass/ret-break-cont-in-block.rs @@ -12,7 +12,7 @@ use core::cmp::Eq; -fn iter(v: ~[T], it: fn(&T) -> bool) { +fn iter(v: ~[T], it: &fn(&T) -> bool) { let mut i = 0u, l = v.len(); while i < l { if !it(&v[i]) { break; } diff --git a/src/test/run-pass/sendfn-is-a-block.rs b/src/test/run-pass/sendfn-is-a-block.rs index 33e6eb6c85585..0d9d01f9e700f 100644 --- a/src/test/run-pass/sendfn-is-a-block.rs +++ b/src/test/run-pass/sendfn-is-a-block.rs @@ -10,7 +10,7 @@ // xfail-fast -fn test(f: fn(uint) -> uint) -> uint { +fn test(f: &fn(uint) -> uint) -> uint { return f(22u); } diff --git a/src/test/run-pass/static-impl.rs b/src/test/run-pass/static-impl.rs index 2ad01557e800e..2ee6f631ea521 100644 --- a/src/test/run-pass/static-impl.rs +++ b/src/test/run-pass/static-impl.rs @@ -26,12 +26,12 @@ mod b { trait uint_utils { fn str() -> ~str; - fn multi(f: fn(uint)); + fn multi(f: &fn(uint)); } impl uint_utils for uint { fn str() -> ~str { uint::to_str(self) } - fn multi(f: fn(uint)) { + fn multi(f: &fn(uint)) { let mut c = 0u; while c < self { f(c); c += 1u; } } @@ -39,14 +39,14 @@ impl uint_utils for uint { trait vec_utils { fn length_() -> uint; - fn iter_(f: fn(&T)); - fn map_(f: fn(&T) -> U) -> ~[U]; + fn iter_(f: &fn(&T)); + fn map_(f: &fn(&T) -> U) -> ~[U]; } impl vec_utils for ~[T] { fn length_() -> uint { vec::len(self) } - fn iter_(f: fn(&T)) { for self.each |x| { f(x); } } - fn map_(f: fn(&T) -> U) -> ~[U] { + fn iter_(f: &fn(&T)) { for self.each |x| { f(x); } } + fn map_(f: &fn(&T) -> U) -> ~[U] { let mut r = ~[]; for self.each |elt| { r += ~[f(elt)]; } r diff --git a/src/test/run-pass/static-method-test.rs b/src/test/run-pass/static-method-test.rs index a2148fb0ef501..0c6359375d306 100644 --- a/src/test/run-pass/static-method-test.rs +++ b/src/test/run-pass/static-method-test.rs @@ -36,33 +36,33 @@ impl bool_like for int { // A trait for sequences that can be constructed imperatively. trait buildable { static pure fn build_sized(size: uint, - builder: fn(push: pure fn(+v: A))) -> Self; + builder: &fn(push: &pure fn(+v: A))) -> Self; } impl buildable for @[A] { #[inline(always)] static pure fn build_sized(size: uint, - builder: fn(push: pure fn(+v: A))) -> @[A] { + builder: &fn(push: &pure fn(+v: A))) -> @[A] { at_vec::build_sized(size, builder) } } impl buildable for ~[A] { #[inline(always)] static pure fn build_sized(size: uint, - builder: fn(push: pure fn(+v: A))) -> ~[A] { + builder: &fn(push: &pure fn(+v: A))) -> ~[A] { vec::build_sized(size, builder) } } #[inline(always)] -pure fn build>(builder: fn(push: pure fn(+v: A))) -> B { +pure fn build>(builder: &fn(push: &pure fn(+v: A))) -> B { buildable::build_sized(4, builder) } /// Apply a function to each element of an iterable and return the results fn map, U, BU: buildable> - (v: IT, f: fn(T) -> U) -> BU { + (v: IT, f: &fn(T) -> U) -> BU { do build |push| { for v.each() |elem| { push(f(*elem)); diff --git a/src/test/run-pass/task-killjoin-rsrc.rs b/src/test/run-pass/task-killjoin-rsrc.rs index 48a2b30209825..39651f86e227b 100644 --- a/src/test/run-pass/task-killjoin-rsrc.rs +++ b/src/test/run-pass/task-killjoin-rsrc.rs @@ -40,7 +40,7 @@ fn notify(ch: Chan, v: @mut bool) -> notify { } fn joinable(f: ~fn()) -> Port { - fn wrapper(c: Chan, f: fn()) { + fn wrapper(c: Chan, f: &fn()) { let b = @mut false; error!("wrapper: task=%? allocated v=%x", task::get_task(), diff --git a/src/test/run-pass/trait-generic.rs b/src/test/run-pass/trait-generic.rs index b375b5f328f88..7b8ebe6d34cab 100644 --- a/src/test/run-pass/trait-generic.rs +++ b/src/test/run-pass/trait-generic.rs @@ -24,10 +24,10 @@ impl to_str for () { } trait map { - fn map(f: fn(&T) -> U) -> ~[U]; + fn map(f: &fn(&T) -> U) -> ~[U]; } impl map for ~[T] { - fn map(f: fn(&T) -> U) -> ~[U] { + fn map(f: &fn(&T) -> U) -> ~[U] { let mut r = ~[]; for self.each |x| { r += ~[f(x)]; } r diff --git a/src/test/run-pass/type-params-in-for-each.rs b/src/test/run-pass/type-params-in-for-each.rs index bf252ee136491..d600ff25f0298 100644 --- a/src/test/run-pass/type-params-in-for-each.rs +++ b/src/test/run-pass/type-params-in-for-each.rs @@ -13,7 +13,7 @@ struct S { b: uint, } -fn range(lo: uint, hi: uint, it: fn(uint)) { +fn range(lo: uint, hi: uint, it: &fn(uint)) { let mut lo_ = lo; while lo_ < hi { it(lo_); lo_ += 1u; } } diff --git a/src/test/run-pass/unnamed_argument_mode.rs b/src/test/run-pass/unnamed_argument_mode.rs index e8ceeab3bf6ce..649f424ec36be 100644 --- a/src/test/run-pass/unnamed_argument_mode.rs +++ b/src/test/run-pass/unnamed_argument_mode.rs @@ -3,7 +3,7 @@ fn good(a: &int) { // unnamed argument &int is now parse x: &int -fn called(f: fn(&int)) { +fn called(f: &fn(&int)) { } pub fn main() { From bd2d17e4a1f75bc7e451fc1054d98ff13c456850 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 7 Mar 2013 15:44:21 -0800 Subject: [PATCH 21/43] libsyntax: Stop parsing bare functions in preparation for switching them over --- src/libcore/hashmap.rs | 4 +++- src/libcore/num/uint-template.rs | 5 ++++- src/libcore/str.rs | 12 +++++++++--- src/libcore/trie.rs | 5 ++++- src/libstd/rl.rs | 2 +- src/libstd/treemap.rs | 4 +++- src/libsyntax/parse/obsolete.rs | 5 +++++ src/libsyntax/parse/parser.rs | 12 +++++++++++- 8 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index 6f63cdbabb57d..2adcee495a738 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -599,7 +599,9 @@ pub mod linear { } /// Visit the values representing the intersection - pure fn intersection(&self, other: &LinearSet, f: &fn(&T) -> bool) { + pure fn intersection(&self, + other: &LinearSet, + f: &fn(&T) -> bool) { for self.each |v| { if other.contains(v) { if !f(v) { return } diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs index 9a141bfd34161..9abbfb03d7a56 100644 --- a/src/libcore/num/uint-template.rs +++ b/src/libcore/num/uint-template.rs @@ -67,7 +67,10 @@ pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T } * Iterate over the range [`start`,`start`+`step`..`stop`) * */ -pub pure fn range_step(start: T, stop: T, step: T_SIGNED, it: &fn(T) -> bool) { +pub pure fn range_step(start: T, + stop: T, + step: T_SIGNED, + it: &fn(T) -> bool) { let mut i = start; if step == 0 { fail!(~"range_step called with step == 0"); diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 415c12e33a8a8..ae778cb7649b7 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -491,7 +491,10 @@ pub pure fn split(s: &str, sepfn: &fn(char) -> bool) -> ~[~str] { * Splits a string into substrings using a character function, cutting at * most `count` times. */ -pub pure fn splitn(s: &str, sepfn: &fn(char) -> bool, count: uint) -> ~[~str] { +pub pure fn splitn(s: &str, + sepfn: &fn(char) -> bool, + count: uint) + -> ~[~str] { split_inner(s, sepfn, count, true) } @@ -1246,8 +1249,11 @@ pub pure fn find_from(s: &str, start: uint, f: &fn(char) * or equal to `len(s)`. `start` must be the index of a character * boundary, as defined by `is_char_boundary`. */ -pub pure fn find_between(s: &str, start: uint, end: uint, f: &fn(char) -> bool) - -> Option { +pub pure fn find_between(s: &str, + start: uint, + end: uint, + f: &fn(char) -> bool) + -> Option { fail_unless!(start <= end); fail_unless!(end <= len(s)); fail_unless!(is_char_boundary(s, start)); diff --git a/src/libcore/trie.rs b/src/libcore/trie.rs index 4bd751adc3c5e..7dc85cba297f1 100644 --- a/src/libcore/trie.rs +++ b/src/libcore/trie.rs @@ -81,7 +81,10 @@ impl Map for TrieMap { /// Visit all values in order #[inline(always)] - pure fn each_value(&self, f: &fn(&T) -> bool) { self.each(|&(_, v)| f(v)) } + pure fn each_value(&self, + f: &fn(&T) -> bool) { + self.each(|&(_, v)| f(v)) + } /// Return the value corresponding to the key in the map #[inline(hint)] diff --git a/src/libstd/rl.rs b/src/libstd/rl.rs index b2b30c1057ef9..a8b25767ce595 100644 --- a/src/libstd/rl.rs +++ b/src/libstd/rl.rs @@ -68,7 +68,7 @@ pub unsafe fn read(prompt: ~str) -> Option<~str> { } } -pub type CompletionCb = @fn(~str, fn(~str)); +pub type CompletionCb<'self> = @fn(~str, &'self fn(~str)); fn complete_key(_v: @CompletionCb) {} diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index f053bcfd397ce..72351aac33975 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -138,7 +138,9 @@ impl Map for TreeMap { pure fn each_key(&self, f: &fn(&K) -> bool) { self.each(|&(k, _)| f(k)) } /// Visit all values in order - pure fn each_value(&self, f: &fn(&V) -> bool) { self.each(|&(_, v)| f(v)) } + pure fn each_value(&self, f: &fn(&V) -> bool) { + self.each(|&(_, v)| f(v)) + } /// Return the value corresponding to the key in the map pure fn find(&self, key: &K) -> Option<&self/V> { diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 97ff175da07fe..757df713fc053 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -53,6 +53,7 @@ pub enum ObsoleteSyntax { ObsoleteRecordPattern, ObsoleteAssertion, ObsoletePostFnTySigil, + ObsoleteBareFnType, } impl to_bytes::IterBytes for ObsoleteSyntax { @@ -166,6 +167,10 @@ pub impl Parser { "Rather than `fn@`, `fn~`, or `fn&`, \ write `@fn`, `~fn`, and `&fn` respectively" ), + ObsoleteBareFnType => ( + "bare function type", + "use `&fn` or `extern fn` instead" + ), }; self.report(sp, kind, kind_str, desc); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 92ff83a39756f..1c3d906e1648a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -76,7 +76,11 @@ use parse::obsolete::{ObsoleteUnsafeBlock, ObsoleteImplSyntax}; use parse::obsolete::{ObsoleteTraitBoundSeparator, ObsoleteMutOwnedPointer}; use parse::obsolete::{ObsoleteMutVector, ObsoleteTraitImplVisibility}; use parse::obsolete::{ObsoleteRecordType, ObsoleteRecordPattern}; +<<<<<<< HEAD use parse::obsolete::{ObsoleteAssertion, ObsoletePostFnTySigil}; +======= +use parse::obsolete::{ObsoleteAssertion, ObsoleteBareFnType}; +>>>>>>> libsyntax: Stop parsing bare functions in preparation for switching them over use parse::prec::{as_prec, token_to_binop}; use parse::token::{can_begin_expr, is_ident, is_ident_or_path}; use parse::token::{is_plain_ident, INTERPOLATED, special_idents}; @@ -647,8 +651,14 @@ pub impl Parser { } else if self.eat_keyword(&~"extern") { self.parse_ty_bare_fn() } else if self.token_is_closure_keyword(© *self.token) { +<<<<<<< HEAD // self.warn(fmt!("Old-school closure keyword")); self.parse_ty_closure(ast::BorrowedSigil, None) +======= + let result = self.parse_ty_closure(None, None); + self.obsolete(*self.last_span, ObsoleteBareFnType); + result +>>>>>>> libsyntax: Stop parsing bare functions in preparation for switching them over } else if *self.token == token::MOD_SEP || is_ident_or_path(&*self.token) { let path = self.parse_path_with_tps(colons_before_params); @@ -2813,7 +2823,7 @@ pub impl Parser { fn parse_fn_decl_with_self( &self, parse_arg_fn: - fn(&Parser) -> arg_or_capture_item + &fn(&Parser) -> arg_or_capture_item ) -> (self_ty, fn_decl) { fn maybe_parse_self_ty( cnstr: &fn(+v: mutability) -> ast::self_ty_, From e48446d060bb35925af0e79fcd2554f83ee26ecd Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 7 Mar 2013 16:36:30 -0800 Subject: [PATCH 22/43] test: Remove newtype enums from the test suite. rs=deenum --- src/test/auxiliary/issue_2472_b.rs | 2 +- src/test/auxiliary/issue_3136_a.rs | 2 +- .../compile-fail/access-mode-in-closures.rs | 2 +- .../compile-fail/borrowck-assign-to-enum.rs | 2 +- .../compile-fail/borrowck-autoref-3261.rs | 3 ++- .../borrowck-loan-in-overloaded-op.rs | 2 +- .../compile-fail/borrowck-mut-deref-comp.rs | 2 +- .../compile-fail/borrowck-unary-move-2.rs | 2 +- src/test/compile-fail/enum-in-scope.rs | 2 +- src/test/compile-fail/issue-2063-resource.rs | 2 +- src/test/compile-fail/issue-2063.rs | 2 +- src/test/compile-fail/issue-2718-a.rs | 2 +- src/test/compile-fail/issue-3080.rs | 2 +- src/test/compile-fail/issue-3344.rs | 2 +- src/test/compile-fail/issue-3953.rs | 2 +- .../compile-fail/liveness-use-after-send.rs | 2 +- .../pat-shadow-in-nested-binding.rs | 2 +- src/test/compile-fail/regions-bounds.rs | 2 +- ...regions-infer-region-in-fn-but-not-type.rs | 2 +- src/test/compile-fail/tps-invariant-enum.rs | 2 +- src/test/compile-fail/tps-invariant-trait.rs | 2 +- src/test/run-pass/alignment-gep-tup-like-2.rs | 2 +- src/test/run-pass/auto-encode.rs | 15 -------------- src/test/run-pass/auto-ref-newtype.rs | 2 +- src/test/run-pass/autoderef-method-newtype.rs | 2 +- src/test/run-pass/const-enum-newtype-align.rs | 17 ---------------- src/test/run-pass/const-newtype-enum.rs | 20 ------------------- src/test/run-pass/instantiable.rs | 2 +- src/test/run-pass/issue-2312.rs | 2 +- src/test/run-pass/issue-2718.rs | 4 ++-- src/test/run-pass/let-destruct.rs | 2 +- src/test/run-pass/log-degen-enum.rs | 17 ---------------- src/test/run-pass/newtype-polymorphic.rs | 2 +- src/test/run-pass/newtype.rs | 2 +- src/test/run-pass/pipe-pingpong-bounded.rs | 4 ++-- src/test/run-pass/reflect-visit-data.rs | 4 ++-- src/test/run-pass/reflect-visit-type.rs | 2 +- src/test/run-pass/regions-mock-trans.rs | 2 +- src/test/run-pass/resource-cycle.rs | 2 +- src/test/run-pass/resource-cycle2.rs | 2 +- src/test/run-pass/resource-cycle3.rs | 2 +- src/test/run-pass/trait-cast.rs | 2 +- 42 files changed, 42 insertions(+), 110 deletions(-) delete mode 100644 src/test/run-pass/const-enum-newtype-align.rs delete mode 100644 src/test/run-pass/const-newtype-enum.rs delete mode 100644 src/test/run-pass/log-degen-enum.rs diff --git a/src/test/auxiliary/issue_2472_b.rs b/src/test/auxiliary/issue_2472_b.rs index e7a9295472554..fd3355d83faab 100644 --- a/src/test/auxiliary/issue_2472_b.rs +++ b/src/test/auxiliary/issue_2472_b.rs @@ -9,7 +9,7 @@ // except according to those terms. -enum S = (); +struct S(()) pub impl S { fn foo() { } diff --git a/src/test/auxiliary/issue_3136_a.rs b/src/test/auxiliary/issue_3136_a.rs index 4de0b900dd3ea..c80457ef1e92c 100644 --- a/src/test/auxiliary/issue_3136_a.rs +++ b/src/test/auxiliary/issue_3136_a.rs @@ -11,7 +11,7 @@ trait x { fn use_x(); } -enum y = (); +struct y(()); impl x for y { fn use_x() { struct foo { //~ ERROR quux diff --git a/src/test/compile-fail/access-mode-in-closures.rs b/src/test/compile-fail/access-mode-in-closures.rs index 24897608880ca..f6b9a82ec676c 100644 --- a/src/test/compile-fail/access-mode-in-closures.rs +++ b/src/test/compile-fail/access-mode-in-closures.rs @@ -9,7 +9,7 @@ // except according to those terms. -enum sty = ~[int]; +struct sty(~[int]); fn unpack(_unpack: &fn(v: &sty) -> ~[int]) {} diff --git a/src/test/compile-fail/borrowck-assign-to-enum.rs b/src/test/compile-fail/borrowck-assign-to-enum.rs index 25a320061d451..ee38ceda3d80b 100644 --- a/src/test/compile-fail/borrowck-assign-to-enum.rs +++ b/src/test/compile-fail/borrowck-assign-to-enum.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum foo = int; +struct foo(int); fn main() { let x = foo(3); diff --git a/src/test/compile-fail/borrowck-autoref-3261.rs b/src/test/compile-fail/borrowck-autoref-3261.rs index 237c1b8671352..b874eac34b18c 100644 --- a/src/test/compile-fail/borrowck-autoref-3261.rs +++ b/src/test/compile-fail/borrowck-autoref-3261.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum X = Either<(uint,uint),extern fn()>; +struct X(Either<(uint,uint),extern fn()>); + pub impl &'self X { fn with(blk: &fn(x: &Either<(uint,uint),extern fn()>)) { blk(&**self) diff --git a/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs b/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs index 7b6484fd4aadb..ece9ae7e86199 100644 --- a/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs +++ b/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs @@ -10,7 +10,7 @@ // xfail-test #3387 -enum foo = ~uint; +struct foo(~uint); impl Add for foo { pure fn add(f: &foo) -> foo { diff --git a/src/test/compile-fail/borrowck-mut-deref-comp.rs b/src/test/compile-fail/borrowck-mut-deref-comp.rs index 3c67b6d5caf8d..540793d4135f2 100644 --- a/src/test/compile-fail/borrowck-mut-deref-comp.rs +++ b/src/test/compile-fail/borrowck-mut-deref-comp.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum foo = ~int; +struct foo(~int); fn borrow(x: @mut foo) { let _y = &***x; //~ ERROR illegal borrow unless pure diff --git a/src/test/compile-fail/borrowck-unary-move-2.rs b/src/test/compile-fail/borrowck-unary-move-2.rs index a25fc8327bd10..05dab4f8c68fb 100644 --- a/src/test/compile-fail/borrowck-unary-move-2.rs +++ b/src/test/compile-fail/borrowck-unary-move-2.rs @@ -24,7 +24,7 @@ fn noncopyable() -> noncopyable { } } -enum wrapper = noncopyable; +struct wrapper(noncopyable); fn main() { let x1 = wrapper(noncopyable()); diff --git a/src/test/compile-fail/enum-in-scope.rs b/src/test/compile-fail/enum-in-scope.rs index 704001de95844..cccf66ef2d54e 100644 --- a/src/test/compile-fail/enum-in-scope.rs +++ b/src/test/compile-fail/enum-in-scope.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum hello = int; +struct hello(int); fn main() { let hello = 0; //~ERROR declaration of `hello` shadows diff --git a/src/test/compile-fail/issue-2063-resource.rs b/src/test/compile-fail/issue-2063-resource.rs index 137ce2d5030fe..db054d5aba700 100644 --- a/src/test/compile-fail/issue-2063-resource.rs +++ b/src/test/compile-fail/issue-2063-resource.rs @@ -16,7 +16,7 @@ struct t { //~ ERROR this type cannot be instantiated to_str: (), } -enum x = @t; //~ ERROR this type cannot be instantiated +struct x(@t); //~ ERROR this type cannot be instantiated fn main() { } diff --git a/src/test/compile-fail/issue-2063.rs b/src/test/compile-fail/issue-2063.rs index 8f344f4260664..515db2b431cf1 100644 --- a/src/test/compile-fail/issue-2063.rs +++ b/src/test/compile-fail/issue-2063.rs @@ -11,7 +11,7 @@ // test that autoderef of a type like this does not // cause compiler to loop. Note that no instances // of such a type could ever be constructed. -enum t = @t; //~ ERROR this type cannot be instantiated +enum t(@t); //~ ERROR this type cannot be instantiated trait to_str_2 { fn to_str() -> ~str; diff --git a/src/test/compile-fail/issue-2718-a.rs b/src/test/compile-fail/issue-2718-a.rs index 925350d9b8804..318982c3b1360 100644 --- a/src/test/compile-fail/issue-2718-a.rs +++ b/src/test/compile-fail/issue-2718-a.rs @@ -16,7 +16,7 @@ pub struct send_packet { mod pingpong { use send_packet; pub type ping = send_packet; - pub enum pong = send_packet; //~ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable + pub struct pong(send_packet); //~ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable } fn main() {} diff --git a/src/test/compile-fail/issue-3080.rs b/src/test/compile-fail/issue-3080.rs index 530dadd7e9094..02df25d87d7fb 100644 --- a/src/test/compile-fail/issue-3080.rs +++ b/src/test/compile-fail/issue-3080.rs @@ -9,7 +9,7 @@ // except according to those terms. // xfail-test -enum x = (); +struct x(()); pub impl x { unsafe fn with() { } // This should fail } diff --git a/src/test/compile-fail/issue-3344.rs b/src/test/compile-fail/issue-3344.rs index 2d31867752ac5..df768860cba94 100644 --- a/src/test/compile-fail/issue-3344.rs +++ b/src/test/compile-fail/issue-3344.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum thing = uint; +struct thing(uint); impl cmp::Ord for thing { //~ ERROR missing method `gt` pure fn lt(&self, other: &thing) -> bool { **self < **other } pure fn le(&self, other: &thing) -> bool { **self < **other } diff --git a/src/test/compile-fail/issue-3953.rs b/src/test/compile-fail/issue-3953.rs index afd8cf892333f..bfc17c589db91 100644 --- a/src/test/compile-fail/issue-3953.rs +++ b/src/test/compile-fail/issue-3953.rs @@ -20,7 +20,7 @@ trait Hahaha: Eq + Eq + Eq + Eq + Eq + //~ ERROR Duplicate supertrait Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq + Eq {} -enum Lol = int; +struct Lol(int); impl Hahaha for Lol { } diff --git a/src/test/compile-fail/liveness-use-after-send.rs b/src/test/compile-fail/liveness-use-after-send.rs index 95dd59eb27f73..c0de60fa58e3f 100644 --- a/src/test/compile-fail/liveness-use-after-send.rs +++ b/src/test/compile-fail/liveness-use-after-send.rs @@ -14,7 +14,7 @@ fn send(ch: _chan, -data: T) { fail!(); } -enum _chan = int; +struct _chan(int); // Tests that "log(debug, message);" is flagged as using // message after the send deinitializes it diff --git a/src/test/compile-fail/pat-shadow-in-nested-binding.rs b/src/test/compile-fail/pat-shadow-in-nested-binding.rs index 3d2587551857a..4d89ec14d94b2 100644 --- a/src/test/compile-fail/pat-shadow-in-nested-binding.rs +++ b/src/test/compile-fail/pat-shadow-in-nested-binding.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum foo = uint; +struct foo(uint); fn main() { let (foo, _) = (2, 3); //~ ERROR declaration of `foo` shadows diff --git a/src/test/compile-fail/regions-bounds.rs b/src/test/compile-fail/regions-bounds.rs index c7a951c9c056d..35bef5a407a55 100644 --- a/src/test/compile-fail/regions-bounds.rs +++ b/src/test/compile-fail/regions-bounds.rs @@ -12,7 +12,7 @@ // nominal types (but not on other types) and that they are type // checked. -enum an_enum = &'self int; +struct an_enum(&'self int); trait a_trait { fn foo() -> &'self int; } diff --git a/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs b/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs index fe37d8990985d..4c3338d2e1d0c 100644 --- a/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs +++ b/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs @@ -11,7 +11,7 @@ // check that the &int here does not cause us to think that `foo` // contains region pointers -enum foo = ~fn(x: &int); +struct foo(~fn(x: &int)); fn take_foo(x: foo<'static>) {} //~ ERROR no region bound is allowed on `foo` diff --git a/src/test/compile-fail/tps-invariant-enum.rs b/src/test/compile-fail/tps-invariant-enum.rs index 967b201908c4b..9e19ecdcb7556 100644 --- a/src/test/compile-fail/tps-invariant-enum.rs +++ b/src/test/compile-fail/tps-invariant-enum.rs @@ -12,7 +12,7 @@ struct box { f: T } -enum box_impl = box; +struct box_impl(box); fn set_box_impl(b: box_impl<@const T>, v: @const T) { b.f = v; diff --git a/src/test/compile-fail/tps-invariant-trait.rs b/src/test/compile-fail/tps-invariant-trait.rs index 94bcea8f1d3bf..9569e5f1e8210 100644 --- a/src/test/compile-fail/tps-invariant-trait.rs +++ b/src/test/compile-fail/tps-invariant-trait.rs @@ -17,7 +17,7 @@ struct box { f: T } -enum box_impl = box; +struct box_impl(box); impl box_trait for box_impl { fn get() -> T { return self.f; } diff --git a/src/test/run-pass/alignment-gep-tup-like-2.rs b/src/test/run-pass/alignment-gep-tup-like-2.rs index 5bf8051cc1a47..22855bce28fca 100644 --- a/src/test/run-pass/alignment-gep-tup-like-2.rs +++ b/src/test/run-pass/alignment-gep-tup-like-2.rs @@ -12,7 +12,7 @@ struct Pair { a: A, b: B } -enum RecEnum = Rec; +struct RecEnum(Rec); struct Rec { val: A, rec: Option<@mut RecEnum> diff --git a/src/test/run-pass/auto-encode.rs b/src/test/run-pass/auto-encode.rs index f9e5ebf261c03..b6fdb07789c8d 100644 --- a/src/test/run-pass/auto-encode.rs +++ b/src/test/run-pass/auto-encode.rs @@ -85,13 +85,6 @@ impl cmp::Eq for Expr { pure fn ne(&self, other: &Expr) -> bool { !(*self).eq(other) } } -impl cmp::Eq for AnEnum { - pure fn eq(&self, other: &AnEnum) -> bool { - (*self).v == other.v - } - pure fn ne(&self, other: &AnEnum) -> bool { !(*self).eq(other) } -} - impl cmp::Eq for Point { pure fn eq(&self, other: &Point) -> bool { self.x == other.x && self.y == other.y @@ -139,10 +132,6 @@ struct Spanned { #[auto_decode] struct SomeStruct { v: ~[uint] } -#[auto_encode] -#[auto_decode] -enum AnEnum = SomeStruct; - #[auto_encode] #[auto_decode] struct Point {x: uint, y: uint} @@ -168,10 +157,6 @@ pub fn main() { test_prettyprint(a, &~"Spanned {lo: 0u, hi: 5u, node: 22u}"); test_ebml(a); - let a = &AnEnum(SomeStruct {v: ~[1u, 2u, 3u]}); - test_prettyprint(a, &~"AnEnum(SomeStruct {v: ~[1u, 2u, 3u]})"); - test_ebml(a); - let a = &Point {x: 3u, y: 5u}; test_prettyprint(a, &~"Point {x: 3u, y: 5u}"); test_ebml(a); diff --git a/src/test/run-pass/auto-ref-newtype.rs b/src/test/run-pass/auto-ref-newtype.rs index cdcf3c54c5838..9a84aa6a10e4a 100644 --- a/src/test/run-pass/auto-ref-newtype.rs +++ b/src/test/run-pass/auto-ref-newtype.rs @@ -11,7 +11,7 @@ // Check that we can define inherent methods on newtype enums that use // an auto-ref'd receiver. -enum Foo = uint; +struct Foo(uint); pub impl Foo { fn len(&self) -> uint { **self } diff --git a/src/test/run-pass/autoderef-method-newtype.rs b/src/test/run-pass/autoderef-method-newtype.rs index 9cd4093787db9..732c26694adb5 100644 --- a/src/test/run-pass/autoderef-method-newtype.rs +++ b/src/test/run-pass/autoderef-method-newtype.rs @@ -16,7 +16,7 @@ impl double for uint { fn double() -> uint { self * 2u } } -enum foo = uint; +struct foo(uint); pub fn main() { let x = foo(3u); diff --git a/src/test/run-pass/const-enum-newtype-align.rs b/src/test/run-pass/const-enum-newtype-align.rs deleted file mode 100644 index 5aa9aeafeed28..0000000000000 --- a/src/test/run-pass/const-enum-newtype-align.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -enum E = u32; -struct S { a: u8, b: E } -const C: S = S { a: 0xA5, b: E(0xDEADBEEF) }; - -pub fn main() { - fail_unless!(C.b == 0xDEADBEEF); -} diff --git a/src/test/run-pass/const-newtype-enum.rs b/src/test/run-pass/const-newtype-enum.rs deleted file mode 100644 index b96b0e957c990..0000000000000 --- a/src/test/run-pass/const-newtype-enum.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -enum Foo = u32; - -const X: Foo = Foo(17); - -pub fn main() { - fail_unless!((*X == 17)); - fail_unless!((*Y == 23)); -} - -const Y: Foo = Foo(23); diff --git a/src/test/run-pass/instantiable.rs b/src/test/run-pass/instantiable.rs index 2230c2df9fcef..c140a66ffe4d6 100644 --- a/src/test/run-pass/instantiable.rs +++ b/src/test/run-pass/instantiable.rs @@ -11,7 +11,7 @@ // check that we do not report a type like this as uninstantiable, // even though it would be if the nxt field had type @foo: -enum foo = X; +struct foo(X); struct X { x: uint, nxt: *foo } diff --git a/src/test/run-pass/issue-2312.rs b/src/test/run-pass/issue-2312.rs index 9e45a6b53c2b6..ad6320aed2bb7 100644 --- a/src/test/run-pass/issue-2312.rs +++ b/src/test/run-pass/issue-2312.rs @@ -12,7 +12,7 @@ trait clam { } -enum foo = int; +struct foo(int); pub impl foo { fn bar>(c: C) -> B { fail!(); } diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index d39f02a357418..1376f20571be6 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -225,8 +225,8 @@ pub mod pingpong { use core::cast; use core::ptr; - pub enum ping = ::pipes::send_packet; - pub enum pong = ::pipes::send_packet; + pub struct ping(::pipes::send_packet); + pub struct pong(::pipes::send_packet); pub fn liberate_ping(-p: ping) -> ::pipes::send_packet { unsafe { diff --git a/src/test/run-pass/let-destruct.rs b/src/test/run-pass/let-destruct.rs index eec3064cbbdf1..05e50e3e66047 100644 --- a/src/test/run-pass/let-destruct.rs +++ b/src/test/run-pass/let-destruct.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum xx = int; +struct xx(int); struct X { x: xx, y: int } diff --git a/src/test/run-pass/log-degen-enum.rs b/src/test/run-pass/log-degen-enum.rs deleted file mode 100644 index 79ad6e8a2506a..0000000000000 --- a/src/test/run-pass/log-degen-enum.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -enum Foo = uint; - -pub fn main() { - let x = Foo(1); - let y = fmt!("%?", x); - fail_unless!(y == ~"Foo(1)"); -} diff --git a/src/test/run-pass/newtype-polymorphic.rs b/src/test/run-pass/newtype-polymorphic.rs index d661fecc52659..18132d15d5787 100644 --- a/src/test/run-pass/newtype-polymorphic.rs +++ b/src/test/run-pass/newtype-polymorphic.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum myvec = ~[X]; +struct myvec(~[X]); fn myvec_deref(mv: myvec) -> ~[X] { return copy *mv; } diff --git a/src/test/run-pass/newtype.rs b/src/test/run-pass/newtype.rs index 41b16193ca1ef..6a82f70d9158a 100644 --- a/src/test/run-pass/newtype.rs +++ b/src/test/run-pass/newtype.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum mytype = Mytype; +struct mytype(Mytype); struct Mytype {compute: extern fn(mytype) -> int, val: int} diff --git a/src/test/run-pass/pipe-pingpong-bounded.rs b/src/test/run-pass/pipe-pingpong-bounded.rs index 2b270a54d80a0..f1686080f4661 100644 --- a/src/test/run-pass/pipe-pingpong-bounded.rs +++ b/src/test/run-pass/pipe-pingpong-bounded.rs @@ -43,8 +43,8 @@ mod pingpong { ptr::addr_of(&(data.ping)) } } - pub enum ping = server::pong; - pub enum pong = client::ping; + pub struct ping(server::pong); + pub struct pong(client::ping); pub mod client { use core::pipes; use core::pipes::*; diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index 90aaafd247ba6..0f3f4db3bbfe2 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -28,7 +28,7 @@ fn align(size: uint, align: uint) -> uint { ((size + align) - 1u) & !(align - 1u) } -enum ptr_visit_adaptor = Inner; +struct ptr_visit_adaptor(Inner); pub impl ptr_visit_adaptor { @@ -470,7 +470,7 @@ impl TyVisitor for ptr_visit_adaptor { } } -enum my_visitor = @mut Stuff; +struct my_visitor(@mut Stuff); struct Stuff { ptr1: *c_void, diff --git a/src/test/run-pass/reflect-visit-type.rs b/src/test/run-pass/reflect-visit-type.rs index 6efd40b1fd6e1..bc67ece79de50 100644 --- a/src/test/run-pass/reflect-visit-type.rs +++ b/src/test/run-pass/reflect-visit-type.rs @@ -10,7 +10,7 @@ // xfail-test use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor}; -enum my_visitor = @mut { types: ~[str] }; +struct my_visitor(@mut { types: ~[str] }); impl TyVisitor for my_visitor { fn visit_bot() -> bool { diff --git a/src/test/run-pass/regions-mock-trans.rs b/src/test/run-pass/regions-mock-trans.rs index 7a1b9ae563aa5..b249a4470cb9e 100644 --- a/src/test/run-pass/regions-mock-trans.rs +++ b/src/test/run-pass/regions-mock-trans.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -enum arena = (); +struct arena(()); struct Bcx { fcx: &'self Fcx<'self> diff --git a/src/test/run-pass/resource-cycle.rs b/src/test/run-pass/resource-cycle.rs index f5a959b2dbcab..058cb4ec77e48 100644 --- a/src/test/run-pass/resource-cycle.rs +++ b/src/test/run-pass/resource-cycle.rs @@ -34,7 +34,7 @@ fn r(v: *int) -> r { } } -enum t = Node; +struct t(Node); struct Node { next: Option<@mut t>, diff --git a/src/test/run-pass/resource-cycle2.rs b/src/test/run-pass/resource-cycle2.rs index cf5f36916a041..e3b03060893a2 100644 --- a/src/test/run-pass/resource-cycle2.rs +++ b/src/test/run-pass/resource-cycle2.rs @@ -34,7 +34,7 @@ fn r(v: U) -> r { } } -enum t = Node; +struct t(Node); struct Node { next: Option<@mut t>, diff --git a/src/test/run-pass/resource-cycle3.rs b/src/test/run-pass/resource-cycle3.rs index 4cd3df0f87f90..c76c1c6aeb910 100644 --- a/src/test/run-pass/resource-cycle3.rs +++ b/src/test/run-pass/resource-cycle3.rs @@ -43,7 +43,7 @@ fn r(v: U, w: int, _x: *int) -> R { } } -enum t = Node; +struct t(Node); struct Node { next: Option<@mut t>, diff --git a/src/test/run-pass/trait-cast.rs b/src/test/run-pass/trait-cast.rs index 677852a74d69e..4cee3c636c572 100644 --- a/src/test/run-pass/trait-cast.rs +++ b/src/test/run-pass/trait-cast.rs @@ -13,7 +13,7 @@ // Test cyclic detector when using trait instances. -enum Tree = @mut TreeR; +struct Tree(@mut TreeR); struct TreeR { left: Option, right: Option, From 4faf63e472f1cd8721be6c498e4db97760665e90 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 7 Mar 2013 17:23:14 -0800 Subject: [PATCH 23/43] libstd: Remove all newtype enums from std and core. --- src/libcore/task/spawn.rs | 2 +- src/librustdoc/extract.rs | 3 +-- src/libstd/arc.rs | 51 +++++++++++++++++++++++++++++---------- src/libstd/sync.rs | 3 ++- 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index 617149f7fd57d..a0db252544156 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -151,7 +151,7 @@ struct AncestorNode { mut ancestors: AncestorList, } -enum AncestorList = Option>; +struct AncestorList(Option>); // Accessors for taskgroup arcs and ancestor arcs that wrap the unsafety. #[inline(always)] diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs index fc784722b256e..5e5c843da26da 100644 --- a/src/librustdoc/extract.rs +++ b/src/librustdoc/extract.rs @@ -322,8 +322,7 @@ fn structdoc_from_struct( fields: do struct_def.fields.map |field| { match field.node.kind { ast::named_field(ident, _, _) => to_str(ident), - ast::unnamed_field => fail!( - ~"what is an unnamed struct field?") + ast::unnamed_field => ~"(unnamed)", } }, sig: None diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index 46e6980be581a..d7d878fa192dd 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -365,9 +365,11 @@ pub impl RWARC { let state = get_shared_mutable_state(&self.x); do (*borrow_rwlock(state)).write_downgrade |write_mode| { check_poison(false, (*state).failed); - blk(RWWriteMode((&mut (*state).data, - write_mode, - PoisonOnFail(&mut (*state).failed)))) + blk(RWWriteMode { + data: &mut (*state).data, + token: write_mode, + poison: PoisonOnFail(&mut (*state).failed) + }) } } } @@ -376,7 +378,11 @@ pub impl RWARC { fn downgrade(&self, token: RWWriteMode/&a) -> RWReadMode/&a { // The rwlock should assert that the token belongs to us for us. let state = unsafe { get_shared_immutable_state(&self.x) }; - let RWWriteMode((data, t, _poison)) = token; + let RWWriteMode { + data: data, + token: t, + poison: _poison + } = token; // Let readers in let new_token = (&state.lock).downgrade(t); // Whatever region the input reference had, it will be safe to use @@ -386,7 +392,10 @@ pub impl RWARC { // Downgrade ensured the token belonged to us. Just a sanity check. fail_unless!(ptr::ref_eq(&state.data, new_data)); // Produce new token - RWReadMode((new_data, new_token)) + RWReadMode { + data: new_data, + token: new_token, + } } } @@ -398,19 +407,28 @@ fn borrow_rwlock(state: *const RWARCInner) -> *RWlock { unsafe { cast::transmute(&const (*state).lock) } } -// FIXME (#3154) ice with struct/& prevents these from being structs. - /// The "write permission" token used for RWARC.write_downgrade(). -pub enum RWWriteMode = - (&self/mut T, sync::RWlockWriteMode/&self, PoisonOnFail); +pub struct RWWriteMode<'self, T> { + data: &'self mut T, + token: sync::RWlockWriteMode<'self>, + poison: PoisonOnFail, +} + /// The "read permission" token used for RWARC.write_downgrade(). -pub enum RWReadMode = (&self/T, sync::RWlockReadMode/&self); +pub struct RWReadMode<'self, T> { + data: &'self T, + token: sync::RWlockReadMode<'self>, +} pub impl RWWriteMode/&self { /// Access the pre-downgrade RWARC in write mode. fn write(&self, blk: &fn(x: &mut T) -> U) -> U { match *self { - RWWriteMode((ref data, ref token, _)) => { + RWWriteMode { + data: ref data, + token: ref token, + poison: _ + } => { do token.write { blk(&mut **data) } @@ -420,7 +438,11 @@ pub impl RWWriteMode/&self { /// Access the pre-downgrade RWARC in write mode with a condvar. fn write_cond(&self, blk: &fn(x: &x/mut T, c: &c/Condvar) -> U) -> U { match *self { - RWWriteMode((ref data, ref token, ref poison)) => { + RWWriteMode { + data: ref data, + token: ref token, + poison: ref poison + } => { do token.write_cond |cond| { unsafe { let cvar = Condvar { @@ -440,7 +462,10 @@ pub impl RWReadMode/&self { /// Access the post-downgrade rwlock in read mode. fn read(&self, blk: &fn(x: &T) -> U) -> U { match *self { - RWReadMode((data, ref token)) => { + RWReadMode { + data: data, + token: ref token + } => { do token.read { blk(data) } } } diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs index a68fe5f10a3c3..2190475d943b6 100644 --- a/src/libstd/sync.rs +++ b/src/libstd/sync.rs @@ -79,8 +79,9 @@ struct SemInner { // a condition variable attached, others should. blocked: Q } + #[doc(hidden)] -enum Sem = Exclusive>; +struct Sem(Exclusive>); #[doc(hidden)] fn new_sem(count: int, q: Q) -> Sem { From dc4869945c42b6df04487955e914319466975ae9 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 7 Mar 2013 17:55:16 -0800 Subject: [PATCH 24/43] librustc: Remove newtype enums from librustc --- src/librustc/middle/liveness.rs | 4 +- src/librustc/middle/ty.rs | 14 +++--- src/librustc/middle/typeck/infer/coercion.rs | 2 +- src/librustc/middle/typeck/infer/glb.rs | 2 +- src/librustc/middle/typeck/infer/lub.rs | 2 +- .../middle/typeck/infer/region_inference.rs | 49 ++++++++++--------- src/librustc/middle/typeck/infer/sub.rs | 2 +- src/librustc/middle/typeck/rscope.rs | 3 +- 8 files changed, 41 insertions(+), 37 deletions(-) diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 1bde1e85843fe..0c17b371694c4 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -137,8 +137,8 @@ use syntax::{visit, ast_util}; // if it detects an outstanding loan (that is, the addr is taken). pub type last_use_map = HashMap; -enum Variable = uint; -enum LiveNode = uint; +struct Variable(uint); +struct LiveNode(uint); impl cmp::Eq for Variable { pure fn eq(&self, other: &Variable) -> bool { *(*self) == *(*other) } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 5552364df239d..b4ef87491a8a3 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -582,18 +582,20 @@ pub enum param_bound { } #[deriving_eq] -pub enum TyVid = uint; +pub struct TyVid(uint); #[deriving_eq] -pub enum IntVid = uint; +pub struct IntVid(uint); #[deriving_eq] -pub enum FloatVid = uint; +pub struct FloatVid(uint); #[deriving_eq] #[auto_encode] #[auto_decode] -pub enum RegionVid = uint; +pub struct RegionVid { + id: uint +} #[deriving_eq] pub enum InferTy { @@ -687,11 +689,11 @@ impl ToStr for FloatVid { } impl Vid for RegionVid { - pure fn to_uint(&self) -> uint { **self } + pure fn to_uint(&self) -> uint { self.id } } impl ToStr for RegionVid { - pure fn to_str(&self) -> ~str { fmt!("%?", self) } + pure fn to_str(&self) -> ~str { fmt!("%?", self.id) } } impl ToStr for FnSig { diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs index 2390e73f16f9a..91c987acc6aa7 100644 --- a/src/librustc/middle/typeck/infer/coercion.rs +++ b/src/librustc/middle/typeck/infer/coercion.rs @@ -84,7 +84,7 @@ use syntax::ast; // Note: Coerce is not actually a combiner, in that it does not // conform to the same interface, though it performs a similar // function. -pub enum Coerce = CombineFields; +pub struct Coerce(CombineFields); pub impl Coerce { fn tys(&self, a: ty::t, b: ty::t) -> CoerceResult { diff --git a/src/librustc/middle/typeck/infer/glb.rs b/src/librustc/middle/typeck/infer/glb.rs index 49e5fe617627e..bba35f02b0c1e 100644 --- a/src/librustc/middle/typeck/infer/glb.rs +++ b/src/librustc/middle/typeck/infer/glb.rs @@ -29,7 +29,7 @@ use util::ppaux::mt_to_str; use std::list; -pub enum Glb = CombineFields; // "greatest lower bound" (common subtype) +pub struct Glb(CombineFields); // "greatest lower bound" (common subtype) impl Combine for Glb { fn infcx(&self) -> @mut InferCtxt { self.infcx } diff --git a/src/librustc/middle/typeck/infer/lub.rs b/src/librustc/middle/typeck/infer/lub.rs index 83cbd4c745c0c..3a12fb31a1a6f 100644 --- a/src/librustc/middle/typeck/infer/lub.rs +++ b/src/librustc/middle/typeck/infer/lub.rs @@ -29,7 +29,7 @@ use syntax::ast::{pure_fn, ret_style, return_val, unsafe_fn}; use syntax::ast::{Onceness, purity}; use syntax::codemap::span; -pub enum Lub = CombineFields; // least-upper-bound: common supertype +pub struct Lub(CombineFields); // least-upper-bound: common supertype pub impl Lub { fn bot_ty(&self, b: ty::t) -> cres { Ok(b) } diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index cceef9fc0c301..33e953b6218d9 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -700,7 +700,7 @@ pub impl RegionVarBindings { match undo_item { Snapshot => {} AddVar(vid) => { - fail_unless!(self.var_spans.len() == *vid + 1); + fail_unless!(self.var_spans.len() == vid.to_uint() + 1); self.var_spans.pop(); } AddConstraint(ref constraint) => { @@ -720,7 +720,7 @@ pub impl RegionVarBindings { fn new_region_var(&mut self, span: span) -> RegionVid { let id = self.num_vars(); self.var_spans.push(span); - let vid = RegionVid(id); + let vid = RegionVid { id: id }; if self.in_snapshot() { self.undo_log.push(AddVar(vid)); } @@ -863,15 +863,15 @@ pub impl RegionVarBindings { } fn resolve_var(&mut self, rid: RegionVid) -> ty::Region { - debug!("RegionVarBindings: resolve_var(%?=%u)", rid, *rid); + debug!("RegionVarBindings: resolve_var(%?=%u)", rid, rid.to_uint()); if self.values.is_empty() { self.tcx.sess.span_bug( - self.var_spans[*rid], + self.var_spans[rid.to_uint()], fmt!("Attempt to resolve region variable before values have \ been computed!")); } - let v = self.values.with_ref(|values| values[*rid]); + let v = self.values.with_ref(|values| values[rid.to_uint()]); match v { Value(r) => r, @@ -886,13 +886,13 @@ pub impl RegionVarBindings { // should ultimately have some bounds. self.tcx.sess.span_err( - self.var_spans[*rid], - fmt!("Unconstrained region variable #%u", *rid)); + self.var_spans[rid.to_uint()], + fmt!("Unconstrained region variable #%u", rid.to_uint())); // Touch of a hack: to suppress duplicate messages, // replace the NoValue entry with ErrorValue. let mut values = self.values.take(); - values[*rid] = ErrorValue; + values[rid.to_uint()] = ErrorValue; self.values.put_back(values); re_static } @@ -1049,7 +1049,7 @@ priv impl RegionVarBindings { (re_infer(ReVar(v_id)), _) | (_, re_infer(ReVar(v_id))) => { self.tcx.sess.span_bug( - self.var_spans[*v_id], + self.var_spans[v_id.to_uint()], fmt!("lub_concrete_regions invoked with \ non-concrete regions: %?, %?", a, b)); } @@ -1111,7 +1111,7 @@ priv impl RegionVarBindings { (re_infer(ReVar(v_id)), _) | (_, re_infer(ReVar(v_id))) => { self.tcx.sess.span_bug( - self.var_spans[*v_id], + self.var_spans[v_id.to_uint()], fmt!("glb_concrete_regions invoked with \ non-concrete regions: %?, %?", a, b)); } @@ -1275,8 +1275,8 @@ pub impl RegionVarBindings { edge_idx: uint) { let edge_dir = edge_dir as uint; graph.edges[edge_idx].next_edge[edge_dir] = - graph.nodes[*node_id].head_edge[edge_dir]; - graph.nodes[*node_id].head_edge[edge_dir] = + graph.nodes[node_id.to_uint()].head_edge[edge_dir]; + graph.nodes[node_id.to_uint()].head_edge[edge_dir] = edge_idx; } } @@ -1285,14 +1285,14 @@ pub impl RegionVarBindings { do iterate_until_fixed_point(~"Expansion", graph) |nodes, edge| { match edge.constraint { ConstrainRegSubVar(a_region, b_vid) => { - let b_node = &mut nodes[*b_vid]; + let b_node = &mut nodes[b_vid.to_uint()]; self.expand_node(a_region, b_vid, b_node) } ConstrainVarSubVar(a_vid, b_vid) => { - match nodes[*a_vid].value { + match nodes[a_vid.to_uint()].value { NoValue | ErrorValue => false, Value(a_region) => { - let b_node = &mut nodes[*b_vid]; + let b_node = &mut nodes[b_vid.to_uint()]; self.expand_node(a_region, b_vid, b_node) } } @@ -1349,16 +1349,16 @@ pub impl RegionVarBindings { false } ConstrainVarSubVar(a_vid, b_vid) => { - match nodes[*b_vid].value { + match nodes[b_vid.to_uint()].value { NoValue | ErrorValue => false, Value(b_region) => { - let a_node = &mut nodes[*a_vid]; + let a_node = &mut nodes[a_vid.to_uint()]; self.contract_node(a_vid, a_node, b_region) } } } ConstrainVarSubReg(a_vid, b_region) => { - let a_node = &mut nodes[*a_vid]; + let a_node = &mut nodes[a_vid.to_uint()]; self.contract_node(a_vid, a_node, b_region) } } @@ -1474,7 +1474,7 @@ pub impl RegionVarBindings { that is not used is not a problem, so if this rule starts to create problems we'll have to revisit this portion of the code and think hard about it. =) */ - let node_vid = RegionVid(idx); + let node_vid = RegionVid { id: idx }; match node.classification { Expanding => { self.report_error_for_expanding_node( @@ -1525,7 +1525,7 @@ pub impl RegionVarBindings { } self.tcx.sess.span_err( - self.var_spans[*node_idx], + self.var_spans[node_idx.to_uint()], fmt!("cannot infer an appropriate lifetime \ due to conflicting requirements")); @@ -1578,7 +1578,7 @@ pub impl RegionVarBindings { } self.tcx.sess.span_err( - self.var_spans[*node_idx], + self.var_spans[node_idx.to_uint()], fmt!("cannot infer an appropriate lifetime \ due to conflicting requirements")); @@ -1616,7 +1616,7 @@ pub impl RegionVarBindings { -> ~[SpannedRegion] { let set = HashMap(); let mut stack = ~[orig_node_idx]; - set.insert(*orig_node_idx, ()); + set.insert(orig_node_idx.to_uint(), ()); let mut result = ~[]; while !vec::is_empty(stack) { let node_idx = stack.pop(); @@ -1627,7 +1627,7 @@ pub impl RegionVarBindings { Incoming => from_vid, Outgoing => to_vid }; - if set.insert(*vid, ()) { + if set.insert(vid.to_uint(), ()) { stack.push(vid); } } @@ -1658,7 +1658,8 @@ pub impl RegionVarBindings { node_idx: RegionVid, dir: Direction, op: &fn(edge: &GraphEdge) -> bool) { - let mut edge_idx = graph.nodes[*node_idx].head_edge[dir as uint]; + let mut edge_idx = + graph.nodes[node_idx.to_uint()].head_edge[dir as uint]; while edge_idx != uint::max_value { let edge_ptr = &graph.edges[edge_idx]; if !op(edge_ptr) { diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index f209116696e10..b4d8905a93627 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -29,7 +29,7 @@ use syntax::ast::{Onceness, m_const, purity, ret_style}; use syntax::codemap::span; -pub enum Sub = CombineFields; // "subtype", "subregion" etc +pub struct Sub(CombineFields); // "subtype", "subregion" etc impl Combine for Sub { fn infcx(&self) -> @mut InferCtxt { self.infcx } diff --git a/src/librustc/middle/typeck/rscope.rs b/src/librustc/middle/typeck/rscope.rs index f0fc173101f2f..f74a0960f6674 100644 --- a/src/librustc/middle/typeck/rscope.rs +++ b/src/librustc/middle/typeck/rscope.rs @@ -74,7 +74,8 @@ impl region_scope for MethodRscope { } } -pub enum type_rscope = Option; +pub struct type_rscope(Option); + impl type_rscope { priv fn replacement(&self) -> ty::Region { if self.is_some() { From 7538450b8d5e831dca7891bdd54ebdf25d865970 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 7 Mar 2013 18:04:21 -0800 Subject: [PATCH 25/43] libsyntax: Remove newtype enums from libsyntax. rs=deenum --- src/libsyntax/ast.rs | 7 +------ src/libsyntax/codemap.rs | 4 ++-- src/libsyntax/ext/auto_encode.rs | 12 ------------ src/libsyntax/ext/pipes/pipec.rs | 4 +--- src/libsyntax/fold.rs | 21 ++++++++------------- src/libsyntax/parse/parser.rs | 6 ++---- 6 files changed, 14 insertions(+), 40 deletions(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index f3e73823f69b3..27dba9c2b5ebc 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1086,16 +1086,11 @@ pub enum variant_kind { #[auto_encode] #[auto_decode] #[deriving_eq] -pub struct enum_def_ { +pub struct enum_def { variants: ~[variant], common: Option<@struct_def>, } -#[auto_encode] -#[auto_decode] -#[deriving_eq] -pub enum enum_def = enum_def_; - #[auto_encode] #[auto_decode] #[deriving_eq] diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 3397ca91c9624..0d6ece8ad92f1 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -35,11 +35,11 @@ pub trait Pos { } /// A byte offset -pub enum BytePos = uint; +pub struct BytePos(uint); /// A character offset. Because of multibyte utf8 characters, a byte offset /// is not equivalent to a character offset. The CodeMap will convert BytePos /// values to CharPos values as necessary. -pub enum CharPos = uint; +pub struct CharPos(uint); // XXX: Lots of boilerplate in these impls, but so far my attempts to fix // have been unsuccessful diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index 8aa03e14fa47f..c99d89776431a 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -1327,16 +1327,4 @@ mod test { CallToEmitEnumVariantArg (1), CallToEmitUint (44)]); } - - pub enum BPos = uint; - - #[auto_encode] - pub struct HasPos { pos : BPos } - - #[test] fn encode_newtype_test () { - check_equal (to_call_log (HasPos {pos:BPos(48)}), - ~[CallToEmitStruct(~"HasPos",1), - CallToEmitField(~"pos",0), - CallToEmitUint(48)]); - } } diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 001e1b0daf63f..fd8b2dbf72f81 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -238,9 +238,7 @@ impl to_type_decls for state { cx.item_enum_poly( name, self.span, - ast::enum_def(enum_def_ { - variants: items_msg, - common: None }), + ast::enum_def { variants: items_msg, common: None }, cx.strip_bounds(&self.generics) ) ] diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 2a5fe7887704d..427760c920f6d 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -254,16 +254,14 @@ pub fn noop_fold_item_underscore(i: &item_, fld: @ast_fold) -> item_ { } item_enum(ref enum_definition, ref generics) => { item_enum( - ast::enum_def( - ast::enum_def_ { - variants: do enum_definition.variants.map |x| { - fld.fold_variant(x) - }, - common: do enum_definition.common.map |x| { - fold_struct_def(*x, fld) - } + ast::enum_def { + variants: do enum_definition.variants.map |x| { + fld.fold_variant(x) + }, + common: do enum_definition.common.map |x| { + fold_struct_def(*x, fld) } - ), + }, fold_generics(generics, fld)) } item_struct(ref struct_def, ref generics) => { @@ -684,10 +682,7 @@ fn noop_fold_variant(v: &variant_, fld: @ast_fold) -> variant_ { fold_struct_def(*x, fld) }; kind = enum_variant_kind( - ast::enum_def(ast::enum_def_ { - variants: variants, - common: common - }) + ast::enum_def { variants: variants, common: common } ); } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1c3d906e1648a..b2f11b8c437ad 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3775,7 +3775,7 @@ pub impl Parser { enum"); } - enum_def(ast::enum_def_ { variants: variants, common: common_fields }) + ast::enum_def { variants: variants, common: common_fields } } fn parse_item_enum(&self) -> item_info { @@ -3801,9 +3801,7 @@ pub impl Parser { return ( id, item_enum( - enum_def( - ast::enum_def_ { variants: ~[variant], common: None } - ), + ast::enum_def { variants: ~[variant], common: None }, generics), None ); From 1fcb0443cf2a5575691b70e7ef80e9720bc4bc07 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 7 Mar 2013 18:15:07 -0800 Subject: [PATCH 26/43] doc: Remove documentation on newtype enums. --- doc/tutorial.md | 80 ++++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 44 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 79553d5aa6ed0..23ab1ce4400c2 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -681,45 +681,6 @@ the value of `North` is 0, `East` is 1, `South` is 2, and `West` is 3. When an enum is C-like, you can apply the `as` cast operator to convert it to its discriminator value as an `int`. - - -There is a special case for enums with a single variant, which are -sometimes called "newtype-style enums" (after Haskell's "newtype" -feature). These are used to define new types in such a way that the -new name is not just a synonym for an existing type, but its own -distinct type: `type` creates a structural synonym, while this form of -`enum` creates a nominal synonym. If you say: - -~~~~ -enum GizmoId = int; -~~~~ - -That is a shorthand for this: - -~~~~ -enum GizmoId { GizmoId(int) } -~~~~ - -You can extract the contents of such an enum type with the -dereference (`*`) unary operator: - -~~~~ -# enum GizmoId = int; -let my_gizmo_id: GizmoId = GizmoId(10); -let id_int: int = *my_gizmo_id; -~~~~ - -Types like this can be useful to differentiate between data that have -the same type but must be used in different ways. - -~~~~ -enum Inches = int; -enum Centimeters = int; -~~~~ - -The above definitions allow for a simple way for programs to avoid -confusing numbers that correspond to different units. - For enum types with multiple variants, destructuring is the only way to get at their contents. All variant constructors can be used as patterns, as in this definition of `area`: @@ -789,10 +750,10 @@ match mytup { ## Tuple structs -Rust also has _nominal tuples_, which behave like both structs and tuples, -except that nominal tuple types have names -(so `Foo(1, 2)` has a different type from `Bar(1, 2)`), -and nominal tuple types' _fields_ do not have names. +Rust also has _tuple structs_, which behave like both structs and tuples, +except that, unlike tuples, tuple structs have names (so `Foo(1, 2)` has a +different type from `Bar(1, 2)`), and tuple structs' _fields_ do not have +names. For example: ~~~~ @@ -803,6 +764,37 @@ match mytup { } ~~~~ + + +There is a special case for tuple structs with a single field, which are +sometimes called "newtypes" (after Haskell's "newtype" feature). These are +used to define new types in such a way that the new name is not just a +synonym for an existing type but is rather its own distinct type. + +~~~~ +struct GizmoId(int); +~~~~ + +For convenience, you can extract the contents of such a struct with the +dereference (`*`) unary operator: + +~~~~ +# struct GizmoId(int); +let my_gizmo_id: GizmoId = GizmoId(10); +let id_int: int = *my_gizmo_id; +~~~~ + +Types like this can be useful to differentiate between data that have +the same type but must be used in different ways. + +~~~~ +struct Inches(int); +struct Centimeters(int); +~~~~ + +The above definitions allow for a simple way for programs to avoid +confusing numbers that correspond to different units. + # Functions We've already seen several function definitions. Like all other static @@ -2294,7 +2286,7 @@ struct level. Note that fields and methods are _public_ by default. pub mod farm { # pub type Chicken = int; # type Cow = int; -# enum Human = int; +# struct Human(int); # impl Human { fn rest(&self) { } } # pub fn make_me_a_farm() -> Farm { Farm { chickens: ~[], cows: ~[], farmer: Human(0) } } pub struct Farm { From a34749c28908997f8c58a646c9238c3dd8ea1103 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 7 Mar 2013 18:59:00 -0800 Subject: [PATCH 27/43] libsyntax: Stop parsing newtype enums --- src/libsyntax/parse/obsolete.rs | 5 +++++ src/libsyntax/parse/parser.rs | 14 ++++---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 757df713fc053..ef858a2d5ebd1 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -54,6 +54,7 @@ pub enum ObsoleteSyntax { ObsoleteAssertion, ObsoletePostFnTySigil, ObsoleteBareFnType, + ObsoleteNewtypeEnum, } impl to_bytes::IterBytes for ObsoleteSyntax { @@ -171,6 +172,10 @@ pub impl Parser { "bare function type", "use `&fn` or `extern fn` instead" ), + ObsoleteNewtypeEnum => ( + "newtype enum", + "instead of `enum Foo = int`, write `struct Foo(int)`" + ), }; self.report(sp, kind, kind_str, desc); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b2f11b8c437ad..99c1c2cb1feec 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -76,11 +76,8 @@ use parse::obsolete::{ObsoleteUnsafeBlock, ObsoleteImplSyntax}; use parse::obsolete::{ObsoleteTraitBoundSeparator, ObsoleteMutOwnedPointer}; use parse::obsolete::{ObsoleteMutVector, ObsoleteTraitImplVisibility}; use parse::obsolete::{ObsoleteRecordType, ObsoleteRecordPattern}; -<<<<<<< HEAD use parse::obsolete::{ObsoleteAssertion, ObsoletePostFnTySigil}; -======= -use parse::obsolete::{ObsoleteAssertion, ObsoleteBareFnType}; ->>>>>>> libsyntax: Stop parsing bare functions in preparation for switching them over +use parse::obsolete::{ObsoleteBareFnType, ObsoleteNewtypeEnum}; use parse::prec::{as_prec, token_to_binop}; use parse::token::{can_begin_expr, is_ident, is_ident_or_path}; use parse::token::{is_plain_ident, INTERPOLATED, special_idents}; @@ -651,14 +648,9 @@ pub impl Parser { } else if self.eat_keyword(&~"extern") { self.parse_ty_bare_fn() } else if self.token_is_closure_keyword(© *self.token) { -<<<<<<< HEAD - // self.warn(fmt!("Old-school closure keyword")); - self.parse_ty_closure(ast::BorrowedSigil, None) -======= - let result = self.parse_ty_closure(None, None); + let result = self.parse_ty_closure(ast::BorrowedSigil, None); self.obsolete(*self.last_span, ObsoleteBareFnType); result ->>>>>>> libsyntax: Stop parsing bare functions in preparation for switching them over } else if *self.token == token::MOD_SEP || is_ident_or_path(&*self.token) { let path = self.parse_path_with_tps(colons_before_params); @@ -3798,6 +3790,8 @@ pub impl Parser { vis: public, }); + self.obsolete(*self.last_span, ObsoleteNewtypeEnum); + return ( id, item_enum( From 1274d4a0063fbb0ae5feaa277caf08c3230b46a9 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 8 Mar 2013 12:10:48 -0800 Subject: [PATCH 28/43] test: Fix tests. rs=tests --- src/libcore/dlist.rs | 2 +- src/test/auxiliary/issue_2472_b.rs | 4 +- src/test/compile-fail/block-coerce-no-2.rs | 2 +- .../compile-fail/borrowck-assign-to-enum.rs | 2 +- .../compile-fail/borrowck-unary-move-2.rs | 2 +- src/test/compile-fail/issue-2063.rs | 2 +- src/test/compile-fail/regions-fn-subtyping.rs | 48 +++++++++---------- src/test/run-pass/issue-1458.rs | 2 +- 8 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/libcore/dlist.rs b/src/libcore/dlist.rs index fd3ba2e6f451f..1b5d03d9eb8cd 100644 --- a/src/libcore/dlist.rs +++ b/src/libcore/dlist.rs @@ -507,7 +507,7 @@ impl BaseIter for @mut DList { * allow for e.g. breadth-first search with in-place enqueues), but * removing the current node is forbidden. */ - pure fn each(&self, f: fn(v: &T) -> bool) { + pure fn each(&self, f: &fn(v: &T) -> bool) { let mut link = self.peek_n(); while option::is_some(&link) { let nobe = option::get(link); diff --git a/src/test/auxiliary/issue_2472_b.rs b/src/test/auxiliary/issue_2472_b.rs index fd3355d83faab..1dd30edcc980b 100644 --- a/src/test/auxiliary/issue_2472_b.rs +++ b/src/test/auxiliary/issue_2472_b.rs @@ -9,13 +9,13 @@ // except according to those terms. -struct S(()) +pub struct S(()); pub impl S { fn foo() { } } -trait T { +pub trait T { fn bar(); } diff --git a/src/test/compile-fail/block-coerce-no-2.rs b/src/test/compile-fail/block-coerce-no-2.rs index b2265f5e959a0..95ff995258fad 100644 --- a/src/test/compile-fail/block-coerce-no-2.rs +++ b/src/test/compile-fail/block-coerce-no-2.rs @@ -15,7 +15,7 @@ fn main() { fn f(f: extern fn(extern fn(extern fn()))) { } - fn g(f: extern fn(fn())) { + fn g(f: extern fn(&fn())) { } f(g); diff --git a/src/test/compile-fail/borrowck-assign-to-enum.rs b/src/test/compile-fail/borrowck-assign-to-enum.rs index ee38ceda3d80b..a35d88a76f393 100644 --- a/src/test/compile-fail/borrowck-assign-to-enum.rs +++ b/src/test/compile-fail/borrowck-assign-to-enum.rs @@ -12,5 +12,5 @@ struct foo(int); fn main() { let x = foo(3); - *x = 4; //~ ERROR assigning to enum content + *x = 4; //~ ERROR assigning to anonymous field } diff --git a/src/test/compile-fail/borrowck-unary-move-2.rs b/src/test/compile-fail/borrowck-unary-move-2.rs index 05dab4f8c68fb..520772f1ceea9 100644 --- a/src/test/compile-fail/borrowck-unary-move-2.rs +++ b/src/test/compile-fail/borrowck-unary-move-2.rs @@ -28,5 +28,5 @@ struct wrapper(noncopyable); fn main() { let x1 = wrapper(noncopyable()); - let _x2 = *x1; //~ ERROR moving out of enum content + let _x2 = *x1; //~ ERROR moving out of anonymous field } diff --git a/src/test/compile-fail/issue-2063.rs b/src/test/compile-fail/issue-2063.rs index 515db2b431cf1..2f174671bd985 100644 --- a/src/test/compile-fail/issue-2063.rs +++ b/src/test/compile-fail/issue-2063.rs @@ -11,7 +11,7 @@ // test that autoderef of a type like this does not // cause compiler to loop. Note that no instances // of such a type could ever be constructed. -enum t(@t); //~ ERROR this type cannot be instantiated +struct t(@t); //~ ERROR this type cannot be instantiated trait to_str_2 { fn to_str() -> ~str; diff --git a/src/test/compile-fail/regions-fn-subtyping.rs b/src/test/compile-fail/regions-fn-subtyping.rs index 526a5de7fefe2..50674ac81fecf 100644 --- a/src/test/compile-fail/regions-fn-subtyping.rs +++ b/src/test/compile-fail/regions-fn-subtyping.rs @@ -17,41 +17,41 @@ fn test_fn(_x: &x/T, _y: &y/T, _z: &z/T) { // subtype::(of::()) will typecheck // iff T1 <: T2. - subtype::( - of::()); + subtype::<&fn(&a/T)>( + of::<&fn(&a/T)>()); - subtype::( - of::()); + subtype::<&fn(&a/T)>( + of::<&fn(&b/T)>()); - subtype::( - of::()); + subtype::<&fn(&b/T)>( + of::<&fn(&x/T)>()); - subtype::( - of::()); //~ ERROR mismatched types + subtype::<&fn(&x/T)>( + of::<&fn(&b/T)>()); //~ ERROR mismatched types - subtype::( - of::()); + subtype::<&fn(&a/T, &b/T)>( + of::<&fn(&a/T, &a/T)>()); - subtype::( - of::()); //~ ERROR mismatched types + subtype::<&fn(&a/T, &a/T)>( + of::<&fn(&a/T, &b/T)>()); //~ ERROR mismatched types - subtype::( - of::()); + subtype::<&fn(&a/T, &b/T)>( + of::<&fn(&x/T, &y/T)>()); - subtype::( - of::()); //~ ERROR mismatched types + subtype::<&fn(&x/T, &y/T)>( + of::<&fn(&a/T, &b/T)>()); //~ ERROR mismatched types - subtype:: @fn(&a/T)>( - of:: @fn(&a/T)>()); + subtype::<&fn(&x/T) -> @fn(&a/T)>( + of::<&fn(&x/T) -> @fn(&a/T)>()); - subtype:: @fn(&a/T)>( - of:: @fn(&b/T)>()); //~ ERROR mismatched types + subtype::<&fn(&a/T) -> @fn(&a/T)>( + of::<&fn(&a/T) -> @fn(&b/T)>()); //~ ERROR mismatched types - subtype:: @fn(&a/T)>( - of:: @fn(&b/T)>()); //~ ERROR mismatched types + subtype::<&fn(&a/T) -> @fn(&a/T)>( + of::<&fn(&x/T) -> @fn(&b/T)>()); //~ ERROR mismatched types - subtype:: @fn(&b/T)>( - of:: @fn(&a/T)>()); + subtype::<&fn(&a/T) -> @fn(&b/T)>( + of::<&fn(&a/T) -> @fn(&a/T)>()); } fn main() {} diff --git a/src/test/run-pass/issue-1458.rs b/src/test/run-pass/issue-1458.rs index 76ec34330d4b8..a6556895dda33 100644 --- a/src/test/run-pass/issue-1458.rs +++ b/src/test/run-pass/issue-1458.rs @@ -12,7 +12,7 @@ fn plus_one(f: &fn() -> int) -> int { return f() + 1; } -fn ret_plus_one() -> extern fn(fn() -> int) -> int { +fn ret_plus_one() -> extern fn(&fn() -> int) -> int { return plus_one; } From 7353568cd8d079fd4d9f928bc49a228276e86d19 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 8 Mar 2013 16:13:01 -0800 Subject: [PATCH 29/43] librustc: Remove old-style operator overloading --- src/librustc/middle/typeck/check/method.rs | 27 +++++++++++++++------- src/librustc/middle/typeck/check/mod.rs | 21 ++++++++++++----- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 3395d9b445146..d6060c1ae316d 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -105,17 +105,24 @@ use syntax::ast::{m_const, m_mutbl, m_imm}; use syntax::ast; use syntax::ast_map; +#[deriving_eq] +pub enum CheckTraitsFlag { + CheckTraitsOnly, + CheckTraitsAndInherentMethods, +} + pub fn lookup( fcx: @mut FnCtxt, // In a call `a.b::(...)`: - expr: @ast::expr, // The expression `a.b`. - self_expr: @ast::expr, // The expression `a`. - callee_id: node_id, // Where to store the type of `a.b` - m_name: ast::ident, // The ident `b`. - self_ty: ty::t, // The type of `a`. - supplied_tps: &[ty::t], // The list of types X, Y, ... . - deref_args: check::DerefArgs) // Whether we autopointer first. + expr: @ast::expr, // The expression `a.b`. + self_expr: @ast::expr, // The expression `a`. + callee_id: node_id, // Where to store the type of `a.b` + m_name: ast::ident, // The ident `b`. + self_ty: ty::t, // The type of `a`. + supplied_tps: &[ty::t], // The list of types X, Y, ... . + deref_args: check::DerefArgs, // Whether we autopointer first. + check_traits: CheckTraitsFlag) // Whether we check traits only. -> Option { let lcx = LookupContext { @@ -129,6 +136,7 @@ pub fn lookup( inherent_candidates: @mut ~[], extension_candidates: @mut ~[], deref_args: deref_args, + check_traits: check_traits, }; let mme = lcx.do_lookup(self_ty); debug!("method lookup for %s yielded %?", @@ -147,6 +155,7 @@ pub struct LookupContext { inherent_candidates: @mut ~[Candidate], extension_candidates: @mut ~[Candidate], deref_args: check::DerefArgs, + check_traits: CheckTraitsFlag, } /** @@ -299,7 +308,9 @@ pub impl LookupContext/&self { self_ty, self_did, &substs); } ty_enum(did, _) | ty_struct(did, _) => { - self.push_inherent_impl_candidates_for_type(did); + if self.check_traits == CheckTraitsAndInherentMethods { + self.push_inherent_impl_candidates_for_type(did); + } } _ => { /* No inherent methods in these types */ } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index f3804934186d4..6617fa3b27c91 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -89,7 +89,8 @@ use middle::typeck::astconv::{AstConv, ast_path_to_ty}; use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty}; use middle::typeck::astconv; use middle::typeck::check::_match::pat_ctxt; -use middle::typeck::check::method::TransformTypeNormally; +use middle::typeck::check::method::{CheckTraitsAndInherentMethods}; +use middle::typeck::check::method::{CheckTraitsOnly, TransformTypeNormally}; use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig; use middle::typeck::check::vtable::{LocationInfo, VtableContext}; use middle::typeck::CrateCtxt; @@ -1371,7 +1372,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, method_name, expr_t, tps, - DontDerefArgs) { + DontDerefArgs, + CheckTraitsAndInherentMethods) { Some(ref entry) => { let method_map = fcx.ccx.method_map; method_map.insert(expr.id, (*entry)); @@ -1453,9 +1455,15 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, +args: ~[@ast::expr], +deref_args: DerefArgs) -> Option<(ty::t, bool)> { - match method::lookup(fcx, op_ex, self_ex, - op_ex.callee_id, opname, self_t, ~[], - deref_args) { + match method::lookup(fcx, + op_ex, + self_ex, + op_ex.callee_id, + opname, + self_t, + ~[], + deref_args, + CheckTraitsOnly) { Some(ref origin) => { let method_ty = fcx.node_ty(op_ex.callee_id); let method_map = fcx.ccx.method_map; @@ -1732,7 +1740,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, field, expr_t, tps, - DontDerefArgs) { + DontDerefArgs, + CheckTraitsAndInherentMethods) { Some(ref entry) => { let method_map = fcx.ccx.method_map; method_map.insert(expr.id, (*entry)); From 08c840205ea477d4f76216abac45be6a4ce9fa4b Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 8 Mar 2013 16:21:58 -0800 Subject: [PATCH 30/43] librustc: Lint the old `drop` destructor notation off --- doc/rust.md | 12 ++++---- doc/tutorial.md | 18 ++++++------ src/libcore/core.rc | 1 + src/librustc/middle/lint.rs | 29 +++++++++++++++++++ src/libsyntax/print/pprust.rs | 29 ++----------------- src/test/compile-fail/issue-2063.rs | 2 ++ src/test/compile-fail/issue-2718-a.rs | 2 ++ src/test/run-pass/coherence-copy-bound.rs | 13 --------- .../operator-overloading-explicit-self.rs | 26 ----------------- 9 files changed, 51 insertions(+), 81 deletions(-) delete mode 100644 src/test/run-pass/coherence-copy-bound.rs delete mode 100644 src/test/run-pass/operator-overloading-explicit-self.rs diff --git a/doc/rust.md b/doc/rust.md index 8924ee6f4f60c..e559af62e360c 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -889,10 +889,10 @@ declared, in an angle-bracket-enclosed, comma-separated list following the function name. ~~~~ {.xfail-test} -fn iter(seq: &[T], f: fn(T)) { +fn iter(seq: &[T], f: &fn(T)) { for seq.each |elt| { f(elt); } } -fn map(seq: &[T], f: fn(T) -> U) -> ~[U] { +fn map(seq: &[T], f: &fn(T) -> U) -> ~[U] { let mut acc = ~[]; for seq.each |elt| { acc.push(f(elt)); } acc @@ -1198,7 +1198,7 @@ These appear after the trait name, using the same syntax used in [generic functi trait Seq { fn len() -> uint; fn elt_at(n: uint) -> T; - fn iter(fn(T)); + fn iter(&fn(T)); } ~~~~ @@ -2074,7 +2074,7 @@ and moving values from the environment into the lambda expression's captured env An example of a lambda expression: ~~~~ -fn ten_times(f: fn(int)) { +fn ten_times(f: &fn(int)) { let mut i = 0; while i < 10 { f(i); @@ -2177,7 +2177,7 @@ If the `expr` is a [field expression](#field-expressions), it is parsed as thoug In this example, both calls to `f` are equivalent: ~~~~ -# fn f(f: fn(int)) { } +# fn f(f: &fn(int)) { } # fn g(i: int) { } f(|j| g(j)); @@ -2755,7 +2755,7 @@ and the cast expression in `main`. Within the body of an item that has type parameter declarations, the names of its type parameters are types: ~~~~~~~ -fn map(f: fn(A) -> B, xs: &[A]) -> ~[B] { +fn map(f: &fn(A) -> B, xs: &[A]) -> ~[B] { if xs.len() == 0 { return ~[]; } let first: B = f(xs[0]); let rest: ~[B] = map(f, xs.slice(1, xs.len())); diff --git a/doc/tutorial.md b/doc/tutorial.md index 23ab1ce4400c2..e4775e1b11b4d 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1361,7 +1361,7 @@ the enclosing scope. ~~~~ # use println = core::io::println; -fn call_closure_with_ten(b: fn(int)) { b(10); } +fn call_closure_with_ten(b: &fn(int)) { b(10); } let captured_var = 20; let closure = |arg| println(fmt!("captured_var=%d, arg=%d", captured_var, arg)); @@ -1447,7 +1447,7 @@ should almost always declare the type of that argument as `fn()`. That way, callers may pass any kind of closure. ~~~~ -fn call_twice(f: fn()) { f(); f(); } +fn call_twice(f: &fn()) { f(); f(); } let closure = || { "I'm a closure, and it doesn't matter what type I am"; }; fn function() { "I'm a normal function"; } call_twice(closure); @@ -1467,7 +1467,7 @@ Consider this function that iterates over a vector of integers, passing in a pointer to each integer in the vector: ~~~~ -fn each(v: &[int], op: fn(v: &int)) { +fn each(v: &[int], op: &fn(v: &int)) { let mut n = 0; while n < v.len() { op(&v[n]); @@ -1488,7 +1488,7 @@ argument, we can write it in a way that has a pleasant, block-like structure. ~~~~ -# fn each(v: &[int], op: fn(v: &int)) { } +# fn each(v: &[int], op: &fn(v: &int)) { } # fn do_some_work(i: &int) { } each([1, 2, 3], |n| { do_some_work(n); @@ -1499,7 +1499,7 @@ This is such a useful pattern that Rust has a special form of function call that can be written more like a built-in control structure: ~~~~ -# fn each(v: &[int], op: fn(v: &int)) { } +# fn each(v: &[int], op: &fn(v: &int)) { } # fn do_some_work(i: &int) { } do each([1, 2, 3]) |n| { do_some_work(n); @@ -1546,7 +1546,7 @@ Consider again our `each` function, this time improved to break early when the iteratee returns `false`: ~~~~ -fn each(v: &[int], op: fn(v: &int) -> bool) { +fn each(v: &[int], op: &fn(v: &int) -> bool) { let mut n = 0; while n < v.len() { if !op(&v[n]) { @@ -1770,7 +1770,7 @@ vector consisting of the result of applying `function` to each element of `vector`: ~~~~ -fn map(vector: &[T], function: fn(v: &T) -> U) -> ~[U] { +fn map(vector: &[T], function: &fn(v: &T) -> U) -> ~[U] { let mut accumulator = ~[]; for vec::each(vector) |element| { accumulator.push(function(element)); @@ -1969,12 +1969,12 @@ types might look like the following: ~~~~ trait Seq { fn len(&self) -> uint; - fn iter(&self, b: fn(v: &T)); + fn iter(&self, b: &fn(v: &T)); } impl Seq for ~[T] { fn len(&self) -> uint { vec::len(*self) } - fn iter(&self, b: fn(v: &T)) { + fn iter(&self, b: &fn(v: &T)) { for vec::each(*self) |elt| { b(elt); } } } diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 4d686c8ab33a1..db1dc1e28aa92 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -52,6 +52,7 @@ Implicitly, all crates behave as if they included the following prologue: #[deny(non_camel_case_types)]; #[allow(deprecated_mutable_fields)]; #[deny(deprecated_self)]; +#[allow(deprecated_drop)]; // On Linux, link to the runtime with -lrt. #[cfg(target_os = "linux")] diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 5ff731a27f030..93f0557028eae 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -77,6 +77,7 @@ pub enum lint { default_methods, deprecated_self, deprecated_mutable_fields, + deprecated_drop, managed_heap_memory, owned_heap_memory, @@ -251,6 +252,13 @@ pub fn get_lint_dict() -> LintDict { default: deny }), + (@~"deprecated_drop", + @LintSpec { + lint: deprecated_drop, + desc: "deprecated \"drop\" notation for the destructor", + default: deny + }), + /* FIXME(#3266)--make liveness warnings lintable (@~"unused_variable", @LintSpec { @@ -483,6 +491,7 @@ fn check_item(i: @ast::item, cx: ty::ctxt) { check_item_default_methods(cx, i); check_item_deprecated_self(cx, i); check_item_deprecated_mutable_fields(cx, i); + check_item_deprecated_drop(cx, i); } // Take a visitor, and modify it so that it will not proceed past subitems. @@ -720,6 +729,26 @@ fn check_item_deprecated_mutable_fields(cx: ty::ctxt, item: @ast::item) { } } +fn check_item_deprecated_drop(cx: ty::ctxt, item: @ast::item) { + match item.node { + ast::item_struct(struct_def, _) => { + match struct_def.dtor { + None => {} + Some(ref dtor) => { + cx.sess.span_lint(deprecated_drop, + item.id, + item.id, + dtor.span, + ~"`drop` notation for destructors is \ + deprecated; implement the `Drop` \ + trait instead"); + } + } + } + _ => {} + } +} + fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) { fn check_foreign_fn(cx: ty::ctxt, fn_id: ast::node_id, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index e7e2435587ef1..49899fdeec415 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -612,36 +612,11 @@ pub fn print_item(s: @ps, &&item: @ast::item) { pub fn print_enum_def(s: @ps, enum_definition: ast::enum_def, generics: &ast::Generics, ident: ast::ident, span: codemap::span, visibility: ast::visibility) { - let mut newtype = - vec::len(enum_definition.variants) == 1u && - ident == enum_definition.variants[0].node.name; - if newtype { - match enum_definition.variants[0].node.kind { - ast::tuple_variant_kind(ref args) if args.len() == 1 => {} - _ => newtype = false - } - } - if newtype { - ibox(s, indent_unit); - word_space(s, visibility_qualified(visibility, ~"enum")); - } else { - head(s, visibility_qualified(visibility, ~"enum")); - } - + head(s, visibility_qualified(visibility, ~"enum")); print_ident(s, ident); print_generics(s, generics); space(s.s); - if newtype { - word_space(s, ~"="); - match /*bad*/ copy enum_definition.variants[0].node.kind { - ast::tuple_variant_kind(args) => print_type(s, args[0].ty), - _ => fail!(~"newtype syntax with struct?") - } - word(s.s, ~";"); - end(s); - } else { - print_variants(s, enum_definition.variants, span); - } + print_variants(s, enum_definition.variants, span); } pub fn print_variants(s: @ps, diff --git a/src/test/compile-fail/issue-2063.rs b/src/test/compile-fail/issue-2063.rs index 2f174671bd985..0ebf0218efe6d 100644 --- a/src/test/compile-fail/issue-2063.rs +++ b/src/test/compile-fail/issue-2063.rs @@ -1,3 +1,5 @@ +// xfail-test + // Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. diff --git a/src/test/compile-fail/issue-2718-a.rs b/src/test/compile-fail/issue-2718-a.rs index 318982c3b1360..8afaf8995c291 100644 --- a/src/test/compile-fail/issue-2718-a.rs +++ b/src/test/compile-fail/issue-2718-a.rs @@ -1,3 +1,5 @@ +// xfail-test + // Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. diff --git a/src/test/run-pass/coherence-copy-bound.rs b/src/test/run-pass/coherence-copy-bound.rs deleted file mode 100644 index 9921389da6674..0000000000000 --- a/src/test/run-pass/coherence-copy-bound.rs +++ /dev/null @@ -1,13 +0,0 @@ -trait X {} - -impl X for A {} - -struct S { - x: int, - drop {} -} - -impl X for S {} - -pub fn main(){} - diff --git a/src/test/run-pass/operator-overloading-explicit-self.rs b/src/test/run-pass/operator-overloading-explicit-self.rs deleted file mode 100644 index 3d2fd649f1562..0000000000000 --- a/src/test/run-pass/operator-overloading-explicit-self.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -struct S { - x: int -} - -pub impl S { - pure fn add(&self, other: &S) -> S { - S { x: self.x + other.x } - } -} - -pub fn main() { - let mut s = S { x: 1 }; - s += S { x: 2 }; - fail_unless!(s.x == 3); -} - From 86cf2482624b89150615313662d2e823cdcaa31d Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Mon, 11 Mar 2013 15:21:00 -0400 Subject: [PATCH 31/43] Add deriving_eq to Cell. --- src/libcore/cell.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 91a4ded60efd6..da247c648fc8c 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -15,6 +15,7 @@ use prelude::*; /// /// Similar to a mutable option type, but friendlier. +#[deriving_eq] pub struct Cell { mut value: Option } From c88ce30c485b8df5f6dfa55d216c19c10cafe5dd Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 9 Mar 2013 19:14:35 -0800 Subject: [PATCH 32/43] core: Add vec::raw::mut_buf_as_slice --- src/libcore/vec.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index aed98f3573e71..697bfe63b189b 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -2145,6 +2145,20 @@ pub mod raw { f(*v) } + /** + * Form a slice from a pointer and length (as a number of units, + * not bytes). + */ + #[inline(always)] + pub unsafe fn mut_buf_as_slice(p: *mut T, + len: uint, + f: &fn(v: &mut [T]) -> U) -> U { + let pair = (p, len * sys::nonzero_size_of::()); + let v : *(&blk/mut [T]) = + ::cast::reinterpret_cast(&addr_of(&pair)); + f(*v) + } + /** * Unchecked vector indexing. */ From 4bc26ce575b4bc6f7254a2cfe9fee0a08de90b49 Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Wed, 13 Feb 2013 23:00:34 -0800 Subject: [PATCH 33/43] rt/core: impl os::getcwd() in rust ref #4812 --- src/libcore/os.rs | 9 ++++++++- src/rt/rust_builtin.cpp | 19 ------------------- src/rt/rustrt.def.in | 2 -- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/src/libcore/os.rs b/src/libcore/os.rs index ba16c14a85add..43e20a1a83f37 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -68,10 +68,17 @@ pub mod rustrt { } pub const TMPBUF_SZ : uint = 1000u; +const BUF_BYTES : uint = 2048u; pub fn getcwd() -> Path { + let buf = [0 as libc::c_char, ..BUF_BYTES]; unsafe { - Path(rustrt::rust_getcwd()) + if(0 as *libc::c_char == libc::getcwd( + &buf[0], + BUF_BYTES as libc::size_t)) { + fail!(); + } + Path(str::raw::from_c_str(&buf[0])) } } diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 1243d82460346..750962b37e8f3 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -52,25 +52,6 @@ timegm(struct tm *tm) } #endif -extern "C" CDECL rust_str * -rust_getcwd() { - rust_task *task = rust_get_current_task(); - LOG(task, task, "rust_getcwd()"); - - char cbuf[BUF_BYTES]; - -#if defined(__WIN32__) - if (!_getcwd(cbuf, sizeof(cbuf))) { -#else - if (!getcwd(cbuf, sizeof(cbuf))) { -#endif - task->fail(); - return NULL; - } - - return make_str(task->kernel, cbuf, strlen(cbuf), "rust_str(getcwd)"); -} - #if defined(__WIN32__) extern "C" CDECL rust_vec_box * rust_env_pairs() { diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index fca10ac3ef49b..ddbd4729782eb 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -29,7 +29,6 @@ rust_new_task_in_sched rust_num_threads rust_path_is_dir rust_path_exists -rust_getcwd rust_get_stdin rust_get_stdout rust_get_stderr @@ -43,7 +42,6 @@ rust_sched_current_nonlazy_threads rust_sched_threads rust_set_exit_status rust_start -rust_getcwd rust_env_pairs rust_task_yield rust_task_is_unwinding From 53db6c7e2a11764a806e87c7268d31288fa9171d Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Thu, 14 Feb 2013 22:16:53 -0800 Subject: [PATCH 34/43] core: rt/core: impl os::env() in rust ref #4812 --- src/libcore/libc.rs | 5 +- src/libcore/os.rs | 64 ++++++++++++++++--- src/libcore/ptr.rs | 132 ++++++++++++++++++++++++++++++++++++++++ src/rt/rust_builtin.cpp | 35 ++--------- 4 files changed, 196 insertions(+), 40 deletions(-) diff --git a/src/libcore/libc.rs b/src/libcore/libc.rs index b59824969bb85..9a45ffc5b2ebf 100644 --- a/src/libcore/libc.rs +++ b/src/libcore/libc.rs @@ -534,6 +534,7 @@ pub mod types { pub type LPCWSTR = *WCHAR; pub type LPCSTR = *CHAR; + pub type LPTCH = *CHAR; pub type LPWSTR = *mut WCHAR; pub type LPSTR = *mut CHAR; @@ -1594,7 +1595,7 @@ pub mod funcs { pub mod kernel32 { use libc::types::os::arch::extra::{BOOL, DWORD, HMODULE}; - use libc::types::os::arch::extra::{LPCWSTR, LPWSTR}; + use libc::types::os::arch::extra::{LPCWSTR, LPWSTR, LPTCH}; use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES}; #[abi = "stdcall"] @@ -1605,6 +1606,8 @@ pub mod funcs { -> DWORD; unsafe fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR) -> BOOL; + unsafe fn GetEnvironmentStringsA() -> LPTCH; + unsafe fn FreeEnvironmentStringsA(env_ptr: LPTCH) -> BOOL; unsafe fn GetModuleFileNameW(hModule: HMODULE, lpFilename: LPWSTR, diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 43e20a1a83f37..a1793cc5efa84 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -171,20 +171,68 @@ fn with_env_lock(f: &fn() -> T) -> T { } pub fn env() -> ~[(~str,~str)] { - extern { - unsafe fn rust_env_pairs() -> ~[~str]; - } - unsafe { - do with_env_lock { + #[cfg(windows)] + unsafe fn get_env_pairs() -> ~[~str] { + use libc::types::os::arch::extra::LPTCH; + use libc::funcs::extra::kernel32::{ + GetEnvironmentStringsA, + FreeEnvironmentStringsA + }; + let ch = GetEnvironmentStringsA(); + if (ch as uint == 0) { + fail!(fmt!("os::env() failure getting env string from OS: %s", + os::last_os_error())); + } + let mut curr_ptr: uint = ch as uint; + let mut result = ~[]; + while(*(curr_ptr as *libc::c_char) != 0 as libc::c_char) { + let env_pair = str::raw::from_c_str( + curr_ptr as *libc::c_char); + result.push(env_pair); + curr_ptr += + libc::strlen(curr_ptr as *libc::c_char) as uint + + 1; + } + FreeEnvironmentStringsA(ch); + result + } + #[cfg(unix)] + unsafe fn get_env_pairs() -> ~[~str] { + extern mod rustrt { + unsafe fn rust_env_pairs() -> **libc::c_char; + } + let environ = rustrt::rust_env_pairs(); + if (environ as uint == 0) { + fail!(fmt!("os::env() failure getting env string from OS: %s", + os::last_os_error())); + } + let mut result = ~[]; + ptr::array_each(environ, |e| { + let env_pair = str::raw::from_c_str(e); + log(debug, fmt!("get_env_pairs: %s", + env_pair)); + result.push(env_pair); + }); + result + } + + fn env_convert(input: ~[~str]) -> ~[(~str, ~str)] { let mut pairs = ~[]; - for vec::each(rust_env_pairs()) |p| { - let vs = str::splitn_char(*p, '=', 1u); - fail_unless!(vec::len(vs) == 2u); + for input.each |p| { + let vs = str::splitn_char(*p, '=', 1); + log(debug, + fmt!("splitting: len: %u", + vs.len())); + assert vs.len() == 2; pairs.push((copy vs[0], copy vs[1])); } pairs } + do with_env_lock { + let unparsed_environ = get_env_pairs(); + env_convert(unparsed_environ) + } } } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index b66c1c4696fcf..042720e1b4e7d 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -18,6 +18,8 @@ use sys; #[cfg(test)] use vec; #[cfg(test)] use str; +#[cfg(test)] use uint; +#[cfg(test)] use debug; #[cfg(notest)] use cmp::{Eq, Ord}; pub mod libc_ { @@ -181,6 +183,46 @@ pub pure fn ref_eq(thing: &a/T, other: &b/T) -> bool { to_uint(thing) == to_uint(other) } +/** + Given a **T (pointer to an array of pointers), + iterate through each *T, up to the provided `len`, + passing to the provided callback function + + SAFETY NOTE: Pointer-arithmetic. Dragons be here. +*/ +pub unsafe fn array_each_with_len(arr: **T, len: uint, cb: fn(*T)) { + log(debug, "array_each_with_len: before iterate"); + if (arr as uint == 0) { + fail!(~"ptr::array_each_with_len failure: arr input is null pointer"); + } + //let start_ptr = *arr; + uint::iterate(0, len, |e| { + let n = offset(arr, e); + cb(*n); + true + }); + log(debug, "array_each_with_len: after iterate"); +} + +/** + Given a null-pointer-terminated **T (pointer to + an array of pointers), iterate through each *T, + passing to the provided callback function + + SAFETY NOTE: This will only work with a null-terminated + pointer array. Barely less-dodgey Pointer Arithmetic. + Dragons be here. +*/ +pub unsafe fn array_each(arr: **T, cb: fn(*T)) { + if (arr as uint == 0) { + fail!(~"ptr::array_each_with_len failure: arr input is null pointer"); + } + let len = buf_len(arr); + log(debug, fmt!("array_each inferred len: %u", + len)); + array_each_with_len(arr, len, cb); +} + pub trait Ptr { pure fn is_null(&self) -> bool; pure fn is_not_null(&self) -> bool; @@ -389,3 +431,93 @@ pub fn test_is_null() { fail_unless!(!mq.is_null()); fail_unless!(mq.is_not_null()); } + +#[cfg(test)] +pub mod ptr_tests { + use debug; + use ptr; + use str; + use libc; + use vec; + #[test] + pub fn test_ptr_array_each_with_len() { + unsafe { + let one = ~"oneOne"; + let two = ~"twoTwo"; + let three = ~"threeThree"; + let arr: ~[*i8] = ~[ + ::cast::transmute(&one[0]), + ::cast::transmute(&two[0]), + ::cast::transmute(&three[0]), + ]; + let expected_arr = [ + one, two, three + ]; + let arr_ptr = &arr[0]; + let mut ctr = 0; + let mut iteration_count = 0; + ptr::array_each_with_len(arr_ptr, vec::len(arr), + |e| { + let actual = str::raw::from_c_str(e); + let expected = copy expected_arr[ctr]; + log(debug, + fmt!("test_ptr_array_each e: %s, a: %s", + expected, actual)); + assert actual == expected; + ctr += 1; + iteration_count += 1; + }); + assert iteration_count == 3u; + } + } + #[test] + pub fn test_ptr_array_each() { + unsafe { + let one = ~"oneOne"; + let two = ~"twoTwo"; + let three = ~"threeThree"; + let arr: ~[*i8] = ~[ + ::cast::transmute(&one[0]), + ::cast::transmute(&two[0]), + ::cast::transmute(&three[0]), + // fake a null terminator + 0 as *i8 + ]; + let expected_arr = [ + one, two, three + ]; + let arr_ptr = &arr[0]; + let mut ctr = 0; + let mut iteration_count = 0; + ptr::array_each(arr_ptr, |e| { + let actual = str::raw::from_c_str(e); + let expected = copy expected_arr[ctr]; + log(debug, + fmt!("test_ptr_array_each e: %s, a: %s", + expected, actual)); + assert actual == expected; + ctr += 1; + iteration_count += 1; + }); + assert iteration_count == 3; + } + } + #[test] + #[should_fail] + pub fn test_ptr_array_each_with_len_null_ptr() { + unsafe { + ptr::array_each_with_len(0 as **libc::c_char, 1, |e| { + str::raw::from_c_str(e); + }); + } + } + #[test] + #[should_fail] + pub fn test_ptr_array_each_null_ptr() { + unsafe { + ptr::array_each(0 as **libc::c_char, |e| { + str::raw::from_c_str(e); + }); + } + } +} diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 750962b37e8f3..2c9c4a706812f 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -53,44 +53,17 @@ timegm(struct tm *tm) #endif #if defined(__WIN32__) -extern "C" CDECL rust_vec_box * +extern "C" CDECL char** rust_env_pairs() { - rust_task *task = rust_get_current_task(); - size_t envc = 0; - LPTCH ch = GetEnvironmentStringsA(); - LPTCH c; - for (c = ch; *c; c += strlen(c) + 1) { - ++envc; - } - c = ch; - rust_vec_box *v = (rust_vec_box *) - task->kernel->malloc(vec_size(envc), - "str vec interior"); - v->body.fill = v->body.alloc = sizeof(rust_vec*) * envc; - for (size_t i = 0; i < envc; ++i) { - size_t n = strlen(c); - rust_str *str = make_str(task->kernel, c, n, "str"); - ((rust_str**)&v->body.data)[i] = str; - c += n + 1; - } - if (ch) { - FreeEnvironmentStrings(ch); - } - return v; + return 0; } #else -extern "C" CDECL rust_vec_box * +extern "C" CDECL char** rust_env_pairs() { - rust_task *task = rust_get_current_task(); #ifdef __APPLE__ char **environ = *_NSGetEnviron(); #endif - char **e = environ; - size_t envc = 0; - while (*e) { - ++envc; ++e; - } - return make_str_vec(task->kernel, envc, environ); + return environ; } #endif From a69a2acfba1c09d2ca47f454ecff7b571c324d57 Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Wed, 20 Feb 2013 22:46:26 -0800 Subject: [PATCH 35/43] rt/core: port os::list_dir to rust ref #4812 --- src/libcore/libc.rs | 33 +++++++- src/libcore/os.rs | 96 ++++++++++++++++++++++-- src/libcore/ptr.rs | 6 +- src/libcore/unstable/exchange_alloc.rs | 15 ++++ src/rt/rust_builtin.cpp | 66 ++++++++-------- src/rt/rust_util.h | 32 -------- src/rt/rustrt.def.in | 5 +- src/test/run-pass/conditional-compile.rs | 4 +- src/test/run-pass/morestack6.rs | 3 - 9 files changed, 174 insertions(+), 86 deletions(-) diff --git a/src/libcore/libc.rs b/src/libcore/libc.rs index 9a45ffc5b2ebf..7f293b98e24a9 100644 --- a/src/libcore/libc.rs +++ b/src/libcore/libc.rs @@ -534,6 +534,7 @@ pub mod types { pub type LPCWSTR = *WCHAR; pub type LPCSTR = *CHAR; + pub type LPCTSTR = *CHAR; pub type LPTCH = *CHAR; pub type LPWSTR = *mut WCHAR; @@ -793,6 +794,7 @@ pub mod consts { pub const ERROR_SUCCESS : int = 0; pub const ERROR_INSUFFICIENT_BUFFER : int = 122; + pub const INVALID_HANDLE_VALUE: int = -1; } } @@ -1116,6 +1118,7 @@ pub mod funcs { pub mod string { use libc::types::common::c95::c_void; use libc::types::os::arch::c95::{c_char, c_int, size_t}; + use libc::types::os::arch::c95::{wchar_t}; pub extern { unsafe fn strcpy(dst: *c_char, src: *c_char) -> *c_char; @@ -1139,6 +1142,7 @@ pub mod funcs { unsafe fn strtok(s: *c_char, t: *c_char) -> *c_char; unsafe fn strxfrm(s: *c_char, ct: *c_char, n: size_t) -> size_t; + unsafe fn wcslen(buf: *wchar_t) -> size_t; // These are fine to execute on the Rust stack. They must be, // in fact, because LLVM generates calls to them! @@ -1382,9 +1386,28 @@ pub mod funcs { use libc::types::os::arch::c95::{c_char, c_int, c_long}; pub extern { + // default bindings for opendir and readdir in + // non-macos unix + #[cfg(target_os = "linux")] + #[cfg(target_os = "android")] + #[cfg(target_os = "freebsd")] unsafe fn opendir(dirname: *c_char) -> *DIR; - unsafe fn closedir(dirp: *DIR) -> c_int; + #[cfg(target_os = "linux")] + #[cfg(target_os = "android")] + #[cfg(target_os = "freebsd")] unsafe fn readdir(dirp: *DIR) -> *dirent_t; + // on OSX (particularly when running with a + // 64bit kernel), we have an issue where there + // are separate bindings for opendir and readdir, + // which we have to explicitly link, as below. + #[cfg(target_os = "macos")] + #[link_name = "opendir$INODE64"] + unsafe fn opendir(dirname: *c_char) -> *DIR; + #[cfg(target_os = "macos")] + #[link_name = "readdir$INODE64"] + unsafe fn readdir(dirp: *DIR) -> *dirent_t; + + unsafe fn closedir(dirp: *DIR) -> c_int; unsafe fn rewinddir(dirp: *DIR); unsafe fn seekdir(dirp: *DIR, loc: c_long); unsafe fn telldir(dirp: *DIR) -> c_long; @@ -1597,6 +1620,7 @@ pub mod funcs { use libc::types::os::arch::extra::{BOOL, DWORD, HMODULE}; use libc::types::os::arch::extra::{LPCWSTR, LPWSTR, LPTCH}; use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES}; + use libc::types::os::arch::extra::{HANDLE}; #[abi = "stdcall"] pub extern { @@ -1626,6 +1650,13 @@ pub mod funcs { unsafe fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL; unsafe fn GetLastError() -> DWORD; + unsafe fn FindFirstFileW(fileName: *u16, + findFileData: HANDLE) + -> HANDLE; + unsafe fn FindNextFileW(findFile: HANDLE, + findFileData: HANDLE) + -> BOOL; + unsafe fn FindClose(findFile: HANDLE) -> BOOL; } } diff --git a/src/libcore/os.rs b/src/libcore/os.rs index a1793cc5efa84..24d5df7140ed5 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -58,10 +58,8 @@ pub mod rustrt { pub extern { unsafe fn rust_get_argc() -> c_int; unsafe fn rust_get_argv() -> **c_char; - unsafe fn rust_getcwd() -> ~str; unsafe fn rust_path_is_dir(path: *libc::c_char) -> c_int; unsafe fn rust_path_exists(path: *libc::c_char) -> c_int; - unsafe fn rust_list_files2(&&path: ~str) -> ~[~str]; unsafe fn rust_process_wait(handle: c_int) -> c_int; unsafe fn rust_set_exit_status(code: libc::intptr_t); } @@ -670,13 +668,95 @@ pub fn make_dir(p: &Path, mode: c_int) -> bool { #[allow(non_implicitly_copyable_typarams)] pub fn list_dir(p: &Path) -> ~[~str] { unsafe { - #[cfg(unix)] - fn star(p: &Path) -> Path { copy *p } - + #[cfg(target_os = "linux")] + #[cfg(target_os = "android")] + #[cfg(target_os = "freebsd")] + #[cfg(target_os = "macos")] + unsafe fn get_list(p: &Path) -> ~[~str] { + use libc::{DIR, dirent_t}; + use libc::{opendir, readdir, closedir}; + extern mod rustrt { + unsafe fn rust_list_dir_val(ptr: *dirent_t) + -> *libc::c_char; + } + let input = p.to_str(); + let mut strings = ~[]; + let input_ptr = ::cast::transmute(&input[0]); + log(debug, "os::list_dir -- BEFORE OPENDIR"); + let dir_ptr = opendir(input_ptr); + if (dir_ptr as uint != 0) { + log(debug, "os::list_dir -- opendir() SUCCESS"); + let mut entry_ptr = readdir(dir_ptr); + while (entry_ptr as uint != 0) { + strings.push( + str::raw::from_c_str( + rustrt::rust_list_dir_val( + entry_ptr))); + entry_ptr = readdir(dir_ptr); + } + closedir(dir_ptr); + } + else { + log(debug, "os::list_dir -- opendir() FAILURE"); + } + log(debug, fmt!("os::list_dir -- AFTER ITERATION -- # of results: %?", strings.len())); + strings + } #[cfg(windows)] - fn star(p: &Path) -> Path { p.push("*") } - - do rustrt::rust_list_files2(star(p).to_str()).filtered |filename| { + unsafe fn get_list(p: &Path) -> ~[~str] { + use libc::types::os::arch::extra::{LPCTSTR, HANDLE, BOOL}; + use libc::consts::os::extra::INVALID_HANDLE_VALUE; + use libc::wcslen; + use libc::funcs::extra::kernel32::{ + FindFirstFileW, + FindNextFileW, + FindClose, + }; + use os::win32::{ + as_utf16_p + }; + use private::exchange_alloc::{malloc_raw, free_raw}; + #[nolink] + extern mod rustrt { + unsafe fn rust_list_dir_wfd_size() -> libc::size_t; + unsafe fn rust_list_dir_wfd_fp_buf(wfd: *libc::c_void) + -> *u16; + } + fn star(p: &Path) -> Path { p.push("*") } + do as_utf16_p(star(p).to_str()) |path_ptr| { + let mut strings = ~[]; + let wfd_ptr = malloc_raw( + rustrt::rust_list_dir_wfd_size() as uint); + let find_handle = + FindFirstFileW( + path_ptr, + ::cast::transmute(wfd_ptr)); + if find_handle as int != INVALID_HANDLE_VALUE { + let mut more_files = 1 as libc::c_int; + while more_files != 0 { + let fp_buf = rustrt::rust_list_dir_wfd_fp_buf( + wfd_ptr); + if fp_buf as uint == 0 { + fail!(~"os::list_dir() failure:"+ + ~" got null ptr from wfd"); + } + else { + let fp_vec = vec::from_buf( + fp_buf, wcslen(fp_buf) as uint); + let fp_str = str::from_utf16(fp_vec); + strings.push(fp_str); + } + more_files = FindNextFileW( + find_handle, + ::cast::transmute(wfd_ptr)); + } + FindClose(find_handle); + free_raw(wfd_ptr); + } + strings + } + } + do get_list(p).filtered |filename| { *filename != ~"." && *filename != ~".." } } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 042720e1b4e7d..9f8ddc92a7728 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -18,9 +18,9 @@ use sys; #[cfg(test)] use vec; #[cfg(test)] use str; -#[cfg(test)] use uint; -#[cfg(test)] use debug; #[cfg(notest)] use cmp::{Eq, Ord}; +use debug; +use uint; pub mod libc_ { use libc::c_void; @@ -504,6 +504,7 @@ pub mod ptr_tests { } #[test] #[should_fail] + #[ignore(cfg(windows))] pub fn test_ptr_array_each_with_len_null_ptr() { unsafe { ptr::array_each_with_len(0 as **libc::c_char, 1, |e| { @@ -513,6 +514,7 @@ pub mod ptr_tests { } #[test] #[should_fail] + #[ignore(cfg(windows))] pub fn test_ptr_array_each_null_ptr() { unsafe { ptr::array_each(0 as **libc::c_char, |e| { diff --git a/src/libcore/unstable/exchange_alloc.rs b/src/libcore/unstable/exchange_alloc.rs index a2815cebc51aa..3b4d86ba86b42 100644 --- a/src/libcore/unstable/exchange_alloc.rs +++ b/src/libcore/unstable/exchange_alloc.rs @@ -41,6 +41,17 @@ pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void { return transmute(box); } } +/** +Thin wrapper around libc::malloc, none of the box header +stuff in exchange_alloc::malloc +*/ +pub unsafe fn malloc_raw(size: uint) -> *c_void { + let p = c_malloc(size as size_t); + if p.is_null() { + fail!(~"Failure in malloc_raw: result ptr is null"); + } + p +} pub unsafe fn free(ptr: *c_void) { let exchange_count = &mut *rust_get_exchange_count_ptr(); @@ -49,6 +60,10 @@ pub unsafe fn free(ptr: *c_void) { fail_unless!(ptr.is_not_null()); c_free(ptr); } +///Thin wrapper around libc::free, as with exchange_alloc::malloc_raw +pub unsafe fn free_raw(ptr: *c_void) { + c_free(ptr); +} fn get_box_size(body_size: uint, body_align: uint) -> uint { let header_size = size_of::(); diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 2c9c4a706812f..a621d61cdf792 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -247,49 +247,43 @@ debug_get_stk_seg() { return task->stk; } -extern "C" CDECL rust_vec_box* -rust_list_files(rust_str *path) { - rust_task *task = rust_get_current_task(); - array_list strings; +extern "C" CDECL char* #if defined(__WIN32__) - WIN32_FIND_DATA FindFileData; - HANDLE hFind = FindFirstFile((char*)path->body.data, &FindFileData); - if (hFind != INVALID_HANDLE_VALUE) { - do { - rust_str *str = make_str(task->kernel, FindFileData.cFileName, - strlen(FindFileData.cFileName), - "list_files_str"); - strings.push(str); - } while (FindNextFile(hFind, &FindFileData)); - FindClose(hFind); - } +rust_list_dir_val(WIN32_FIND_DATA* entry_ptr) { + return entry_ptr->cFileName; +} #else - DIR *dirp = opendir((char*)path->body.data); - if (dirp) { - struct dirent *dp; - while ((dp = readdir(dirp))) { - rust_vec_box *str = make_str(task->kernel, dp->d_name, - strlen(dp->d_name), - "list_files_str"); - strings.push(str); - } - closedir(dirp); - } +rust_list_dir_val(dirent* entry_ptr) { + return entry_ptr->d_name; +} #endif - rust_vec_box *vec = (rust_vec_box *) - task->kernel->malloc(vec_size(strings.size()), - "list_files_vec"); - size_t alloc_sz = sizeof(rust_vec*) * strings.size(); - vec->body.fill = vec->body.alloc = alloc_sz; - memcpy(&vec->body.data[0], strings.data(), alloc_sz); - return vec; +extern "C" CDECL size_t +#if defined(__WIN32__) +rust_list_dir_wfd_size() { + return sizeof(WIN32_FIND_DATAW); +} +#else +rust_list_dir_wfd_size() { + return 0; } +#endif -extern "C" CDECL rust_vec_box* -rust_list_files2(rust_str **path) { - return rust_list_files(*path); +extern "C" CDECL void* +#if defined(__WIN32__) +rust_list_dir_wfd_fp_buf(WIN32_FIND_DATAW* wfd) { + if(wfd == NULL) { + return 0; + } + else { + return wfd->cFileName; + } } +#else +rust_list_dir_wfd_fp_buf(void* wfd) { + return 0; +} +#endif extern "C" CDECL int rust_path_is_dir(char *path) { diff --git a/src/rt/rust_util.h b/src/rt/rust_util.h index fbedb9bc6efb2..101d04c880475 100644 --- a/src/rt/rust_util.h +++ b/src/rt/rust_util.h @@ -79,38 +79,6 @@ inline void reserve_vec_exact(rust_vec_box** vpp, typedef rust_vec_box rust_str; -inline rust_str * -make_str(rust_kernel* kernel, const char* c, size_t strlen, - const char* name) { - size_t str_fill = strlen + 1; - size_t str_alloc = str_fill; - rust_str *str = (rust_str *) - kernel->malloc(vec_size(str_fill), name); - str->header.td = &str_body_tydesc; - str->body.fill = str_fill; - str->body.alloc = str_alloc; - memcpy(&str->body.data, c, strlen); - str->body.data[strlen] = '\0'; - return str; -} - -inline rust_vec_box * -make_str_vec(rust_kernel* kernel, size_t nstrs, char **strs) { - rust_vec_box *v = (rust_vec_box *) - kernel->malloc(vec_size(nstrs), - "str vec interior"); - // FIXME: should have a real td (Issue #2639) - v->header.td = NULL; - v->body.fill = v->body.alloc = sizeof(rust_vec_box*) * nstrs; - for (size_t i = 0; i < nstrs; ++i) { - rust_str *str = make_str(kernel, strs[i], - strlen(strs[i]), - "str"); - ((rust_str**)&v->body.data)[i] = str; - } - return v; -} - inline size_t get_box_size(size_t body_size, size_t body_align) { size_t header_size = sizeof(rust_opaque_box); // FIXME (#2699): This alignment calculation is suspicious. Is it right? diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index ddbd4729782eb..284f827bc753a 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -32,8 +32,9 @@ rust_path_exists rust_get_stdin rust_get_stdout rust_get_stderr -rust_list_files -rust_list_files2 +rust_list_dir_val +rust_list_dir_wfd_size +rust_list_dir_wfd_fp_buf rust_log_console_on rust_log_console_off rust_process_wait diff --git a/src/test/run-pass/conditional-compile.rs b/src/test/run-pass/conditional-compile.rs index 0a579916e93ce..fa6f59999f84c 100644 --- a/src/test/run-pass/conditional-compile.rs +++ b/src/test/run-pass/conditional-compile.rs @@ -112,8 +112,8 @@ mod test_foreign_items { #[abi = "cdecl"] pub extern { #[cfg(bogus)] - pub fn rust_getcwd() -> ~str; - pub fn rust_getcwd() -> ~str; + pub fn rust_get_stdin() -> ~str; + pub fn rust_get_stdin() -> ~str; } } } diff --git a/src/test/run-pass/morestack6.rs b/src/test/run-pass/morestack6.rs index 9d210f2580b8b..7e0b4b47846e0 100644 --- a/src/test/run-pass/morestack6.rs +++ b/src/test/run-pass/morestack6.rs @@ -17,7 +17,6 @@ mod rustrt { pub fn rust_get_sched_id() -> libc::intptr_t; pub fn rust_get_argc() -> libc::c_int; - pub fn rust_getcwd() -> ~str; pub fn get_task_id() -> libc::intptr_t; pub fn rust_sched_threads(); pub fn rust_get_task(); @@ -26,7 +25,6 @@ mod rustrt { fn calllink01() { unsafe { rustrt::rust_get_sched_id(); } } fn calllink02() { unsafe { rustrt::rust_get_argc(); } } -fn calllink03() { unsafe { rustrt::rust_getcwd(); } } fn calllink08() { unsafe { rustrt::get_task_id(); } } fn calllink09() { unsafe { rustrt::rust_sched_threads(); } } fn calllink10() { unsafe { rustrt::rust_get_task(); } } @@ -59,7 +57,6 @@ pub fn main() { let fns = ~[ calllink01, calllink02, - calllink03, calllink08, calllink09, calllink10 From 25c3c363a82c1bd45065b4f865ef1a086e0b3907 Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Wed, 6 Mar 2013 10:25:02 -0800 Subject: [PATCH 36/43] core: change import of exchange_alloc for win32 os::_list_dir --- src/libcore/os.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 24d5df7140ed5..ee14758221a44 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -715,7 +715,7 @@ pub fn list_dir(p: &Path) -> ~[~str] { use os::win32::{ as_utf16_p }; - use private::exchange_alloc::{malloc_raw, free_raw}; + use unstable::exchange_alloc::{malloc_raw, free_raw}; #[nolink] extern mod rustrt { unsafe fn rust_list_dir_wfd_size() -> libc::size_t; From a04ba76f8e436d1c1919b0a97bc91190c7252d7a Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Wed, 6 Mar 2013 22:02:01 -0800 Subject: [PATCH 37/43] core: fix broken tests on windows --- src/libcore/os.rs | 5 ++--- src/libcore/vec.rs | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/os.rs b/src/libcore/os.rs index ee14758221a44..c7c0302a099ff 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -1409,9 +1409,8 @@ mod tests { setenv(~"USERPROFILE", ~"/home/PaloAlto"); fail_unless!(os::homedir() == Some(Path("/home/MountainView"))); - option::iter(&oldhome, |s| setenv(~"HOME", *s)); - option::iter(&olduserprofile, - |s| setenv(~"USERPROFILE", *s)); + oldhome.each(|s| {setenv(~"HOME", *s);true}); + olduserprofile.each(|s| {setenv(~"USERPROFILE", *s);true}); } #[test] diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 697bfe63b189b..68dca608a480d 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -2692,6 +2692,7 @@ mod tests { #[test] #[should_fail] + #[ignore(cfg(windows))] fn test_last_empty() { let a: ~[int] = ~[]; a.last(); From cf82360e729eb941c2de080fbcf715dea3417edd Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Fri, 8 Mar 2013 12:47:34 -0800 Subject: [PATCH 38/43] core: formatting appeasement --- src/libcore/os.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libcore/os.rs b/src/libcore/os.rs index c7c0302a099ff..a6e95af45eaf0 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -685,7 +685,7 @@ pub fn list_dir(p: &Path) -> ~[~str] { log(debug, "os::list_dir -- BEFORE OPENDIR"); let dir_ptr = opendir(input_ptr); if (dir_ptr as uint != 0) { - log(debug, "os::list_dir -- opendir() SUCCESS"); + log(debug, "os::list_dir -- opendir() SUCCESS"); let mut entry_ptr = readdir(dir_ptr); while (entry_ptr as uint != 0) { strings.push( @@ -697,9 +697,11 @@ pub fn list_dir(p: &Path) -> ~[~str] { closedir(dir_ptr); } else { - log(debug, "os::list_dir -- opendir() FAILURE"); + log(debug, "os::list_dir -- opendir() FAILURE"); } - log(debug, fmt!("os::list_dir -- AFTER ITERATION -- # of results: %?", strings.len())); + log(debug, + fmt!("os::list_dir -- AFTER -- #: %?", + strings.len())); strings } #[cfg(windows)] From 5ff66f04050569321dc2b722ade6f972322edd58 Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Fri, 8 Mar 2013 16:05:50 -0800 Subject: [PATCH 39/43] core: link pthreads explicitly in linux build --- src/libcore/core.rc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/core.rc b/src/libcore/core.rc index db1dc1e28aa92..7b12bae746716 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -58,6 +58,7 @@ Implicitly, all crates behave as if they included the following prologue: #[cfg(target_os = "linux")] pub mod linkhack { #[link_args="-lrustrt -lrt"] + #[link_args = "-lpthread"] extern { } } From 3aa92a91c90ac2b46a705f6cae6e9803aa956a74 Mon Sep 17 00:00:00 2001 From: Jeff Olson Date: Fri, 8 Mar 2013 16:06:05 -0800 Subject: [PATCH 40/43] core: convert asserts to fail_unless! --- src/libcore/os.rs | 2 +- src/libcore/ptr.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcore/os.rs b/src/libcore/os.rs index a6e95af45eaf0..aa4a6feb76f71 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -222,7 +222,7 @@ pub fn env() -> ~[(~str,~str)] { log(debug, fmt!("splitting: len: %u", vs.len())); - assert vs.len() == 2; + fail_unless!(vs.len() == 2); pairs.push((copy vs[0], copy vs[1])); } pairs diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 9f8ddc92a7728..e622b0c4ca325 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -463,11 +463,11 @@ pub mod ptr_tests { log(debug, fmt!("test_ptr_array_each e: %s, a: %s", expected, actual)); - assert actual == expected; + fail_unless!(actual == expected); ctr += 1; iteration_count += 1; }); - assert iteration_count == 3u; + fail_unless!(iteration_count == 3u); } } #[test] @@ -495,11 +495,11 @@ pub mod ptr_tests { log(debug, fmt!("test_ptr_array_each e: %s, a: %s", expected, actual)); - assert actual == expected; + fail_unless!(actual == expected); ctr += 1; iteration_count += 1; }); - assert iteration_count == 3; + fail_unless!(iteration_count == 3); } } #[test] From 7e5995197fa41002fd0ea78bf08208247e20ad51 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 11 Mar 2013 15:42:00 -0700 Subject: [PATCH 41/43] core: Convert obsolete fn syntax --- src/libcore/ptr.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index e622b0c4ca325..ace70d7f061d3 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -190,7 +190,7 @@ pub pure fn ref_eq(thing: &a/T, other: &b/T) -> bool { SAFETY NOTE: Pointer-arithmetic. Dragons be here. */ -pub unsafe fn array_each_with_len(arr: **T, len: uint, cb: fn(*T)) { +pub unsafe fn array_each_with_len(arr: **T, len: uint, cb: &fn(*T)) { log(debug, "array_each_with_len: before iterate"); if (arr as uint == 0) { fail!(~"ptr::array_each_with_len failure: arr input is null pointer"); @@ -213,7 +213,7 @@ pub unsafe fn array_each_with_len(arr: **T, len: uint, cb: fn(*T)) { pointer array. Barely less-dodgey Pointer Arithmetic. Dragons be here. */ -pub unsafe fn array_each(arr: **T, cb: fn(*T)) { +pub unsafe fn array_each(arr: **T, cb: &fn(*T)) { if (arr as uint == 0) { fail!(~"ptr::array_each_with_len failure: arr input is null pointer"); } From 676e0290ed4d306e6d7b517de1409c109309a0b2 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 3 Feb 2013 18:15:43 -0800 Subject: [PATCH 42/43] core: Add rt mod and add the new scheduler code --- src/libcore/core.rc | 3 +- src/libcore/option.rs | 38 + src/libcore/rt/context.rs | 156 +++ src/libcore/rt/io.rs | 45 + src/libcore/rt/mod.rs | 51 + src/libcore/rt/sched.rs | 564 +++++++++++ src/libcore/rt/stack.rs | 49 + src/libcore/rt/thread.rs | 44 + src/libcore/rt/thread_local_storage.rs | 91 ++ src/libcore/rt/uv.rs | 919 ++++++++++++++++++ src/libcore/rt/uvio.rs | 475 +++++++++ src/libcore/rt/work_queue.rs | 47 + src/libcore/unstable.rs | 22 +- .../uv_ll.rs => libcore/unstable/uvll.rs} | 406 ++++---- src/libstd/net_ip.rs | 28 +- src/libstd/std.rc | 3 +- src/libstd/uv.rs | 2 +- src/libuv | 2 +- src/rt/arch/i386/_context.S | 10 +- src/rt/arch/i386/context.cpp | 3 +- src/rt/arch/x86_64/_context.S | 10 +- src/rt/arch/x86_64/context.cpp | 3 +- src/rt/rust.cpp | 15 + src/rt/rust_builtin.cpp | 8 +- src/rt/rust_uv.cpp | 41 +- src/rt/rustrt.def.in | 7 + 26 files changed, 2789 insertions(+), 253 deletions(-) create mode 100644 src/libcore/rt/context.rs create mode 100644 src/libcore/rt/io.rs create mode 100644 src/libcore/rt/mod.rs create mode 100644 src/libcore/rt/sched.rs create mode 100644 src/libcore/rt/stack.rs create mode 100644 src/libcore/rt/thread.rs create mode 100644 src/libcore/rt/thread_local_storage.rs create mode 100644 src/libcore/rt/uv.rs create mode 100644 src/libcore/rt/uvio.rs create mode 100644 src/libcore/rt/work_queue.rs rename src/{libstd/uv_ll.rs => libcore/unstable/uvll.rs} (86%) diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 7b12bae746716..026f49cac45b1 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -243,7 +243,8 @@ pub mod unicode; #[path = "num/cmath.rs"] pub mod cmath; pub mod stackwalk; - +#[path = "rt/mod.rs"] +pub mod rt; // A curious inner-module that's not exported that contains the binding // 'core' so that macro-expanded references to core::error and such diff --git a/src/libcore/option.rs b/src/libcore/option.rs index e0393fdf5e35a..6a38eff0343bd 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -130,6 +130,27 @@ pub pure fn get_ref(opt: &r/Option) -> &r/T { } } +pub pure fn get_mut_ref(opt: &r/mut Option) -> &r/mut T { + /*! + Gets a mutable reference to the value inside an option. + + # Failure + + Fails if the value equals `None` + + # Safety note + + In general, because this function may fail, its use is discouraged + (calling `get` on `None` is akin to dereferencing a null pointer). + Instead, prefer to use pattern matching and handle the `None` + case explicitly. + */ + match *opt { + Some(ref mut x) => x, + None => fail!(~"option::get_mut_ref none") + } +} + #[inline(always)] pub pure fn map(opt: &r/Option, f: &fn(x: &r/T) -> U) -> Option { //! Maps a `some` value by reference from one type to another @@ -364,6 +385,23 @@ pub impl Option { #[inline(always)] pure fn get_ref(&self) -> &self/T { get_ref(self) } + /** + Gets a mutable reference to the value inside an option. + + # Failure + + Fails if the value equals `None` + + # Safety note + + In general, because this function may fail, its use is discouraged + (calling `get` on `None` is akin to dereferencing a null pointer). + Instead, prefer to use pattern matching and handle the `None` + case explicitly. + */ + #[inline(always)] + pure fn get_mut_ref(&mut self) -> &self/mut T { get_mut_ref(self) } + /** * Gets the value out of an option without copying. * diff --git a/src/libcore/rt/context.rs b/src/libcore/rt/context.rs new file mode 100644 index 0000000000000..de96a7d17932b --- /dev/null +++ b/src/libcore/rt/context.rs @@ -0,0 +1,156 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use super::stack::StackSegment; +use libc::c_void; +use cast::{transmute, transmute_mut_unsafe, + transmute_region, transmute_mut_region}; + +// XXX: Registers is boxed so that it is 16-byte aligned, for storing +// SSE regs. It would be marginally better not to do this. In C++ we +// use an attribute on a struct. +pub struct Context(~Registers); + +pub impl Context { + static fn empty() -> Context { + Context(new_regs()) + } + + /// Create a new context that will resume execution by running ~fn() + /// # Safety Note + /// The `start` closure must remain valid for the life of the Task + static fn new(start: &~fn(), stack: &mut StackSegment) -> Context { + + // The C-ABI function that is the task entry point + extern fn task_start_wrapper(f: &~fn()) { (*f)() } + + let fp: *c_void = task_start_wrapper as *c_void; + let argp: *c_void = unsafe { transmute::<&~fn(), *c_void>(&*start) }; + let sp: *uint = stack.end(); + let sp: *mut uint = unsafe { transmute_mut_unsafe(sp) }; + + // Save and then immediately load the current context, + // which we will then modify to call the given function when restored + let mut regs = new_regs(); + unsafe { + swap_registers(transmute_mut_region(&mut *regs), + transmute_region(&*regs)) + }; + + initialize_call_frame(&mut *regs, fp, argp, sp); + + return Context(regs); + } + + static fn swap(out_context: &mut Context, in_context: &Context) { + let out_regs: &mut Registers = match out_context { + &Context(~ref mut r) => r + }; + let in_regs: &Registers = match in_context { + &Context(~ref r) => r + }; + + unsafe { swap_registers(out_regs, in_regs) }; + } +} + +extern { + fn swap_registers(out_regs: *mut Registers, in_regs: *Registers); +} + +// Definitions of these registers are in rt/arch/x86_64/regs.h +#[cfg(target_arch = "x86_64")] +type Registers = [uint * 22]; + +#[cfg(target_arch = "x86_64")] +fn new_regs() -> ~Registers { ~[0, .. 22] } + +#[cfg(target_arch = "x86_64")] +fn initialize_call_frame(regs: &mut Registers, + fptr: *c_void, arg: *c_void, sp: *mut uint) { + + // Redefinitions from regs.h + const RUSTRT_ARG0: uint = 3; + const RUSTRT_RSP: uint = 1; + const RUSTRT_IP: uint = 8; + const RUSTRT_RBP: uint = 2; + + let sp = align_down(sp); + let sp = mut_offset(sp, -1); + + // The final return address. 0 indicates the bottom of the stack + unsafe { *sp = 0; } + + rtdebug!("creating call frame"); + rtdebug!("fptr %x", fptr as uint); + rtdebug!("arg %x", arg as uint); + rtdebug!("sp %x", sp as uint); + + regs[RUSTRT_ARG0] = arg as uint; + regs[RUSTRT_RSP] = sp as uint; + regs[RUSTRT_IP] = fptr as uint; + + // Last base pointer on the stack should be 0 + regs[RUSTRT_RBP] = 0; +} + +#[cfg(target_arch = "x86")] +struct Registers { + eax: u32, ebx: u32, ecx: u32, edx: u32, + ebp: u32, esi: u32, edi: u32, esp: u32, + cs: u16, ds: u16, ss: u16, es: u16, fs: u16, gs: u16, + eflags: u32, eip: u32 +} + +#[cfg(target_arch = "x86")] +fn new_regs() -> ~Registers { + ~Registers { + eax: 0, ebx: 0, ecx: 0, edx: 0, + ebp: 0, esi: 0, edi: 0, esp: 0, + cs: 0, ds: 0, ss: 0, es: 0, fs: 0, gs: 0, + eflags: 0, eip: 0 + } +} + +#[cfg(target_arch = "x86")] +fn initialize_call_frame(regs: &mut Registers, + fptr: *c_void, arg: *c_void, sp: *mut uint) { + + let sp = align_down(sp); + let sp = mut_offset(sp, -4); // XXX: -4 words? Needs this be done at all? + + unsafe { *sp = arg as uint; } + let sp = mut_offset(sp, -1); + unsafe { *sp = 0; } // The final return address + + regs.esp = sp as u32; + regs.eip = fptr as u32; + + // Last base pointer on the stack is 0 + regs.ebp = 0; +} + +fn align_down(sp: *mut uint) -> *mut uint { + unsafe { + let sp = transmute::<*mut uint, uint>(sp); + let sp = sp & !(16 - 1); + transmute::(sp) + } +} + +// XXX: ptr::offset is positive ints only +#[inline(always)] +pub pure fn mut_offset(ptr: *mut T, count: int) -> *mut T { + use core::sys::size_of; + unsafe { + (ptr as int + count * (size_of::() as int)) as *mut T + } +} + diff --git a/src/libcore/rt/io.rs b/src/libcore/rt/io.rs new file mode 100644 index 0000000000000..3a94c01e0a419 --- /dev/null +++ b/src/libcore/rt/io.rs @@ -0,0 +1,45 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use option::*; +use result::*; + +// XXX: ~object doesn't work currently so these are some placeholder +// types to use instead +pub type EventLoopObject = super::uvio::UvEventLoop; +pub type IoFactoryObject = super::uvio::UvIoFactory; +pub type StreamObject = super::uvio::UvStream; +pub type TcpListenerObject = super::uvio::UvTcpListener; + +pub trait EventLoop { + fn run(&mut self); + fn callback(&mut self, ~fn()); + /// The asynchronous I/O services. Not all event loops may provide one + fn io(&mut self) -> Option<&self/mut IoFactoryObject>; +} + +pub trait IoFactory { + fn connect(&mut self, addr: IpAddr) -> Option<~StreamObject>; + fn bind(&mut self, addr: IpAddr) -> Option<~TcpListenerObject>; +} + +pub trait TcpListener { + fn listen(&mut self) -> Option<~StreamObject>; +} + +pub trait Stream { + fn read(&mut self, buf: &mut [u8]) -> Result; + fn write(&mut self, buf: &[u8]) -> Result<(), ()>; +} + +pub enum IpAddr { + Ipv4(u8, u8, u8, u8, u16), + Ipv6 +} diff --git a/src/libcore/rt/mod.rs b/src/libcore/rt/mod.rs new file mode 100644 index 0000000000000..772690c8dcdc6 --- /dev/null +++ b/src/libcore/rt/mod.rs @@ -0,0 +1,51 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// XXX: Missing some implementation for other architectures +#[cfg(target_os = "linux")]; +#[cfg(target_os = "mac")]; +#[cfg(target_os = "win32")]; + +// Some basic logging +macro_rules! rtdebug ( + ($( $arg:expr),+) => ( { + dumb_println(fmt!( $($arg),+ )); + + fn dumb_println(s: &str) { + use str::as_c_str; + use libc::c_char; + + extern { + fn printf(s: *c_char); + } + + do as_c_str(s.to_str() + "\n") |s| { + unsafe { printf(s); } + } + } + + } ) +) + +// An alternate version with no output, for turning off logging +macro_rules! rtdebug_ ( + ($( $arg:expr),+) => ( $(let _ = $arg)*; ) +) + +mod sched; +mod io; +mod uvio; +mod uv; +// FIXME #5248: The import in `sched` doesn't resolve unless this is pub! +pub mod thread_local_storage; +mod work_queue; +mod stack; +mod context; +mod thread; diff --git a/src/libcore/rt/sched.rs b/src/libcore/rt/sched.rs new file mode 100644 index 0000000000000..8f315452e5e5c --- /dev/null +++ b/src/libcore/rt/sched.rs @@ -0,0 +1,564 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use option::*; +use sys; +use cast::transmute; +use libc::c_void; +use ptr::mut_null; + +use super::work_queue::WorkQueue; +use super::stack::{StackPool, StackSegment}; +use super::io::{EventLoop, EventLoopObject}; +use super::context::Context; +use tls = super::thread_local_storage; + +#[cfg(test)] use super::uvio::UvEventLoop; +#[cfg(test)] use unstable::run_in_bare_thread; +#[cfg(test)] use int; + +/// The Scheduler is responsible for coordinating execution of Tasks +/// on a single thread. When the scheduler is running it is owned by +/// thread local storage and the running task is owned by the +/// scheduler. +pub struct Scheduler { + task_queue: WorkQueue<~Task>, + stack_pool: StackPool, + /// The event loop used to drive the scheduler and perform I/O + event_loop: ~EventLoopObject, + /// The scheduler's saved context. + /// Always valid when a task is executing, otherwise not + priv saved_context: Context, + /// The currently executing task + priv current_task: Option<~Task>, + /// A queue of jobs to perform immediately upon return from task + /// context to scheduler context. + /// XXX: This probably should be a single cleanup action and it + /// should run after a context switch, not on return from the + /// scheduler + priv cleanup_jobs: ~[CleanupJob] +} + +// XXX: Some hacks to put a &fn in Scheduler without borrowck +// complaining +type UnsafeTaskReceiver = sys::Closure; +trait HackAroundBorrowCk { + static fn from_fn(&fn(&mut Scheduler, ~Task)) -> Self; + fn to_fn(self) -> &fn(&mut Scheduler, ~Task); +} +impl HackAroundBorrowCk for UnsafeTaskReceiver { + static fn from_fn(f: &fn(&mut Scheduler, ~Task)) -> UnsafeTaskReceiver { + unsafe { transmute(f) } + } + fn to_fn(self) -> &fn(&mut Scheduler, ~Task) { + unsafe { transmute(self) } + } +} + +enum CleanupJob { + RescheduleTask(~Task), + RecycleTask(~Task), + GiveTask(~Task, UnsafeTaskReceiver) +} + +pub impl Scheduler { + + static fn new(event_loop: ~EventLoopObject) -> Scheduler { + Scheduler { + event_loop: event_loop, + task_queue: WorkQueue::new(), + stack_pool: StackPool::new(), + saved_context: Context::empty(), + current_task: None, + cleanup_jobs: ~[] + } + } + + // XXX: This may eventually need to be refactored so that + // the scheduler itself doesn't have to call event_loop.run. + // That will be important for embedding the runtime into external + // event loops. + fn run(~self) -> ~Scheduler { + fail_unless!(!self.in_task_context()); + + // Give ownership of the scheduler (self) to the thread + do self.install |scheduler| { + fn run_scheduler_once() { + do Scheduler::local |scheduler| { + if scheduler.resume_task_from_queue() { + // Ok, a task ran. Nice! We'll do it again later + scheduler.event_loop.callback(run_scheduler_once); + } + } + } + + scheduler.event_loop.callback(run_scheduler_once); + scheduler.event_loop.run(); + } + } + + fn install(~self, f: &fn(&mut Scheduler)) -> ~Scheduler { + let mut tlsched = ThreadLocalScheduler::new(); + tlsched.put_scheduler(self); + { + let sched = tlsched.get_scheduler(); + f(sched); + } + return tlsched.take_scheduler(); + } + + static fn local(f: &fn(&mut Scheduler)) { + let mut tlsched = ThreadLocalScheduler::new(); + f(tlsched.get_scheduler()); + } + + // * Scheduler-context operations + + fn resume_task_from_queue(&mut self) -> bool { + fail_unless!(!self.in_task_context()); + + let mut self = self; + match self.task_queue.pop_front() { + Some(task) => { + self.resume_task_immediately(task); + return true; + } + None => { + rtdebug!("no tasks in queue"); + return false; + } + } + } + + fn resume_task_immediately(&mut self, task: ~Task) { + fail_unless!(!self.in_task_context()); + + rtdebug!("scheduling a task"); + + // Store the task in the scheduler so it can be grabbed later + self.current_task = Some(task); + self.swap_in_task(); + // The running task should have passed ownership elsewhere + fail_unless!(self.current_task.is_none()); + + // Running tasks may have asked us to do some cleanup + self.run_cleanup_jobs(); + } + + + // * Task-context operations + + /// Called by a running task to end execution, after which it will + /// be recycled by the scheduler for reuse in a new task. + fn terminate_current_task(&mut self) { + fail_unless!(self.in_task_context()); + + rtdebug!("ending running task"); + + let dead_task = self.current_task.swap_unwrap(); + self.enqueue_cleanup_job(RecycleTask(dead_task)); + let dead_task = self.task_from_last_cleanup_job(); + self.swap_out_task(dead_task); + } + + /// Block a running task, context switch to the scheduler, then pass the + /// blocked task to a closure. + /// + /// # Safety note + /// + /// The closure here is a *stack* closure that lives in the + /// running task. It gets transmuted to the scheduler's lifetime + /// and called while the task is blocked. + fn block_running_task_and_then(&mut self, f: &fn(&mut Scheduler, ~Task)) { + fail_unless!(self.in_task_context()); + + rtdebug!("blocking task"); + + let blocked_task = self.current_task.swap_unwrap(); + let f_fake_region = unsafe { + transmute::<&fn(&mut Scheduler, ~Task), + &fn(&mut Scheduler, ~Task)>(f) + }; + let f_opaque = HackAroundBorrowCk::from_fn(f_fake_region); + self.enqueue_cleanup_job(GiveTask(blocked_task, f_opaque)); + let blocked_task = self.task_from_last_cleanup_job(); + + self.swap_out_task(blocked_task); + } + + /// Switch directly to another task, without going through the scheduler. + /// You would want to think hard about doing this, e.g. if there are + /// pending I/O events it would be a bad idea. + fn resume_task_from_running_task_direct(&mut self, next_task: ~Task) { + fail_unless!(self.in_task_context()); + + rtdebug!("switching tasks"); + + let old_running_task = self.current_task.swap_unwrap(); + self.enqueue_cleanup_job(RescheduleTask(old_running_task)); + let old_running_task = self.task_from_last_cleanup_job(); + + self.current_task = Some(next_task); + self.swap_in_task_from_running_task(old_running_task); + } + + + // * Context switching + + // NB: When switching to a task callers are expected to first set + // self.running_task. When switching away from a task likewise move + // out of the self.running_task + + priv fn swap_in_task(&mut self) { + // Take pointers to both the task and scheduler's saved registers. + let running_task: &~Task = self.current_task.get_ref(); + let task_context = &running_task.saved_context; + let scheduler_context = &mut self.saved_context; + + // Context switch to the task, restoring it's registers + // and saving the scheduler's + Context::swap(scheduler_context, task_context); + } + + priv fn swap_out_task(&mut self, running_task: &mut Task) { + let task_context = &mut running_task.saved_context; + let scheduler_context = &self.saved_context; + Context::swap(task_context, scheduler_context); + } + + priv fn swap_in_task_from_running_task(&mut self, + running_task: &mut Task) { + let running_task_context = &mut running_task.saved_context; + let next_context = &self.current_task.get_ref().saved_context; + Context::swap(running_task_context, next_context); + } + + + // * Other stuff + + fn in_task_context(&self) -> bool { self.current_task.is_some() } + + fn enqueue_cleanup_job(&mut self, job: CleanupJob) { + self.cleanup_jobs.unshift(job); + } + + fn run_cleanup_jobs(&mut self) { + fail_unless!(!self.in_task_context()); + rtdebug!("running cleanup jobs"); + + while !self.cleanup_jobs.is_empty() { + match self.cleanup_jobs.pop() { + RescheduleTask(task) => { + // NB: Pushing to the *front* of the queue + self.task_queue.push_front(task); + } + RecycleTask(task) => task.recycle(&mut self.stack_pool), + GiveTask(task, f) => (f.to_fn())(self, task) + } + } + } + + // XXX: Hack. This should return &self/mut but I don't know how to + // make the borrowcheck happy + fn task_from_last_cleanup_job(&mut self) -> &mut Task { + fail_unless!(!self.cleanup_jobs.is_empty()); + let last_job: &self/mut CleanupJob = &mut self.cleanup_jobs[0]; + let last_task: &self/Task = match last_job { + &RescheduleTask(~ref task) => task, + &RecycleTask(~ref task) => task, + &GiveTask(~ref task, _) => task, + }; + // XXX: Pattern matching mutable pointers above doesn't work + // because borrowck thinks the three patterns are conflicting + // borrows + return unsafe { transmute::<&Task, &mut Task>(last_task) }; + } +} + +const TASK_MIN_STACK_SIZE: uint = 10000000; // XXX: Too much stack + +pub struct Task { + /// The task entry point, saved here for later destruction + priv start: ~~fn(), + /// The segment of stack on which the task is currently running or, + /// if the task is blocked, on which the task will resume execution + priv current_stack_segment: StackSegment, + /// These are always valid when the task is not running, unless + /// the task is dead + priv saved_context: Context, +} + +impl Task { + static fn new(stack_pool: &mut StackPool, start: ~fn()) -> Task { + // XXX: Putting main into a ~ so it's a thin pointer and can + // be passed to the spawn function. Another unfortunate + // allocation + let start = ~Task::build_start_wrapper(start); + let mut stack = stack_pool.take_segment(TASK_MIN_STACK_SIZE); + // NB: Context holds a pointer to that ~fn + let initial_context = Context::new(&*start, &mut stack); + return Task { + start: start, + current_stack_segment: stack, + saved_context: initial_context, + }; + } + + static priv fn build_start_wrapper(start: ~fn()) -> ~fn() { + // XXX: The old code didn't have this extra allocation + let wrapper: ~fn() = || { + start(); + + let mut sched = ThreadLocalScheduler::new(); + let sched = sched.get_scheduler(); + sched.terminate_current_task(); + }; + return wrapper; + } + + /// Destroy the task and try to reuse its components + fn recycle(~self, stack_pool: &mut StackPool) { + match self { + ~Task {current_stack_segment, _} => { + stack_pool.give_segment(current_stack_segment); + } + } + } +} + +// NB: This is a type so we can use make use of the &self region. +struct ThreadLocalScheduler(tls::Key); + +impl ThreadLocalScheduler { + static fn new() -> ThreadLocalScheduler { + unsafe { + // NB: This assumes that the TLS key has been created prior. + // Currently done in rust_start. + let key: *mut c_void = rust_get_sched_tls_key(); + let key: &mut tls::Key = transmute(key); + ThreadLocalScheduler(*key) + } + } + + fn put_scheduler(&mut self, scheduler: ~Scheduler) { + unsafe { + let key = match self { &ThreadLocalScheduler(key) => key }; + let value: *mut c_void = + transmute::<~Scheduler, *mut c_void>(scheduler); + tls::set(key, value); + } + } + + fn get_scheduler(&mut self) -> &self/mut Scheduler { + unsafe { + let key = match self { &ThreadLocalScheduler(key) => key }; + let mut value: *mut c_void = tls::get(key); + fail_unless!(value.is_not_null()); + { + let value_ptr = &mut value; + let sched: &mut ~Scheduler = + transmute::<&mut *mut c_void, &mut ~Scheduler>(value_ptr); + let sched: &mut Scheduler = &mut **sched; + return sched; + } + } + } + + fn take_scheduler(&mut self) -> ~Scheduler { + unsafe { + let key = match self { &ThreadLocalScheduler(key) => key }; + let value: *mut c_void = tls::get(key); + fail_unless!(value.is_not_null()); + let sched = transmute(value); + tls::set(key, mut_null()); + return sched; + } + } +} + +extern { + fn rust_get_sched_tls_key() -> *mut c_void; +} + +#[test] +fn thread_local_scheduler_smoke_test() { + let scheduler = ~UvEventLoop::new_scheduler(); + let mut tls_scheduler = ThreadLocalScheduler::new(); + tls_scheduler.put_scheduler(scheduler); + { + let _scheduler = tls_scheduler.get_scheduler(); + } + let _scheduler = tls_scheduler.take_scheduler(); +} + +#[test] +fn thread_local_scheduler_two_instances() { + let scheduler = ~UvEventLoop::new_scheduler(); + let mut tls_scheduler = ThreadLocalScheduler::new(); + tls_scheduler.put_scheduler(scheduler); + { + + let _scheduler = tls_scheduler.get_scheduler(); + } + { + let scheduler = tls_scheduler.take_scheduler(); + tls_scheduler.put_scheduler(scheduler); + } + + let mut tls_scheduler = ThreadLocalScheduler::new(); + { + let _scheduler = tls_scheduler.get_scheduler(); + } + let _scheduler = tls_scheduler.take_scheduler(); +} + +#[test] +fn test_simple_scheduling() { + do run_in_bare_thread { + let mut task_ran = false; + let task_ran_ptr: *mut bool = &mut task_ran; + + let mut sched = ~UvEventLoop::new_scheduler(); + let task = ~do Task::new(&mut sched.stack_pool) { + unsafe { *task_ran_ptr = true; } + }; + sched.task_queue.push_back(task); + sched.run(); + fail_unless!(task_ran); + } +} + +#[test] +fn test_several_tasks() { + do run_in_bare_thread { + let total = 10; + let mut task_count = 0; + let task_count_ptr: *mut int = &mut task_count; + + let mut sched = ~UvEventLoop::new_scheduler(); + for int::range(0, total) |_| { + let task = ~do Task::new(&mut sched.stack_pool) { + unsafe { *task_count_ptr = *task_count_ptr + 1; } + }; + sched.task_queue.push_back(task); + } + sched.run(); + fail_unless!(task_count == total); + } +} + +#[test] +fn test_swap_tasks() { + do run_in_bare_thread { + let mut count = 0; + let count_ptr: *mut int = &mut count; + + let mut sched = ~UvEventLoop::new_scheduler(); + let task1 = ~do Task::new(&mut sched.stack_pool) { + unsafe { *count_ptr = *count_ptr + 1; } + do Scheduler::local |sched| { + let task2 = ~do Task::new(&mut sched.stack_pool) { + unsafe { *count_ptr = *count_ptr + 1; } + }; + // Context switch directly to the new task + sched.resume_task_from_running_task_direct(task2); + } + unsafe { *count_ptr = *count_ptr + 1; } + }; + sched.task_queue.push_back(task1); + sched.run(); + fail_unless!(count == 3); + } +} + +#[bench] #[test] #[ignore(reason = "long test")] +fn test_run_a_lot_of_tasks_queued() { + do run_in_bare_thread { + const MAX: int = 1000000; + let mut count = 0; + let count_ptr: *mut int = &mut count; + + let mut sched = ~UvEventLoop::new_scheduler(); + + let start_task = ~do Task::new(&mut sched.stack_pool) { + run_task(count_ptr); + }; + sched.task_queue.push_back(start_task); + sched.run(); + + fail_unless!(count == MAX); + + fn run_task(count_ptr: *mut int) { + do Scheduler::local |sched| { + let task = ~do Task::new(&mut sched.stack_pool) { + unsafe { + *count_ptr = *count_ptr + 1; + if *count_ptr != MAX { + run_task(count_ptr); + } + } + }; + sched.task_queue.push_back(task); + } + }; + } +} + +#[bench] #[test] #[ignore(reason = "too much stack allocation")] +fn test_run_a_lot_of_tasks_direct() { + do run_in_bare_thread { + const MAX: int = 100000; + let mut count = 0; + let count_ptr: *mut int = &mut count; + + let mut sched = ~UvEventLoop::new_scheduler(); + + let start_task = ~do Task::new(&mut sched.stack_pool) { + run_task(count_ptr); + }; + sched.task_queue.push_back(start_task); + sched.run(); + + fail_unless!(count == MAX); + + fn run_task(count_ptr: *mut int) { + do Scheduler::local |sched| { + let task = ~do Task::new(&mut sched.stack_pool) { + unsafe { + *count_ptr = *count_ptr + 1; + if *count_ptr != MAX { + run_task(count_ptr); + } + } + }; + // Context switch directly to the new task + sched.resume_task_from_running_task_direct(task); + } + }; + } +} + +#[test] +fn test_block_task() { + do run_in_bare_thread { + let mut sched = ~UvEventLoop::new_scheduler(); + let task = ~do Task::new(&mut sched.stack_pool) { + do Scheduler::local |sched| { + fail_unless!(sched.in_task_context()); + do sched.block_running_task_and_then() |sched, task| { + fail_unless!(!sched.in_task_context()); + sched.task_queue.push_back(task); + } + } + }; + sched.task_queue.push_back(task); + sched.run(); + } +} diff --git a/src/libcore/rt/stack.rs b/src/libcore/rt/stack.rs new file mode 100644 index 0000000000000..02c47218ed83f --- /dev/null +++ b/src/libcore/rt/stack.rs @@ -0,0 +1,49 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use vec; + +pub struct StackSegment { + buf: ~[u8] +} + +pub impl StackSegment { + static fn new(size: uint) -> StackSegment { + // Crate a block of uninitialized values + let mut stack = vec::with_capacity(size); + unsafe { + vec::raw::set_len(&mut stack, size); + } + + StackSegment { + buf: stack + } + } + + fn end(&self) -> *uint { + unsafe { + vec::raw::to_ptr(self.buf).offset(self.buf.len()) as *uint + } + } +} + +pub struct StackPool(()); + +impl StackPool { + + static fn new() -> StackPool { StackPool(()) } + + fn take_segment(&self, min_size: uint) -> StackSegment { + StackSegment::new(min_size) + } + + fn give_segment(&self, _stack: StackSegment) { + } +} diff --git a/src/libcore/rt/thread.rs b/src/libcore/rt/thread.rs new file mode 100644 index 0000000000000..cd46127451281 --- /dev/null +++ b/src/libcore/rt/thread.rs @@ -0,0 +1,44 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use libc; +use ops::Drop; + +#[allow(non_camel_case_types)] // runtime type +type raw_thread = libc::c_void; + +struct Thread { + main: ~fn(), + raw_thread: *raw_thread +} + +impl Thread { + static fn start(main: ~fn()) -> Thread { + fn substart(main: &fn()) -> *raw_thread { + unsafe { rust_raw_thread_start(main) } + } + let raw = substart(main); + Thread { + main: main, + raw_thread: raw + } + } +} + +impl Drop for Thread { + fn finalize(&self) { + unsafe { rust_raw_thread_join_delete(self.raw_thread) } + } +} + +extern { + pub unsafe fn rust_raw_thread_start(f: &fn()) -> *raw_thread; + pub unsafe fn rust_raw_thread_join_delete(thread: *raw_thread); +} diff --git a/src/libcore/rt/thread_local_storage.rs b/src/libcore/rt/thread_local_storage.rs new file mode 100644 index 0000000000000..58b5a54438606 --- /dev/null +++ b/src/libcore/rt/thread_local_storage.rs @@ -0,0 +1,91 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use libc::{c_void}; +#[cfg(unix)] +use libc::{c_uint, c_int}; +#[cfg(unix)] +use ptr::null; +#[cfg(windows)] +use libc::types::os::arch::extra::{DWORD, LPVOID, BOOL}; + +#[cfg(unix)] +pub type Key = pthread_key_t; + +#[cfg(unix)] +pub unsafe fn create(key: &mut Key) { + unsafe { fail_unless!(0 == pthread_key_create(key, null())); } +} + +#[cfg(unix)] +pub unsafe fn set(key: Key, value: *mut c_void) { + unsafe { fail_unless!(0 == pthread_setspecific(key, value)); } +} + +#[cfg(unix)] +pub unsafe fn get(key: Key) -> *mut c_void { + unsafe { pthread_getspecific(key) } +} + +#[cfg(unix)] +#[allow(non_camel_case_types)] // foreign type +type pthread_key_t = c_uint; + +#[cfg(unix)] +extern { + fn pthread_key_create(key: *mut pthread_key_t, dtor: *u8) -> c_int; + fn pthread_setspecific(key: pthread_key_t, value: *mut c_void) -> c_int; + fn pthread_getspecific(key: pthread_key_t) -> *mut c_void; +} + +#[cfg(windows)] +pub type Key = DWORD; + +#[cfg(windows)] +pub unsafe fn create(key: &mut Key) { + const TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF; + *key = unsafe { TlsAlloc() }; + fail_unless!(*key != TLS_OUT_OF_INDEXES); +} + +#[cfg(windows)] +pub unsafe fn set(key: Key, value: *mut c_void) { + unsafe { fail_unless!(0 != TlsSetValue(key, value)) } +} + +#[cfg(windows)] +pub unsafe fn get(key: Key) -> *mut c_void { + TlsGetValue(key) +} + +#[cfg(windows)] +#[abi = "stdcall"] +extern { + fn TlsAlloc() -> DWORD; + fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL; + fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID; +} + +#[test] +fn tls_smoke_test() { + use cast::transmute; + unsafe { + let mut key = 0; + let value = ~20; + create(&mut key); + set(key, transmute(value)); + let value: ~int = transmute(get(key)); + fail_unless!(value == ~20); + let value = ~30; + set(key, transmute(value)); + let value: ~int = transmute(get(key)); + fail_unless!(value == ~30); + } +} diff --git a/src/libcore/rt/uv.rs b/src/libcore/rt/uv.rs new file mode 100644 index 0000000000000..c947e4dde4c15 --- /dev/null +++ b/src/libcore/rt/uv.rs @@ -0,0 +1,919 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/*! + +Bindings to libuv. + +UV types consist of the event loop (Loop), Watchers, Requests and +Callbacks. + +Watchers and Requests encapsulate pointers to uv *handles*, which have +subtyping relationships with each other. This subtyping is reflected +in the bindings with explicit or implicit coercions. For example, an +upcast from TcpWatcher to StreamWatcher is done with +`tcp_watcher.as_stream()`. In other cases a callback on a specific +type of watcher will be passed a watcher of a supertype. + +Currently all use of Request types (connect/write requests) are +encapsulated in the bindings and don't need to be dealt with by the +caller. + +# Safety note + +Due to the complex lifecycle of uv handles, as well as compiler bugs, +this module is not memory safe and requires explicit memory management, +via `close` and `delete` methods. + +*/ + +use option::*; +use str::raw::from_c_str; +use to_str::ToStr; +use vec; +use ptr; +use libc::{c_void, c_int, size_t, malloc, free, ssize_t}; +use cast::{transmute, transmute_mut_region}; +use ptr::null; +use sys::size_of; +use unstable::uvll; +use super::io::{IpAddr, Ipv4, Ipv6}; + +#[cfg(test)] use unstable::run_in_bare_thread; +#[cfg(test)] use super::thread::Thread; +#[cfg(test)] use cell::Cell; + +fn ip4_to_uv_ip4(addr: IpAddr) -> uvll::sockaddr_in { + match addr { + Ipv4(a, b, c, d, p) => { + unsafe { + uvll::ip4_addr(fmt!("%u.%u.%u.%u", + a as uint, + b as uint, + c as uint, + d as uint), p as int) + } + } + Ipv6 => fail!() + } +} + +/// A trait for callbacks to implement. Provides a little extra type safety +/// for generic, unsafe interop functions like `set_watcher_callback`. +trait Callback { } + +type NullCallback = ~fn(); +impl Callback for NullCallback { } + +/// A type that wraps a native handle +trait NativeHandle { + static pub fn from_native_handle(T) -> Self; + pub fn native_handle(&self) -> T; +} + +/// XXX: Loop(*handle) is buggy with destructors. Normal structs +/// with dtors may not be destructured, but tuple structs can, +/// but the results are not correct. +pub struct Loop { + handle: *uvll::uv_loop_t +} + +pub impl Loop { + static fn new() -> Loop { + let handle = unsafe { uvll::loop_new() }; + fail_unless!(handle.is_not_null()); + NativeHandle::from_native_handle(handle) + } + + fn run(&mut self) { + unsafe { uvll::run(self.native_handle()) }; + } + + fn close(&mut self) { + unsafe { uvll::loop_delete(self.native_handle()) }; + } +} + +impl NativeHandle<*uvll::uv_loop_t> for Loop { + static fn from_native_handle(handle: *uvll::uv_loop_t) -> Loop { + Loop { handle: handle } + } + fn native_handle(&self) -> *uvll::uv_loop_t { + self.handle + } +} + +/// The trait implemented by uv 'watchers' (handles). Watchers are +/// non-owning wrappers around the uv handles and are not completely +/// safe - there may be multiple instances for a single underlying +/// handle. Watchers are generally created, then `start`ed, `stop`ed +/// and `close`ed, but due to their complex life cycle may not be +/// entirely memory safe if used in unanticipated patterns. +trait Watcher { + fn event_loop(&self) -> Loop; +} + +pub struct IdleWatcher(*uvll::uv_idle_t); + +impl Watcher for IdleWatcher { + fn event_loop(&self) -> Loop { + loop_from_watcher(self) + } +} + +type IdleCallback = ~fn(IdleWatcher, Option); +impl Callback for IdleCallback { } + +pub impl IdleWatcher { + static fn new(loop_: &mut Loop) -> IdleWatcher { + unsafe { + let handle = uvll::idle_new(); + fail_unless!(handle.is_not_null()); + fail_unless!(0 == uvll::idle_init(loop_.native_handle(), handle)); + uvll::set_data_for_uv_handle(handle, null::<()>()); + NativeHandle::from_native_handle(handle) + } + } + + fn start(&mut self, cb: IdleCallback) { + + set_watcher_callback(self, cb); + unsafe { + fail_unless!(0 == uvll::idle_start(self.native_handle(), idle_cb)) + }; + + extern fn idle_cb(handle: *uvll::uv_idle_t, status: c_int) { + let idle_watcher: IdleWatcher = + NativeHandle::from_native_handle(handle); + let cb: &IdleCallback = + borrow_callback_from_watcher(&idle_watcher); + let status = status_to_maybe_uv_error(handle, status); + (*cb)(idle_watcher, status); + } + } + + fn stop(&mut self) { + unsafe { fail_unless!(0 == uvll::idle_stop(self.native_handle())); } + } + + fn close(self) { + unsafe { uvll::close(self.native_handle(), close_cb) }; + + extern fn close_cb(handle: *uvll::uv_idle_t) { + let mut idle_watcher = NativeHandle::from_native_handle(handle); + drop_watcher_callback::(&mut idle_watcher); + unsafe { uvll::idle_delete(handle) }; + } + } +} + +impl NativeHandle<*uvll::uv_idle_t> for IdleWatcher { + static fn from_native_handle(handle: *uvll::uv_idle_t) -> IdleWatcher { + IdleWatcher(handle) + } + fn native_handle(&self) -> *uvll::uv_idle_t { + match self { &IdleWatcher(ptr) => ptr } + } +} + +// uv_stream t is the parent class of uv_tcp_t, uv_pipe_t, uv_tty_t +// and uv_file_t +pub struct StreamWatcher(*uvll::uv_stream_t); + +impl Watcher for StreamWatcher { + fn event_loop(&self) -> Loop { + loop_from_watcher(self) + } +} + +type ReadCallback = ~fn(StreamWatcher, int, Buf, Option); +impl Callback for ReadCallback { } + +// XXX: The uv alloc callback also has a *uv_handle_t arg +pub type AllocCallback = ~fn(uint) -> Buf; +impl Callback for AllocCallback { } + +pub impl StreamWatcher { + + fn read_start(&mut self, alloc: AllocCallback, cb: ReadCallback) { + // XXX: Borrowchk problems + let data = get_watcher_data(unsafe { transmute_mut_region(self) }); + data.alloc_cb = Some(alloc); + data.read_cb = Some(cb); + + let handle = self.native_handle(); + unsafe { uvll::read_start(handle, alloc_cb, read_cb); } + + extern fn alloc_cb(stream: *uvll::uv_stream_t, + suggested_size: size_t) -> Buf { + let mut stream_watcher: StreamWatcher = + NativeHandle::from_native_handle(stream); + let data = get_watcher_data(&mut stream_watcher); + let alloc_cb = data.alloc_cb.get_ref(); + return (*alloc_cb)(suggested_size as uint); + } + + extern fn read_cb(stream: *uvll::uv_stream_t, + nread: ssize_t, ++buf: Buf) { + rtdebug!("buf addr: %x", buf.base as uint); + rtdebug!("buf len: %d", buf.len as int); + let mut stream_watcher: StreamWatcher = + NativeHandle::from_native_handle(stream); + let data = get_watcher_data(&mut stream_watcher); + let cb = data.read_cb.get_ref(); + let status = status_to_maybe_uv_error(stream, nread as c_int); + (*cb)(stream_watcher, nread as int, buf, status); + } + } + + fn read_stop(&mut self) { + // It would be nice to drop the alloc and read callbacks here, + // but read_stop may be called from inside one of them and we + // would end up freeing the in-use environment + let handle = self.native_handle(); + unsafe { uvll::read_stop(handle); } + } + + // XXX: Needs to take &[u8], not ~[u8] + fn write(&mut self, msg: ~[u8], cb: ConnectionCallback) { + // XXX: Borrowck + let data = get_watcher_data(unsafe { transmute_mut_region(self) }); + fail_unless!(data.write_cb.is_none()); + data.write_cb = Some(cb); + + let req = WriteRequest::new(); + let buf = vec_to_uv_buf(msg); + // XXX: Allocation + let bufs = ~[buf]; + unsafe { + fail_unless!(0 == uvll::write(req.native_handle(), + self.native_handle(), + &bufs, write_cb)); + } + // XXX: Freeing immediately after write. Is this ok? + let _v = vec_from_uv_buf(buf); + + extern fn write_cb(req: *uvll::uv_write_t, status: c_int) { + let write_request: WriteRequest = + NativeHandle::from_native_handle(req); + let mut stream_watcher = write_request.stream(); + write_request.delete(); + let cb = get_watcher_data(&mut stream_watcher) + .write_cb.swap_unwrap(); + let status = status_to_maybe_uv_error( + stream_watcher.native_handle(), status); + cb(stream_watcher, status); + } + } + + fn accept(&mut self, stream: StreamWatcher) { + let self_handle = self.native_handle() as *c_void; + let stream_handle = stream.native_handle() as *c_void; + unsafe { + fail_unless!(0 == uvll::accept(self_handle, stream_handle)); + } + } + + fn close(self, cb: NullCallback) { + { + let mut self = self; + let data = get_watcher_data(&mut self); + fail_unless!(data.close_cb.is_none()); + data.close_cb = Some(cb); + } + + unsafe { uvll::close(self.native_handle(), close_cb); } + + extern fn close_cb(handle: *uvll::uv_stream_t) { + let mut stream_watcher: StreamWatcher = + NativeHandle::from_native_handle(handle); + { + let mut data = get_watcher_data(&mut stream_watcher); + data.close_cb.swap_unwrap()(); + } + drop_watcher_data(&mut stream_watcher); + unsafe { free(handle as *c_void) } + } + } +} + +impl NativeHandle<*uvll::uv_stream_t> for StreamWatcher { + static fn from_native_handle( + handle: *uvll::uv_stream_t) -> StreamWatcher { + StreamWatcher(handle) + } + fn native_handle(&self) -> *uvll::uv_stream_t { + match self { &StreamWatcher(ptr) => ptr } + } +} + +pub struct TcpWatcher(*uvll::uv_tcp_t); + +impl Watcher for TcpWatcher { + fn event_loop(&self) -> Loop { + loop_from_watcher(self) + } +} + +type ConnectionCallback = ~fn(StreamWatcher, Option); +impl Callback for ConnectionCallback { } + +pub impl TcpWatcher { + static fn new(loop_: &mut Loop) -> TcpWatcher { + unsafe { + let size = size_of::() as size_t; + let handle = malloc(size) as *uvll::uv_tcp_t; + fail_unless!(handle.is_not_null()); + fail_unless!(0 == uvll::tcp_init(loop_.native_handle(), handle)); + let mut watcher = NativeHandle::from_native_handle(handle); + install_watcher_data(&mut watcher); + return watcher; + } + } + + fn bind(&mut self, address: IpAddr) { + match address { + Ipv4(*) => { + let addr = ip4_to_uv_ip4(address); + let result = unsafe { + uvll::tcp_bind(self.native_handle(), &addr) + }; + // XXX: bind is likely to fail. need real error handling + fail_unless!(result == 0); + } + _ => fail!() + } + } + + fn connect(&mut self, address: IpAddr, cb: ConnectionCallback) { + unsafe { + fail_unless!(get_watcher_data(self).connect_cb.is_none()); + get_watcher_data(self).connect_cb = Some(cb); + + let mut connect_watcher = ConnectRequest::new(); + let connect_handle = connect_watcher.native_handle(); + match address { + Ipv4(*) => { + let addr = ip4_to_uv_ip4(address); + rtdebug!("connect_t: %x", connect_handle as uint); + fail_unless!(0 == uvll::tcp_connect(connect_handle, + self.native_handle(), + &addr, connect_cb)); + } + _ => fail!() + } + + extern fn connect_cb(req: *uvll::uv_connect_t, status: c_int) { + rtdebug!("connect_t: %x", req as uint); + let connect_request: ConnectRequest = + NativeHandle::from_native_handle(req); + let mut stream_watcher = connect_request.stream(); + connect_request.delete(); + let cb: ConnectionCallback = { + let data = get_watcher_data(&mut stream_watcher); + data.connect_cb.swap_unwrap() + }; + let status = status_to_maybe_uv_error( + stream_watcher.native_handle(), status); + cb(stream_watcher, status); + } + } + } + + fn listen(&mut self, cb: ConnectionCallback) { + // XXX: Borrowck + let data = get_watcher_data(unsafe { transmute_mut_region(self) }); + fail_unless!(data.connect_cb.is_none()); + data.connect_cb = Some(cb); + + unsafe { + const BACKLOG: c_int = 128; // XXX should be configurable + // XXX: This can probably fail + fail_unless!(0 == uvll::listen(self.native_handle(), + BACKLOG, connection_cb)); + } + + extern fn connection_cb(handle: *uvll::uv_stream_t, status: c_int) { + rtdebug!("connection_cb"); + let mut stream_watcher: StreamWatcher = + NativeHandle::from_native_handle(handle); + let cb = get_watcher_data(&mut stream_watcher) + .connect_cb.swap_unwrap(); + let status = status_to_maybe_uv_error( + stream_watcher.native_handle(), status); + cb(stream_watcher, status); + } + } + + fn as_stream(&self) -> StreamWatcher { + NativeHandle::from_native_handle( + self.native_handle() as *uvll::uv_stream_t) + } +} + +impl NativeHandle<*uvll::uv_tcp_t> for TcpWatcher { + static fn from_native_handle(handle: *uvll::uv_tcp_t) -> TcpWatcher { + TcpWatcher(handle) + } + fn native_handle(&self) -> *uvll::uv_tcp_t { + match self { &TcpWatcher(ptr) => ptr } + } +} + +trait Request { } + +type ConnectCallback = ~fn(ConnectRequest, Option); +impl Callback for ConnectCallback { } + +// uv_connect_t is a subclass of uv_req_t +struct ConnectRequest(*uvll::uv_connect_t); + +impl Request for ConnectRequest { } + +impl ConnectRequest { + + static fn new() -> ConnectRequest { + let connect_handle = unsafe { + malloc(size_of::() as size_t) + }; + fail_unless!(connect_handle.is_not_null()); + let connect_handle = connect_handle as *uvll::uv_connect_t; + ConnectRequest(connect_handle) + } + + fn stream(&self) -> StreamWatcher { + unsafe { + let stream_handle = + uvll::get_stream_handle_from_connect_req( + self.native_handle()); + NativeHandle::from_native_handle(stream_handle) + } + } + + fn delete(self) { + unsafe { free(self.native_handle() as *c_void) } + } +} + +impl NativeHandle<*uvll::uv_connect_t> for ConnectRequest { + static fn from_native_handle( + handle: *uvll:: uv_connect_t) -> ConnectRequest { + ConnectRequest(handle) + } + fn native_handle(&self) -> *uvll::uv_connect_t { + match self { &ConnectRequest(ptr) => ptr } + } +} + +pub struct WriteRequest(*uvll::uv_write_t); + +impl Request for WriteRequest { } + +impl WriteRequest { + + static fn new() -> WriteRequest { + let write_handle = unsafe { + malloc(size_of::() as size_t) + }; + fail_unless!(write_handle.is_not_null()); + let write_handle = write_handle as *uvll::uv_write_t; + WriteRequest(write_handle) + } + + fn stream(&self) -> StreamWatcher { + unsafe { + let stream_handle = + uvll::get_stream_handle_from_write_req(self.native_handle()); + NativeHandle::from_native_handle(stream_handle) + } + } + + fn delete(self) { + unsafe { free(self.native_handle() as *c_void) } + } +} + +impl NativeHandle<*uvll::uv_write_t> for WriteRequest { + static fn from_native_handle(handle: *uvll:: uv_write_t) -> WriteRequest { + WriteRequest(handle) + } + fn native_handle(&self) -> *uvll::uv_write_t { + match self { &WriteRequest(ptr) => ptr } + } +} + +// XXX: Need to define the error constants like EOF so they can be +// compared to the UvError type + +struct UvError(uvll::uv_err_t); + +impl UvError { + + pure fn name(&self) -> ~str { + unsafe { + let inner = match self { &UvError(ref a) => a }; + let name_str = uvll::err_name(inner); + fail_unless!(name_str.is_not_null()); + from_c_str(name_str) + } + } + + pure fn desc(&self) -> ~str { + unsafe { + let inner = match self { &UvError(ref a) => a }; + let desc_str = uvll::strerror(inner); + fail_unless!(desc_str.is_not_null()); + from_c_str(desc_str) + } + } +} + +impl ToStr for UvError { + pure fn to_str(&self) -> ~str { + fmt!("%s: %s", self.name(), self.desc()) + } +} + +#[test] +fn error_smoke_test() { + let err = uvll::uv_err_t { code: 1, sys_errno_: 1 }; + let err: UvError = UvError(err); + fail_unless!(err.to_str() == ~"EOF: end of file"); +} + + +/// Given a uv handle, convert a callback status to a UvError +// XXX: Follow the pattern below by parameterizing over T: Watcher, not T +fn status_to_maybe_uv_error(handle: *T, status: c_int) -> Option { + if status != -1 { + None + } else { + unsafe { + rtdebug!("handle: %x", handle as uint); + let loop_ = uvll::get_loop_for_uv_handle(handle); + rtdebug!("loop: %x", loop_ as uint); + let err = uvll::last_error(loop_); + Some(UvError(err)) + } + } +} + +/// Get the uv event loop from a Watcher +pub fn loop_from_watcher>( + watcher: &W) -> Loop { + + let handle = watcher.native_handle(); + let loop_ = unsafe { uvll::get_loop_for_uv_handle(handle) }; + NativeHandle::from_native_handle(loop_) +} + +/// Set the custom data on a handle to a callback Note: This is only +/// suitable for watchers that make just one type of callback. For +/// others use WatcherData +fn set_watcher_callback, CB: Callback>( + watcher: &mut W, cb: CB) { + + drop_watcher_callback::(watcher); + // XXX: Boxing the callback so it fits into a + // pointer. Unfortunate extra allocation + let boxed_cb = ~cb; + let data = unsafe { transmute::<~CB, *c_void>(boxed_cb) }; + unsafe { uvll::set_data_for_uv_handle(watcher.native_handle(), data) }; +} + +/// Delete a callback from a handle's custom data +fn drop_watcher_callback, CB: Callback>( + watcher: &mut W) { + + unsafe { + let handle = watcher.native_handle(); + let handle_data: *c_void = uvll::get_data_for_uv_handle(handle); + if handle_data.is_not_null() { + // Take ownership of the callback and drop it + let _cb = transmute::<*c_void, ~CB>(handle_data); + // Make sure the pointer is zeroed + uvll::set_data_for_uv_handle( + watcher.native_handle(), null::<()>()); + } + } +} + +/// Take a pointer to the callback installed as custom data +fn borrow_callback_from_watcher, + CB: Callback>(watcher: &W) -> &CB { + + unsafe { + let handle = watcher.native_handle(); + let handle_data: *c_void = uvll::get_data_for_uv_handle(handle); + fail_unless!(handle_data.is_not_null()); + let cb = transmute::<&*c_void, &~CB>(&handle_data); + return &**cb; + } +} + +/// Take ownership of the callback installed as custom data +fn take_callback_from_watcher, CB: Callback>( + watcher: &mut W) -> CB { + + unsafe { + let handle = watcher.native_handle(); + let handle_data: *c_void = uvll::get_data_for_uv_handle(handle); + fail_unless!(handle_data.is_not_null()); + uvll::set_data_for_uv_handle(handle, null::<()>()); + let cb: ~CB = transmute::<*c_void, ~CB>(handle_data); + let cb = match cb { ~cb => cb }; + return cb; + } +} + +/// Callbacks used by StreamWatchers, set as custom data on the foreign handle +struct WatcherData { + read_cb: Option, + write_cb: Option, + connect_cb: Option, + close_cb: Option, + alloc_cb: Option +} + +fn install_watcher_data>(watcher: &mut W) { + unsafe { + let data = ~WatcherData { + read_cb: None, + write_cb: None, + connect_cb: None, + close_cb: None, + alloc_cb: None + }; + let data = transmute::<~WatcherData, *c_void>(data); + uvll::set_data_for_uv_handle(watcher.native_handle(), data); + } +} + +fn get_watcher_data>( + watcher: &r/mut W) -> &r/mut WatcherData { + + unsafe { + let data = uvll::get_data_for_uv_handle(watcher.native_handle()); + let data = transmute::<&*c_void, &mut ~WatcherData>(&data); + return &mut **data; + } +} + +fn drop_watcher_data>(watcher: &mut W) { + unsafe { + let data = uvll::get_data_for_uv_handle(watcher.native_handle()); + let _data = transmute::<*c_void, ~WatcherData>(data); + uvll::set_data_for_uv_handle(watcher.native_handle(), null::<()>()); + } +} + +#[test] +fn test_slice_to_uv_buf() { + let slice = [0, .. 20]; + let buf = slice_to_uv_buf(slice); + + fail_unless!(buf.len == 20); + + unsafe { + let base = transmute::<*u8, *mut u8>(buf.base); + (*base) = 1; + (*ptr::mut_offset(base, 1)) = 2; + } + + fail_unless!(slice[0] == 1); + fail_unless!(slice[1] == 2); +} + +/// The uv buffer type +pub type Buf = uvll::uv_buf_t; + +/// Borrow a slice to a Buf +pub fn slice_to_uv_buf(v: &[u8]) -> Buf { + let data = unsafe { vec::raw::to_ptr(v) }; + unsafe { uvll::buf_init(data, v.len()) } +} + +// XXX: Do these conversions without copying + +/// Transmute an owned vector to a Buf +fn vec_to_uv_buf(v: ~[u8]) -> Buf { + let data = unsafe { malloc(v.len() as size_t) } as *u8; + fail_unless!(data.is_not_null()); + do vec::as_imm_buf(v) |b, l| { + let data = data as *mut u8; + unsafe { ptr::copy_memory(data, b, l) } + } + let buf = unsafe { uvll::buf_init(data, v.len()) }; + return buf; +} + +/// Transmute a Buf that was once a ~[u8] back to ~[u8] +fn vec_from_uv_buf(buf: Buf) -> Option<~[u8]> { + if !(buf.len == 0 && buf.base.is_null()) { + let v = unsafe { vec::from_buf(buf.base, buf.len as uint) }; + unsafe { free(buf.base as *c_void) }; + return Some(v); + } else { + // No buffer + return None; + } +} + +#[test] +fn loop_smoke_test() { + do run_in_bare_thread { + let mut loop_ = Loop::new(); + loop_.run(); + loop_.close(); + } +} + +#[test] +#[ignore(reason = "valgrind - loop destroyed before watcher?")] +fn idle_new_then_close() { + do run_in_bare_thread { + let mut loop_ = Loop::new(); + let mut idle_watcher = { IdleWatcher::new(&mut loop_) }; + idle_watcher.close(); + } +} + +#[test] +fn idle_smoke_test() { + do run_in_bare_thread { + let mut loop_ = Loop::new(); + let mut idle_watcher = { IdleWatcher::new(&mut loop_) }; + let mut count = 10; + let count_ptr: *mut int = &mut count; + do idle_watcher.start |idle_watcher, status| { + let mut idle_watcher = idle_watcher; + fail_unless!(status.is_none()); + if unsafe { *count_ptr == 10 } { + idle_watcher.stop(); + idle_watcher.close(); + } else { + unsafe { *count_ptr = *count_ptr + 1; } + } + } + loop_.run(); + loop_.close(); + fail_unless!(count == 10); + } +} + +#[test] +fn idle_start_stop_start() { + do run_in_bare_thread { + let mut loop_ = Loop::new(); + let mut idle_watcher = { IdleWatcher::new(&mut loop_) }; + do idle_watcher.start |idle_watcher, status| { + let mut idle_watcher = idle_watcher; + fail_unless!(status.is_none()); + idle_watcher.stop(); + do idle_watcher.start |idle_watcher, status| { + fail_unless!(status.is_none()); + let mut idle_watcher = idle_watcher; + idle_watcher.stop(); + idle_watcher.close(); + } + } + loop_.run(); + loop_.close(); + } +} + +#[test] +#[ignore(reason = "ffi struct issues")] +fn connect_close() { + do run_in_bare_thread() { + let mut loop_ = Loop::new(); + let mut tcp_watcher = { TcpWatcher::new(&mut loop_) }; + // Connect to a port where nobody is listening + let addr = Ipv4(127, 0, 0, 1, 2923); + do tcp_watcher.connect(addr) |stream_watcher, status| { + rtdebug!("tcp_watcher.connect!"); + fail_unless!(status.is_some()); + fail_unless!(status.get().name() == ~"ECONNREFUSED"); + stream_watcher.close(||()); + } + loop_.run(); + loop_.close(); + } +} + +#[test] +#[ignore(reason = "need a server to connect to")] +fn connect_read() { + do run_in_bare_thread() { + let mut loop_ = Loop::new(); + let mut tcp_watcher = { TcpWatcher::new(&mut loop_) }; + let addr = Ipv4(127, 0, 0, 1, 2924); + do tcp_watcher.connect(addr) |stream_watcher, status| { + let mut stream_watcher = stream_watcher; + rtdebug!("tcp_watcher.connect!"); + fail_unless!(status.is_none()); + let alloc: AllocCallback = |size| { + vec_to_uv_buf(vec::from_elem(size, 0)) + }; + do stream_watcher.read_start(alloc) + |stream_watcher, nread, buf, status| { + + let buf = vec_from_uv_buf(buf); + rtdebug!("read cb!"); + if status.is_none() { + let bytes = buf.unwrap(); + rtdebug!("%s", bytes.slice(0, nread as uint).to_str()); + } else { + rtdebug!("status after read: %s", status.get().to_str()); + rtdebug!("closing"); + stream_watcher.close(||()); + } + } + } + loop_.run(); + loop_.close(); + } +} + +#[test] +#[ignore(reason = "ffi struct issues")] +fn listen() { + do run_in_bare_thread() { + const MAX: int = 10; + let mut loop_ = Loop::new(); + let mut server_tcp_watcher = { TcpWatcher::new(&mut loop_) }; + let addr = Ipv4(127, 0, 0, 1, 2925); + server_tcp_watcher.bind(addr); + let loop_ = loop_; + rtdebug!("listening"); + do server_tcp_watcher.listen |server_stream_watcher, status| { + rtdebug!("listened!"); + fail_unless!(status.is_none()); + let mut server_stream_watcher = server_stream_watcher; + let mut loop_ = loop_; + let mut client_tcp_watcher = TcpWatcher::new(&mut loop_); + let mut client_tcp_watcher = client_tcp_watcher.as_stream(); + server_stream_watcher.accept(client_tcp_watcher); + let count_cell = Cell(0); + let server_stream_watcher = server_stream_watcher; + rtdebug!("starting read"); + let alloc: AllocCallback = |size| { + vec_to_uv_buf(vec::from_elem(size, 0)) + }; + do client_tcp_watcher.read_start(alloc) + |stream_watcher, nread, buf, status| { + + rtdebug!("i'm reading!"); + let buf = vec_from_uv_buf(buf); + let mut count = count_cell.take(); + if status.is_none() { + rtdebug!("got %d bytes", nread); + let buf = buf.unwrap(); + for buf.view(0, nread as uint).each |byte| { + fail_unless!(*byte == count as u8); + rtdebug!("%u", *byte as uint); + count += 1; + } + } else { + fail_unless!(count == MAX); + do stream_watcher.close { + server_stream_watcher.close(||()); + } + } + count_cell.put_back(count); + } + } + + let _client_thread = do Thread::start { + rtdebug!("starting client thread"); + let mut loop_ = Loop::new(); + let mut tcp_watcher = { TcpWatcher::new(&mut loop_) }; + do tcp_watcher.connect(addr) |stream_watcher, status| { + rtdebug!("connecting"); + fail_unless!(status.is_none()); + let mut stream_watcher = stream_watcher; + let msg = ~[0, 1, 2, 3, 4, 5, 6 ,7 ,8, 9]; + do stream_watcher.write(msg) |stream_watcher, status| { + rtdebug!("writing"); + fail_unless!(status.is_none()); + stream_watcher.close(||()); + } + } + loop_.run(); + loop_.close(); + }; + + let mut loop_ = loop_; + loop_.run(); + loop_.close(); + } +} diff --git a/src/libcore/rt/uvio.rs b/src/libcore/rt/uvio.rs new file mode 100644 index 0000000000000..f7275652e7f39 --- /dev/null +++ b/src/libcore/rt/uvio.rs @@ -0,0 +1,475 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use option::*; +use result::*; + +use super::uv::*; +use super::io::*; +use ops::Drop; +use cell::{Cell, empty_cell}; +use cast::transmute; +use super::StreamObject; +use super::sched::Scheduler; +use super::IoFactoryObject; + +#[cfg(test)] use super::sched::Task; +#[cfg(test)] use unstable::run_in_bare_thread; +#[cfg(test)] use uint; + +pub struct UvEventLoop { + uvio: UvIoFactory +} + +pub impl UvEventLoop { + static fn new() -> UvEventLoop { + UvEventLoop { + uvio: UvIoFactory(Loop::new()) + } + } + + /// A convenience constructor + static fn new_scheduler() -> Scheduler { + Scheduler::new(~UvEventLoop::new()) + } +} + +impl Drop for UvEventLoop { + fn finalize(&self) { + // XXX: Need mutable finalizer + let self = unsafe { + transmute::<&UvEventLoop, &mut UvEventLoop>(self) + }; + let mut uv_loop = self.uvio.uv_loop(); + uv_loop.close(); + } +} + +impl EventLoop for UvEventLoop { + + fn run(&mut self) { + self.uvio.uv_loop().run(); + } + + fn callback(&mut self, f: ~fn()) { + let mut idle_watcher = IdleWatcher::new(self.uvio.uv_loop()); + do idle_watcher.start |idle_watcher, status| { + fail_unless!(status.is_none()); + let mut idle_watcher = idle_watcher; + idle_watcher.stop(); + idle_watcher.close(); + f(); + } + } + + fn io(&mut self) -> Option<&self/mut IoFactoryObject> { + Some(&mut self.uvio) + } +} + +#[test] +fn test_callback_run_once() { + do run_in_bare_thread { + let mut event_loop = UvEventLoop::new(); + let mut count = 0; + let count_ptr: *mut int = &mut count; + do event_loop.callback { + unsafe { *count_ptr += 1 } + } + event_loop.run(); + fail_unless!(count == 1); + } +} + +pub struct UvIoFactory(Loop); + +pub impl UvIoFactory { + fn uv_loop(&mut self) -> &self/mut Loop { + match self { &UvIoFactory(ref mut ptr) => ptr } + } +} + +impl IoFactory for UvIoFactory { + // Connect to an address and return a new stream + // NB: This blocks the task waiting on the connection. + // It would probably be better to return a future + fn connect(&mut self, addr: IpAddr) -> Option<~StreamObject> { + // Create a cell in the task to hold the result. We will fill + // the cell before resuming the task. + let result_cell = empty_cell(); + let result_cell_ptr: *Cell> = &result_cell; + + do Scheduler::local |scheduler| { + fail_unless!(scheduler.in_task_context()); + + // Block this task and take ownership, switch to scheduler context + do scheduler.block_running_task_and_then |scheduler, task| { + + rtdebug!("connect: entered scheduler context"); + fail_unless!(!scheduler.in_task_context()); + let mut tcp_watcher = TcpWatcher::new(self.uv_loop()); + let task_cell = Cell(task); + + // Wait for a connection + do tcp_watcher.connect(addr) |stream_watcher, status| { + rtdebug!("connect: in connect callback"); + let maybe_stream = if status.is_none() { + rtdebug!("status is none"); + Some(~UvStream(stream_watcher)) + } else { + rtdebug!("status is some"); + stream_watcher.close(||()); + None + }; + + // Store the stream in the task's stack + unsafe { (*result_cell_ptr).put_back(maybe_stream); } + + // Context switch + do Scheduler::local |scheduler| { + scheduler.resume_task_immediately(task_cell.take()); + } + } + } + } + + fail_unless!(!result_cell.is_empty()); + return result_cell.take(); + } + + fn bind(&mut self, addr: IpAddr) -> Option<~TcpListenerObject> { + let mut watcher = TcpWatcher::new(self.uv_loop()); + watcher.bind(addr); + return Some(~UvTcpListener(watcher)); + } +} + +pub struct UvTcpListener(TcpWatcher); + +impl UvTcpListener { + fn watcher(&self) -> TcpWatcher { + match self { &UvTcpListener(w) => w } + } + + fn close(&self) { + // XXX: Need to wait until close finishes before returning + self.watcher().as_stream().close(||()); + } +} + +impl Drop for UvTcpListener { + fn finalize(&self) { + // XXX: Again, this never gets called. Use .close() instead + //self.watcher().as_stream().close(||()); + } +} + +impl TcpListener for UvTcpListener { + + fn listen(&mut self) -> Option<~StreamObject> { + rtdebug!("entering listen"); + let result_cell = empty_cell(); + let result_cell_ptr: *Cell> = &result_cell; + + let server_tcp_watcher = self.watcher(); + + do Scheduler::local |scheduler| { + fail_unless!(scheduler.in_task_context()); + + do scheduler.block_running_task_and_then |_, task| { + let task_cell = Cell(task); + let mut server_tcp_watcher = server_tcp_watcher; + do server_tcp_watcher.listen |server_stream_watcher, status| { + let maybe_stream = if status.is_none() { + let mut server_stream_watcher = server_stream_watcher; + let mut loop_ = + loop_from_watcher(&server_stream_watcher); + let mut client_tcp_watcher = + TcpWatcher::new(&mut loop_); + let mut client_tcp_watcher = + client_tcp_watcher.as_stream(); + // XXX: Need's to be surfaced in interface + server_stream_watcher.accept(client_tcp_watcher); + Some(~UvStream::new(client_tcp_watcher)) + } else { + None + }; + + unsafe { (*result_cell_ptr).put_back(maybe_stream); } + + rtdebug!("resuming task from listen"); + // Context switch + do Scheduler::local |scheduler| { + scheduler.resume_task_immediately(task_cell.take()); + } + } + } + } + + fail_unless!(!result_cell.is_empty()); + return result_cell.take(); + } +} + +pub struct UvStream(StreamWatcher); + +impl UvStream { + static fn new(watcher: StreamWatcher) -> UvStream { + UvStream(watcher) + } + + fn watcher(&self) -> StreamWatcher { + match self { &UvStream(w) => w } + } + + // XXX: finalize isn't working for ~UvStream??? + fn close(&self) { + // XXX: Need to wait until this finishes before returning + self.watcher().close(||()); + } +} + +impl Drop for UvStream { + fn finalize(&self) { + rtdebug!("closing stream"); + //self.watcher().close(||()); + } +} + +impl Stream for UvStream { + fn read(&mut self, buf: &mut [u8]) -> Result { + let result_cell = empty_cell(); + let result_cell_ptr: *Cell> = &result_cell; + + do Scheduler::local |scheduler| { + fail_unless!(scheduler.in_task_context()); + let watcher = self.watcher(); + let buf_ptr: *&mut [u8] = &buf; + do scheduler.block_running_task_and_then |scheduler, task| { + rtdebug!("read: entered scheduler context"); + fail_unless!(!scheduler.in_task_context()); + let mut watcher = watcher; + let task_cell = Cell(task); + // XXX: We shouldn't reallocate these callbacks every + // call to read + let alloc: AllocCallback = |_| unsafe { + slice_to_uv_buf(*buf_ptr) + }; + do watcher.read_start(alloc) |watcher, nread, _buf, status| { + + // Stop reading so that no read callbacks are + // triggered before the user calls `read` again. + // XXX: Is there a performance impact to calling + // stop here? + let mut watcher = watcher; + watcher.read_stop(); + + let result = if status.is_none() { + fail_unless!(nread >= 0); + Ok(nread as uint) + } else { + Err(()) + }; + + unsafe { (*result_cell_ptr).put_back(result); } + + do Scheduler::local |scheduler| { + scheduler.resume_task_immediately(task_cell.take()); + } + } + } + } + + fail_unless!(!result_cell.is_empty()); + return result_cell.take(); + } + + fn write(&mut self, buf: &[u8]) -> Result<(), ()> { + let result_cell = empty_cell(); + let result_cell_ptr: *Cell> = &result_cell; + do Scheduler::local |scheduler| { + fail_unless!(scheduler.in_task_context()); + let watcher = self.watcher(); + let buf_ptr: *&[u8] = &buf; + do scheduler.block_running_task_and_then |_, task| { + let mut watcher = watcher; + let task_cell = Cell(task); + let buf = unsafe { &*buf_ptr }; + // XXX: OMGCOPIES + let buf = buf.to_vec(); + do watcher.write(buf) |_watcher, status| { + let result = if status.is_none() { + Ok(()) + } else { + Err(()) + }; + + unsafe { (*result_cell_ptr).put_back(result); } + + do Scheduler::local |scheduler| { + scheduler.resume_task_immediately(task_cell.take()); + } + } + } + } + + fail_unless!(!result_cell.is_empty()); + return result_cell.take(); + } +} + +#[test] +#[ignore(reason = "ffi struct issues")] +fn test_simple_io_no_connect() { + do run_in_bare_thread { + let mut sched = ~UvEventLoop::new_scheduler(); + let task = ~do Task::new(&mut sched.stack_pool) { + do Scheduler::local |sched| { + let io = sched.event_loop.io().unwrap(); + let addr = Ipv4(127, 0, 0, 1, 2926); + let maybe_chan = io.connect(addr); + fail_unless!(maybe_chan.is_none()); + } + }; + sched.task_queue.push_back(task); + sched.run(); + } +} + +#[test] +#[ignore(reason = "ffi struct issues")] +fn test_simple_tcp_server_and_client() { + do run_in_bare_thread { + let mut sched = ~UvEventLoop::new_scheduler(); + let addr = Ipv4(127, 0, 0, 1, 2929); + + let client_task = ~do Task::new(&mut sched.stack_pool) { + do Scheduler::local |sched| { + let io = sched.event_loop.io().unwrap(); + let mut stream = io.connect(addr).unwrap(); + stream.write([0, 1, 2, 3, 4, 5, 6, 7]); + stream.close(); + } + }; + + let server_task = ~do Task::new(&mut sched.stack_pool) { + do Scheduler::local |sched| { + let io = sched.event_loop.io().unwrap(); + let mut listener = io.bind(addr).unwrap(); + let mut stream = listener.listen().unwrap(); + let mut buf = [0, .. 2048]; + let nread = stream.read(buf).unwrap(); + fail_unless!(nread == 8); + for uint::range(0, nread) |i| { + rtdebug!("%u", buf[i] as uint); + fail_unless!(buf[i] == i as u8); + } + stream.close(); + listener.close(); + } + }; + + // Start the server first so it listens before the client connects + sched.task_queue.push_back(server_task); + sched.task_queue.push_back(client_task); + sched.run(); + } +} + +#[test] #[ignore(reason = "busted")] +fn test_read_and_block() { + do run_in_bare_thread { + let mut sched = ~UvEventLoop::new_scheduler(); + let addr = Ipv4(127, 0, 0, 1, 2930); + + let client_task = ~do Task::new(&mut sched.stack_pool) { + do Scheduler::local |sched| { + let io = sched.event_loop.io().unwrap(); + let mut stream = io.connect(addr).unwrap(); + stream.write([0, 1, 2, 3, 4, 5, 6, 7]); + stream.write([0, 1, 2, 3, 4, 5, 6, 7]); + stream.write([0, 1, 2, 3, 4, 5, 6, 7]); + stream.write([0, 1, 2, 3, 4, 5, 6, 7]); + stream.close(); + } + }; + + let server_task = ~do Task::new(&mut sched.stack_pool) { + do Scheduler::local |sched| { + let io = sched.event_loop.io().unwrap(); + let mut listener = io.bind(addr).unwrap(); + let mut stream = listener.listen().unwrap(); + let mut buf = [0, .. 2048]; + + let expected = 32; + let mut current = 0; + let mut reads = 0; + + while current < expected { + let nread = stream.read(buf).unwrap(); + for uint::range(0, nread) |i| { + let val = buf[i] as uint; + fail_unless!(val == current % 8); + current += 1; + } + reads += 1; + + do Scheduler::local |scheduler| { + // Yield to the other task in hopes that it + // will trigger a read callback while we are + // not ready for it + do scheduler.block_running_task_and_then + |scheduler, task| { + scheduler.task_queue.push_back(task); + } + } + } + + // Make sure we had multiple reads + fail_unless!(reads > 1); + + stream.close(); + listener.close(); + } + }; + + // Start the server first so it listens before the client connects + sched.task_queue.push_back(server_task); + sched.task_queue.push_back(client_task); + sched.run(); + } +} + +#[test] #[ignore(reason = "needs server")] +fn test_read_read_read() { + do run_in_bare_thread { + let mut sched = ~UvEventLoop::new_scheduler(); + let addr = Ipv4(127, 0, 0, 1, 2931); + + let client_task = ~do Task::new(&mut sched.stack_pool) { + do Scheduler::local |sched| { + let io = sched.event_loop.io().unwrap(); + let mut stream = io.connect(addr).unwrap(); + let mut buf = [0, .. 2048]; + let mut total_bytes_read = 0; + while total_bytes_read < 500000000 { + let nread = stream.read(buf).unwrap(); + rtdebug!("read %u bytes", nread as uint); + total_bytes_read += nread; + } + rtdebug_!("read %u bytes total", total_bytes_read as uint); + stream.close(); + } + }; + + sched.task_queue.push_back(client_task); + sched.run(); + } +} diff --git a/src/libcore/rt/work_queue.rs b/src/libcore/rt/work_queue.rs new file mode 100644 index 0000000000000..1be2eb26e6292 --- /dev/null +++ b/src/libcore/rt/work_queue.rs @@ -0,0 +1,47 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use option::*; + +pub struct WorkQueue { + priv queue: ~[T] +} + +pub impl WorkQueue { + static fn new() -> WorkQueue { + WorkQueue { + queue: ~[] + } + } + + fn push_back(&mut self, value: T) { + self.queue.push(value) + } + + fn pop_back(&mut self) -> Option { + if !self.queue.is_empty() { + Some(self.queue.pop()) + } else { + None + } + } + + fn push_front(&mut self, value: T) { + self.queue.unshift(value) + } + + fn pop_front(&mut self) -> Option { + if !self.queue.is_empty() { + Some(self.queue.shift()) + } else { + None + } + } +} diff --git a/src/libcore/unstable.rs b/src/libcore/unstable.rs index 4f45535d0f856..7936b18dbe20c 100644 --- a/src/libcore/unstable.rs +++ b/src/libcore/unstable.rs @@ -35,6 +35,8 @@ pub mod extfmt; #[path = "unstable/lang.rs"] #[cfg(notest)] pub mod lang; +#[path = "unstable/uvll.rs"] +pub mod uvll; mod rustrt { use unstable::{raw_thread, rust_little_lock}; @@ -61,7 +63,7 @@ for it to terminate. The executing thread has no access to a task pointer and will be using a normal large stack. */ -pub unsafe fn run_in_bare_thread(f: ~fn()) { +pub fn run_in_bare_thread(f: ~fn()) { let (port, chan) = comm::stream(); // FIXME #4525: Unfortunate that this creates an extra scheduler but it's // necessary since rust_raw_thread_join_delete is blocking @@ -80,22 +82,18 @@ pub unsafe fn run_in_bare_thread(f: ~fn()) { #[test] fn test_run_in_bare_thread() { - unsafe { - let i = 100; - do run_in_bare_thread { - fail_unless!(i == 100); - } + let i = 100; + do run_in_bare_thread { + fail_unless!(i == 100); } } #[test] fn test_run_in_bare_thread_exchange() { - unsafe { - // Does the exchange heap work without the runtime? - let i = ~100; - do run_in_bare_thread { - fail_unless!(i == ~100); - } + // Does the exchange heap work without the runtime? + let i = ~100; + do run_in_bare_thread { + fail_unless!(i == ~100); } } diff --git a/src/libstd/uv_ll.rs b/src/libcore/unstable/uvll.rs similarity index 86% rename from src/libstd/uv_ll.rs rename to src/libcore/unstable/uvll.rs index fa415e0875b3e..0aed2567a220f 100644 --- a/src/libstd/uv_ll.rs +++ b/src/libcore/unstable/uvll.rs @@ -32,14 +32,15 @@ #[allow(non_camel_case_types)]; // C types -use core::libc::size_t; -use core::libc; -use core::prelude::*; -use core::ptr::to_unsafe_ptr; -use core::ptr; -use core::str; -use core::vec; -use core::comm::{stream, Chan, SharedChan, Port}; +use libc::size_t; +use libc::c_void; +use prelude::*; +use ptr::to_unsafe_ptr; + +pub type uv_handle_t = c_void; +pub type uv_loop_t = c_void; +pub type uv_idle_t = c_void; +pub type uv_idle_cb = *u8; // libuv struct mappings pub struct uv_ip4_addr { @@ -355,7 +356,10 @@ pub struct uv_getaddrinfo_t { } pub mod uv_ll_struct_stubgen { - use uv_ll::{ + + use ptr; + + use super::{ uv_async_t, uv_connect_t, uv_getaddrinfo_t, @@ -369,15 +373,13 @@ pub mod uv_ll_struct_stubgen { #[cfg(target_os = "android")] #[cfg(target_os = "macos")] #[cfg(target_os = "freebsd")] - use uv_ll::{ + use super::{ uv_async_t_32bit_unix_riders, uv_tcp_t_32bit_unix_riders, uv_timer_t_32bit_unix_riders, uv_write_t_32bit_unix_riders, }; - use core::ptr; - pub fn gen_stub_uv_tcp_t() -> uv_tcp_t { return gen_stub_os(); #[cfg(target_os = "linux")] @@ -724,157 +726,157 @@ pub mod uv_ll_struct_stubgen { } } -pub mod rustrt { - use super::{addrinfo, sockaddr_in, sockaddr_in6, uv_async_t, uv_buf_t}; - use super::{uv_connect_t, uv_err_t, uv_getaddrinfo_t, uv_stream_t}; - use super::{uv_tcp_t, uv_timer_t, uv_write_t}; - - use core::libc; - - #[nolink] - pub extern { - // libuv public API - unsafe fn rust_uv_loop_new() -> *libc::c_void; - unsafe fn rust_uv_loop_delete(lp: *libc::c_void); - unsafe fn rust_uv_run(loop_handle: *libc::c_void); - unsafe fn rust_uv_close(handle: *libc::c_void, cb: *u8); - unsafe fn rust_uv_walk(loop_handle: *libc::c_void, cb: *u8, - arg: *libc::c_void); - unsafe fn rust_uv_async_send(handle: *uv_async_t); - unsafe fn rust_uv_async_init(loop_handle: *libc::c_void, - async_handle: *uv_async_t, - cb: *u8) -> libc::c_int; - unsafe fn rust_uv_tcp_init( - loop_handle: *libc::c_void, - handle_ptr: *uv_tcp_t) -> libc::c_int; - // FIXME ref #2604 .. ? - unsafe fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8, - len: libc::size_t); - unsafe fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t; - // FIXME ref #2064 - unsafe fn rust_uv_strerror(err: *uv_err_t) -> *libc::c_char; - // FIXME ref #2064 - unsafe fn rust_uv_err_name(err: *uv_err_t) -> *libc::c_char; - unsafe fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int) - -> sockaddr_in; - unsafe fn rust_uv_ip6_addr(ip: *u8, port: libc::c_int) - -> sockaddr_in6; - unsafe fn rust_uv_ip4_name(src: *sockaddr_in, - dst: *u8, - size: libc::size_t) - -> libc::c_int; - unsafe fn rust_uv_ip6_name(src: *sockaddr_in6, - dst: *u8, - size: libc::size_t) - -> libc::c_int; - unsafe fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint; - unsafe fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint; - // FIXME ref #2064 - unsafe fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t, - tcp_handle_ptr: *uv_tcp_t, - ++after_cb: *u8, - ++addr: *sockaddr_in) -> libc::c_int; - // FIXME ref #2064 - unsafe fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, - ++addr: *sockaddr_in) -> libc::c_int; - // FIXME ref #2064 - unsafe fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t, - tcp_handle_ptr: *uv_tcp_t, - ++after_cb: *u8, - ++addr: *sockaddr_in6) -> libc::c_int; - // FIXME ref #2064 - unsafe fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, - ++addr: *sockaddr_in6) -> libc::c_int; - unsafe fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, - ++name: *sockaddr_in) - -> libc::c_int; - unsafe fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, - ++name: *sockaddr_in6) - -> libc::c_int; - unsafe fn rust_uv_listen(stream: *libc::c_void, - backlog: libc::c_int, - cb: *u8) -> libc::c_int; - unsafe fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void) - -> libc::c_int; - unsafe fn rust_uv_write(req: *libc::c_void, - stream: *libc::c_void, - ++buf_in: *uv_buf_t, - buf_cnt: libc::c_int, - cb: *u8) - -> libc::c_int; - unsafe fn rust_uv_read_start(stream: *libc::c_void, - on_alloc: *u8, - on_read: *u8) - -> libc::c_int; - unsafe fn rust_uv_read_stop(stream: *libc::c_void) -> libc::c_int; - unsafe fn rust_uv_timer_init(loop_handle: *libc::c_void, - timer_handle: *uv_timer_t) - -> libc::c_int; - unsafe fn rust_uv_timer_start( - timer_handle: *uv_timer_t, - cb: *u8, - timeout: libc::c_uint, - repeat: libc::c_uint) -> libc::c_int; - unsafe fn rust_uv_timer_stop(handle: *uv_timer_t) -> libc::c_int; - - unsafe fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void, - handle: *uv_getaddrinfo_t, - cb: *u8, - node_name_ptr: *u8, - service_name_ptr: *u8, - // should probably only pass ptr::null() - hints: *addrinfo) - -> libc::c_int; - unsafe fn rust_uv_freeaddrinfo(res: *addrinfo); - - // data accessors/helpers for rust-mapped uv structs - unsafe fn rust_uv_helper_get_INADDR_NONE() -> u32; - unsafe fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool; - unsafe fn rust_uv_is_ipv6_addrinfo(input: *addrinfo) -> bool; - unsafe fn rust_uv_get_next_addrinfo(input: *addrinfo) -> *addrinfo; - unsafe fn rust_uv_addrinfo_as_sockaddr_in(input: *addrinfo) - -> *sockaddr_in; - unsafe fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo) - -> *sockaddr_in6; - unsafe fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8; - unsafe fn rust_uv_free_base_of_buf(++buf: uv_buf_t); - unsafe fn rust_uv_get_stream_handle_from_connect_req( - connect_req: *uv_connect_t) - -> *uv_stream_t; - unsafe fn rust_uv_get_stream_handle_from_write_req( - write_req: *uv_write_t) - -> *uv_stream_t; - unsafe fn rust_uv_get_loop_for_uv_handle(handle: *libc::c_void) - -> *libc::c_void; - unsafe fn rust_uv_get_data_for_uv_loop(loop_ptr: *libc::c_void) - -> *libc::c_void; - unsafe fn rust_uv_set_data_for_uv_loop(loop_ptr: *libc::c_void, - data: *libc::c_void); - unsafe fn rust_uv_get_data_for_uv_handle(handle: *libc::c_void) - -> *libc::c_void; - unsafe fn rust_uv_set_data_for_uv_handle(handle: *libc::c_void, - data: *libc::c_void); - unsafe fn rust_uv_get_data_for_req(req: *libc::c_void) - -> *libc::c_void; - unsafe fn rust_uv_set_data_for_req(req: *libc::c_void, +#[nolink] +extern mod rustrt { + + // libuv public API + unsafe fn rust_uv_loop_new() -> *libc::c_void; + unsafe fn rust_uv_loop_delete(lp: *libc::c_void); + unsafe fn rust_uv_run(loop_handle: *libc::c_void); + unsafe fn rust_uv_close(handle: *libc::c_void, cb: *u8); + unsafe fn rust_uv_walk(loop_handle: *libc::c_void, cb: *u8, + arg: *libc::c_void); + + unsafe fn rust_uv_idle_new() -> *uv_idle_t; + unsafe fn rust_uv_idle_delete(handle: *uv_idle_t); + unsafe fn rust_uv_idle_init(loop_handle: *uv_loop_t, + handle: *uv_idle_t) -> libc::c_int; + unsafe fn rust_uv_idle_start(handle: *uv_idle_t, + cb: uv_idle_cb) -> libc::c_int; + unsafe fn rust_uv_idle_stop(handle: *uv_idle_t) -> libc::c_int; + + unsafe fn rust_uv_async_send(handle: *uv_async_t); + unsafe fn rust_uv_async_init(loop_handle: *libc::c_void, + async_handle: *uv_async_t, + cb: *u8) -> libc::c_int; + unsafe fn rust_uv_tcp_init( + loop_handle: *libc::c_void, + handle_ptr: *uv_tcp_t) -> libc::c_int; + // FIXME ref #2604 .. ? + unsafe fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8, + len: libc::size_t); + unsafe fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t; + // FIXME ref #2064 + unsafe fn rust_uv_strerror(err: *uv_err_t) -> *libc::c_char; + // FIXME ref #2064 + unsafe fn rust_uv_err_name(err: *uv_err_t) -> *libc::c_char; + unsafe fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int) + -> sockaddr_in; + unsafe fn rust_uv_ip6_addr(ip: *u8, port: libc::c_int) + -> sockaddr_in6; + unsafe fn rust_uv_ip4_name(src: *sockaddr_in, + dst: *u8, + size: libc::size_t) + -> libc::c_int; + unsafe fn rust_uv_ip6_name(src: *sockaddr_in6, + dst: *u8, + size: libc::size_t) + -> libc::c_int; + unsafe fn rust_uv_ip4_port(src: *sockaddr_in) -> libc::c_uint; + unsafe fn rust_uv_ip6_port(src: *sockaddr_in6) -> libc::c_uint; + // FIXME ref #2064 + unsafe fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t, + tcp_handle_ptr: *uv_tcp_t, + ++after_cb: *u8, + ++addr: *sockaddr_in) -> libc::c_int; + // FIXME ref #2064 + unsafe fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, + ++addr: *sockaddr_in) -> libc::c_int; + // FIXME ref #2064 + unsafe fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t, + tcp_handle_ptr: *uv_tcp_t, + ++after_cb: *u8, + ++addr: *sockaddr_in6) -> libc::c_int; + // FIXME ref #2064 + unsafe fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, + ++addr: *sockaddr_in6) -> libc::c_int; + unsafe fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, + ++name: *sockaddr_in) -> libc::c_int; + unsafe fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, + ++name: *sockaddr_in6) ->libc::c_int; + unsafe fn rust_uv_listen(stream: *libc::c_void, + backlog: libc::c_int, + cb: *u8) -> libc::c_int; + unsafe fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void) + -> libc::c_int; + unsafe fn rust_uv_write(req: *libc::c_void, + stream: *libc::c_void, + ++buf_in: *uv_buf_t, + buf_cnt: libc::c_int, + cb: *u8) + -> libc::c_int; + unsafe fn rust_uv_read_start(stream: *libc::c_void, + on_alloc: *u8, + on_read: *u8) + -> libc::c_int; + unsafe fn rust_uv_read_stop(stream: *libc::c_void) -> libc::c_int; + unsafe fn rust_uv_timer_init(loop_handle: *libc::c_void, + timer_handle: *uv_timer_t) + -> libc::c_int; + unsafe fn rust_uv_timer_start( + timer_handle: *uv_timer_t, + cb: *u8, + timeout: libc::c_uint, + repeat: libc::c_uint) -> libc::c_int; + unsafe fn rust_uv_timer_stop(handle: *uv_timer_t) -> libc::c_int; + + unsafe fn rust_uv_getaddrinfo(loop_ptr: *libc::c_void, + handle: *uv_getaddrinfo_t, + cb: *u8, + node_name_ptr: *u8, + service_name_ptr: *u8, + // should probably only pass ptr::null() + hints: *addrinfo) + -> libc::c_int; + unsafe fn rust_uv_freeaddrinfo(res: *addrinfo); + + // data accessors/helpers for rust-mapped uv structs + unsafe fn rust_uv_helper_get_INADDR_NONE() -> u32; + unsafe fn rust_uv_is_ipv4_addrinfo(input: *addrinfo) -> bool; + unsafe fn rust_uv_is_ipv6_addrinfo(input: *addrinfo) -> bool; + unsafe fn rust_uv_get_next_addrinfo(input: *addrinfo) -> *addrinfo; + unsafe fn rust_uv_addrinfo_as_sockaddr_in(input: *addrinfo) + -> *sockaddr_in; + unsafe fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo) + -> *sockaddr_in6; + unsafe fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8; + unsafe fn rust_uv_free_base_of_buf(++buf: uv_buf_t); + unsafe fn rust_uv_get_stream_handle_from_connect_req( + connect_req: *uv_connect_t) + -> *uv_stream_t; + unsafe fn rust_uv_get_stream_handle_from_write_req( + write_req: *uv_write_t) + -> *uv_stream_t; + unsafe fn rust_uv_get_loop_for_uv_handle(handle: *libc::c_void) + -> *libc::c_void; + unsafe fn rust_uv_get_data_for_uv_loop(loop_ptr: *libc::c_void) + -> *libc::c_void; + unsafe fn rust_uv_set_data_for_uv_loop(loop_ptr: *libc::c_void, data: *libc::c_void); - unsafe fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8; - unsafe fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t; - - // sizeof testing helpers - unsafe fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint; - unsafe fn rust_uv_helper_uv_connect_t_size() -> libc::c_uint; - unsafe fn rust_uv_helper_uv_buf_t_size() -> libc::c_uint; - unsafe fn rust_uv_helper_uv_write_t_size() -> libc::c_uint; - unsafe fn rust_uv_helper_uv_err_t_size() -> libc::c_uint; - unsafe fn rust_uv_helper_sockaddr_in_size() -> libc::c_uint; - unsafe fn rust_uv_helper_sockaddr_in6_size() -> libc::c_uint; - unsafe fn rust_uv_helper_uv_async_t_size() -> libc::c_uint; - unsafe fn rust_uv_helper_uv_timer_t_size() -> libc::c_uint; - unsafe fn rust_uv_helper_uv_getaddrinfo_t_size() -> libc::c_uint; - unsafe fn rust_uv_helper_addrinfo_size() -> libc::c_uint; - unsafe fn rust_uv_helper_addr_in_size() -> libc::c_uint; - } + unsafe fn rust_uv_get_data_for_uv_handle(handle: *libc::c_void) + -> *libc::c_void; + unsafe fn rust_uv_set_data_for_uv_handle(handle: *libc::c_void, + data: *libc::c_void); + unsafe fn rust_uv_get_data_for_req(req: *libc::c_void) + -> *libc::c_void; + unsafe fn rust_uv_set_data_for_req(req: *libc::c_void, + data: *libc::c_void); + unsafe fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8; + unsafe fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t; + + // sizeof testing helpers + unsafe fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint; + unsafe fn rust_uv_helper_uv_connect_t_size() -> libc::c_uint; + unsafe fn rust_uv_helper_uv_buf_t_size() -> libc::c_uint; + unsafe fn rust_uv_helper_uv_write_t_size() -> libc::c_uint; + unsafe fn rust_uv_helper_uv_err_t_size() -> libc::c_uint; + unsafe fn rust_uv_helper_sockaddr_in_size() -> libc::c_uint; + unsafe fn rust_uv_helper_sockaddr_in6_size() -> libc::c_uint; + unsafe fn rust_uv_helper_uv_async_t_size() -> libc::c_uint; + unsafe fn rust_uv_helper_uv_timer_t_size() -> libc::c_uint; + unsafe fn rust_uv_helper_uv_getaddrinfo_t_size() -> libc::c_uint; + unsafe fn rust_uv_helper_addrinfo_size() -> libc::c_uint; + unsafe fn rust_uv_helper_addr_in_size() -> libc::c_uint; } pub unsafe fn loop_new() -> *libc::c_void { @@ -897,6 +899,27 @@ pub unsafe fn walk(loop_handle: *libc::c_void, cb: *u8, arg: *libc::c_void) { rustrt::rust_uv_walk(loop_handle, cb, arg); } +pub unsafe fn idle_new() -> *uv_idle_t { + rustrt::rust_uv_idle_new() +} + +pub unsafe fn idle_delete(handle: *uv_idle_t) { + rustrt::rust_uv_idle_delete(handle) +} + +pub unsafe fn idle_init(loop_handle: *uv_loop_t, + handle: *uv_idle_t) -> libc::c_int { + rustrt::rust_uv_idle_init(loop_handle, handle) +} + +pub unsafe fn idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> libc::c_int { + rustrt::rust_uv_idle_start(handle, cb) +} + +pub unsafe fn idle_stop(handle: *uv_idle_t) -> libc::c_int { + rustrt::rust_uv_idle_stop(handle) +} + pub unsafe fn tcp_init(loop_handle: *libc::c_void, handle: *uv_tcp_t) -> libc::c_int { return rustrt::rust_uv_tcp_init(loop_handle, handle); @@ -1215,19 +1238,11 @@ pub unsafe fn addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6 { rustrt::rust_uv_addrinfo_as_sockaddr_in6(input) } -//#[cfg(test)] +#[cfg(test)] pub mod test { - use core::prelude::*; - - use uv_ll::*; - - use core::comm::{SharedChan, stream}; - use core::libc; - use core::ptr; - use core::str; - use core::sys; - use core::task; - use core::vec; + use prelude::*; + use super::*; + use comm::{SharedChan, stream, GenericChan, GenericPort}; enum tcp_read_data { tcp_read_eof, @@ -1473,7 +1488,7 @@ pub mod test { let client_data = get_data_for_uv_handle( client_stream_ptr as *libc::c_void) as *tcp_server_data; - let server_kill_msg = (*client_data).server_kill_msg; + let server_kill_msg = copy (*client_data).server_kill_msg; let write_req = (*client_data).server_write_req; if str::contains(request_str, server_kill_msg) { log(debug, ~"SERVER: client req contains kill_msg!"); @@ -1606,8 +1621,8 @@ pub mod test { fn impl_uv_tcp_server(server_ip: &str, server_port: int, - +kill_server_msg: ~str, - +server_resp_msg: ~str, + kill_server_msg: ~str, + server_resp_msg: ~str, server_chan: SharedChan<~str>, continue_chan: SharedChan) { unsafe { @@ -1725,10 +1740,12 @@ pub mod test { let (continue_port, continue_chan) = stream::(); let continue_chan = SharedChan(continue_chan); + let kill_server_msg_copy = copy kill_server_msg; + let server_resp_msg_copy = copy server_resp_msg; do task::spawn_sched(task::ManualThreads(1)) { impl_uv_tcp_server(bind_ip, port, - kill_server_msg, - server_resp_msg, + copy kill_server_msg_copy, + copy server_resp_msg_copy, server_chan.clone(), continue_chan.clone()); }; @@ -1738,9 +1755,10 @@ pub mod test { continue_port.recv(); log(debug, ~"received on continue port, set up tcp client"); + let kill_server_msg_copy = copy kill_server_msg; do task::spawn_sched(task::ManualThreads(1u)) { impl_uv_tcp_request(request_ip, port, - kill_server_msg, + kill_server_msg_copy, client_chan.clone()); }; @@ -1760,11 +1778,10 @@ pub mod test { pub mod tcp_and_server_client_test { #[cfg(target_arch="x86_64")] pub mod impl64 { - use uv_ll::test::*; #[test] pub fn test_uv_ll_tcp_server_and_request() { unsafe { - impl_uv_tcp_server_and_request(); + super::super::impl_uv_tcp_server_and_request(); } } } @@ -1772,12 +1789,11 @@ pub mod test { #[cfg(target_arch="arm")] #[cfg(target_arch="mips")] pub mod impl32 { - use uv_ll::test::*; #[test] #[ignore(cfg(target_os = "linux"))] pub fn test_uv_ll_tcp_server_and_request() { unsafe { - impl_uv_tcp_server_and_request(); + super::super::impl_uv_tcp_server_and_request(); } } } @@ -1804,7 +1820,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"uv_tcp_t", - ::uv_ll::rustrt::rust_uv_helper_uv_tcp_t_size() + super::rustrt::rust_uv_helper_uv_tcp_t_size() ); } } @@ -1813,7 +1829,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"uv_connect_t", - ::uv_ll::rustrt::rust_uv_helper_uv_connect_t_size() + super::rustrt::rust_uv_helper_uv_connect_t_size() ); } } @@ -1822,7 +1838,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"uv_buf_t", - ::uv_ll::rustrt::rust_uv_helper_uv_buf_t_size() + super::rustrt::rust_uv_helper_uv_buf_t_size() ); } } @@ -1831,7 +1847,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"uv_write_t", - ::uv_ll::rustrt::rust_uv_helper_uv_write_t_size() + super::rustrt::rust_uv_helper_uv_write_t_size() ); } } @@ -1841,7 +1857,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"sockaddr_in", - ::uv_ll::rustrt::rust_uv_helper_sockaddr_in_size() + super::rustrt::rust_uv_helper_sockaddr_in_size() ); } } @@ -1849,7 +1865,7 @@ pub mod test { fn test_uv_ll_struct_size_sockaddr_in6() { unsafe { let foreign_handle_size = - ::uv_ll::rustrt::rust_uv_helper_sockaddr_in6_size(); + super::rustrt::rust_uv_helper_sockaddr_in6_size(); let rust_handle_size = sys::size_of::(); let output = fmt!("sockaddr_in6 -- foreign: %u rust: %u", foreign_handle_size as uint, rust_handle_size); @@ -1868,7 +1884,7 @@ pub mod test { fn test_uv_ll_struct_size_addr_in() { unsafe { let foreign_handle_size = - ::uv_ll::rustrt::rust_uv_helper_addr_in_size(); + super::rustrt::rust_uv_helper_addr_in_size(); let rust_handle_size = sys::size_of::(); let output = fmt!("addr_in -- foreign: %u rust: %u", foreign_handle_size as uint, rust_handle_size); @@ -1884,7 +1900,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"uv_async_t", - ::uv_ll::rustrt::rust_uv_helper_uv_async_t_size() + super::rustrt::rust_uv_helper_uv_async_t_size() ); } } @@ -1894,7 +1910,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"uv_timer_t", - ::uv_ll::rustrt::rust_uv_helper_uv_timer_t_size() + super::rustrt::rust_uv_helper_uv_timer_t_size() ); } } @@ -1905,7 +1921,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"uv_getaddrinfo_t", - ::uv_ll::rustrt::rust_uv_helper_uv_getaddrinfo_t_size() + super::rustrt::rust_uv_helper_uv_getaddrinfo_t_size() ); } } @@ -1916,7 +1932,7 @@ pub mod test { unsafe { struct_size_check_common::( ~"addrinfo", - ::uv_ll::rustrt::rust_uv_helper_uv_timer_t_size() + super::rustrt::rust_uv_helper_uv_timer_t_size() ); } } diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs index 8021162188f79..a5e689077738b 100644 --- a/src/libstd/net_ip.rs +++ b/src/libstd/net_ip.rs @@ -21,20 +21,20 @@ use core::vec; use iotask = uv::iotask::IoTask; use interact = uv::iotask::interact; -use sockaddr_in = uv::ll::sockaddr_in; -use sockaddr_in6 = uv::ll::sockaddr_in6; -use addrinfo = uv::ll::addrinfo; -use uv_getaddrinfo_t = uv::ll::uv_getaddrinfo_t; -use uv_ip4_name = uv::ll::ip4_name; -use uv_ip4_port = uv::ll::ip4_port; -use uv_ip6_name = uv::ll::ip6_name; -use uv_ip6_port = uv::ll::ip6_port; -use uv_getaddrinfo = uv::ll::getaddrinfo; -use uv_freeaddrinfo = uv::ll::freeaddrinfo; -use create_uv_getaddrinfo_t = uv::ll::getaddrinfo_t; -use set_data_for_req = uv::ll::set_data_for_req; -use get_data_for_req = uv::ll::get_data_for_req; -use ll = uv::ll; +use sockaddr_in = core::unstable::uvll::sockaddr_in; +use sockaddr_in6 = core::unstable::uvll::sockaddr_in6; +use addrinfo = core::unstable::uvll::addrinfo; +use uv_getaddrinfo_t = core::unstable::uvll::uv_getaddrinfo_t; +use uv_ip4_name = core::unstable::uvll::ip4_name; +use uv_ip4_port = core::unstable::uvll::ip4_port; +use uv_ip6_name = core::unstable::uvll::ip6_name; +use uv_ip6_port = core::unstable::uvll::ip6_port; +use uv_getaddrinfo = core::unstable::uvll::getaddrinfo; +use uv_freeaddrinfo = core::unstable::uvll::freeaddrinfo; +use create_uv_getaddrinfo_t = core::unstable::uvll::getaddrinfo_t; +use set_data_for_req = core::unstable::uvll::set_data_for_req; +use get_data_for_req = core::unstable::uvll::get_data_for_req; +use ll = core::unstable::uvll; /// An IP address pub enum IpAddr { diff --git a/src/libstd/std.rc b/src/libstd/std.rc index a3b18e50df26a..85e914a60a140 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -36,6 +36,8 @@ not required in or otherwise suitable for the core library. extern mod core(vers = "0.6"); use core::*; +pub use uv_ll = core::unstable::uvll; + // General io and system-services modules pub mod net; @@ -45,7 +47,6 @@ pub mod net_url; // libuv modules pub mod uv; -pub mod uv_ll; pub mod uv_iotask; pub mod uv_global_loop; diff --git a/src/libstd/uv.rs b/src/libstd/uv.rs index 1a4f8e8990646..aaddc9b6836f3 100644 --- a/src/libstd/uv.rs +++ b/src/libstd/uv.rs @@ -33,6 +33,6 @@ * facilities. */ -pub use ll = uv_ll; +pub use ll = core::unstable::uvll; pub use iotask = uv_iotask; pub use global_loop = uv_global_loop; diff --git a/src/libuv b/src/libuv index 218ab86721eef..576ab1db8ea03 160000 --- a/src/libuv +++ b/src/libuv @@ -1 +1 @@ -Subproject commit 218ab86721eefd7b7e97fa6d9f95a80a1fa8686c +Subproject commit 576ab1db8ea03889eb7b2274654afe7c5c867230 diff --git a/src/rt/arch/i386/_context.S b/src/rt/arch/i386/_context.S index a9e329f0bf358..d8b7281e72b75 100644 --- a/src/rt/arch/i386/_context.S +++ b/src/rt/arch/i386/_context.S @@ -15,9 +15,15 @@ getcontext. The registers_t variable is in (%esp) */ +#if defined(__APPLE__) || defined(_WIN32) +#define SWAP_REGISTERS _swap_registers +#else +#define SWAP_REGISTERS swap_registers +#endif + // swap_registers(registers_t *oregs, registers_t *regs) -.globl swap_registers -swap_registers: +.globl SWAP_REGISTERS +SWAP_REGISTERS: // save the old context movl 4(%esp), %eax movl %ebx, 4(%eax) diff --git a/src/rt/arch/i386/context.cpp b/src/rt/arch/i386/context.cpp index 50a15e8d86c82..94e6f0418d07c 100644 --- a/src/rt/arch/i386/context.cpp +++ b/src/rt/arch/i386/context.cpp @@ -13,8 +13,7 @@ #include "../../rust_globals.h" extern "C" uint32_t CDECL swap_registers(registers_t *oregs, - registers_t *regs) - asm ("swap_registers"); + registers_t *regs); context::context() { diff --git a/src/rt/arch/x86_64/_context.S b/src/rt/arch/x86_64/_context.S index 7fdc6114b0a6b..1f9ae1c83c565 100644 --- a/src/rt/arch/x86_64/_context.S +++ b/src/rt/arch/x86_64/_context.S @@ -49,9 +49,15 @@ First four arguments: anyhow. */ +#if defined(__APPLE__) || defined(_WIN32) +#define SWAP_REGISTERS _swap_registers +#else +#define SWAP_REGISTERS swap_registers +#endif + // swap_registers(registers_t *oregs, registers_t *regs) -.globl swap_registers -swap_registers: +.globl SWAP_REGISTERS +SWAP_REGISTERS: // n.b. when we enter, the return address is at the top of // the stack (i.e., 0(%RSP)) and the argument is in // RUSTRT_ARG0_S. We diff --git a/src/rt/arch/x86_64/context.cpp b/src/rt/arch/x86_64/context.cpp index b7f82b574680b..6a265dff76156 100644 --- a/src/rt/arch/x86_64/context.cpp +++ b/src/rt/arch/x86_64/context.cpp @@ -13,8 +13,7 @@ #include "../../rust_globals.h" extern "C" void CDECL swap_registers(registers_t *oregs, - registers_t *regs) -asm ("swap_registers"); + registers_t *regs); context::context() { diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index 803da32cbc8ac..d9ef6a52dbef6 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -21,6 +21,17 @@ void* global_crate_map = NULL; +#ifndef _WIN32 +pthread_key_t sched_key; +#else +DWORD sched_key; +#endif + +extern "C" void* +rust_get_sched_tls_key() { + return &sched_key; +} + /** The runtime entrypoint. The (C ABI) main function generated by rustc calls `rust_start`, providing the address of the Rust ABI main function, the @@ -30,6 +41,10 @@ void* global_crate_map = NULL; extern "C" CDECL int rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) { +#ifndef _WIN32 + pthread_key_create(&sched_key, NULL); +#endif + // Load runtime configuration options from the environment. // FIXME #1497: Should provide a way to get these from the command // line as well. diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index a621d61cdf792..248f851e5b9f8 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -769,20 +769,20 @@ extern "C" CDECL void record_sp_limit(void *limit); class raw_thread: public rust_thread { public: - fn_env_pair *fn; + fn_env_pair fn; - raw_thread(fn_env_pair *fn) : fn(fn) { } + raw_thread(fn_env_pair fn) : fn(fn) { } virtual void run() { record_sp_limit(0); - fn->f(NULL, fn->env, NULL); + fn.f(NULL, fn.env, NULL); } }; extern "C" raw_thread* rust_raw_thread_start(fn_env_pair *fn) { assert(fn); - raw_thread *thread = new raw_thread(fn); + raw_thread *thread = new raw_thread(*fn); thread->start(); return thread; } diff --git a/src/rt/rust_uv.cpp b/src/rt/rust_uv.cpp index f08261c336dcd..5159434873733 100644 --- a/src/rt/rust_uv.cpp +++ b/src/rt/rust_uv.cpp @@ -376,16 +376,7 @@ current_kernel_malloc_alloc_cb(uv_handle_t* handle, extern "C" void rust_uv_buf_init(uv_buf_t* out_buf, char* base, size_t len) { - rust_task* task = rust_get_current_task(); - LOG(task, stdlib,"rust_uv_buf_init: base: %lu" \ - "len: %lu", - (unsigned long int)base, - (unsigned long int)len); *out_buf = uv_buf_init(base, len); - LOG(task, stdlib, "rust_uv_buf_init: after: " - "result->base: %" PRIxPTR " len: %" PRIxPTR, - (unsigned long int)(*out_buf).base, - (unsigned long int)(*out_buf).len); } extern "C" uv_loop_t* @@ -481,18 +472,11 @@ rust_uv_free_base_of_buf(uv_buf_t buf) { extern "C" struct sockaddr_in rust_uv_ip4_addr(const char* ip, int port) { - rust_task* task = rust_get_current_task(); - LOG(task, stdlib, "before creating addr_ptr.. ip %s" \ - " port %d\n", ip, port); struct sockaddr_in addr = uv_ip4_addr(ip, port); - LOG(task, stdlib, "after creating .. port: %d", addr.sin_port); return addr; } extern "C" struct sockaddr_in6 rust_uv_ip6_addr(const char* ip, int port) { - rust_task* task = rust_get_current_task(); - LOG(task, stdlib, "before creating addr_ptr.. ip %s" \ - " port %d\n", ip, port); return uv_ip6_addr(ip, port); } extern "C" int @@ -554,3 +538,28 @@ extern "C" sockaddr_in6* rust_uv_addrinfo_as_sockaddr_in6(addrinfo* input) { return (sockaddr_in6*)input->ai_addr; } + +extern "C" uv_idle_t* +rust_uv_idle_new() { + return new uv_idle_t; +} + +extern "C" void +rust_uv_idle_delete(uv_idle_t* handle) { + delete handle; +} + +extern "C" int +rust_uv_idle_init(uv_loop_t* loop, uv_idle_t* idle) { + return uv_idle_init(loop, idle); +} + +extern "C" int +rust_uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) { + return uv_idle_start(idle, cb); +} + +extern "C" int +rust_uv_idle_stop(uv_idle_t* idle) { + return uv_idle_stop(idle); +} diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 284f827bc753a..e27e0d5240503 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -140,6 +140,11 @@ rust_uv_current_kernel_malloc rust_uv_current_kernel_free rust_uv_getaddrinfo rust_uv_freeaddrinfo +rust_uv_idle_new +rust_uv_idle_delete +rust_uv_idle_init +rust_uv_idle_start +rust_uv_idle_stop rust_dbg_lock_create rust_dbg_lock_destroy rust_dbg_lock_lock @@ -187,3 +192,5 @@ rust_get_global_data_ptr rust_inc_kernel_live_count rust_dec_kernel_live_count rust_get_exchange_count_ptr +rust_get_sched_tls_key +swap_registers From 1e1efbf2c355c4ddb1356abe535d79525bad72ba Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Tue, 12 Mar 2013 00:49:06 -0400 Subject: [PATCH 43/43] Avoid propagating link_arg values that are unlikely to be resolveable under arbitrary directories. --- src/librustc/back/link.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index fec3f77668137..1437a3af7ddb6 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -818,7 +818,11 @@ pub fn link_binary(sess: Session, do cstore::iter_crate_data(cstore) |crate_num, _| { let link_args = csearch::get_link_args_for_crate(cstore, crate_num); do vec::consume(link_args) |_, link_arg| { - cc_args.push(link_arg); + // Linker arguments that don't begin with - are likely file names, + // so they should not be necessary. + if link_arg.starts_with("-") { + cc_args.push(link_arg); + } } }