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 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 afb21a19965b8..5d505e55d2c91 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 @@ -3415,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/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/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/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/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/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/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/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/creader.rs b/src/librustc/metadata/creader.rs index 8ce4a2f8eed86..50c22f6bf1bba 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() { @@ -128,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 => () @@ -154,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 { @@ -179,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 @@ -269,14 +260,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, @@ -284,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); @@ -304,17 +301,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,27 +319,35 @@ 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(), data: metadata, cnum_map: cnum_map, - cnum: cnum + cnum: cnum, + 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()) } } @@ -368,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); @@ -390,8 +387,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(), } } @@ -401,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/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 { 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/loader.rs b/src/librustc/metadata/loader.rs index 4f4ef31e15b37..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) { @@ -494,14 +502,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/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 e48b8fc9db4cd..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, @@ -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, 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/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/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/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/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/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/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/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/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/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"); 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/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/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/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/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/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 } } 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/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/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/ext/expand.rs b/src/libsyntax/ext/expand.rs index 747ab583e792a..1cff1d0f295e8 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 }; @@ -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 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/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 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/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(); 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/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/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/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 = *~(); +} 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) + } +} 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()); + } +} 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 { 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,)); +}