From dc49018679e75e8641c8a8bb295075ec5f247d99 Mon Sep 17 00:00:00 2001 From: Jim Radford Date: Mon, 7 Apr 2014 17:55:14 -0700 Subject: [PATCH 01/16] sync: remove unsafe and add Send+Share to Deref (enabled by autoderef vtables) --- src/libsync/arc.rs | 6 ++---- src/libsync/lock.rs | 12 +++++------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/libsync/arc.rs b/src/libsync/arc.rs index ae76357a2be83..ecfeade2fb437 100644 --- a/src/libsync/arc.rs +++ b/src/libsync/arc.rs @@ -124,12 +124,10 @@ impl Clone for Arc { } } -// FIXME(#13042): this should have T: Send, and use self.inner() -impl Deref for Arc { +impl Deref for Arc { #[inline] fn deref<'a>(&'a self) -> &'a T { - let inner = unsafe { &*self.x }; - &inner.data + &self.inner().data } } diff --git a/src/libsync/lock.rs b/src/libsync/lock.rs index 67b725f040b4d..b83bdf9df299e 100644 --- a/src/libsync/lock.rs +++ b/src/libsync/lock.rs @@ -231,11 +231,10 @@ impl Mutex { } } -// FIXME(#13042): these should both have T: Send -impl<'a, T> Deref for MutexGuard<'a, T> { +impl<'a, T: Send> Deref for MutexGuard<'a, T> { fn deref<'a>(&'a self) -> &'a T { &*self.data } } -impl<'a, T> DerefMut for MutexGuard<'a, T> { +impl<'a, T: Send> DerefMut for MutexGuard<'a, T> { fn deref_mut<'a>(&'a mut self) -> &'a mut T { &mut *self.data } } @@ -363,14 +362,13 @@ impl<'a, T: Send + Share> RWLockWriteGuard<'a, T> { } } -// FIXME(#13042): these should all have T: Send + Share -impl<'a, T> Deref for RWLockReadGuard<'a, T> { +impl<'a, T: Send + Share> Deref for RWLockReadGuard<'a, T> { fn deref<'a>(&'a self) -> &'a T { self.data } } -impl<'a, T> Deref for RWLockWriteGuard<'a, T> { +impl<'a, T: Send + Share> Deref for RWLockWriteGuard<'a, T> { fn deref<'a>(&'a self) -> &'a T { &*self.data } } -impl<'a, T> DerefMut for RWLockWriteGuard<'a, T> { +impl<'a, T: Send + Share> DerefMut for RWLockWriteGuard<'a, T> { fn deref_mut<'a>(&'a mut self) -> &'a mut T { &mut *self.data } } From bc234ae1307f6c1ff72782a82b8222691bf67525 Mon Sep 17 00:00:00 2001 From: Tobba Date: Tue, 8 Apr 2014 01:08:49 +0200 Subject: [PATCH 02/16] Made libflate functions return Options instead of outright failing --- src/libflate/lib.rs | 34 ++++++++++++++++++------------- src/librustc/back/link.rs | 7 +++++-- src/librustc/back/lto.rs | 5 ++++- src/librustc/metadata/loader.rs | 9 +++++--- src/librustc/middle/trans/base.rs | 5 ++++- 5 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index 97e03561b8715..753a3120c2157 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -54,43 +54,49 @@ static LZ_NORM : c_int = 0x80; // LZ with 128 probes, "normal" static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adler32 checksum static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum -fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> CVec { +fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option> { unsafe { let mut outsz : size_t = 0; let res = rustrt::tdefl_compress_mem_to_heap(bytes.as_ptr() as *c_void, bytes.len() as size_t, &mut outsz, flags); - assert!(!res.is_null()); - CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res)) + if !res.is_null() { + Some(CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res))) + } else { + None + } } } -pub fn deflate_bytes(bytes: &[u8]) -> CVec { +pub fn deflate_bytes(bytes: &[u8]) -> Option> { deflate_bytes_internal(bytes, LZ_NORM) } -pub fn deflate_bytes_zlib(bytes: &[u8]) -> CVec { +pub fn deflate_bytes_zlib(bytes: &[u8]) -> Option> { deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER) } -fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> CVec { +fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option> { unsafe { let mut outsz : size_t = 0; let res = rustrt::tinfl_decompress_mem_to_heap(bytes.as_ptr() as *c_void, bytes.len() as size_t, &mut outsz, flags); - assert!(!res.is_null()); - CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res)) + if !res.is_null() { + Some(CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res))) + } else { + None + } } } -pub fn inflate_bytes(bytes: &[u8]) -> CVec { +pub fn inflate_bytes(bytes: &[u8]) -> Option> { inflate_bytes_internal(bytes, 0) } -pub fn inflate_bytes_zlib(bytes: &[u8]) -> CVec { +pub fn inflate_bytes_zlib(bytes: &[u8]) -> Option> { inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER) } @@ -117,8 +123,8 @@ mod tests { } debug!("de/inflate of {} bytes of random word-sequences", input.len()); - let cmp = deflate_bytes(input); - let out = inflate_bytes(cmp.as_slice()); + let cmp = deflate_bytes(input).expect("deflation failed"); + let out = inflate_bytes(cmp.as_slice()).expect("inflation failed"); debug!("{} bytes deflated to {} ({:.1f}% size)", input.len(), cmp.len(), 100.0 * ((cmp.len() as f64) / (input.len() as f64))); @@ -129,8 +135,8 @@ mod tests { #[test] fn test_zlib_flate() { let bytes = vec!(1, 2, 3, 4, 5); - let deflated = deflate_bytes(bytes.as_slice()); - let inflated = inflate_bytes(deflated.as_slice()); + let deflated = deflate_bytes(bytes.as_slice()).expect("deflation failed"); + let inflated = inflate_bytes(deflated.as_slice()).expect("inflation failed"); assert_eq!(inflated.as_slice(), bytes.as_slice()); } } diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 61725bc27d122..0946e375e4f7f 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -945,11 +945,14 @@ fn link_rlib<'a>(sess: &'a Session, let bc_deflated = obj_filename.with_extension("bc.deflate"); match fs::File::open(&bc).read_to_end().and_then(|data| { fs::File::create(&bc_deflated) - .write(flate::deflate_bytes(data.as_slice()).as_slice()) + .write(match flate::deflate_bytes(data.as_slice()) { + Some(compressed) => compressed, + None => sess.fatal("failed to compress bytecode") + }.as_slice()) }) { Ok(()) => {} Err(e) => { - sess.err(format!("failed to compress bytecode: {}", e)); + sess.err(format!("failed to write compressed bytecode: {}", e)); sess.abort_if_errors() } } diff --git a/src/librustc/back/lto.rs b/src/librustc/back/lto.rs index 3171114985e1f..8319be02bdbc3 100644 --- a/src/librustc/back/lto.rs +++ b/src/librustc/back/lto.rs @@ -56,7 +56,10 @@ pub fn run(sess: &session::Session, llmod: ModuleRef, archive.read(format!("{}.bc.deflate", name))); let bc = bc.expect("missing compressed bytecode in archive!"); let bc = time(sess.time_passes(), format!("inflate {}.bc", name), (), |_| - flate::inflate_bytes(bc)); + match flate::inflate_bytes(bc) { + Some(bc) => bc, + None => sess.fatal(format!("failed to decompress bc of `{}`", name)) + }); let ptr = bc.as_slice().as_ptr(); debug!("linking {}", name); time(sess.time_passes(), format!("ll link {}", name), (), |()| unsafe { diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 4f4ef31e15b37..8dea36d8152a2 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -494,14 +494,17 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Result found = Ok(MetadataVec(inflated)), + None => found = Err(format!("failed to decompress metadata for: '{}'", + filename.display())) + } }); if found.is_ok() { return found; diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index e48b8fc9db4cd..58edb717bf0bd 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2236,7 +2236,10 @@ pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec { let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item); let metadata = encoder::encode_metadata(encode_parms, krate); let compressed = encoder::metadata_encoding_version + - flate::deflate_bytes(metadata.as_slice()).as_slice(); + match flate::deflate_bytes(metadata.as_slice()) { + Some(compressed) => compressed, + None => cx.sess().fatal(format!("failed to compress metadata", )) + }.as_slice(); let llmeta = C_bytes(cx, compressed); let llconst = C_struct(cx, [llmeta], false); let name = format!("rust_metadata_{}_{}_{}", cx.link_meta.crateid.name, From c83afb9719ad6e2ae7d819b8096524e1147c4065 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 7 Apr 2014 14:34:56 -0700 Subject: [PATCH 03/16] doc: Document flavorful variations of paths Closes #4293 --- src/doc/rust.md | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/doc/rust.md b/src/doc/rust.md index afb21a19965b8..886c95b2c7560 100644 --- a/src/doc/rust.md +++ b/src/doc/rust.md @@ -432,7 +432,7 @@ operators](#binary-operator-expressions), or [keywords](#keywords). ## Paths ~~~~ {.notrust .ebnf .gram} -expr_path : ident [ "::" expr_path_tail ] + ; +expr_path : [ "::" ] ident [ "::" expr_path_tail ] + ; expr_path_tail : '<' type_expr [ ',' type_expr ] + '>' | expr_path ; @@ -475,6 +475,51 @@ let x = id::(10); // Type arguments used in a call expression # } ~~~~ +Paths can be denoted with various leading qualifiers to change the meaning of +how it is resolved: + +* Paths starting with `::` are considered to be global paths where the + components of the path start being resolved from the crate root. Each + identifier in the path must resolve to an item. + + ```rust + mod a { + pub fn foo() {} + } + mod b { + pub fn foo() { + ::a::foo(); // call a's foo function + } + } + # fn main() {} + ``` + +* Paths starting with the keyword `super` begin resolution relative to the + parent module. Each further identifier must resolve to an item + + ```rust + mod a { + pub fn foo() {} + } + mod b { + pub fn foo() { + super::a::foo(); // call a's foo function + } + } + # fn main() {} + ``` + +* Paths starting with the keyword `self` begin resolution relative to the + current module. Each further identifier must resolve to an item. + + ```rust + fn foo() {} + fn bar() { + self::foo(); + } + # fn main() {} + ``` + # Syntax extensions A number of minor features of Rust are not central enough to have their own From c3ea3e439fbc5251279d914a95cd8344556982cb Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 7 Apr 2014 13:30:48 -0700 Subject: [PATCH 04/16] Register new snapshots --- src/doc/complement-cheatsheet.md | 2 +- src/doc/rust.md | 2 +- src/libcollections/deque.rs | 2 +- src/libgreen/basic.rs | 4 +- src/liblibc/lib.rs | 9 +--- src/libnative/io/p | 0 src/libnative/io/process.rs | 4 +- src/libnative/task.rs | 6 +-- src/librand/distributions/mod.rs | 4 +- src/librand/lib.rs | 2 +- src/librustc/front/config.rs | 2 +- src/librustc/lib.rs | 2 +- src/librustc/metadata/decoder.rs | 12 ++--- src/librustc/metadata/encoder.rs | 6 +-- src/librustc/metadata/filesearch.rs | 2 +- src/librustc/metadata/tydecode.rs | 2 +- src/librustc/middle/trans/_match.rs | 2 +- src/librustc/middle/trans/base.rs | 2 +- src/librustc/middle/trans/tvec.rs | 2 +- src/librustc/middle/ty_fold.rs | 12 ++--- .../middle/typeck/check/regionmanip.rs | 2 +- src/librustc/middle/typeck/infer/lattice.rs | 4 +- src/librustc/util/common.rs | 4 +- src/libstd/c_vec.rs | 4 +- src/libstd/io/net/unix.rs | 2 +- src/libstd/iter.rs | 36 +++++++------- src/libstd/lib.rs | 1 - src/libstd/rt/at_exit_imp.rs | 4 +- src/libstd/rt/mod.rs | 4 +- src/libstd/rt/rtio.rs | 2 +- src/libstd/rt/task.rs | 4 +- src/libstd/rt/thread.rs | 12 ++--- src/libstd/slice.rs | 26 +++++----- src/libstd/str.rs | 2 +- src/libstd/task.rs | 18 +++---- src/libstd/unstable/finally.rs | 4 +- src/libstd/unstable/mod.rs | 2 +- src/libstd/vec.rs | 1 + src/libsync/future.rs | 6 +-- src/libsync/task_pool.rs | 10 ++-- src/libsyntax/ast_util.rs | 2 +- src/libsyntax/ext/deriving/generic.rs | 6 +-- src/libsyntax/parse/parser.rs | 49 +++++++------------ src/libtest/lib.rs | 4 +- src/libworkcache/lib.rs | 4 +- src/snapshots.txt | 8 +++ src/test/auxiliary/iss.rs | 2 +- ...bounds-cant-promote-superkind-in-struct.rs | 6 +-- src/test/compile-fail/issue-4335.rs | 2 +- src/test/compile-fail/issue-4523.rs | 2 +- src/test/compile-fail/kindck-nonsendable-1.rs | 6 +-- ...ased-on-type-no-recursive-stack-closure.rs | 2 +- src/test/compile-fail/proc-bounds.rs | 6 +-- .../regionck-closure-lifetimes.rs | 4 +- src/test/compile-fail/regions-freevar.rs | 2 +- .../regions-infer-at-fn-not-param.rs | 6 +-- ...ns-infer-invariance-due-to-mutability-3.rs | 2 +- ...ns-infer-invariance-due-to-mutability-4.rs | 2 +- .../compile-fail/regions-infer-not-param.rs | 4 +- .../compile-fail/regions-steal-closure.rs | 4 +- src/test/debug-info/recursive-enum.rs | 2 +- src/test/run-fail/unwind-box-fn-unique.rs | 2 +- src/test/run-fail/unwind-lambda.rs | 2 +- src/test/run-pass/clone-with-exterior.rs | 2 +- src/test/run-pass/closure-syntax.rs | 4 +- src/test/run-pass/issue-1516.rs | 2 +- src/test/run-pass/issue-2190-1.rs | 4 +- src/test/run-pass/issue-3609.rs | 2 +- src/test/run-pass/last-use-in-cap-clause.rs | 4 +- src/test/run-pass/proc-bounds.rs | 16 +++--- src/test/run-pass/sendfn-spawn-with-fn-arg.rs | 2 +- src/test/run-pass/tempfile.rs | 4 +- src/test/run-pass/uniq-cc-generic.rs | 4 +- src/test/run-pass/uniq-cc.rs | 2 +- 74 files changed, 194 insertions(+), 208 deletions(-) create mode 100644 src/libnative/io/p diff --git a/src/doc/complement-cheatsheet.md b/src/doc/complement-cheatsheet.md index 4f7583f0855af..328998ba9fa1c 100644 --- a/src/doc/complement-cheatsheet.md +++ b/src/doc/complement-cheatsheet.md @@ -152,7 +152,7 @@ struct Foo { } struct FooClosure<'a> { - myfunc: 'a |int, uint| -> i32 + myfunc: |int, uint|: 'a -> i32 } fn a(a: int, b: uint) -> i32 { diff --git a/src/doc/rust.md b/src/doc/rust.md index 886c95b2c7560..5d505e55d2c91 100644 --- a/src/doc/rust.md +++ b/src/doc/rust.md @@ -3460,7 +3460,7 @@ fn add(x: int, y: int) -> int { let mut x = add(5,7); -type Binop<'a> = 'a |int,int| -> int; +type Binop<'a> = |int,int|: 'a -> int; let bo: Binop = add; x = bo(5,7); ~~~~ diff --git a/src/libcollections/deque.rs b/src/libcollections/deque.rs index 6c1391e7ca816..def8f4f356113 100644 --- a/src/libcollections/deque.rs +++ b/src/libcollections/deque.rs @@ -96,7 +96,7 @@ pub mod bench { map.insert(*k, 1); } - rng.shuffle_mut(keys); + rng.shuffle(keys); // measure let mut i = 0; diff --git a/src/libgreen/basic.rs b/src/libgreen/basic.rs index d2599aab14c9f..62b6f71ae9c6b 100644 --- a/src/libgreen/basic.rs +++ b/src/libgreen/basic.rs @@ -27,7 +27,7 @@ pub fn event_loop() -> ~EventLoop:Send { } struct BasicLoop { - work: ~[proc:Send()], // pending work + work: ~[proc():Send], // pending work idle: Option<*mut BasicPausable>, // only one is allowed remotes: ~[(uint, ~Callback:Send)], next_remote: uint, @@ -135,7 +135,7 @@ impl EventLoop for BasicLoop { } } - fn callback(&mut self, f: proc:Send()) { + fn callback(&mut self, f: proc():Send) { self.work.push(f); } diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index fc7044ed88ad5..6b519fa7b83b7 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -9,7 +9,7 @@ // except according to those terms. #![feature(globs)] -#![crate_id = "libc#0.10-pre"] +#![crate_id = "libc#0.11-pre"] #![experimental] #![no_std] // we don't need std, and we can't have std, since it doesn't exist // yet. std depends on us. @@ -75,8 +75,6 @@ #![allow(missing_doc)] #![allow(uppercase_variables)] -#![feature(link_args)] // NOTE: remove after stage0 - #[cfg(test)] extern crate std; #[cfg(test)] extern crate test; #[cfg(test)] extern crate native; @@ -199,11 +197,6 @@ pub use funcs::posix88::unistd::{rmdir, unlink, write}; #[link(name = "m")] extern {} -// NOTE: remove this after a stage0 snap -#[cfg(stage0, windows)] -#[link_args = "-Wl,--enable-long-section-names"] -extern {} - /// A wrapper for a nullable pointer. Don't use this except for interacting /// with libc. Basically Option, but without the dependance on libstd. // If/when libprim happens, this can be removed in favor of that diff --git a/src/libnative/io/p b/src/libnative/io/p new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/src/libnative/io/process.rs b/src/libnative/io/process.rs index d1edea4df7105..d4ed52ef140cd 100644 --- a/src/libnative/io/process.rs +++ b/src/libnative/io/process.rs @@ -609,7 +609,7 @@ fn spawn_process_os(config: p::ProcessConfig, } #[cfg(unix)] -fn with_argv(prog: &str, args: &[~str], cb: proc:(**libc::c_char) -> T) -> T { +fn with_argv(prog: &str, args: &[~str], cb: proc(**libc::c_char) -> T) -> T { use std::slice; // We can't directly convert `str`s into `*char`s, as someone needs to hold @@ -635,7 +635,7 @@ fn with_argv(prog: &str, args: &[~str], cb: proc:(**libc::c_char) -> T) -> T } #[cfg(unix)] -fn with_envp(env: Option<~[(~str, ~str)]>, cb: proc:(*c_void) -> T) -> T { +fn with_envp(env: Option<~[(~str, ~str)]>, cb: proc(*c_void) -> T) -> T { use std::slice; // On posixy systems we can pass a char** for envp, which is a diff --git a/src/libnative/task.rs b/src/libnative/task.rs index 662c6417ca82e..871fc94bde46a 100644 --- a/src/libnative/task.rs +++ b/src/libnative/task.rs @@ -50,13 +50,13 @@ fn ops() -> ~Ops { } /// Spawns a function with the default configuration -pub fn spawn(f: proc:Send()) { +pub fn spawn(f: proc():Send) { spawn_opts(TaskOpts::new(), f) } /// Spawns a new task given the configuration options and a procedure to run /// inside the task. -pub fn spawn_opts(opts: TaskOpts, f: proc:Send()) { +pub fn spawn_opts(opts: TaskOpts, f: proc():Send) { let TaskOpts { notify_chan, name, stack_size, stderr, stdout, @@ -238,7 +238,7 @@ impl rt::Runtime for Ops { } } - fn spawn_sibling(~self, mut cur_task: ~Task, opts: TaskOpts, f: proc:Send()) { + fn spawn_sibling(~self, mut cur_task: ~Task, opts: TaskOpts, f: proc():Send) { cur_task.put_runtime(self); Local::put(cur_task); diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs index af63e52e885aa..b3535a695eaf3 100644 --- a/src/librand/distributions/mod.rs +++ b/src/librand/distributions/mod.rs @@ -209,8 +209,8 @@ fn ziggurat( symmetric: bool, x_tab: ziggurat_tables::ZigTable, f_tab: ziggurat_tables::ZigTable, - pdf: 'static |f64| -> f64, - zero_case: 'static |&mut R, f64| -> f64) + pdf: |f64|: 'static -> f64, + zero_case: |&mut R, f64|: 'static -> f64) -> f64 { static SCALE: f64 = (1u64 << 53) as f64; loop { diff --git a/src/librand/lib.rs b/src/librand/lib.rs index 57b910093e0ea..c9e4c81901e7e 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -801,7 +801,7 @@ mod test { #[test] fn test_shuffle() { let mut r = task_rng(); - let mut empty: &mut [int] = &mut []; + let empty: &mut [int] = &mut []; r.shuffle(empty); let mut one = [1]; r.shuffle(one); diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index cfbe772a165db..703ff51b3b0e2 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -13,7 +13,7 @@ use syntax::{ast, fold, attr}; use syntax::codemap; struct Context<'a> { - in_cfg: 'a |attrs: &[ast::Attribute]| -> bool, + in_cfg: |attrs: &[ast::Attribute]|: 'a -> bool, } // Support conditional compilation by transforming the AST, stripping out diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 95627cd1039af..3f72be673e0a0 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -364,7 +364,7 @@ fn parse_crate_attrs(sess: &session::Session, input: &d::Input) -> /// /// The diagnostic emitter yielded to the procedure should be used for reporting /// errors of the compiler. -pub fn monitor(f: proc:Send()) { +pub fn monitor(f: proc():Send) { // FIXME: This is a hack for newsched since it doesn't support split stacks. // rustc needs a lot of stack! When optimizations are disabled, it needs // even *more* stack than usual as well. diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 556f0a38b0354..40f0b719f2dcb 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -76,7 +76,7 @@ fn lookup_hash<'a>(d: ebml::Doc<'a>, eq_fn: |&[u8]| -> bool, ret } -pub type GetCrateDataCb<'a> = 'a |ast::CrateNum| -> Cmd; +pub type GetCrateDataCb<'a> = |ast::CrateNum|: 'a -> Cmd; pub fn maybe_find_item<'a>(item_id: ast::NodeId, items: ebml::Doc<'a>) -> Option> { @@ -637,11 +637,11 @@ pub fn get_item_path(cdata: Cmd, id: ast::NodeId) -> Vec { item_path(lookup_item(id, cdata.data())) } -pub type DecodeInlinedItem<'a> = 'a |cdata: @cstore::crate_metadata, - tcx: &ty::ctxt, - path: Vec, - par_doc: ebml::Doc| - -> Result >; +pub type DecodeInlinedItem<'a> = |cdata: @cstore::crate_metadata, + tcx: &ty::ctxt, + path: Vec, + par_doc: ebml::Doc|: 'a + -> Result >; pub fn maybe_get_item_ast(cdata: Cmd, tcx: &ty::ctxt, id: ast::NodeId, decode_inlined_item: DecodeInlinedItem) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index e453acac8109e..fcb0e3136a76e 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -64,9 +64,9 @@ pub enum InlinedItemRef<'a> { pub type Encoder<'a> = writer::Encoder<'a, MemWriter>; -pub type EncodeInlinedItem<'a> = 'a |ecx: &EncodeContext, - ebml_w: &mut Encoder, - ii: InlinedItemRef|; +pub type EncodeInlinedItem<'a> = |ecx: &EncodeContext, + ebml_w: &mut Encoder, + ii: InlinedItemRef|: 'a; pub struct EncodeParams<'a> { pub diag: &'a SpanHandler, diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index b83f42da0a056..7a531c5c128bf 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -23,7 +23,7 @@ pub enum FileMatch { FileMatches, FileDoesntMatch } /// Functions with type `pick` take a parent directory as well as /// a file found in that directory. -pub type pick<'a> = 'a |path: &Path| -> FileMatch; +pub type pick<'a> = |path: &Path|: 'a -> FileMatch; pub struct FileSearch<'a> { pub sysroot: &'a Path, diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 73fc089d930bf..599a1dad33d22 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -54,7 +54,7 @@ pub enum DefIdSource { RegionParameter, } pub type conv_did<'a> = - 'a |source: DefIdSource, ast::DefId| -> ast::DefId; + |source: DefIdSource, ast::DefId|: 'a -> ast::DefId; pub struct PState<'a> { data: &'a [u8], diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index c4fe5a3ebbba6..49163ce969967 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -503,7 +503,7 @@ fn assert_is_binding_or_wild(bcx: &Block, p: @ast::Pat) { } } -type enter_pat<'a> = 'a |@ast::Pat| -> Option>; +type enter_pat<'a> = |@ast::Pat|: 'a -> Option>; fn enter_match<'r,'b>( bcx: &'b Block<'b>, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 58edb717bf0bd..d5646c611a041 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -613,7 +613,7 @@ pub fn compare_scalar_values<'a>( } pub type val_and_ty_fn<'r,'b> = - 'r |&'b Block<'b>, ValueRef, ty::t| -> &'b Block<'b>; + |&'b Block<'b>, ValueRef, ty::t|: 'r -> &'b Block<'b>; // Iterates through the elements of a structural type. pub fn iter_structural_ty<'r, diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 1f2147b02e55c..73370357a92b1 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -525,7 +525,7 @@ pub fn get_base_and_len(bcx: &Block, } pub type iter_vec_block<'r,'b> = - 'r |&'b Block<'b>, ValueRef, ty::t| -> &'b Block<'b>; + |&'b Block<'b>, ValueRef, ty::t|: 'r -> &'b Block<'b>; pub fn iter_vec_loop<'r, 'b>( diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 686452a5e443c..8b14741f88145 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -217,7 +217,7 @@ pub fn super_fold_trait_store(this: &mut T, pub struct BottomUpFolder<'a> { pub tcx: &'a ty::ctxt, - pub fldop: 'a |ty::t| -> ty::t, + pub fldop: |ty::t|: 'a -> ty::t, } impl<'a> TypeFolder for BottomUpFolder<'a> { @@ -234,14 +234,14 @@ impl<'a> TypeFolder for BottomUpFolder<'a> { pub struct RegionFolder<'a> { tcx: &'a ty::ctxt, - fld_t: 'a |ty::t| -> ty::t, - fld_r: 'a |ty::Region| -> ty::Region, + fld_t: |ty::t|: 'a -> ty::t, + fld_r: |ty::Region|: 'a -> ty::Region, } impl<'a> RegionFolder<'a> { pub fn general(tcx: &'a ty::ctxt, - fld_r: 'a |ty::Region| -> ty::Region, - fld_t: 'a |ty::t| -> ty::t) + fld_r: |ty::Region|: 'a -> ty::Region, + fld_t: |ty::t|: 'a -> ty::t) -> RegionFolder<'a> { RegionFolder { tcx: tcx, @@ -250,7 +250,7 @@ impl<'a> RegionFolder<'a> { } } - pub fn regions(tcx: &'a ty::ctxt, fld_r: 'a |ty::Region| -> ty::Region) + pub fn regions(tcx: &'a ty::ctxt, fld_r: |ty::Region|: 'a -> ty::Region) -> RegionFolder<'a> { fn noop(t: ty::t) -> ty::t { t } diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index 8f59bb2800074..febf47add4339 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -86,7 +86,7 @@ pub fn relate_nested_regions(tcx: &ty::ctxt, struct RegionRelator<'a> { tcx: &'a ty::ctxt, stack: Vec, - relate_op: 'a |ty::Region, ty::Region|, + relate_op: |ty::Region, ty::Region|: 'a, } // FIXME(#10151) -- Define more precisely when a region is diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/typeck/infer/lattice.rs index 000d2843cca9c..83cc929424448 100644 --- a/src/librustc/middle/typeck/infer/lattice.rs +++ b/src/librustc/middle/typeck/infer/lattice.rs @@ -54,7 +54,7 @@ pub trait LatticeValue { } pub type LatticeOp<'a, T> = - 'a |cf: &CombineFields, a: &T, b: &T| -> cres; + |cf: &CombineFields, a: &T, b: &T|: 'a -> cres; impl LatticeValue for ty::t { fn sub(cf: &CombineFields, a: &ty::t, b: &ty::t) -> ures { @@ -407,7 +407,7 @@ pub fn super_lattice_tys(this: &L, } } -pub type LatticeDirOp<'a, T> = 'a |a: &T, b: &T| -> cres; +pub type LatticeDirOp<'a, T> = |a: &T, b: &T|: 'a -> cres; #[deriving(Clone)] pub enum LatticeVarResult { diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index ce8a34c4c23f5..0d14c036ba7f1 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -64,7 +64,7 @@ pub fn indenter() -> _indenter { } struct LoopQueryVisitor<'a> { - p: 'a |&ast::Expr_| -> bool, + p: |&ast::Expr_|: 'a -> bool, flag: bool, } @@ -92,7 +92,7 @@ pub fn loop_query(b: &ast::Block, p: |&ast::Expr_| -> bool) -> bool { } struct BlockQueryVisitor<'a> { - p: 'a |&ast::Expr| -> bool, + p: |&ast::Expr|: 'a -> bool, flag: bool, } diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs index 3b6b914cf14e5..4ef5af9275c87 100644 --- a/src/libstd/c_vec.rs +++ b/src/libstd/c_vec.rs @@ -46,7 +46,7 @@ use raw; pub struct CVec { base: *mut T, len: uint, - dtor: Option, + dtor: Option, } #[unsafe_destructor] @@ -90,7 +90,7 @@ impl CVec { /// * dtor - A proc to run when the value is destructed, useful /// for freeing the buffer, etc. pub unsafe fn new_with_dtor(base: *mut T, len: uint, - dtor: proc:Send()) -> CVec { + dtor: proc():Send) -> CVec { assert!(base != ptr::mut_null()); CVec { base: base, diff --git a/src/libstd/io/net/unix.rs b/src/libstd/io/net/unix.rs index 0d64a7b141ec6..a58cdbdba446f 100644 --- a/src/libstd/io/net/unix.rs +++ b/src/libstd/io/net/unix.rs @@ -141,7 +141,7 @@ mod tests { use io::*; use io::test::*; - pub fn smalltest(server: proc:Send(UnixStream), client: proc:Send(UnixStream)) { + pub fn smalltest(server: proc(UnixStream):Send, client: proc(UnixStream):Send) { let path1 = next_test_unix(); let path2 = path1.clone(); diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs index d7424fc9f61a1..1c7579e6b8e75 100644 --- a/src/libstd/iter.rs +++ b/src/libstd/iter.rs @@ -156,7 +156,7 @@ pub trait Iterator { /// assert!(it.next().is_none()); /// ``` #[inline] - fn map<'r, B>(self, f: 'r |A| -> B) -> Map<'r, A, B, Self> { + fn map<'r, B>(self, f: |A|: 'r -> B) -> Map<'r, A, B, Self> { Map{iter: self, f: f} } @@ -173,7 +173,7 @@ pub trait Iterator { /// assert!(it.next().is_none()); /// ``` #[inline] - fn filter<'r>(self, predicate: 'r |&A| -> bool) -> Filter<'r, A, Self> { + fn filter<'r>(self, predicate: |&A|: 'r -> bool) -> Filter<'r, A, Self> { Filter{iter: self, predicate: predicate} } @@ -190,7 +190,7 @@ pub trait Iterator { /// assert!(it.next().is_none()); /// ``` #[inline] - fn filter_map<'r, B>(self, f: 'r |A| -> Option) -> FilterMap<'r, A, B, Self> { + fn filter_map<'r, B>(self, f: |A|: 'r -> Option) -> FilterMap<'r, A, B, Self> { FilterMap { iter: self, f: f } } @@ -249,7 +249,7 @@ pub trait Iterator { /// assert!(it.next().is_none()); /// ``` #[inline] - fn skip_while<'r>(self, predicate: 'r |&A| -> bool) -> SkipWhile<'r, A, Self> { + fn skip_while<'r>(self, predicate: |&A|: 'r -> bool) -> SkipWhile<'r, A, Self> { SkipWhile{iter: self, flag: false, predicate: predicate} } @@ -267,7 +267,7 @@ pub trait Iterator { /// assert!(it.next().is_none()); /// ``` #[inline] - fn take_while<'r>(self, predicate: 'r |&A| -> bool) -> TakeWhile<'r, A, Self> { + fn take_while<'r>(self, predicate: |&A|: 'r -> bool) -> TakeWhile<'r, A, Self> { TakeWhile{iter: self, flag: false, predicate: predicate} } @@ -327,7 +327,7 @@ pub trait Iterator { /// assert!(it.next().is_none()); /// ``` #[inline] - fn scan<'r, St, B>(self, initial_state: St, f: 'r |&mut St, A| -> Option) + fn scan<'r, St, B>(self, initial_state: St, f: |&mut St, A|: 'r -> Option) -> Scan<'r, A, B, Self, St> { Scan{iter: self, f: f, state: initial_state} } @@ -351,7 +351,7 @@ pub trait Iterator { /// } /// ``` #[inline] - fn flat_map<'r, B, U: Iterator>(self, f: 'r |A| -> U) + fn flat_map<'r, B, U: Iterator>(self, f: |A|: 'r -> U) -> FlatMap<'r, A, Self, U> { FlatMap{iter: self, f: f, frontiter: None, backiter: None } } @@ -405,7 +405,7 @@ pub trait Iterator { /// println!("{}", sum); /// ``` #[inline] - fn inspect<'r>(self, f: 'r |&A|) -> Inspect<'r, A, Self> { + fn inspect<'r>(self, f: |&A|: 'r) -> Inspect<'r, A, Self> { Inspect{iter: self, f: f} } @@ -1235,7 +1235,7 @@ RandomAccessIterator<(A, B)> for Zip { /// An iterator which maps the values of `iter` with `f` pub struct Map<'a, A, B, T> { iter: T, - f: 'a |A| -> B + f: |A|: 'a -> B } impl<'a, A, B, T> Map<'a, A, B, T> { @@ -1284,7 +1284,7 @@ impl<'a, A, B, T: RandomAccessIterator> RandomAccessIterator for Map<'a, A /// An iterator which filters the elements of `iter` with `predicate` pub struct Filter<'a, A, T> { iter: T, - predicate: 'a |&A| -> bool + predicate: |&A|: 'a -> bool } impl<'a, A, T: Iterator> Iterator for Filter<'a, A, T> { @@ -1328,7 +1328,7 @@ impl<'a, A, T: DoubleEndedIterator> DoubleEndedIterator for Filter<'a, A, /// An iterator which uses `f` to both filter and map elements from `iter` pub struct FilterMap<'a, A, B, T> { iter: T, - f: 'a |A| -> Option + f: |A|: 'a -> Option } impl<'a, A, B, T: Iterator> Iterator for FilterMap<'a, A, B, T> { @@ -1477,7 +1477,7 @@ impl<'a, A, T: Iterator> Peekable { pub struct SkipWhile<'a, A, T> { iter: T, flag: bool, - predicate: 'a |&A| -> bool + predicate: |&A|: 'a -> bool } impl<'a, A, T: Iterator> Iterator for SkipWhile<'a, A, T> { @@ -1515,7 +1515,7 @@ impl<'a, A, T: Iterator> Iterator for SkipWhile<'a, A, T> { pub struct TakeWhile<'a, A, T> { iter: T, flag: bool, - predicate: 'a |&A| -> bool + predicate: |&A|: 'a -> bool } impl<'a, A, T: Iterator> Iterator for TakeWhile<'a, A, T> { @@ -1662,7 +1662,7 @@ impl> RandomAccessIterator for Take { /// An iterator to maintain state while iterating another iterator pub struct Scan<'a, A, B, T, St> { iter: T, - f: 'a |&mut St, A| -> Option, + f: |&mut St, A|: 'a -> Option, /// The current internal state to be passed to the closure next. pub state: St, @@ -1686,7 +1686,7 @@ impl<'a, A, B, T: Iterator, St> Iterator for Scan<'a, A, B, T, St> { /// pub struct FlatMap<'a, A, T, U> { iter: T, - f: 'a |A| -> U, + f: |A|: 'a -> U, frontiter: Option, backiter: Option, } @@ -1817,7 +1817,7 @@ impl Fuse { /// element before yielding it. pub struct Inspect<'a, A, T> { iter: T, - f: 'a |&A| + f: |&A|: 'a } impl<'a, A, T> Inspect<'a, A, T> { @@ -1869,7 +1869,7 @@ for Inspect<'a, A, T> { /// An iterator which just modifies the contained state throughout iteration. pub struct Unfold<'a, A, St> { - f: 'a |&mut St| -> Option, + f: |&mut St|: 'a -> Option, /// Internal state that will be yielded on the next iteration pub state: St, } @@ -1878,7 +1878,7 @@ impl<'a, A, St> Unfold<'a, A, St> { /// Creates a new iterator with the specified closure as the "iterator /// function" and an initial state to eventually pass to the iterator #[inline] - pub fn new<'a>(initial_state: St, f: 'a |&mut St| -> Option) + pub fn new<'a>(initial_state: St, f: |&mut St|: 'a -> Option) -> Unfold<'a, A, St> { Unfold { f: f, diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 1a5ca76d5c05d..985f8a8eb0a1e 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -58,7 +58,6 @@ #![no_std] #![deny(missing_doc)] -#![allow(unknown_features)] // NOTE: remove after a stage0 snap // When testing libstd, bring in libuv as the I/O backend so tests can print // things and all of the std::io tests have an I/O interface to run on top diff --git a/src/libstd/rt/at_exit_imp.rs b/src/libstd/rt/at_exit_imp.rs index a5bfaf190d906..4be9c8a84acd3 100644 --- a/src/libstd/rt/at_exit_imp.rs +++ b/src/libstd/rt/at_exit_imp.rs @@ -21,7 +21,7 @@ use ptr::RawPtr; use unstable::sync::Exclusive; use slice::OwnedVector; -type Queue = Exclusive<~[proc:Send()]>; +type Queue = Exclusive<~[proc():Send]>; // You'll note that these variables are *not* atomic, and this is done on // purpose. This module is designed to have init() called *once* in a @@ -40,7 +40,7 @@ pub fn init() { } } -pub fn push(f: proc:Send()) { +pub fn push(f: proc():Send) { unsafe { rtassert!(!RUNNING); rtassert!(!QUEUE.is_null()); diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 5e2f8efd2e35c..f4a4fd9ab2e9b 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -157,7 +157,7 @@ pub trait Runtime { // Miscellaneous calls which are very different depending on what context // you're in. - fn spawn_sibling(~self, cur_task: ~Task, opts: TaskOpts, f: proc:Send()); + fn spawn_sibling(~self, cur_task: ~Task, opts: TaskOpts, f: proc():Send); fn local_io<'a>(&'a mut self) -> Option>; /// The (low, high) edges of the current stack. fn stack_bounds(&self) -> (uint, uint); // (lo, hi) @@ -196,7 +196,7 @@ pub fn init(argc: int, argv: **u8) { /// /// It is forbidden for procedures to register more `at_exit` handlers when they /// are running, and doing so will lead to a process abort. -pub fn at_exit(f: proc:Send()) { +pub fn at_exit(f: proc():Send) { at_exit_imp::push(f); } diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs index 54708d19a1b4f..1750e685627d8 100644 --- a/src/libstd/rt/rtio.rs +++ b/src/libstd/rt/rtio.rs @@ -36,7 +36,7 @@ pub trait Callback { pub trait EventLoop { fn run(&mut self); - fn callback(&mut self, arg: proc:Send()); + fn callback(&mut self, arg: proc():Send); fn pausable_idle_callback(&mut self, ~Callback:Send) -> ~PausableIdleCallback:Send; fn remote_callback(&mut self, ~Callback:Send) -> ~RemoteCallback:Send; diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index fc266df11e4be..bae20d3bb9b90 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -70,7 +70,7 @@ pub enum BlockedTask { pub enum DeathAction { /// Action to be done with the exit code. If set, also makes the task wait /// until all its watched children exit before collecting the status. - Execute(proc:Send(TaskResult)), + Execute(proc(TaskResult):Send), /// A channel to send the result of the task on when the task exits SendMessage(Sender), } @@ -236,7 +236,7 @@ impl Task { /// Spawns a sibling to this task. The newly spawned task is configured with /// the `opts` structure and will run `f` as the body of its code. - pub fn spawn_sibling(mut ~self, opts: TaskOpts, f: proc:Send()) { + pub fn spawn_sibling(mut ~self, opts: TaskOpts, f: proc():Send) { let ops = self.imp.take_unwrap(); ops.spawn_sibling(self, opts, f) } diff --git a/src/libstd/rt/thread.rs b/src/libstd/rt/thread.rs index c35ffac064cfd..b1c7c5aab020f 100644 --- a/src/libstd/rt/thread.rs +++ b/src/libstd/rt/thread.rs @@ -68,13 +68,13 @@ impl Thread<()> { /// to finish executing. This means that even if `join` is not explicitly /// called, when the `Thread` falls out of scope its destructor will block /// waiting for the OS thread. - pub fn start(main: proc:Send() -> T) -> Thread { + pub fn start(main: proc():Send -> T) -> Thread { Thread::start_stack(DEFAULT_STACK_SIZE, main) } /// Performs the same functionality as `start`, but specifies an explicit /// stack size for the new thread. - pub fn start_stack(stack: uint, main: proc:Send() -> T) -> Thread { + pub fn start_stack(stack: uint, main: proc():Send -> T) -> Thread { // We need the address of the packet to fill in to be stable so when // `main` fills it in it's still valid, so allocate an extra ~ box to do @@ -99,13 +99,13 @@ impl Thread<()> { /// This corresponds to creating threads in the 'detached' state on unix /// systems. Note that platforms may not keep the main program alive even if /// there are detached thread still running around. - pub fn spawn(main: proc:Send()) { + pub fn spawn(main: proc():Send) { Thread::spawn_stack(DEFAULT_STACK_SIZE, main) } /// Performs the same functionality as `spawn`, but explicitly specifies a /// stack size for the new thread. - pub fn spawn_stack(stack: uint, main: proc:Send()) { + pub fn spawn_stack(stack: uint, main: proc():Send) { unsafe { let handle = imp::create(stack, ~main); imp::detach(handle); @@ -156,7 +156,7 @@ mod imp { pub type rust_thread = HANDLE; pub type rust_thread_return = DWORD; - pub unsafe fn create(stack: uint, p: ~proc:Send()) -> rust_thread { + pub unsafe fn create(stack: uint, p: ~proc():Send) -> rust_thread { let arg: *mut libc::c_void = cast::transmute(p); // FIXME On UNIX, we guard against stack sizes that are too small but // that's because pthreads enforces that stacks are at least @@ -215,7 +215,7 @@ mod imp { pub type rust_thread = libc::pthread_t; pub type rust_thread_return = *u8; - pub unsafe fn create(stack: uint, p: ~proc:Send()) -> rust_thread { + pub unsafe fn create(stack: uint, p: ~proc():Send) -> rust_thread { let mut native: libc::pthread_t = mem::uninit(); let mut attr: libc::pthread_attr_t = mem::uninit(); assert_eq!(pthread_attr_init(&mut attr), 0); diff --git a/src/libstd/slice.rs b/src/libstd/slice.rs index f15e3e61ca1f8..fced9b5dd5b94 100644 --- a/src/libstd/slice.rs +++ b/src/libstd/slice.rs @@ -235,7 +235,7 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] { pub struct Splits<'a, T> { v: &'a [T], n: uint, - pred: 'a |t: &T| -> bool, + pred: |t: &T|: 'a -> bool, finished: bool } @@ -284,7 +284,7 @@ impl<'a, T> Iterator<&'a [T]> for Splits<'a, T> { pub struct RevSplits<'a, T> { v: &'a [T], n: uint, - pred: 'a |t: &T| -> bool, + pred: |t: &T|: 'a -> bool, finished: bool } @@ -810,23 +810,23 @@ pub trait ImmutableVector<'a, T> { /// Returns an iterator over the subslices of the vector which are /// separated by elements that match `pred`. The matched element /// is not contained in the subslices. - fn split(self, pred: 'a |&T| -> bool) -> Splits<'a, T>; + fn split(self, pred: |&T|: 'a -> bool) -> Splits<'a, T>; /// Returns an iterator over the subslices of the vector which are /// separated by elements that match `pred`, limited to splitting /// at most `n` times. The matched element is not contained in /// the subslices. - fn splitn(self, n: uint, pred: 'a |&T| -> bool) -> Splits<'a, T>; + fn splitn(self, n: uint, pred: |&T|: 'a -> bool) -> Splits<'a, T>; /// Returns an iterator over the subslices of the vector which are /// separated by elements that match `pred`. This starts at the /// end of the vector and works backwards. The matched element is /// not contained in the subslices. - fn rsplit(self, pred: 'a |&T| -> bool) -> RevSplits<'a, T>; + fn rsplit(self, pred: |&T|: 'a -> bool) -> RevSplits<'a, T>; /// Returns an iterator over the subslices of the vector which are /// separated by elements that match `pred` limited to splitting /// at most `n` times. This starts at the end of the vector and /// works backwards. The matched element is not contained in the /// subslices. - fn rsplitn(self, n: uint, pred: 'a |&T| -> bool) -> RevSplits<'a, T>; + fn rsplitn(self, n: uint, pred: |&T|: 'a -> bool) -> RevSplits<'a, T>; /** * Returns an iterator over all contiguous windows of length @@ -1003,12 +1003,12 @@ impl<'a,T> ImmutableVector<'a, T> for &'a [T] { } #[inline] - fn split(self, pred: 'a |&T| -> bool) -> Splits<'a, T> { + fn split(self, pred: |&T|: 'a -> bool) -> Splits<'a, T> { self.splitn(uint::MAX, pred) } #[inline] - fn splitn(self, n: uint, pred: 'a |&T| -> bool) -> Splits<'a, T> { + fn splitn(self, n: uint, pred: |&T|: 'a -> bool) -> Splits<'a, T> { Splits { v: self, n: n, @@ -1018,12 +1018,12 @@ impl<'a,T> ImmutableVector<'a, T> for &'a [T] { } #[inline] - fn rsplit(self, pred: 'a |&T| -> bool) -> RevSplits<'a, T> { + fn rsplit(self, pred: |&T|: 'a -> bool) -> RevSplits<'a, T> { self.rsplitn(uint::MAX, pred) } #[inline] - fn rsplitn(self, n: uint, pred: 'a |&T| -> bool) -> RevSplits<'a, T> { + fn rsplitn(self, n: uint, pred: |&T|: 'a -> bool) -> RevSplits<'a, T> { RevSplits { v: self, n: n, @@ -2027,7 +2027,7 @@ pub trait MutableVector<'a, T> { /// Returns an iterator over the mutable subslices of the vector /// which are separated by elements that match `pred`. The /// matched element is not contained in the subslices. - fn mut_split(self, pred: 'a |&T| -> bool) -> MutSplits<'a, T>; + fn mut_split(self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T>; /** * Returns an iterator over `size` elements of the vector at a time. @@ -2299,7 +2299,7 @@ impl<'a,T> MutableVector<'a, T> for &'a mut [T] { } #[inline] - fn mut_split(self, pred: 'a |&T| -> bool) -> MutSplits<'a, T> { + fn mut_split(self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T> { MutSplits { v: self, pred: pred, finished: false } } @@ -2736,7 +2736,7 @@ pub type RevMutItems<'a, T> = Rev>; /// by elements that match `pred`. pub struct MutSplits<'a, T> { v: &'a mut [T], - pred: 'a |t: &T| -> bool, + pred: |t: &T|: 'a -> bool, finished: bool } diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 1d80af70b9756..e24011ca021d0 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -241,7 +241,7 @@ impl CharEq for char { fn only_ascii(&self) -> bool { (*self as uint) < 128 } } -impl<'a> CharEq for 'a |char| -> bool { +impl<'a> CharEq for |char|: 'a -> bool { #[inline] fn matches(&self, c: char) -> bool { (*self)(c) } diff --git a/src/libstd/task.rs b/src/libstd/task.rs index a3d919921ae6d..ed10f6d15cd66 100644 --- a/src/libstd/task.rs +++ b/src/libstd/task.rs @@ -86,7 +86,7 @@ pub struct TaskOpts { pub struct TaskBuilder { /// Options to spawn the new task with pub opts: TaskOpts, - gen_body: Option proc:Send()>, + gen_body: Option proc():Send>, nocopy: Option, } @@ -151,7 +151,7 @@ impl TaskBuilder { * existing body generator to the new body generator. */ pub fn with_wrapper(mut self, - wrapper: proc:Send(v: proc:Send()) -> proc:Send()) + wrapper: proc(v: proc():Send):Send -> proc():Send) -> TaskBuilder { self.gen_body = match self.gen_body.take() { @@ -168,7 +168,7 @@ impl TaskBuilder { * the provided unique closure. The task has the properties and behavior * specified by the task_builder. */ - pub fn spawn(mut self, f: proc:Send()) { + pub fn spawn(mut self, f: proc():Send) { let gen_body = self.gen_body.take(); let f = match gen_body { Some(gen) => gen(f), @@ -191,7 +191,7 @@ impl TaskBuilder { * # Failure * Fails if a future_result was already set for this task. */ - pub fn try(mut self, f: proc:Send() -> T) -> Result { + pub fn try(mut self, f: proc():Send -> T) -> Result { let (tx, rx) = channel(); let result = self.future_result(); @@ -233,12 +233,12 @@ impl TaskOpts { /// the provided unique closure. /// /// This function is equivalent to `task().spawn(f)`. -pub fn spawn(f: proc:Send()) { +pub fn spawn(f: proc():Send) { let task = task(); task.spawn(f) } -pub fn try(f: proc:Send() -> T) -> Result { +pub fn try(f: proc():Send -> T) -> Result { /*! * Execute a function in another task and return either the return value * of the function or result::err. @@ -338,7 +338,7 @@ fn test_run_basic() { fn test_with_wrapper() { let (tx, rx) = channel(); task().with_wrapper(proc(body) { - let result: proc:Send() = proc() { + let result: proc():Send = proc() { body(); tx.send(()); }; @@ -424,7 +424,7 @@ fn test_spawn_sched_childs_on_default_sched() { } #[cfg(test)] -fn avoid_copying_the_body(spawnfn: |v: proc:Send()|) { +fn avoid_copying_the_body(spawnfn: |v: proc():Send|) { let (tx, rx) = channel::(); let x = ~1; @@ -470,7 +470,7 @@ fn test_child_doesnt_ref_parent() { // (well, it would if the constant were 8000+ - I lowered it to be more // valgrind-friendly. try this at home, instead..!) static generations: uint = 16; - fn child_no(x: uint) -> proc:Send() { + fn child_no(x: uint) -> proc():Send { return proc() { if x < generations { task().spawn(child_no(x+1)); diff --git a/src/libstd/unstable/finally.rs b/src/libstd/unstable/finally.rs index 6fb8981b681c3..82119ad21b990 100644 --- a/src/libstd/unstable/finally.rs +++ b/src/libstd/unstable/finally.rs @@ -39,7 +39,7 @@ pub trait Finally { fn finally(&self, dtor: ||) -> T; } -impl<'a,T> Finally for 'a || -> T { +impl<'a,T> Finally for ||: 'a -> T { fn finally(&self, dtor: ||) -> T { try_finally(&mut (), (), |_, _| (*self)(), @@ -101,7 +101,7 @@ pub fn try_finally(mutate: &mut T, struct Finallyalizer<'a,A> { mutate: &'a mut A, - dtor: 'a |&mut A| + dtor: |&mut A|: 'a } #[unsafe_destructor] diff --git a/src/libstd/unstable/mod.rs b/src/libstd/unstable/mod.rs index ddbf650e64a97..f660d7ae97a99 100644 --- a/src/libstd/unstable/mod.rs +++ b/src/libstd/unstable/mod.rs @@ -28,7 +28,7 @@ for it to terminate. The executing thread has no access to a task pointer and will be using a normal large stack. */ -pub fn run_in_bare_thread(f: proc:Send()) { +pub fn run_in_bare_thread(f: proc():Send) { use rt::thread::Thread; Thread::start(f).join() } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 30416b2824136..3c5cdfcf94ec4 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1574,6 +1574,7 @@ mod tests { assert_eq!(v, three) } + #[test] fn test_grow_fn() { let mut v = Vec::from_slice([0u, 1]); v.grow_fn(3, |i| i); diff --git a/src/libsync/future.rs b/src/libsync/future.rs index cfe942afc129b..ac4150a67e0ee 100644 --- a/src/libsync/future.rs +++ b/src/libsync/future.rs @@ -34,7 +34,7 @@ pub struct Future { } enum FutureState { - Pending(proc:Send() -> A), + Pending(proc():Send -> A), Evaluating, Forced(A) } @@ -90,7 +90,7 @@ impl Future { Future {state: Forced(val)} } - pub fn from_fn(f: proc:Send() -> A) -> Future { + pub fn from_fn(f: proc():Send -> A) -> Future { /*! * Create a future from a function. * @@ -117,7 +117,7 @@ impl Future { }) } - pub fn spawn(blk: proc:Send() -> A) -> Future { + pub fn spawn(blk: proc():Send -> A) -> Future { /*! * Create a future from a unique closure. * diff --git a/src/libsync/task_pool.rs b/src/libsync/task_pool.rs index fc249996882df..75e5d19b2e22d 100644 --- a/src/libsync/task_pool.rs +++ b/src/libsync/task_pool.rs @@ -16,7 +16,7 @@ use std::task; enum Msg { - Execute(proc:Send(&T)), + Execute(proc(&T):Send), Quit } @@ -41,7 +41,7 @@ impl TaskPool { /// returns a function which, given the index of the task, should return /// local data to be kept around in that task. pub fn new(n_tasks: uint, - init_fn_factory: || -> proc:Send(uint) -> T) + init_fn_factory: || -> proc(uint):Send -> T) -> TaskPool { assert!(n_tasks >= 1); @@ -73,7 +73,7 @@ impl TaskPool { /// Executes the function `f` on a task in the pool. The function /// receives a reference to the local data returned by the `init_fn`. - pub fn execute(&mut self, f: proc:Send(&T)) { + pub fn execute(&mut self, f: proc(&T):Send) { self.channels.get(self.next_index).send(Execute(f)); self.next_index += 1; if self.next_index == self.channels.len() { self.next_index = 0; } @@ -82,8 +82,8 @@ impl TaskPool { #[test] fn test_task_pool() { - let f: || -> proc:Send(uint) -> uint = || { - let g: proc:Send(uint) -> uint = proc(i) i; + let f: || -> proc(uint):Send -> uint = || { + let g: proc(uint):Send -> uint = proc(i) i; g }; let mut pool = TaskPool::new(4, f); diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 631489a65b230..ec9c02ac82a73 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -613,7 +613,7 @@ pub trait EachViewItem { } struct EachViewItemData<'a> { - callback: 'a |&ast::ViewItem| -> bool, + callback: |&ast::ViewItem|: 'a -> bool, } impl<'a> Visitor<()> for EachViewItemData<'a> { diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 0d851647b3de1..1dcb753624d83 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -303,7 +303,7 @@ Combine the values of all the fields together. The last argument is all the fields of all the structures, see above for details. */ pub type CombineSubstructureFunc<'a> = - 'a |&mut ExtCtxt, Span, &Substructure| -> @Expr; + |&mut ExtCtxt, Span, &Substructure|: 'a -> @Expr; /** Deal with non-matching enum variants, the arguments are a list @@ -311,10 +311,10 @@ representing each variant: (variant index, ast::Variant instance, [variant fields]), and a list of the nonself args of the type */ pub type EnumNonMatchFunc<'a> = - 'a |&mut ExtCtxt, + |&mut ExtCtxt, Span, &[(uint, P, Vec<(Span, Option, @Expr)> )], - &[@Expr]| + &[@Expr]|: 'a -> @Expr; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 62ce0f1e11399..c8ea0b6aac283 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -905,31 +905,23 @@ impl<'a> Parser<'a> { */ - // NOTE: remove after the next stage0 snap - let (decl, lifetimes, bounds) = if self.token == token::COLON { - let (_, bounds) = self.parse_optional_ty_param_bounds(false); - let (decl, lifetimes) = self.parse_ty_fn_decl(false); - (decl, lifetimes, bounds) + let lifetimes = if self.eat(&token::LT) { + let lifetimes = self.parse_lifetimes(); + self.expect_gt(); + lifetimes } else { - let lifetimes = if self.eat(&token::LT) { - let lifetimes = self.parse_lifetimes(); - self.expect_gt(); - lifetimes - } else { - Vec::new() - }; - - let (inputs, variadic) = self.parse_fn_args(false, false); - let (_, bounds) = self.parse_optional_ty_param_bounds(false); - let (ret_style, ret_ty) = self.parse_ret_ty(); - let decl = P(FnDecl { - inputs: inputs, - output: ret_ty, - cf: ret_style, - variadic: variadic - }); - (decl, lifetimes, bounds) + Vec::new() }; + + let (inputs, variadic) = self.parse_fn_args(false, false); + let (_, bounds) = self.parse_optional_ty_param_bounds(false); + let (ret_style, ret_ty) = self.parse_ret_ty(); + let decl = P(FnDecl { + inputs: inputs, + output: ret_ty, + cf: ret_style, + variadic: variadic + }); TyClosure(@ClosureTy { sigil: OwnedSigil, region: None, @@ -957,8 +949,6 @@ impl<'a> Parser<'a> { */ - // NOTE: remove 'let region' after a stage0 snap - let region = self.parse_opt_lifetime(); let purity = self.parse_unsafety(); let onceness = if self.eat_keyword(keywords::Once) {Once} else {Many}; @@ -982,10 +972,7 @@ impl<'a> Parser<'a> { inputs }; - let (new_region, bounds) = self.parse_optional_ty_param_bounds(true); - - // NOTE: this should be removed after a stage0 snap - let region = new_region.or(region); + let (region, bounds) = self.parse_optional_ty_param_bounds(true); let (return_style, output) = self.parse_ret_ty(); let decl = P(FnDecl { @@ -1246,9 +1233,7 @@ impl<'a> Parser<'a> { } else if self.token_is_closure_keyword() || self.token == token::BINOP(token::OR) || self.token == token::OROR || - self.token == token::LT || - // NOTE: remove this clause after a stage0 snap - Parser::token_is_lifetime(&self.token) { + self.token == token::LT { // CLOSURE // // FIXME(pcwalton): Eventually `token::LT` will not unambiguously diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 622375d8a6c88..5c74715fd2969 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -123,7 +123,7 @@ pub enum TestFn { StaticTestFn(fn()), StaticBenchFn(fn(&mut BenchHarness)), StaticMetricFn(proc(&mut MetricMap)), - DynTestFn(proc:Send()), + DynTestFn(proc():Send), DynMetricFn(proc(&mut MetricMap)), DynBenchFn(~TDynBenchFn) } @@ -948,7 +948,7 @@ pub fn run_test(force_ignore: bool, #[allow(deprecated_owned_vector)] fn run_test_inner(desc: TestDesc, monitor_ch: Sender, - testfn: proc:Send()) { + testfn: proc():Send) { spawn(proc() { let (tx, rx) = channel(); let mut reader = ChanReader::new(rx); diff --git a/src/libworkcache/lib.rs b/src/libworkcache/lib.rs index af1958127f974..748ca378e4d53 100644 --- a/src/libworkcache/lib.rs +++ b/src/libworkcache/lib.rs @@ -394,14 +394,14 @@ impl<'a> Prep<'a> { pub fn exec<'a, T:Send + Encodable, io::IoError> + Decodable>( - &'a self, blk: proc:Send(&mut Exec) -> T) -> T { + &'a self, blk: proc(&mut Exec):Send -> T) -> T { self.exec_work(blk).unwrap() } fn exec_work<'a, T:Send + Encodable, io::IoError> + Decodable>( // FIXME(#5121) - &'a self, blk: proc:Send(&mut Exec) -> T) -> Work<'a, T> { + &'a self, blk: proc(&mut Exec):Send -> T) -> Work<'a, T> { let mut bo = Some(blk); debug!("exec_work: looking up {} and {:?}", self.fn_name, diff --git a/src/snapshots.txt b/src/snapshots.txt index 83a8e7bb9658d..0e9f6d80369da 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -1,3 +1,11 @@ +S 2014-04-07 c7fac44 + freebsd-x86_64 3c01e2a52a1487c360a8e075df0d4fd412d84fe9 + linux-i386 145f83ec557db77160a207aa2a17e2db8e254b84 + linux-x86_64 647d2922311a497280d49e91e4946a271d44a232 + macos-i386 fa19ebca45f83e224911bad13475e40d531e6515 + macos-x86_64 c0b4df5eed015c527a2a23ca3f2755a44782f61d + winnt-i386 e93af6e5ce88e1220f8b4b4cce14436af0b4279a + S 2014-04-03 e7fe207 freebsd-x86_64 6d40f547d13896ab9d9dd4a4fdf2e72be553b01b linux-i386 875a8f6956f7d703f7206db91ca2a9b67c244cf8 diff --git a/src/test/auxiliary/iss.rs b/src/test/auxiliary/iss.rs index 28437c4585d84..96cb6c3273aaf 100644 --- a/src/test/auxiliary/iss.rs +++ b/src/test/auxiliary/iss.rs @@ -13,7 +13,7 @@ // part of issue-6919.rs struct C<'a> { - pub k: 'a ||, + pub k: ||: 'a, } fn no_op() { } diff --git a/src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs b/src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs index e5898b33e7785..951354d964d9f 100644 --- a/src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs +++ b/src/test/compile-fail/closure-bounds-cant-promote-superkind-in-struct.rs @@ -9,11 +9,11 @@ // except according to those terms. struct X { - field: 'static ||:Send, + field: ||:'static + Send, } -fn foo(blk: 'static ||:) -> X { - return X { field: blk }; //~ ERROR expected bounds `Send` but found no bounds +fn foo(blk: ||:'static) -> X { + return X { field: blk }; //~ ERROR expected bounds `'static+Send` } fn main() { diff --git a/src/test/compile-fail/issue-4335.rs b/src/test/compile-fail/issue-4335.rs index 8e4aa799d1fb9..08ff575f63bfb 100644 --- a/src/test/compile-fail/issue-4335.rs +++ b/src/test/compile-fail/issue-4335.rs @@ -10,7 +10,7 @@ fn id(t: T) -> T { t } -fn f<'r, T>(v: &'r T) -> 'r || -> T { +fn f<'r, T>(v: &'r T) -> ||: 'r -> T { id(|| *v) //~ ERROR cannot infer } diff --git a/src/test/compile-fail/issue-4523.rs b/src/test/compile-fail/issue-4523.rs index 952a528b427ba..026327a358a46 100644 --- a/src/test/compile-fail/issue-4523.rs +++ b/src/test/compile-fail/issue-4523.rs @@ -10,7 +10,7 @@ fn foopy() {} -static f: 'static || = foopy; //~ ERROR found extern fn +static f: ||: 'static = foopy; //~ ERROR found extern fn fn main () { f(); diff --git a/src/test/compile-fail/kindck-nonsendable-1.rs b/src/test/compile-fail/kindck-nonsendable-1.rs index 51687fffd1150..8fe9694b0cb46 100644 --- a/src/test/compile-fail/kindck-nonsendable-1.rs +++ b/src/test/compile-fail/kindck-nonsendable-1.rs @@ -14,8 +14,8 @@ fn foo(_x: @uint) {} fn main() { let x = @3u; - let _: proc:Send() = proc() foo(x); //~ ERROR does not fulfill `Send` - let _: proc:Send() = proc() foo(x); //~ ERROR does not fulfill `Send` - let _: proc:Send() = proc() foo(x); //~ ERROR does not fulfill `Send` + let _: proc():Send = proc() foo(x); //~ ERROR does not fulfill `Send` + let _: proc():Send = proc() foo(x); //~ ERROR does not fulfill `Send` + let _: proc():Send = proc() foo(x); //~ ERROR does not fulfill `Send` let _: proc() = proc() foo(x); } diff --git a/src/test/compile-fail/moves-based-on-type-no-recursive-stack-closure.rs b/src/test/compile-fail/moves-based-on-type-no-recursive-stack-closure.rs index 03b9b7ba78f4d..e9053b46bbbf1 100644 --- a/src/test/compile-fail/moves-based-on-type-no-recursive-stack-closure.rs +++ b/src/test/compile-fail/moves-based-on-type-no-recursive-stack-closure.rs @@ -16,7 +16,7 @@ struct R<'a> { // This struct is needed to create the // otherwise infinite type of a fn that // accepts itself as argument: - c: 'a |&R, bool| + c: |&R, bool|: 'a } fn innocent_looking_victim() { diff --git a/src/test/compile-fail/proc-bounds.rs b/src/test/compile-fail/proc-bounds.rs index e4d2c801070b9..0875212b7dee3 100644 --- a/src/test/compile-fail/proc-bounds.rs +++ b/src/test/compile-fail/proc-bounds.rs @@ -13,13 +13,13 @@ fn is_freeze() {} fn is_static() {} fn main() { - is_send::(); + is_send::(); //~^ ERROR: instantiating a type parameter with an incompatible type - is_freeze::(); + is_freeze::(); //~^ ERROR: instantiating a type parameter with an incompatible type - is_static::(); + is_static::(); //~^ ERROR: instantiating a type parameter with an incompatible type } diff --git a/src/test/compile-fail/regionck-closure-lifetimes.rs b/src/test/compile-fail/regionck-closure-lifetimes.rs index ec51f2dc21244..e9ef23ebe09e8 100644 --- a/src/test/compile-fail/regionck-closure-lifetimes.rs +++ b/src/test/compile-fail/regionck-closure-lifetimes.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn env<'a>(_: &'a uint, blk: |p: 'a |||) { +fn env<'a>(_: &'a uint, blk: |p: ||: 'a|) { // Test that the closure here cannot be assigned // the lifetime `'a`, which outlives the current // block. @@ -21,7 +21,7 @@ fn env<'a>(_: &'a uint, blk: |p: 'a |||) { blk(|| *statep = 1); //~ ERROR cannot infer } -fn no_env_no_for<'a>(_: &'a uint, blk: |p: 'a |||) { +fn no_env_no_for<'a>(_: &'a uint, blk: |p: |||: 'a) { // Test that a closure with no free variables CAN // outlive the block in which it is created. // diff --git a/src/test/compile-fail/regions-freevar.rs b/src/test/compile-fail/regions-freevar.rs index 68920065d1967..285e11fa9a2e1 100644 --- a/src/test/compile-fail/regions-freevar.rs +++ b/src/test/compile-fail/regions-freevar.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn wants_static_fn(_x: 'static ||) {} +fn wants_static_fn(_x: ||: 'static) {} fn main() { let i = 3; diff --git a/src/test/compile-fail/regions-infer-at-fn-not-param.rs b/src/test/compile-fail/regions-infer-at-fn-not-param.rs index ad6d1b2742d10..4c883656d61a5 100644 --- a/src/test/compile-fail/regions-infer-at-fn-not-param.rs +++ b/src/test/compile-fail/regions-infer-at-fn-not-param.rs @@ -9,15 +9,15 @@ // except according to those terms. struct parameterized1<'a> { - g: 'a || + g: ||: 'a } struct not_parameterized1 { - g: 'static || + g: ||: 'static } struct not_parameterized2 { - g: 'static || + g: ||: 'static } fn take1(p: parameterized1) -> parameterized1 { p } diff --git a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs index ae1cbcf3e6874..53d013c0e6b8c 100644 --- a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs +++ b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-3.rs @@ -11,7 +11,7 @@ #![feature(managed_boxes)] struct invariant<'a> { - f: 'static |x: &mut &'a int| + f: |x: &mut &'a int|: 'static } fn to_same_lifetime<'r>(bi: invariant<'r>) { diff --git a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs index 096d8912f8b84..edab5b219911e 100644 --- a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs +++ b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-4.rs @@ -11,7 +11,7 @@ #![feature(managed_boxes)] struct invariant<'a> { - f: 'static || -> &mut &'a int + f: ||: 'static -> &mut &'a int } fn to_same_lifetime<'r>(bi: invariant<'r>) { diff --git a/src/test/compile-fail/regions-infer-not-param.rs b/src/test/compile-fail/regions-infer-not-param.rs index 6596a1d8c2384..86f98d5cc3515 100644 --- a/src/test/compile-fail/regions-infer-not-param.rs +++ b/src/test/compile-fail/regions-infer-not-param.rs @@ -14,12 +14,12 @@ struct direct<'a> { struct indirect1 { // Here the lifetime parameter of direct is bound by the fn() - g: 'static |direct| + g: |direct|: 'static } struct indirect2<'a> { // But here it is set to 'a - g: 'static |direct<'a>| + g: |direct<'a>|: 'static } fn take_direct(p: direct) -> direct { p } //~ ERROR mismatched types diff --git a/src/test/compile-fail/regions-steal-closure.rs b/src/test/compile-fail/regions-steal-closure.rs index f80e5616bd555..7ffc6a75cff8c 100644 --- a/src/test/compile-fail/regions-steal-closure.rs +++ b/src/test/compile-fail/regions-steal-closure.rs @@ -9,10 +9,10 @@ // except according to those terms. struct closure_box<'a> { - cl: 'a || + cl: ||: 'a } -fn box_it<'r>(x: 'r ||) -> closure_box<'r> { +fn box_it<'r>(x: ||: 'r) -> closure_box<'r> { closure_box {cl: x} } diff --git a/src/test/debug-info/recursive-enum.rs b/src/test/debug-info/recursive-enum.rs index 8279119a09caa..c02d3f0e07630 100644 --- a/src/test/debug-info/recursive-enum.rs +++ b/src/test/debug-info/recursive-enum.rs @@ -26,7 +26,7 @@ struct WindowCallbacks<'a> { pos_callback: Option>, } -pub type WindowPosCallback<'a> = 'a |&Window, i32, i32|; +pub type WindowPosCallback<'a> = |&Window, i32, i32|: 'a; fn main() { let x = WindowCallbacks { pos_callback: None }; diff --git a/src/test/run-fail/unwind-box-fn-unique.rs b/src/test/run-fail/unwind-box-fn-unique.rs index 4a6f37c91b788..da4210b9fa8cc 100644 --- a/src/test/run-fail/unwind-box-fn-unique.rs +++ b/src/test/run-fail/unwind-box-fn-unique.rs @@ -18,7 +18,7 @@ fn failfn() { fn main() { let y = ~0; - let x: @proc:Send() = @(proc() { + let x: @proc():Send = @(proc() { println!("{:?}", y.clone()); }); failfn(); diff --git a/src/test/run-fail/unwind-lambda.rs b/src/test/run-fail/unwind-lambda.rs index ee570fa2e950d..f544d474c4fe7 100644 --- a/src/test/run-fail/unwind-lambda.rs +++ b/src/test/run-fail/unwind-lambda.rs @@ -16,7 +16,7 @@ fn main() { let cheese = ~"roquefort"; let carrots = @~"crunchy"; - let result: 'static |@~str, |~str|| = (|tasties, macerate| { + let result: |@~str, |~str||: 'static = (|tasties, macerate| { macerate((*tasties).clone()); }); result(carrots, |food| { diff --git a/src/test/run-pass/clone-with-exterior.rs b/src/test/run-pass/clone-with-exterior.rs index 4f3db3a5f77f9..038c0418ecb4c 100644 --- a/src/test/run-pass/clone-with-exterior.rs +++ b/src/test/run-pass/clone-with-exterior.rs @@ -18,7 +18,7 @@ struct Pair { pub fn main() { let z = ~Pair { a : 10, b : 12}; - let f: proc:Send() = proc() { + let f: proc():Send = proc() { assert_eq!(z.a, 10); assert_eq!(z.b, 12); }; diff --git a/src/test/run-pass/closure-syntax.rs b/src/test/run-pass/closure-syntax.rs index 798808a157277..983cd00f39cb8 100644 --- a/src/test/run-pass/closure-syntax.rs +++ b/src/test/run-pass/closure-syntax.rs @@ -61,7 +61,7 @@ fn bar<'b>() { foo::(int, f32, &'a int):'static + Share -> &'a int>(); // issue #11209 - let _: 'b ||; // for comparison + let _: ||: 'b; // for comparison let _: <'a> ||; let _: Option<||:'b>; @@ -69,7 +69,7 @@ fn bar<'b>() { let _: Option< <'a>||>; // issue #11210 - let _: 'static ||; + let _: ||: 'static; } pub fn main() { diff --git a/src/test/run-pass/issue-1516.rs b/src/test/run-pass/issue-1516.rs index f3ffed7dc7bc3..3aaa480d776c2 100644 --- a/src/test/run-pass/issue-1516.rs +++ b/src/test/run-pass/issue-1516.rs @@ -9,5 +9,5 @@ // except according to those terms. pub fn main() { - let early_error: 'static |&str| -> ! = |_msg| { fail!() }; + let early_error: |&str|: 'static -> ! = |_msg| { fail!() }; } diff --git a/src/test/run-pass/issue-2190-1.rs b/src/test/run-pass/issue-2190-1.rs index d04717e380be5..c8735e79e502c 100644 --- a/src/test/run-pass/issue-2190-1.rs +++ b/src/test/run-pass/issue-2190-1.rs @@ -12,13 +12,13 @@ use std::task; static generations: uint = 1024+256+128+49; -fn spawn(f: proc:Send()) { +fn spawn(f: proc():Send) { let mut t = task::task(); t.opts.stack_size = Some(32 * 1024); t.spawn(f); } -fn child_no(x: uint) -> proc:Send() { +fn child_no(x: uint) -> proc():Send { proc() { if x < generations { spawn(child_no(x+1)); diff --git a/src/test/run-pass/issue-3609.rs b/src/test/run-pass/issue-3609.rs index 1f1de9ddb9ba1..95bbf77024c8f 100644 --- a/src/test/run-pass/issue-3609.rs +++ b/src/test/run-pass/issue-3609.rs @@ -11,7 +11,7 @@ use std::task; type RingBuffer = Vec ; -type SamplesFn = proc:Send(samples: &RingBuffer); +type SamplesFn = proc(samples: &RingBuffer):Send; enum Msg { diff --git a/src/test/run-pass/last-use-in-cap-clause.rs b/src/test/run-pass/last-use-in-cap-clause.rs index b72ef59075ce2..ec26dc0b3ed36 100644 --- a/src/test/run-pass/last-use-in-cap-clause.rs +++ b/src/test/run-pass/last-use-in-cap-clause.rs @@ -12,10 +12,10 @@ struct A { a: ~int } -fn foo() -> 'static || -> int { +fn foo() -> ||: 'static -> int { let k = ~22; let _u = A {a: k.clone()}; - let result: 'static || -> int = || 22; + let result: ||: 'static -> int = || 22; result } diff --git a/src/test/run-pass/proc-bounds.rs b/src/test/run-pass/proc-bounds.rs index 900e266584bd3..c103e08736396 100644 --- a/src/test/run-pass/proc-bounds.rs +++ b/src/test/run-pass/proc-bounds.rs @@ -17,18 +17,18 @@ fn is_static() {} pub fn main() { foo::(); - foo::(); - foo::(); - foo::(); - foo::(); + foo::(); + foo::(); + foo::(); + foo::(); - is_send::(); - is_freeze::(); - is_static::(); + is_send::(); + is_freeze::(); + is_static::(); let a = 3; - bar::(proc() { + bar::(proc() { let b = &a; println!("{}", *b); }); diff --git a/src/test/run-pass/sendfn-spawn-with-fn-arg.rs b/src/test/run-pass/sendfn-spawn-with-fn-arg.rs index ac3dd80c383bb..a62c1ec33146b 100644 --- a/src/test/run-pass/sendfn-spawn-with-fn-arg.rs +++ b/src/test/run-pass/sendfn-spawn-with-fn-arg.rs @@ -18,7 +18,7 @@ fn test05_start(f: proc(int)) { fn test05() { let three = ~3; - let fn_to_send: proc:Send(int) = proc(n) { + let fn_to_send: proc(int):Send = proc(n) { println!("{}", *three + n); // will copy x into the closure assert_eq!(*three, 3); }; diff --git a/src/test/run-pass/tempfile.rs b/src/test/run-pass/tempfile.rs index d11e879b494a7..437d6faea3854 100644 --- a/src/test/run-pass/tempfile.rs +++ b/src/test/run-pass/tempfile.rs @@ -35,7 +35,7 @@ fn test_tempdir() { fn test_rm_tempdir() { let (tx, rx) = channel(); - let f: proc:Send() = proc() { + let f: proc():Send = proc() { let tmp = TempDir::new("test_rm_tempdir").unwrap(); tx.send(tmp.path().clone()); fail!("fail to unwind past `tmp`"); @@ -46,7 +46,7 @@ fn test_rm_tempdir() { let tmp = TempDir::new("test_rm_tempdir").unwrap(); let path = tmp.path().clone(); - let f: proc:Send() = proc() { + let f: proc():Send = proc() { let _tmp = tmp; fail!("fail to unwind past `tmp`"); }; diff --git a/src/test/run-pass/uniq-cc-generic.rs b/src/test/run-pass/uniq-cc-generic.rs index 78fa7520f33fa..3c164d3e2dab5 100644 --- a/src/test/run-pass/uniq-cc-generic.rs +++ b/src/test/run-pass/uniq-cc-generic.rs @@ -19,10 +19,10 @@ enum maybe_pointy { struct Pointy { a : maybe_pointy, - d : proc:Send() -> uint, + d : proc():Send -> uint, } -fn make_uniq_closure(a: A) -> proc:Send() -> uint { +fn make_uniq_closure(a: A) -> proc():Send -> uint { proc() { &a as *A as uint } } diff --git a/src/test/run-pass/uniq-cc.rs b/src/test/run-pass/uniq-cc.rs index aa048a239dbf3..6c273199c6f7c 100644 --- a/src/test/run-pass/uniq-cc.rs +++ b/src/test/run-pass/uniq-cc.rs @@ -20,7 +20,7 @@ enum maybe_pointy { struct Pointy { a : maybe_pointy, c : ~int, - d : proc:Send()->(), + d : proc():Send->(), } fn empty_pointy() -> @RefCell { From ef37cfdeccbdf8151129d2d182a568d7310754c1 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 7 Apr 2014 14:00:19 -0700 Subject: [PATCH 05/16] std: Add more docs for ptr mod --- src/libstd/ptr.rs | 235 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 182 insertions(+), 53 deletions(-) diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index 504c613bf4c17..19eee8755a0cc 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -8,7 +8,87 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Unsafe pointer utility functions +//! Conveniences for working with unsafe pointers, the `*T`, and `*mut T` types. +//! +//! Working with unsafe pointers in Rust is fairly uncommon, +//! and often limited to some narrow use cases: holding +//! an unsafe pointer when safe pointers are unsuitable; +//! checking for null; and converting back to safe pointers. +//! As a result, there is not yet an abundance of library code +//! for working with unsafe poniters, and in particular, +//! since pointer math is fairly uncommon in Rust, it is not +//! all that convenient. +//! +//! Use the [`null` function](fn.null.html) to create null pointers, +//! the [`is_null`](trait.RawPtr.html#tymethod.is_null) +//! and [`is_not_null`](trait.RawPtr.html#method.is_not_null) +//! methods of the [`RawPtr` trait](trait.RawPtr.html) to check for null. +//! The `RawPtr` trait is imported by the prelude, so `is_null` etc. +//! work everywhere. +//! +//! # Common ways to create unsafe pointers +//! +//! ## 1. Coerce a reference (`&T`) or mutable reference (`&mut T`). +//! +//! ``` +//! let my_num: int = 10; +//! let my_num_ptr: *int = &my_num; +//! let mut my_speed: int = 88; +//! let my_speed_ptr: *mut int = &mut my_speed; +//! ``` +//! +//! This does not take ownership of the original allocation +//! and requires no resource management later, +//! but you must not use the pointer after its lifetime. +//! +//! ## 2. Transmute an owned box (`~T`). +//! +//! The `transmute` function takes, by value, whatever it's given +//! and returns it as whatever type is requested, as long as the +//! types are the same size. Because `~T` and `*T` have the same +//! representation they can be trivially, +//! though unsafely, transformed from one type to the other. +//! +//! ``` +//! use std::cast; +//! +//! unsafe { +//! let my_num: ~int = ~10; +//! let my_num: *int = cast::transmute(my_num); +//! let my_speed: ~int = ~88; +//! let my_speed: *mut int = cast::transmute(my_speed); +//! +//! // By taking ownership of the original `~T` though +//! // we are obligated to transmute it back later to be destroyed. +//! drop(cast::transmute::<_, ~int>(my_speed)); +//! drop(cast::transmute::<_, ~int>(my_num)); +//! } +//! ``` +//! +//! Note that here the call to `drop` is for clarity - it indicates +//! that we are done with the given value and it should be destroyed. +//! +//! ## 3. Get it from C. +//! +//! ``` +//! extern crate libc; +//! +//! use std::mem; +//! +//! fn main() { +//! unsafe { +//! let my_num: *mut int = libc::malloc(mem::size_of::() as libc::size_t) as *mut int; +//! if my_num.is_null() { +//! fail!("failed to allocate memory"); +//! } +//! libc::free(my_num as *mut libc::c_void); +//! } +//! } +//! ``` +//! +//! Usually you wouldn't literally use `malloc` and `free` from Rust, +//! but C APIs hand out a lot of pointers generally, so are a common source +//! of unsafe pointers in Rust. use cast; use clone::Clone; @@ -51,31 +131,97 @@ pub unsafe fn position(buf: *T, f: |&T| -> bool) -> uint { } } -/// Create an unsafe null pointer +/// Create an null pointer. +/// +/// # Example +/// +/// ``` +/// use std::ptr; +/// +/// let p: *int = ptr::null(); +/// assert!(p.is_null()); +/// ``` #[inline] pub fn null() -> *T { 0 as *T } -/// Create an unsafe mutable null pointer +/// Create an unsafe mutable null pointer. +/// +/// # Example +/// +/// ``` +/// use std::ptr; +/// +/// let p: *mut int = ptr::mut_null(); +/// assert!(p.is_null()); +/// ``` #[inline] pub fn mut_null() -> *mut T { 0 as *mut T } -/** - * Copies data from one location to another. - * - * Copies `count` elements (not bytes) from `src` to `dst`. The source - * and destination may overlap. - */ +/// Copies data from one location to another. +/// +/// Copies `count` elements (not bytes) from `src` to `dst`. The source +/// and destination may overlap. +/// +/// `copy_memory` is semantically equivalent to C's `memmove`. +/// +/// # Example +/// +/// Efficiently create a Rust vector from an unsafe buffer: +/// +/// ``` +/// use std::ptr; +/// use std::slice; +/// +/// unsafe fn from_buf_raw(ptr: *T, elts: uint) -> ~[T] { +/// let mut dst = slice::with_capacity(elts); +/// dst.set_len(elts); +/// ptr::copy_memory(dst.as_mut_ptr(), ptr, elts); +/// dst +/// } +/// ``` +/// #[inline] pub unsafe fn copy_memory(dst: *mut T, src: *T, count: uint) { intrinsics::copy_memory(dst, src, count) } -/** - * Copies data from one location to another. - * - * Copies `count` elements (not bytes) from `src` to `dst`. The source - * and destination may *not* overlap. - */ +/// Copies data from one location to another. +/// +/// Copies `count` elements (not bytes) from `src` to `dst`. The source +/// and destination may *not* overlap. +/// +/// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`. +/// +/// # Example +/// +/// A safe swap function: +/// +/// ``` +/// use std::cast; +/// use std::mem; +/// use std::ptr; +/// +/// fn swap(x: &mut T, y: &mut T) { +/// unsafe { +/// // Give ourselves some scratch space to work with +/// let mut t: T = mem::uninit(); +/// +/// // Perform the swap, `&mut` pointers never alias +/// ptr::copy_nonoverlapping_memory(&mut t, &*x, 1); +/// ptr::copy_nonoverlapping_memory(x, &*y, 1); +/// ptr::copy_nonoverlapping_memory(y, &t, 1); +/// +/// // y and t now point to the same thing, but we need to completely forget `tmp` +/// // because it's no longer relevant. +/// cast::forget(t); +/// } +/// } +/// ``` +/// +/// # Safety Note +/// +/// If the source and destination overlap then the behavior of this +/// function is undefined. #[inline] pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, src: *T, @@ -83,27 +229,21 @@ pub unsafe fn copy_nonoverlapping_memory(dst: *mut T, intrinsics::copy_nonoverlapping_memory(dst, src, count) } -/** - * Invokes memset on the specified pointer, setting `count * size_of::()` - * bytes of memory starting at `dst` to `c`. - */ +/// Invokes memset on the specified pointer, setting `count * size_of::()` +/// bytes of memory starting at `dst` to `c`. #[inline] pub unsafe fn set_memory(dst: *mut T, c: u8, count: uint) { intrinsics::set_memory(dst, c, count) } -/** - * Zeroes out `count * size_of::` bytes of memory at `dst` - */ +/// Zeroes out `count * size_of::` bytes of memory at `dst` #[inline] pub unsafe fn zero_memory(dst: *mut T, count: uint) { set_memory(dst, 0, count); } -/** - * Swap the values at two mutable locations of the same type, without - * deinitialising either. They may overlap. - */ +/// Swap the values at two mutable locations of the same type, without +/// deinitialising either. They may overlap. #[inline] pub unsafe fn swap(x: *mut T, y: *mut T) { // Give ourselves some scratch space to work with @@ -120,19 +260,15 @@ pub unsafe fn swap(x: *mut T, y: *mut T) { cast::forget(tmp); } -/** - * Replace the value at a mutable location with a new one, returning the old - * value, without deinitialising either. - */ +/// Replace the value at a mutable location with a new one, returning the old +/// value, without deinitialising either. #[inline] pub unsafe fn replace(dest: *mut T, mut src: T) -> T { mem::swap(cast::transmute(dest), &mut src); // cannot overlap src } -/** - * Reads the value from `*src` and returns it. - */ +/// Reads the value from `*src` and returns it. #[inline(always)] pub unsafe fn read(src: *T) -> T { let mut tmp: T = mem::uninit(); @@ -140,10 +276,8 @@ pub unsafe fn read(src: *T) -> T { tmp } -/** - * Reads the value from `*src` and nulls it out. - * This currently prevents destructors from executing. - */ +/// Reads the value from `*src` and nulls it out. +/// This currently prevents destructors from executing. #[inline(always)] pub unsafe fn read_and_zero(dest: *mut T) -> T { // Copy the data out from `dest`: @@ -155,13 +289,9 @@ pub unsafe fn read_and_zero(dest: *mut T) -> T { tmp } -/** - 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. -*/ +/// Given a **T (pointer to an array of pointers), +/// iterate through each *T, up to the provided `len`, +/// passing to the provided callback function pub unsafe fn array_each_with_len(arr: **T, len: uint, cb: |*T|) { if arr.is_null() { fail!("ptr::array_each_with_len failure: arr input is null pointer"); @@ -173,15 +303,14 @@ pub unsafe fn array_each_with_len(arr: **T, len: uint, cb: |*T|) { } } -/** - 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-dodgy Pointer Arithmetic. - Dragons be here. -*/ +/// 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. pub unsafe fn array_each(arr: **T, cb: |*T|) { if arr.is_null() { fail!("ptr::array_each_with_len failure: arr input is null pointer"); From 31755e2452b280fe4038140012dcd19560b6f03d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 7 Apr 2014 12:14:33 -0700 Subject: [PATCH 06/16] rustc: Use CStore, not a separate crate cache This separate crate cache is one factor which is causing libstd to be loaded twice during normal compilation. The crates loaded for syntax extensions have a separate cache than the crates loaded for linking, so all crates are loaded once per #[phase] they're tagged with. This removes the cache and instead uses the CStore structure itself as the cache for loaded crates. This should allow crates loaded during the syntax phase to be shared with the crates loaded during the link phase. --- src/librustc/metadata/creader.rs | 119 +++++++++++++------------------ src/librustc/metadata/cstore.rs | 12 ++++ 2 files changed, 61 insertions(+), 70 deletions(-) diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 8ce4a2f8eed86..9c0c73288eb0d 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -18,6 +18,7 @@ use driver::{driver, session}; use driver::session::Session; use metadata::csearch; use metadata::cstore; +use metadata::cstore::CStore; use metadata::decoder; use metadata::loader; use metadata::loader::Os; @@ -38,6 +39,13 @@ use syntax::parse::token; use syntax::crateid::CrateId; use syntax::visit; +struct Env<'a> { + sess: &'a Session, + os: loader::Os, + next_crate_num: ast::CrateNum, + intr: Rc +} + // Traverses an AST, reading all the information about use'd crates and extern // libraries necessary for later resolving, typechecking, linking, etc. pub fn read_crates(sess: &Session, @@ -47,16 +55,13 @@ pub fn read_crates(sess: &Session, let mut e = Env { sess: sess, os: os, - crate_cache: @RefCell::new(Vec::new()), - next_crate_num: 1, + next_crate_num: sess.cstore.next_crate_num(), intr: intr }; visit_crate(&e, krate); visit::walk_crate(&mut e, krate, ()); - dump_crates(e.crate_cache.borrow().as_slice()); - warn_if_multiple_versions(&mut e, - sess.diagnostic(), - e.crate_cache.borrow().as_slice()); + dump_crates(&sess.cstore); + warn_if_multiple_versions(sess.diagnostic(), &sess.cstore) } impl<'a> visit::Visitor<()> for Env<'a> { @@ -70,55 +75,36 @@ impl<'a> visit::Visitor<()> for Env<'a> { } } -#[deriving(Clone)] -struct cache_entry { - cnum: ast::CrateNum, - span: Span, - hash: Svh, - crate_id: CrateId, -} - -fn dump_crates(crate_cache: &[cache_entry]) { +fn dump_crates(cstore: &CStore) { debug!("resolved crates:"); - for entry in crate_cache.iter() { - debug!("cnum: {:?}", entry.cnum); - debug!("span: {:?}", entry.span); - debug!("hash: {:?}", entry.hash); - } + cstore.iter_crate_data(|_, data| { + debug!("crate_id: {}", data.crate_id()); + debug!(" cnum: {}", data.cnum); + debug!(" hash: {}", data.hash()); + }) } -fn warn_if_multiple_versions(e: &mut Env, - diag: &SpanHandler, - crate_cache: &[cache_entry]) { - if crate_cache.len() != 0u { - let name = crate_cache[crate_cache.len() - 1].crate_id.name.clone(); - - let (matches, non_matches) = crate_cache.partitioned(|entry| - name == entry.crate_id.name); +fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) { + let mut map = HashMap::new(); - assert!(!matches.is_empty()); + cstore.iter_crate_data(|cnum, data| { + let crateid = data.crate_id(); + let key = (crateid.name.clone(), crateid.path.clone()); + map.find_or_insert_with(key, |_| Vec::new()).push(cnum); + }); - if matches.len() != 1u { - diag.handler().warn( - format!("using multiple versions of crate `{}`", name)); - for match_ in matches.iter() { - diag.span_note(match_.span, "used here"); - loader::note_crateid_attr(diag, &match_.crate_id); - } + for ((name, _), dupes) in map.move_iter() { + if dupes.len() == 1 { continue } + diag.handler().warn( + format!("using multiple versions of crate `{}`", name)); + for dupe in dupes.move_iter() { + let data = cstore.get_crate_data(dupe); + diag.span_note(data.span, "used here"); + loader::note_crateid_attr(diag, &data.crate_id()); } - - warn_if_multiple_versions(e, diag, non_matches); } } -struct Env<'a> { - sess: &'a Session, - os: loader::Os, - crate_cache: @RefCell>, - next_crate_num: ast::CrateNum, - intr: Rc -} - fn visit_crate(e: &Env, c: &ast::Crate) { for a in c.attrs.iter().filter(|m| m.name().equiv(&("link_args"))) { match a.value_str() { @@ -269,14 +255,18 @@ fn visit_item(e: &Env, i: &ast::Item) { fn existing_match(e: &Env, crate_id: &CrateId, hash: Option<&Svh>) -> Option { - for c in e.crate_cache.borrow().iter() { - if !crate_id.matches(&c.crate_id) { continue } - match hash { - Some(hash) if *hash != c.hash => {} - Some(..) | None => return Some(c.cnum) + let mut ret = None; + e.sess.cstore.iter_crate_data(|cnum, data| { + let other_id = data.crate_id(); + if crate_id.matches(&other_id) { + let other_hash = data.hash(); + match hash { + Some(hash) if *hash != other_hash => {} + Some(..) | None => { ret = Some(cnum); } + } } - } - None + }); + return ret; } fn resolve_crate<'a>(e: &mut Env, @@ -304,17 +294,8 @@ fn resolve_crate<'a>(e: &mut Env, dylib, rlib, metadata } = load_ctxt.load_library_crate(root); - let crate_id = decoder::get_crate_id(metadata.as_slice()); - let hash = decoder::get_crate_hash(metadata.as_slice()); - // Claim this crate number and cache it let cnum = e.next_crate_num; - e.crate_cache.borrow_mut().push(cache_entry { - cnum: cnum, - span: span, - hash: hash, - crate_id: crate_id, - }); e.next_crate_num += 1; // Stash paths for top-most crate locally if necessary. @@ -331,16 +312,15 @@ fn resolve_crate<'a>(e: &mut Env, let root = if root.is_some() { root } else { &crate_paths }; // Now resolve the crates referenced by this crate - let cnum_map = resolve_crate_deps(e, - root, - metadata.as_slice(), - span); + let cnum_map = resolve_crate_deps(e, root, metadata.as_slice(), + span); let cmeta = @cstore::crate_metadata { name: load_ctxt.crate_id.name.to_owned(), data: metadata, cnum_map: cnum_map, - cnum: cnum + cnum: cnum, + span: span, }; e.sess.cstore.set_crate_data(cnum, cmeta); @@ -390,8 +370,7 @@ impl<'a> Loader<'a> { env: Env { sess: sess, os: os, - crate_cache: @RefCell::new(Vec::new()), - next_crate_num: 1, + next_crate_num: sess.cstore.next_crate_num(), intr: token::get_ident_interner(), } } @@ -406,7 +385,7 @@ impl<'a> CrateLoader for Loader<'a> { let library = self.env.sess.cstore.get_used_crate_source(cnum).unwrap(); MacroCrate { lib: library.dylib, - cnum: cnum + cnum: cnum, } } diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index e3a3239bdb5b8..2d46f92e88fa4 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -22,6 +22,8 @@ use std::c_vec::CVec; use std::rc::Rc; use collections::HashMap; use syntax::ast; +use syntax::crateid::CrateId; +use syntax::codemap::Span; use syntax::parse::token::IdentInterner; // A map from external crate numbers (as decoded from some crate file) to @@ -40,6 +42,7 @@ pub struct crate_metadata { pub data: MetadataBlob, pub cnum_map: cnum_map, pub cnum: ast::CrateNum, + pub span: Span, } #[deriving(Eq)] @@ -88,6 +91,10 @@ impl CStore { } } + pub fn next_crate_num(&self) -> ast::CrateNum { + self.metas.borrow().len() as ast::CrateNum + 1 + } + pub fn get_crate_data(&self, cnum: ast::CrateNum) -> @crate_metadata { *self.metas.borrow().get(&cnum) } @@ -121,6 +128,9 @@ impl CStore { .map(|source| source.clone()) } + pub fn dump_phase_syntax_crates(&self) { + } + pub fn reset(&self) { self.metas.borrow_mut().clear(); self.extern_mod_crate_map.borrow_mut().clear(); @@ -202,6 +212,8 @@ impl CStore { impl crate_metadata { pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() } + pub fn crate_id(&self) -> CrateId { decoder::get_crate_id(self.data()) } + pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) } } impl MetadataBlob { From 5367c32c7ddb873babec89f739a936409d45476a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 7 Apr 2014 12:16:43 -0700 Subject: [PATCH 07/16] rustc: Never register syntax crates in CStore When linking, all crates in the local CStore are used to link the final product. With #[phase(syntax)], crates want to be omitted from this linkage phase, and this was achieved by dumping the entire CStore after loading crates. This causes crates like the standard library to get loaded twice. This loading process is a fairly expensive operation when dealing with decompressing metadata. This commit alters the loading process to never register syntax crates in CStore. Instead, only phase(link) crates ever make their way into the map of crates. The CrateLoader trait was altered to return everything in one method instead of having separate methods for finding information. --- src/librustc/driver/driver.rs | 2 - src/librustc/metadata/creader.rs | 79 ++++++++++++++++++-------------- src/libsyntax/ext/base.rs | 5 +- src/libsyntax/ext/expand.rs | 8 ++-- 4 files changed, 51 insertions(+), 43 deletions(-) diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 0668abea2b12f..8a593d5f92a2a 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -241,8 +241,6 @@ pub fn phase_2_configure_and_expand(sess: &Session, cfg, krate) }); - // dump the syntax-time crates - sess.cstore.reset(); // strip again, in case expansion added anything with a #[cfg]. krate = time(time_passes, "configuration 2", krate, |krate| diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 9c0c73288eb0d..50c22f6bf1bba 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -114,22 +114,25 @@ fn visit_crate(e: &Env, c: &ast::Crate) { } } -fn visit_view_item(e: &mut Env, i: &ast::ViewItem) { - let should_load = i.attrs.iter().all(|attr| { +fn should_link(i: &ast::ViewItem) -> bool { + i.attrs.iter().all(|attr| { attr.name().get() != "phase" || attr.meta_item_list().map_or(false, |phases| { attr::contains_name(phases.as_slice(), "link") }) - }); + }) +} - if !should_load { +fn visit_view_item(e: &mut Env, i: &ast::ViewItem) { + if !should_link(i) { return; } match extract_crate_info(e, i) { Some(info) => { - let cnum = resolve_crate(e, &None, info.ident, &info.crate_id, None, - i.span); + let (cnum, _, _) = resolve_crate(e, &None, info.ident, + &info.crate_id, None, true, + i.span); e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum); } None => () @@ -140,6 +143,7 @@ struct CrateInfo { ident: ~str, crate_id: CrateId, id: ast::NodeId, + should_link: bool, } fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option { @@ -165,6 +169,7 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option { ident: ident.get().to_str(), crate_id: crate_id, id: id, + should_link: should_link(i), }) } _ => None @@ -274,8 +279,10 @@ fn resolve_crate<'a>(e: &mut Env, ident: &str, crate_id: &CrateId, hash: Option<&Svh>, + should_link: bool, span: Span) - -> ast::CrateNum { + -> (ast::CrateNum, @cstore::crate_metadata, + cstore::CrateSource) { match existing_match(e, crate_id, hash) { None => { let id_hash = link::crate_id_hash(crate_id); @@ -312,8 +319,11 @@ fn resolve_crate<'a>(e: &mut Env, let root = if root.is_some() { root } else { &crate_paths }; // Now resolve the crates referenced by this crate - let cnum_map = resolve_crate_deps(e, root, metadata.as_slice(), - span); + let cnum_map = if should_link { + resolve_crate_deps(e, root, metadata.as_slice(), span) + } else { + @RefCell::new(HashMap::new()) + }; let cmeta = @cstore::crate_metadata { name: load_ctxt.crate_id.name.to_owned(), @@ -323,15 +333,21 @@ fn resolve_crate<'a>(e: &mut Env, span: span, }; - e.sess.cstore.set_crate_data(cnum, cmeta); - e.sess.cstore.add_used_crate_source(cstore::CrateSource { + let source = cstore::CrateSource { dylib: dylib, rlib: rlib, cnum: cnum, - }); - cnum + }; + + if should_link { + e.sess.cstore.set_crate_data(cnum, cmeta); + e.sess.cstore.add_used_crate_source(source.clone()); + } + (cnum, cmeta, source) } - Some(cnum) => cnum + Some(cnum) => (cnum, + e.sess.cstore.get_crate_data(cnum), + e.sess.cstore.get_used_crate_source(cnum).unwrap()) } } @@ -348,11 +364,12 @@ fn resolve_crate_deps(e: &mut Env, for dep in r.iter() { let extrn_cnum = dep.cnum; debug!("resolving dep crate {} hash: `{}`", dep.crate_id, dep.hash); - let local_cnum = resolve_crate(e, root, - dep.crate_id.name.as_slice(), - &dep.crate_id, - Some(&dep.hash), - span); + let (local_cnum, _, _) = resolve_crate(e, root, + dep.crate_id.name.as_slice(), + &dep.crate_id, + Some(&dep.hash), + true, + span); cnum_map.insert(extrn_cnum, local_cnum); } return @RefCell::new(cnum_map); @@ -380,23 +397,17 @@ impl<'a> Loader<'a> { impl<'a> CrateLoader for Loader<'a> { fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate { let info = extract_crate_info(&self.env, krate).unwrap(); - let cnum = resolve_crate(&mut self.env, &None, info.ident, - &info.crate_id, None, krate.span); - let library = self.env.sess.cstore.get_used_crate_source(cnum).unwrap(); + let (cnum, data, library) = resolve_crate(&mut self.env, &None, + info.ident, &info.crate_id, + None, true, krate.span); + let macros = decoder::get_exported_macros(data); + let cstore = &self.env.sess.cstore; + let registrar = csearch::get_macro_registrar_fn(cstore, cnum) + .map(|did| csearch::get_symbol(cstore, did)); MacroCrate { lib: library.dylib, - cnum: cnum, + macros: macros.move_iter().collect(), + registrar_symbol: registrar, } } - - fn get_exported_macros(&mut self, cnum: ast::CrateNum) -> Vec<~str> { - csearch::get_exported_macros(&self.env.sess.cstore, cnum).move_iter() - .collect() - } - - fn get_registrar_symbol(&mut self, cnum: ast::CrateNum) -> Option<~str> { - let cstore = &self.env.sess.cstore; - csearch::get_macro_registrar_fn(cstore, cnum) - .map(|did| csearch::get_symbol(cstore, did)) - } } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 7ff7792313251..3bf1ed95f380e 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -293,13 +293,12 @@ pub fn syntax_expander_table() -> SyntaxEnv { pub struct MacroCrate { pub lib: Option, - pub cnum: ast::CrateNum, + pub macros: Vec<~str>, + pub registrar_symbol: Option<~str>, } pub trait CrateLoader { fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate; - fn get_exported_macros(&mut self, crate_num: ast::CrateNum) -> Vec<~str> ; - fn get_registrar_symbol(&mut self, crate_num: ast::CrateNum) -> Option<~str>; } // One of these is made during expansion and incrementally updated as we go; diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 747ab583e792a..5c3c7d995d67a 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -487,7 +487,8 @@ pub fn expand_view_item(vi: &ast::ViewItem, } fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) { - let MacroCrate { lib, cnum } = fld.cx.ecfg.loader.load_crate(krate); + let MacroCrate { lib, macros, registrar_symbol } = + fld.cx.ecfg.loader.load_crate(krate); let crate_name = match krate.node { ast::ViewItemExternCrate(name, _, _) => name, @@ -495,8 +496,7 @@ fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) { }; let name = format!("<{} macros>", token::get_ident(crate_name)); - let exported_macros = fld.cx.ecfg.loader.get_exported_macros(cnum); - for source in exported_macros.iter() { + for source in macros.iter() { let item = parse::parse_item_from_source_str(name.clone(), (*source).clone(), fld.cx.cfg(), @@ -512,7 +512,7 @@ fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) { // Make sure the path contains a / or the linker will search for it. let path = os::make_absolute(&path); - let registrar = match fld.cx.ecfg.loader.get_registrar_symbol(cnum) { + let registrar = match registrar_symbol { Some(registrar) => registrar, None => return }; From cced02fcacfe4a6d1598e987003e00aa65713efb Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 7 Apr 2014 13:13:21 -0700 Subject: [PATCH 08/16] rustc: Don't read both rlib and dylib metadata This is an optimization which is quite impactful for compiling small crates. Reading libstd's metadata takes about 50ms, and a hello world before this change took about 100ms (this change halves that time). Recent changes made it such that this optimization wasn't performed, but I think it's a better idea do to this for now. See #10786 for tracking this issue. --- src/librustc/metadata/loader.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index 8dea36d8152a2..5a342e39d701a 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -317,15 +317,23 @@ impl<'a> Context<'a> { // read the metadata from it if `*slot` is `None`. If the metadata couldn't // be read, it is assumed that the file isn't a valid rust library (no // errors are emitted). - // - // FIXME(#10786): for an optimization, we only read one of the library's - // metadata sections. In theory we should read both, but - // reading dylib metadata is quite slow. fn extract_one(&mut self, m: HashSet, flavor: &str, slot: &mut Option) -> Option { let mut ret = None::; let mut error = 0; + if slot.is_some() { + // FIXME(#10786): for an optimization, we only read one of the + // library's metadata sections. In theory we should + // read both, but reading dylib metadata is quite + // slow. + if m.len() == 0 { + return None + } else if m.len() == 1 { + return Some(m.move_iter().next().unwrap()) + } + } + for lib in m.move_iter() { info!("{} reading metadata from: {}", flavor, lib.display()); let metadata = match get_metadata_section(self.os, &lib) { From de2567dec9cfceec59db5d6d17df09c05f70d5a1 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 7 Apr 2014 12:36:36 -0400 Subject: [PATCH 09/16] fix ~ZeroSizeType rvalues Closes #13360 --- src/librustc/middle/trans/expr.rs | 8 ++++++-- .../run-pass/empty-allocation-rvalue-non-null.rs | 13 +++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 src/test/run-pass/empty-allocation-rvalue-non-null.rs diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 95bf2a7f2753a..e47362e8d9ece 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1802,11 +1802,15 @@ fn deref_once<'a>(bcx: &'a Block<'a>, RvalueExpr(Rvalue { mode: ByRef }) => { let scope = cleanup::temporary_scope(bcx.tcx(), expr.id); let ptr = Load(bcx, datum.val); - bcx.fcx.schedule_free_value(scope, ptr, cleanup::HeapExchange); + if !type_is_zero_size(bcx.ccx(), content_ty) { + bcx.fcx.schedule_free_value(scope, ptr, cleanup::HeapExchange); + } } RvalueExpr(Rvalue { mode: ByValue }) => { let scope = cleanup::temporary_scope(bcx.tcx(), expr.id); - bcx.fcx.schedule_free_value(scope, datum.val, cleanup::HeapExchange); + if !type_is_zero_size(bcx.ccx(), content_ty) { + bcx.fcx.schedule_free_value(scope, datum.val, cleanup::HeapExchange); + } } LvalueExpr => { } } diff --git a/src/test/run-pass/empty-allocation-rvalue-non-null.rs b/src/test/run-pass/empty-allocation-rvalue-non-null.rs new file mode 100644 index 0000000000000..a5fc8425cf6b0 --- /dev/null +++ b/src/test/run-pass/empty-allocation-rvalue-non-null.rs @@ -0,0 +1,13 @@ +// Copyright 2014 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. + +pub fn main() { + let x = *~(); +} From 00cbda2d0af81a054ba61bd237f98e033ba7a2fa Mon Sep 17 00:00:00 2001 From: Boris Egorov Date: Mon, 7 Apr 2014 19:01:10 +0700 Subject: [PATCH 10/16] Improve searching for XXX in tidy script (#3303) Few places where previous version of tidy script cannot find XXX: * inside one-line comment preceding by a few spaces; * inside multiline comments (now it finds it if multiline comment starts on the same line with XXX). Change occurences of XXX found by new tidy script. --- src/etc/tidy.py | 5 +++-- src/librustuv/addrinfo.rs | 4 ++-- src/libstd/rt/local_ptr.rs | 2 +- src/test/bench/shootout-threadring.rs | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/etc/tidy.py b/src/etc/tidy.py index 6529b4d084e0a..3d44c27a16e6f 100644 --- a/src/etc/tidy.py +++ b/src/etc/tidy.py @@ -65,10 +65,11 @@ def do_license_check(name, contents): check_tab = False if line.find(linelength_flag) != -1: check_linelength = False - if line.find("// XXX") != -1: - report_err("XXX is no longer necessary, use FIXME") if line.find("TODO") != -1: report_err("TODO is deprecated; use FIXME") + match = re.match(r'^.*/(\*|/!?)\s*XXX', line) + if match: + report_err("XXX is no longer necessary, use FIXME") match = re.match(r'^.*//\s*(NOTE.*)$', line) if match: m = match.group(1) diff --git a/src/librustuv/addrinfo.rs b/src/librustuv/addrinfo.rs index 7a23a3466da40..1621435de55ab 100644 --- a/src/librustuv/addrinfo.rs +++ b/src/librustuv/addrinfo.rs @@ -120,7 +120,7 @@ impl Drop for Addrinfo { } fn each_ai_flag(_f: |c_int, ai::Flag|) { - /* XXX: do we really want to support these? + /* FIXME: do we really want to support these? unsafe { f(uvll::rust_AI_ADDRCONFIG(), ai::AddrConfig); f(uvll::rust_AI_ALL(), ai::All); @@ -150,7 +150,7 @@ pub fn accum_addrinfo(addr: &Addrinfo) -> ~[ai::Info] { } }); - /* XXX: do we really want to support these + /* FIXME: do we really want to support these let protocol = match (*addr).ai_protocol { p if p == uvll::rust_IPPROTO_UDP() => Some(ai::UDP), p if p == uvll::rust_IPPROTO_TCP() => Some(ai::TCP), diff --git a/src/libstd/rt/local_ptr.rs b/src/libstd/rt/local_ptr.rs index e486932ac3c37..e3f64f40c0d40 100644 --- a/src/libstd/rt/local_ptr.rs +++ b/src/libstd/rt/local_ptr.rs @@ -12,7 +12,7 @@ //! //! The runtime will use this for storing ~Task. //! -//! XXX: Add runtime checks for usage of inconsistent pointer types. +//! FIXME: Add runtime checks for usage of inconsistent pointer types. //! and for overwriting an existing pointer. #![allow(dead_code)] diff --git a/src/test/bench/shootout-threadring.rs b/src/test/bench/shootout-threadring.rs index 7ee294b8e632a..72d91ac645e2a 100644 --- a/src/test/bench/shootout-threadring.rs +++ b/src/test/bench/shootout-threadring.rs @@ -15,7 +15,7 @@ use std::os; fn start(n_tasks: int, token: int) { let (tx, mut rx) = channel(); tx.send(token); - // XXX could not get this to work with a range closure + // FIXME could not get this to work with a range closure let mut i = 2; while i <= n_tasks { let (tx, next_rx) = channel(); From 6ac34926a4f704ecab09167f07b94aa269df5b98 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 7 Apr 2014 01:11:31 -0700 Subject: [PATCH 11/16] std: User a smaller stdin buffer on windows Apparently windows doesn't like reading from stdin with a large buffer size, and it also apparently is ok with a smaller buffer size. This changes the reader returned by stdin() to return an 8k buffered reader for stdin rather than a 64k buffered reader. Apparently libuv has run into this before, taking a peek at their code, with a specific comment in their console code saying that "ReadConsole can't handle big buffers", which I presume is related to invoking ReadFile as if it were a file descriptor. Closes #13304 --- src/libstd/io/stdio.rs | 10 ++++- src/test/run-pass/issue-13304.rs | 63 ++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/issue-13304.rs diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index ae98333ca9614..33306dba8defe 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -99,7 +99,15 @@ fn src(fd: libc::c_int, readable: bool, f: |StdSource| -> T) -> T { /// /// See `stdout()` for more notes about this function. pub fn stdin() -> BufferedReader { - BufferedReader::new(stdin_raw()) + // The default buffer capacity is 64k, but apparently windows doesn't like + // 64k reads on stdin. See #13304 for details, but the idea is that on + // windows we use a slighly smaller buffer that's been seen to be + // acceptable. + if cfg!(windows) { + BufferedReader::with_capacity(8 * 1024, stdin_raw()) + } else { + BufferedReader::new(stdin_raw()) + } } /// Creates a new non-blocking handle to the stdin of the current process. diff --git a/src/test/run-pass/issue-13304.rs b/src/test/run-pass/issue-13304.rs new file mode 100644 index 0000000000000..20bd8e51a48ca --- /dev/null +++ b/src/test/run-pass/issue-13304.rs @@ -0,0 +1,63 @@ +// Copyright 2014 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. + +// ignore-fast + +extern crate green; +extern crate rustuv; +extern crate native; + +use std::os; +use std::io; +use std::str; + +#[start] +fn start(argc: int, argv: **u8) -> int { + green::start(argc, argv, rustuv::event_loop, main) +} + +fn main() { + let args = os::args(); + if args.len() > 1 && args[1].as_slice() == "child" { + if args[2].as_slice() == "green" { + child(); + } else { + let (tx, rx) = channel(); + native::task::spawn(proc() { tx.send(child()); }); + rx.recv(); + } + } else { + parent(~"green"); + parent(~"native"); + let (tx, rx) = channel(); + native::task::spawn(proc() { + parent(~"green"); + parent(~"native"); + tx.send(()); + }); + rx.recv(); + } +} + +fn parent(flavor: ~str) { + let args = os::args(); + let mut p = io::Process::new(args[0].as_slice(), [~"child", flavor]).unwrap(); + p.stdin.get_mut_ref().write_str("test1\ntest2\ntest3").unwrap(); + let out = p.wait_with_output(); + assert!(out.status.success()); + let s = str::from_utf8(out.output.as_slice()).unwrap(); + assert_eq!(s, "test1\n\ntest2\n\ntest3\n"); +} + +fn child() { + for line in io::stdin().lines() { + println!("{}", line.unwrap()); + } +} From 22b632560f9dc1d11121a8c129181b87ea80d7d7 Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Sun, 6 Apr 2014 22:51:59 -0400 Subject: [PATCH 12/16] Fix spelling errors in comments. --- src/libstd/io/mod.rs | 8 ++++---- src/rt/sundown/Makefile | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 97519adbc3f82..f384000896cfe 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -632,28 +632,28 @@ pub trait Reader { /// Reads a little-endian unsigned integer. /// - /// The number of bytes returned is system-dependant. + /// The number of bytes returned is system-dependent. fn read_le_uint(&mut self) -> IoResult { self.read_le_uint_n(uint::BYTES).map(|i| i as uint) } /// Reads a little-endian integer. /// - /// The number of bytes returned is system-dependant. + /// The number of bytes returned is system-dependent. fn read_le_int(&mut self) -> IoResult { self.read_le_int_n(int::BYTES).map(|i| i as int) } /// Reads a big-endian unsigned integer. /// - /// The number of bytes returned is system-dependant. + /// The number of bytes returned is system-dependent. fn read_be_uint(&mut self) -> IoResult { self.read_be_uint_n(uint::BYTES).map(|i| i as uint) } /// Reads a big-endian integer. /// - /// The number of bytes returned is system-dependant. + /// The number of bytes returned is system-dependent. fn read_be_int(&mut self) -> IoResult { self.read_be_int_n(int::BYTES).map(|i| i as int) } diff --git a/src/rt/sundown/Makefile b/src/rt/sundown/Makefile index baca6875a20a8..b8b198cb99210 100644 --- a/src/rt/sundown/Makefile +++ b/src/rt/sundown/Makefile @@ -16,7 +16,7 @@ DEPDIR=depends -# "Machine-dependant" options +# "Machine-dependent" options #MFLAGS=-fPIC CFLAGS=-c -g -O3 -fPIC -Wall -Werror -Wsign-compare -Isrc -Ihtml From 87334fb05ff2a665419241d877c13d6c4770a3f4 Mon Sep 17 00:00:00 2001 From: Dmitry Promsky Date: Fri, 4 Apr 2014 20:17:30 +0400 Subject: [PATCH 13/16] Made 'make install' include libs for additional targets --- mk/dist.mk | 34 +++++++++++++++++++++------------- mk/install.mk | 4 ++-- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/mk/dist.mk b/mk/dist.mk index 43af4f9014067..b96d5bee3af91 100644 --- a/mk/dist.mk +++ b/mk/dist.mk @@ -203,19 +203,17 @@ distcheck-osx: dist-osx # Unix binary installer tarballs ###################################################################### -define DEF_INSTALLER - -$$(eval $$(call DEF_PREPARE,dir-$(1))) - -dist-install-dir-$(1): PREPARE_HOST=$(1) -dist-install-dir-$(1): PREPARE_TARGETS=$(1) -dist-install-dir-$(1): PREPARE_DEST_DIR=tmp/dist/$$(PKG_NAME)-$(1) -dist-install-dir-$(1): PREPARE_DIR_CMD=$(DEFAULT_PREPARE_DIR_CMD) -dist-install-dir-$(1): PREPARE_BIN_CMD=$(DEFAULT_PREPARE_BIN_CMD) -dist-install-dir-$(1): PREPARE_LIB_CMD=$(DEFAULT_PREPARE_LIB_CMD) -dist-install-dir-$(1): PREPARE_MAN_CMD=$(DEFAULT_PREPARE_MAN_CMD) -dist-install-dir-$(1): PREPARE_CLEAN=true -dist-install-dir-$(1): prepare-base-dir-$(1) docs compiler-docs +define DEF_PREPARE_DIST_DIR + +dist-install-dir-$(1)$(3): PREPARE_HOST=$(1) +dist-install-dir-$(1)$(3): PREPARE_TARGETS=$(2) +dist-install-dir-$(1)$(3): PREPARE_DEST_DIR=tmp/dist/$$(PKG_NAME)-$(1) +dist-install-dir-$(1)$(3): PREPARE_DIR_CMD=$(DEFAULT_PREPARE_DIR_CMD) +dist-install-dir-$(1)$(3): PREPARE_BIN_CMD=$(DEFAULT_PREPARE_BIN_CMD) +dist-install-dir-$(1)$(3): PREPARE_LIB_CMD=$(DEFAULT_PREPARE_LIB_CMD) +dist-install-dir-$(1)$(3): PREPARE_MAN_CMD=$(DEFAULT_PREPARE_MAN_CMD) +dist-install-dir-$(1)$(3): PREPARE_CLEAN=true +dist-install-dir-$(1)$(3): prepare-base-dir-$(1) docs compiler-docs $$(Q)(cd $$(PREPARE_DEST_DIR)/ && find . -type f | sed 's/^\.\///') \ > tmp/dist/manifest-$(1).in $$(Q)mv tmp/dist/manifest-$(1).in $$(PREPARE_DEST_DIR)/$$(CFG_LIBDIR_RELATIVE)/rustlib/manifest.in @@ -227,6 +225,16 @@ dist-install-dir-$(1): prepare-base-dir-$(1) docs compiler-docs $$(Q)cp -r doc $$(PREPARE_DEST_DIR) $$(Q)$$(PREPARE_BIN_CMD) $$(S)src/etc/install.sh $$(PREPARE_DEST_DIR) +endef + +define DEF_INSTALLER + +$$(eval $$(call DEF_PREPARE,dir-$(1))) + +$$(eval $$(call DEF_PREPARE_DIST_DIR,$(1),$(1),)) + +$$(eval $$(call DEF_PREPARE_DIST_DIR,$(1),$(CFG_TARGET),-with-target-libs)) + dist/$$(PKG_NAME)-$(1).tar.gz: dist-install-dir-$(1) @$(call E, build: $$@) $$(Q)tar -czf dist/$$(PKG_NAME)-$(1).tar.gz -C tmp/dist $$(PKG_NAME)-$(1) diff --git a/mk/install.mk b/mk/install.mk index bcc2a5fbaaac0..206046faeb6ef 100644 --- a/mk/install.mk +++ b/mk/install.mk @@ -14,12 +14,12 @@ else MAYBE_DISABLE_VERIFY= endif -install: dist-install-dir-$(CFG_BUILD) +install: dist-install-dir-$(CFG_BUILD)-with-target-libs $(Q)sh tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)" "$(MAYBE_DISABLE_VERIFY)" # Remove tmp files while we can because they may have been created under sudo $(Q)rm -R tmp/dist -uninstall: dist-install-dir-$(CFG_BUILD) +uninstall: dist-install-dir-$(CFG_BUILD)-with-target-libs $(Q)sh tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --uninstall --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)" # Remove tmp files while we can because they may have been created under sudo $(Q)rm -R tmp/dist From 7a281718f0d32ea678f031252c0e130035fc2a80 Mon Sep 17 00:00:00 2001 From: Kang Seonghoon Date: Thu, 3 Apr 2014 16:40:56 +0900 Subject: [PATCH 14/16] std: make vec!() macro handle a trailing comma Fixes #12910. --- src/libstd/macros.rs | 3 ++- .../compile-fail/vec-macro-with-comma-only.rs | 13 +++++++++++++ .../run-pass/vec-macro-with-trailing-comma.rs | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/vec-macro-with-comma-only.rs create mode 100644 src/test/run-pass/vec-macro-with-trailing-comma.rs diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 1a35252f8cadd..fbb48f2ebcb26 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -273,7 +273,8 @@ macro_rules! vec( let mut _temp = ::std::vec::Vec::new(); $(_temp.push($e);)* _temp - }) + }); + ($($e:expr),+,) => (vec!($($e),+)) ) diff --git a/src/test/compile-fail/vec-macro-with-comma-only.rs b/src/test/compile-fail/vec-macro-with-comma-only.rs new file mode 100644 index 0000000000000..8c8e789cd9640 --- /dev/null +++ b/src/test/compile-fail/vec-macro-with-comma-only.rs @@ -0,0 +1,13 @@ +// Copyright 2014 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. + +pub fn main() { + vec!(,); //~ ERROR unexpected token +} diff --git a/src/test/run-pass/vec-macro-with-trailing-comma.rs b/src/test/run-pass/vec-macro-with-trailing-comma.rs new file mode 100644 index 0000000000000..07033d6049747 --- /dev/null +++ b/src/test/run-pass/vec-macro-with-trailing-comma.rs @@ -0,0 +1,15 @@ +// Copyright 2014 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. + + +pub fn main() { + assert_eq!(vec!(1), vec!(1,)); + assert_eq!(vec!(1, 2, 3), vec!(1, 2, 3,)); +} From cdf349d442351eece966a5f8ea560f5b5ad30d80 Mon Sep 17 00:00:00 2001 From: JustAPerson Date: Wed, 2 Apr 2014 23:31:00 -0500 Subject: [PATCH 15/16] Add test for #11881 Closes #11881. This code has been copied from the original issue and updated for modern Rust APIs. --- src/test/run-pass/issue-11881.rs | 60 ++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/test/run-pass/issue-11881.rs diff --git a/src/test/run-pass/issue-11881.rs b/src/test/run-pass/issue-11881.rs new file mode 100644 index 0000000000000..2bf846fe3419c --- /dev/null +++ b/src/test/run-pass/issue-11881.rs @@ -0,0 +1,60 @@ +// Copyright 2014 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. + +extern crate ser = "serialize"; + +use serialize = self::ser; + //necessary for deriving(Encodable) +use ser::{Encodable, Encoder}; +use ser::json; +use ser::ebml::writer; +use std::io::MemWriter; +use std::str::from_utf8_owned; + +#[deriving(Encodable)] +struct Foo { + baz: bool, +} + +#[deriving(Encodable)] +struct Bar { + froboz: uint, +} + +enum WireProtocol { + JSON, + EBML, + // ... +} + +fn encode_json<'a, + T: Encodable, + std::io::IoError>>(val: &T, + wr: &'a mut MemWriter) { + let mut encoder = json::Encoder::new(wr); + val.encode(&mut encoder); +} +fn encode_ebml<'a, + T: Encodable, + std::io::IoError>>(val: &T, + wr: &'a mut MemWriter) { + let mut encoder = writer::Encoder(wr); + val.encode(&mut encoder); +} + +pub fn main() { + let target = Foo{baz: false,}; + let mut wr = MemWriter::new(); + let proto = JSON; + match proto { + JSON => encode_json(&target, &mut wr), + EBML => encode_ebml(&target, &mut wr) + } +} From da8d4fddc6445c19ad434a1f104c1c310c6c3c34 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 7 Apr 2014 22:28:08 -0700 Subject: [PATCH 16/16] Test fixes from rollup Closes #13394 (sync: remove unsafe and add Send+Share to Deref (enabled by autoderef vtables)) Closes #13389 (Made libflate functions return Options instead of outright failing) Closes #13388 (doc: Document flavorful variations of paths) Closes #13387 (Register new snapshots) Closes #13386 (std: Add more docs for ptr mod) Closes #13384 (Tweak crate loading to load less metadata) Closes #13382 (fix ~ZeroSizeType rvalues) Closes #13378 (Update tidy script, replace XXX with FIXME) Closes #13377 (std: User a smaller stdin buffer on windows) Closes #13369 (Fix spelling errors in comments.) Closes #13314 (Made 'make install' include libs for additional targets) Closes #13278 (std: make vec!() macro handle a trailing comma) Closes #13276 (Add test for #11881) --- src/libsyntax/ext/expand.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 5c3c7d995d67a..1cff1d0f295e8 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1019,14 +1019,6 @@ mod test { fn load_crate(&mut self, _: &ast::ViewItem) -> MacroCrate { fail!("lolwut") } - - fn get_exported_macros(&mut self, _: ast::CrateNum) -> Vec<~str> { - fail!("lolwut") - } - - fn get_registrar_symbol(&mut self, _: ast::CrateNum) -> Option<~str> { - fail!("lolwut") - } } // these following tests are quite fragile, in that they don't test what