auto merge of #13397 : alexcrichton/rust/rollup, r=alexcrichton

This commit is contained in:
bors 2014-04-08 08:16:52 -07:00
commit 02f51211ed
102 changed files with 804 additions and 445 deletions

View File

@ -203,19 +203,17 @@ distcheck-osx: dist-osx
# Unix binary installer tarballs # Unix binary installer tarballs
###################################################################### ######################################################################
define DEF_INSTALLER define DEF_PREPARE_DIST_DIR
$$(eval $$(call DEF_PREPARE,dir-$(1))) dist-install-dir-$(1)$(3): PREPARE_HOST=$(1)
dist-install-dir-$(1)$(3): PREPARE_TARGETS=$(2)
dist-install-dir-$(1): PREPARE_HOST=$(1) dist-install-dir-$(1)$(3): PREPARE_DEST_DIR=tmp/dist/$$(PKG_NAME)-$(1)
dist-install-dir-$(1): PREPARE_TARGETS=$(1) dist-install-dir-$(1)$(3): PREPARE_DIR_CMD=$(DEFAULT_PREPARE_DIR_CMD)
dist-install-dir-$(1): PREPARE_DEST_DIR=tmp/dist/$$(PKG_NAME)-$(1) dist-install-dir-$(1)$(3): PREPARE_BIN_CMD=$(DEFAULT_PREPARE_BIN_CMD)
dist-install-dir-$(1): PREPARE_DIR_CMD=$(DEFAULT_PREPARE_DIR_CMD) dist-install-dir-$(1)$(3): PREPARE_LIB_CMD=$(DEFAULT_PREPARE_LIB_CMD)
dist-install-dir-$(1): PREPARE_BIN_CMD=$(DEFAULT_PREPARE_BIN_CMD) dist-install-dir-$(1)$(3): PREPARE_MAN_CMD=$(DEFAULT_PREPARE_MAN_CMD)
dist-install-dir-$(1): PREPARE_LIB_CMD=$(DEFAULT_PREPARE_LIB_CMD) dist-install-dir-$(1)$(3): PREPARE_CLEAN=true
dist-install-dir-$(1): PREPARE_MAN_CMD=$(DEFAULT_PREPARE_MAN_CMD) dist-install-dir-$(1)$(3): prepare-base-dir-$(1) docs compiler-docs
dist-install-dir-$(1): PREPARE_CLEAN=true
dist-install-dir-$(1): prepare-base-dir-$(1) docs compiler-docs
$$(Q)(cd $$(PREPARE_DEST_DIR)/ && find . -type f | sed 's/^\.\///') \ $$(Q)(cd $$(PREPARE_DEST_DIR)/ && find . -type f | sed 's/^\.\///') \
> tmp/dist/manifest-$(1).in > tmp/dist/manifest-$(1).in
$$(Q)mv tmp/dist/manifest-$(1).in $$(PREPARE_DEST_DIR)/$$(CFG_LIBDIR_RELATIVE)/rustlib/manifest.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)cp -r doc $$(PREPARE_DEST_DIR)
$$(Q)$$(PREPARE_BIN_CMD) $$(S)src/etc/install.sh $$(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) dist/$$(PKG_NAME)-$(1).tar.gz: dist-install-dir-$(1)
@$(call E, build: $$@) @$(call E, build: $$@)
$$(Q)tar -czf dist/$$(PKG_NAME)-$(1).tar.gz -C tmp/dist $$(PKG_NAME)-$(1) $$(Q)tar -czf dist/$$(PKG_NAME)-$(1).tar.gz -C tmp/dist $$(PKG_NAME)-$(1)

View File

@ -14,12 +14,12 @@ else
MAYBE_DISABLE_VERIFY= MAYBE_DISABLE_VERIFY=
endif 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)" $(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 # Remove tmp files while we can because they may have been created under sudo
$(Q)rm -R tmp/dist $(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)" $(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 # Remove tmp files while we can because they may have been created under sudo
$(Q)rm -R tmp/dist $(Q)rm -R tmp/dist

View File

@ -152,7 +152,7 @@ struct Foo {
} }
struct FooClosure<'a> { struct FooClosure<'a> {
myfunc: 'a |int, uint| -> i32 myfunc: |int, uint|: 'a -> i32
} }
fn a(a: int, b: uint) -> i32 { fn a(a: int, b: uint) -> i32 {

View File

@ -432,7 +432,7 @@ operators](#binary-operator-expressions), or [keywords](#keywords).
## Paths ## Paths
~~~~ {.notrust .ebnf .gram} ~~~~ {.notrust .ebnf .gram}
expr_path : ident [ "::" expr_path_tail ] + ; expr_path : [ "::" ] ident [ "::" expr_path_tail ] + ;
expr_path_tail : '<' type_expr [ ',' type_expr ] + '>' expr_path_tail : '<' type_expr [ ',' type_expr ] + '>'
| expr_path ; | expr_path ;
@ -475,6 +475,51 @@ let x = id::<int>(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 # Syntax extensions
A number of minor features of Rust are not central enough to have their own 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); let mut x = add(5,7);
type Binop<'a> = 'a |int,int| -> int; type Binop<'a> = |int,int|: 'a -> int;
let bo: Binop = add; let bo: Binop = add;
x = bo(5,7); x = bo(5,7);
~~~~ ~~~~

View File

@ -65,10 +65,11 @@ try:
check_tab = False check_tab = False
if line.find(linelength_flag) != -1: if line.find(linelength_flag) != -1:
check_linelength = False check_linelength = False
if line.find("// XXX") != -1:
report_err("XXX is no longer necessary, use FIXME")
if line.find("TODO") != -1: if line.find("TODO") != -1:
report_err("TODO is deprecated; use FIXME") 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) match = re.match(r'^.*//\s*(NOTE.*)$', line)
if match: if match:
m = match.group(1) m = match.group(1)

View File

@ -96,7 +96,7 @@ pub mod bench {
map.insert(*k, 1); map.insert(*k, 1);
} }
rng.shuffle_mut(keys); rng.shuffle(keys);
// measure // measure
let mut i = 0; let mut i = 0;

View File

@ -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 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 static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum
fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> CVec<u8> { fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
unsafe { unsafe {
let mut outsz : size_t = 0; let mut outsz : size_t = 0;
let res = rustrt::tdefl_compress_mem_to_heap(bytes.as_ptr() as *c_void, let res = rustrt::tdefl_compress_mem_to_heap(bytes.as_ptr() as *c_void,
bytes.len() as size_t, bytes.len() as size_t,
&mut outsz, &mut outsz,
flags); flags);
assert!(!res.is_null()); if !res.is_null() {
CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res)) 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<u8> { pub fn deflate_bytes(bytes: &[u8]) -> Option<CVec<u8>> {
deflate_bytes_internal(bytes, LZ_NORM) deflate_bytes_internal(bytes, LZ_NORM)
} }
pub fn deflate_bytes_zlib(bytes: &[u8]) -> CVec<u8> { pub fn deflate_bytes_zlib(bytes: &[u8]) -> Option<CVec<u8>> {
deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER) deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER)
} }
fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> CVec<u8> { fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
unsafe { unsafe {
let mut outsz : size_t = 0; let mut outsz : size_t = 0;
let res = rustrt::tinfl_decompress_mem_to_heap(bytes.as_ptr() as *c_void, let res = rustrt::tinfl_decompress_mem_to_heap(bytes.as_ptr() as *c_void,
bytes.len() as size_t, bytes.len() as size_t,
&mut outsz, &mut outsz,
flags); flags);
assert!(!res.is_null()); if !res.is_null() {
CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res)) 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<u8> { pub fn inflate_bytes(bytes: &[u8]) -> Option<CVec<u8>> {
inflate_bytes_internal(bytes, 0) inflate_bytes_internal(bytes, 0)
} }
pub fn inflate_bytes_zlib(bytes: &[u8]) -> CVec<u8> { pub fn inflate_bytes_zlib(bytes: &[u8]) -> Option<CVec<u8>> {
inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER) inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER)
} }
@ -117,8 +123,8 @@ mod tests {
} }
debug!("de/inflate of {} bytes of random word-sequences", debug!("de/inflate of {} bytes of random word-sequences",
input.len()); input.len());
let cmp = deflate_bytes(input); let cmp = deflate_bytes(input).expect("deflation failed");
let out = inflate_bytes(cmp.as_slice()); let out = inflate_bytes(cmp.as_slice()).expect("inflation failed");
debug!("{} bytes deflated to {} ({:.1f}% size)", debug!("{} bytes deflated to {} ({:.1f}% size)",
input.len(), cmp.len(), input.len(), cmp.len(),
100.0 * ((cmp.len() as f64) / (input.len() as f64))); 100.0 * ((cmp.len() as f64) / (input.len() as f64)));
@ -129,8 +135,8 @@ mod tests {
#[test] #[test]
fn test_zlib_flate() { fn test_zlib_flate() {
let bytes = vec!(1, 2, 3, 4, 5); let bytes = vec!(1, 2, 3, 4, 5);
let deflated = deflate_bytes(bytes.as_slice()); let deflated = deflate_bytes(bytes.as_slice()).expect("deflation failed");
let inflated = inflate_bytes(deflated.as_slice()); let inflated = inflate_bytes(deflated.as_slice()).expect("inflation failed");
assert_eq!(inflated.as_slice(), bytes.as_slice()); assert_eq!(inflated.as_slice(), bytes.as_slice());
} }
} }

View File

@ -27,7 +27,7 @@ pub fn event_loop() -> ~EventLoop:Send {
} }
struct BasicLoop { struct BasicLoop {
work: ~[proc:Send()], // pending work work: ~[proc():Send], // pending work
idle: Option<*mut BasicPausable>, // only one is allowed idle: Option<*mut BasicPausable>, // only one is allowed
remotes: ~[(uint, ~Callback:Send)], remotes: ~[(uint, ~Callback:Send)],
next_remote: uint, 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); self.work.push(f);
} }

View File

@ -9,7 +9,7 @@
// except according to those terms. // except according to those terms.
#![feature(globs)] #![feature(globs)]
#![crate_id = "libc#0.10-pre"] #![crate_id = "libc#0.11-pre"]
#![experimental] #![experimental]
#![no_std] // we don't need std, and we can't have std, since it doesn't exist #![no_std] // we don't need std, and we can't have std, since it doesn't exist
// yet. std depends on us. // yet. std depends on us.
@ -75,8 +75,6 @@
#![allow(missing_doc)] #![allow(missing_doc)]
#![allow(uppercase_variables)] #![allow(uppercase_variables)]
#![feature(link_args)] // NOTE: remove after stage0
#[cfg(test)] extern crate std; #[cfg(test)] extern crate std;
#[cfg(test)] extern crate test; #[cfg(test)] extern crate test;
#[cfg(test)] extern crate native; #[cfg(test)] extern crate native;
@ -199,11 +197,6 @@ pub use funcs::posix88::unistd::{rmdir, unlink, write};
#[link(name = "m")] #[link(name = "m")]
extern {} 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 /// A wrapper for a nullable pointer. Don't use this except for interacting
/// with libc. Basically Option, but without the dependance on libstd. /// with libc. Basically Option, but without the dependance on libstd.
// If/when libprim happens, this can be removed in favor of that // If/when libprim happens, this can be removed in favor of that

0
src/libnative/io/p Normal file
View File

View File

@ -639,7 +639,7 @@ fn spawn_process_os(config: p::ProcessConfig,
} }
#[cfg(unix)] #[cfg(unix)]
fn with_argv<T>(prog: &str, args: &[~str], cb: proc:(**libc::c_char) -> T) -> T { fn with_argv<T>(prog: &str, args: &[~str], cb: proc(**libc::c_char) -> T) -> T {
use std::slice; use std::slice;
// We can't directly convert `str`s into `*char`s, as someone needs to hold // We can't directly convert `str`s into `*char`s, as someone needs to hold
@ -665,7 +665,7 @@ fn with_argv<T>(prog: &str, args: &[~str], cb: proc:(**libc::c_char) -> T) -> T
} }
#[cfg(unix)] #[cfg(unix)]
fn with_envp<T>(env: Option<~[(~str, ~str)]>, cb: proc:(*c_void) -> T) -> T { fn with_envp<T>(env: Option<~[(~str, ~str)]>, cb: proc(*c_void) -> T) -> T {
use std::slice; use std::slice;
// On posixy systems we can pass a char** for envp, which is a // On posixy systems we can pass a char** for envp, which is a

View File

@ -50,13 +50,13 @@ fn ops() -> ~Ops {
} }
/// Spawns a function with the default configuration /// Spawns a function with the default configuration
pub fn spawn(f: proc:Send()) { pub fn spawn(f: proc():Send) {
spawn_opts(TaskOpts::new(), f) spawn_opts(TaskOpts::new(), f)
} }
/// Spawns a new task given the configuration options and a procedure to run /// Spawns a new task given the configuration options and a procedure to run
/// inside the task. /// inside the task.
pub fn spawn_opts(opts: TaskOpts, f: proc:Send()) { pub fn spawn_opts(opts: TaskOpts, f: proc():Send) {
let TaskOpts { let TaskOpts {
notify_chan, name, stack_size, notify_chan, name, stack_size,
stderr, stdout, 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); cur_task.put_runtime(self);
Local::put(cur_task); Local::put(cur_task);

View File

@ -209,8 +209,8 @@ fn ziggurat<R:Rng>(
symmetric: bool, symmetric: bool,
x_tab: ziggurat_tables::ZigTable, x_tab: ziggurat_tables::ZigTable,
f_tab: ziggurat_tables::ZigTable, f_tab: ziggurat_tables::ZigTable,
pdf: 'static |f64| -> f64, pdf: |f64|: 'static -> f64,
zero_case: 'static |&mut R, f64| -> f64) zero_case: |&mut R, f64|: 'static -> f64)
-> f64 { -> f64 {
static SCALE: f64 = (1u64 << 53) as f64; static SCALE: f64 = (1u64 << 53) as f64;
loop { loop {

View File

@ -801,7 +801,7 @@ mod test {
#[test] #[test]
fn test_shuffle() { fn test_shuffle() {
let mut r = task_rng(); let mut r = task_rng();
let mut empty: &mut [int] = &mut []; let empty: &mut [int] = &mut [];
r.shuffle(empty); r.shuffle(empty);
let mut one = [1]; let mut one = [1];
r.shuffle(one); r.shuffle(one);

View File

@ -945,11 +945,14 @@ fn link_rlib<'a>(sess: &'a Session,
let bc_deflated = obj_filename.with_extension("bc.deflate"); let bc_deflated = obj_filename.with_extension("bc.deflate");
match fs::File::open(&bc).read_to_end().and_then(|data| { match fs::File::open(&bc).read_to_end().and_then(|data| {
fs::File::create(&bc_deflated) 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(()) => {} Ok(()) => {}
Err(e) => { Err(e) => {
sess.err(format!("failed to compress bytecode: {}", e)); sess.err(format!("failed to write compressed bytecode: {}", e));
sess.abort_if_errors() sess.abort_if_errors()
} }
} }

View File

@ -56,7 +56,10 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
archive.read(format!("{}.bc.deflate", name))); archive.read(format!("{}.bc.deflate", name)));
let bc = bc.expect("missing compressed bytecode in archive!"); let bc = bc.expect("missing compressed bytecode in archive!");
let bc = time(sess.time_passes(), format!("inflate {}.bc", name), (), |_| 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(); let ptr = bc.as_slice().as_ptr();
debug!("linking {}", name); debug!("linking {}", name);
time(sess.time_passes(), format!("ll link {}", name), (), |()| unsafe { time(sess.time_passes(), format!("ll link {}", name), (), |()| unsafe {

View File

@ -241,8 +241,6 @@ pub fn phase_2_configure_and_expand(sess: &Session,
cfg, cfg,
krate) krate)
}); });
// dump the syntax-time crates
sess.cstore.reset();
// strip again, in case expansion added anything with a #[cfg]. // strip again, in case expansion added anything with a #[cfg].
krate = time(time_passes, "configuration 2", krate, |krate| krate = time(time_passes, "configuration 2", krate, |krate|

View File

@ -13,7 +13,7 @@ use syntax::{ast, fold, attr};
use syntax::codemap; use syntax::codemap;
struct Context<'a> { 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 // Support conditional compilation by transforming the AST, stripping out

View File

@ -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 /// The diagnostic emitter yielded to the procedure should be used for reporting
/// errors of the compiler. /// 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. // 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 // rustc needs a lot of stack! When optimizations are disabled, it needs
// even *more* stack than usual as well. // even *more* stack than usual as well.

View File

@ -18,6 +18,7 @@ use driver::{driver, session};
use driver::session::Session; use driver::session::Session;
use metadata::csearch; use metadata::csearch;
use metadata::cstore; use metadata::cstore;
use metadata::cstore::CStore;
use metadata::decoder; use metadata::decoder;
use metadata::loader; use metadata::loader;
use metadata::loader::Os; use metadata::loader::Os;
@ -38,6 +39,13 @@ use syntax::parse::token;
use syntax::crateid::CrateId; use syntax::crateid::CrateId;
use syntax::visit; use syntax::visit;
struct Env<'a> {
sess: &'a Session,
os: loader::Os,
next_crate_num: ast::CrateNum,
intr: Rc<IdentInterner>
}
// Traverses an AST, reading all the information about use'd crates and extern // Traverses an AST, reading all the information about use'd crates and extern
// libraries necessary for later resolving, typechecking, linking, etc. // libraries necessary for later resolving, typechecking, linking, etc.
pub fn read_crates(sess: &Session, pub fn read_crates(sess: &Session,
@ -47,16 +55,13 @@ pub fn read_crates(sess: &Session,
let mut e = Env { let mut e = Env {
sess: sess, sess: sess,
os: os, os: os,
crate_cache: @RefCell::new(Vec::new()), next_crate_num: sess.cstore.next_crate_num(),
next_crate_num: 1,
intr: intr intr: intr
}; };
visit_crate(&e, krate); visit_crate(&e, krate);
visit::walk_crate(&mut e, krate, ()); visit::walk_crate(&mut e, krate, ());
dump_crates(e.crate_cache.borrow().as_slice()); dump_crates(&sess.cstore);
warn_if_multiple_versions(&mut e, warn_if_multiple_versions(sess.diagnostic(), &sess.cstore)
sess.diagnostic(),
e.crate_cache.borrow().as_slice());
} }
impl<'a> visit::Visitor<()> for Env<'a> { impl<'a> visit::Visitor<()> for Env<'a> {
@ -70,55 +75,36 @@ impl<'a> visit::Visitor<()> for Env<'a> {
} }
} }
#[deriving(Clone)] fn dump_crates(cstore: &CStore) {
struct cache_entry {
cnum: ast::CrateNum,
span: Span,
hash: Svh,
crate_id: CrateId,
}
fn dump_crates(crate_cache: &[cache_entry]) {
debug!("resolved crates:"); debug!("resolved crates:");
for entry in crate_cache.iter() { cstore.iter_crate_data(|_, data| {
debug!("cnum: {:?}", entry.cnum); debug!("crate_id: {}", data.crate_id());
debug!("span: {:?}", entry.span); debug!(" cnum: {}", data.cnum);
debug!("hash: {:?}", entry.hash); debug!(" hash: {}", data.hash());
} })
} }
fn warn_if_multiple_versions(e: &mut Env, fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) {
diag: &SpanHandler, let mut map = HashMap::new();
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| cstore.iter_crate_data(|cnum, data| {
name == entry.crate_id.name); let crateid = data.crate_id();
let key = (crateid.name.clone(), crateid.path.clone());
map.find_or_insert_with(key, |_| Vec::new()).push(cnum);
});
assert!(!matches.is_empty()); for ((name, _), dupes) in map.move_iter() {
if dupes.len() == 1 { continue }
if matches.len() != 1u { diag.handler().warn(
diag.handler().warn( format!("using multiple versions of crate `{}`", name));
format!("using multiple versions of crate `{}`", name)); for dupe in dupes.move_iter() {
for match_ in matches.iter() { let data = cstore.get_crate_data(dupe);
diag.span_note(match_.span, "used here"); diag.span_note(data.span, "used here");
loader::note_crateid_attr(diag, &match_.crate_id); 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<Vec<cache_entry>>,
next_crate_num: ast::CrateNum,
intr: Rc<IdentInterner>
}
fn visit_crate(e: &Env, c: &ast::Crate) { fn visit_crate(e: &Env, c: &ast::Crate) {
for a in c.attrs.iter().filter(|m| m.name().equiv(&("link_args"))) { for a in c.attrs.iter().filter(|m| m.name().equiv(&("link_args"))) {
match a.value_str() { 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) { fn should_link(i: &ast::ViewItem) -> bool {
let should_load = i.attrs.iter().all(|attr| { i.attrs.iter().all(|attr| {
attr.name().get() != "phase" || attr.name().get() != "phase" ||
attr.meta_item_list().map_or(false, |phases| { attr.meta_item_list().map_or(false, |phases| {
attr::contains_name(phases.as_slice(), "link") 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; return;
} }
match extract_crate_info(e, i) { match extract_crate_info(e, i) {
Some(info) => { Some(info) => {
let cnum = resolve_crate(e, &None, info.ident, &info.crate_id, None, let (cnum, _, _) = resolve_crate(e, &None, info.ident,
i.span); &info.crate_id, None, true,
i.span);
e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum); e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
} }
None => () None => ()
@ -154,6 +143,7 @@ struct CrateInfo {
ident: ~str, ident: ~str,
crate_id: CrateId, crate_id: CrateId,
id: ast::NodeId, id: ast::NodeId,
should_link: bool,
} }
fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> { fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
@ -179,6 +169,7 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
ident: ident.get().to_str(), ident: ident.get().to_str(),
crate_id: crate_id, crate_id: crate_id,
id: id, id: id,
should_link: should_link(i),
}) })
} }
_ => None _ => None
@ -269,14 +260,18 @@ fn visit_item(e: &Env, i: &ast::Item) {
fn existing_match(e: &Env, crate_id: &CrateId, fn existing_match(e: &Env, crate_id: &CrateId,
hash: Option<&Svh>) -> Option<ast::CrateNum> { hash: Option<&Svh>) -> Option<ast::CrateNum> {
for c in e.crate_cache.borrow().iter() { let mut ret = None;
if !crate_id.matches(&c.crate_id) { continue } e.sess.cstore.iter_crate_data(|cnum, data| {
match hash { let other_id = data.crate_id();
Some(hash) if *hash != c.hash => {} if crate_id.matches(&other_id) {
Some(..) | None => return Some(c.cnum) 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, fn resolve_crate<'a>(e: &mut Env,
@ -284,8 +279,10 @@ fn resolve_crate<'a>(e: &mut Env,
ident: &str, ident: &str,
crate_id: &CrateId, crate_id: &CrateId,
hash: Option<&Svh>, hash: Option<&Svh>,
should_link: bool,
span: Span) span: Span)
-> ast::CrateNum { -> (ast::CrateNum, @cstore::crate_metadata,
cstore::CrateSource) {
match existing_match(e, crate_id, hash) { match existing_match(e, crate_id, hash) {
None => { None => {
let id_hash = link::crate_id_hash(crate_id); let id_hash = link::crate_id_hash(crate_id);
@ -304,17 +301,8 @@ fn resolve_crate<'a>(e: &mut Env,
dylib, rlib, metadata dylib, rlib, metadata
} = load_ctxt.load_library_crate(root); } = 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 // Claim this crate number and cache it
let cnum = e.next_crate_num; 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; e.next_crate_num += 1;
// Stash paths for top-most crate locally if necessary. // 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 }; let root = if root.is_some() { root } else { &crate_paths };
// Now resolve the crates referenced by this crate // Now resolve the crates referenced by this crate
let cnum_map = resolve_crate_deps(e, let cnum_map = if should_link {
root, resolve_crate_deps(e, root, metadata.as_slice(), span)
metadata.as_slice(), } else {
span); @RefCell::new(HashMap::new())
};
let cmeta = @cstore::crate_metadata { let cmeta = @cstore::crate_metadata {
name: load_ctxt.crate_id.name.to_owned(), name: load_ctxt.crate_id.name.to_owned(),
data: metadata, data: metadata,
cnum_map: cnum_map, cnum_map: cnum_map,
cnum: cnum cnum: cnum,
span: span,
}; };
e.sess.cstore.set_crate_data(cnum, cmeta); let source = cstore::CrateSource {
e.sess.cstore.add_used_crate_source(cstore::CrateSource {
dylib: dylib, dylib: dylib,
rlib: rlib, rlib: rlib,
cnum: cnum, 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() { for dep in r.iter() {
let extrn_cnum = dep.cnum; let extrn_cnum = dep.cnum;
debug!("resolving dep crate {} hash: `{}`", dep.crate_id, dep.hash); debug!("resolving dep crate {} hash: `{}`", dep.crate_id, dep.hash);
let local_cnum = resolve_crate(e, root, let (local_cnum, _, _) = resolve_crate(e, root,
dep.crate_id.name.as_slice(), dep.crate_id.name.as_slice(),
&dep.crate_id, &dep.crate_id,
Some(&dep.hash), Some(&dep.hash),
span); true,
span);
cnum_map.insert(extrn_cnum, local_cnum); cnum_map.insert(extrn_cnum, local_cnum);
} }
return @RefCell::new(cnum_map); return @RefCell::new(cnum_map);
@ -390,8 +387,7 @@ impl<'a> Loader<'a> {
env: Env { env: Env {
sess: sess, sess: sess,
os: os, os: os,
crate_cache: @RefCell::new(Vec::new()), next_crate_num: sess.cstore.next_crate_num(),
next_crate_num: 1,
intr: token::get_ident_interner(), intr: token::get_ident_interner(),
} }
} }
@ -401,23 +397,17 @@ impl<'a> Loader<'a> {
impl<'a> CrateLoader for Loader<'a> { impl<'a> CrateLoader for Loader<'a> {
fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate { fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate {
let info = extract_crate_info(&self.env, krate).unwrap(); let info = extract_crate_info(&self.env, krate).unwrap();
let cnum = resolve_crate(&mut self.env, &None, info.ident, let (cnum, data, library) = resolve_crate(&mut self.env, &None,
&info.crate_id, None, krate.span); info.ident, &info.crate_id,
let library = self.env.sess.cstore.get_used_crate_source(cnum).unwrap(); 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 { MacroCrate {
lib: library.dylib, 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))
}
} }

View File

@ -22,6 +22,8 @@ use std::c_vec::CVec;
use std::rc::Rc; use std::rc::Rc;
use collections::HashMap; use collections::HashMap;
use syntax::ast; use syntax::ast;
use syntax::crateid::CrateId;
use syntax::codemap::Span;
use syntax::parse::token::IdentInterner; use syntax::parse::token::IdentInterner;
// A map from external crate numbers (as decoded from some crate file) to // 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 data: MetadataBlob,
pub cnum_map: cnum_map, pub cnum_map: cnum_map,
pub cnum: ast::CrateNum, pub cnum: ast::CrateNum,
pub span: Span,
} }
#[deriving(Eq)] #[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 { pub fn get_crate_data(&self, cnum: ast::CrateNum) -> @crate_metadata {
*self.metas.borrow().get(&cnum) *self.metas.borrow().get(&cnum)
} }
@ -121,6 +128,9 @@ impl CStore {
.map(|source| source.clone()) .map(|source| source.clone())
} }
pub fn dump_phase_syntax_crates(&self) {
}
pub fn reset(&self) { pub fn reset(&self) {
self.metas.borrow_mut().clear(); self.metas.borrow_mut().clear();
self.extern_mod_crate_map.borrow_mut().clear(); self.extern_mod_crate_map.borrow_mut().clear();
@ -202,6 +212,8 @@ impl CStore {
impl crate_metadata { impl crate_metadata {
pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() } 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 { impl MetadataBlob {

View File

@ -76,7 +76,7 @@ fn lookup_hash<'a>(d: ebml::Doc<'a>, eq_fn: |&[u8]| -> bool,
ret 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, pub fn maybe_find_item<'a>(item_id: ast::NodeId,
items: ebml::Doc<'a>) -> Option<ebml::Doc<'a>> { items: ebml::Doc<'a>) -> Option<ebml::Doc<'a>> {
@ -637,11 +637,11 @@ pub fn get_item_path(cdata: Cmd, id: ast::NodeId) -> Vec<ast_map::PathElem> {
item_path(lookup_item(id, cdata.data())) item_path(lookup_item(id, cdata.data()))
} }
pub type DecodeInlinedItem<'a> = 'a |cdata: @cstore::crate_metadata, pub type DecodeInlinedItem<'a> = |cdata: @cstore::crate_metadata,
tcx: &ty::ctxt, tcx: &ty::ctxt,
path: Vec<ast_map::PathElem>, path: Vec<ast_map::PathElem>,
par_doc: ebml::Doc| par_doc: ebml::Doc|: 'a
-> Result<ast::InlinedItem, Vec<ast_map::PathElem> >; -> Result<ast::InlinedItem, Vec<ast_map::PathElem> >;
pub fn maybe_get_item_ast(cdata: Cmd, tcx: &ty::ctxt, id: ast::NodeId, pub fn maybe_get_item_ast(cdata: Cmd, tcx: &ty::ctxt, id: ast::NodeId,
decode_inlined_item: DecodeInlinedItem) decode_inlined_item: DecodeInlinedItem)

View File

@ -64,9 +64,9 @@ pub enum InlinedItemRef<'a> {
pub type Encoder<'a> = writer::Encoder<'a, MemWriter>; pub type Encoder<'a> = writer::Encoder<'a, MemWriter>;
pub type EncodeInlinedItem<'a> = 'a |ecx: &EncodeContext, pub type EncodeInlinedItem<'a> = |ecx: &EncodeContext,
ebml_w: &mut Encoder, ebml_w: &mut Encoder,
ii: InlinedItemRef|; ii: InlinedItemRef|: 'a;
pub struct EncodeParams<'a> { pub struct EncodeParams<'a> {
pub diag: &'a SpanHandler, pub diag: &'a SpanHandler,

View File

@ -23,7 +23,7 @@ pub enum FileMatch { FileMatches, FileDoesntMatch }
/// Functions with type `pick` take a parent directory as well as /// Functions with type `pick` take a parent directory as well as
/// a file found in that directory. /// 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 struct FileSearch<'a> {
pub sysroot: &'a Path, pub sysroot: &'a Path,

View File

@ -317,15 +317,23 @@ impl<'a> Context<'a> {
// read the metadata from it if `*slot` is `None`. If the metadata couldn't // 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 // be read, it is assumed that the file isn't a valid rust library (no
// errors are emitted). // 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<Path>, flavor: &str, fn extract_one(&mut self, m: HashSet<Path>, flavor: &str,
slot: &mut Option<MetadataBlob>) -> Option<Path> { slot: &mut Option<MetadataBlob>) -> Option<Path> {
let mut ret = None::<Path>; let mut ret = None::<Path>;
let mut error = 0; 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() { for lib in m.move_iter() {
info!("{} reading metadata from: {}", flavor, lib.display()); info!("{} reading metadata from: {}", flavor, lib.display());
let metadata = match get_metadata_section(self.os, &lib) { let metadata = match get_metadata_section(self.os, &lib) {
@ -494,14 +502,17 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Result<MetadataBlob, ~st
let version_ok = slice::raw::buf_as_slice(cvbuf, minsz, let version_ok = slice::raw::buf_as_slice(cvbuf, minsz,
|buf0| buf0 == encoder::metadata_encoding_version); |buf0| buf0 == encoder::metadata_encoding_version);
if !version_ok { return Err(format!("incompatible metadata version found: '{}'", if !version_ok { return Err(format!("incompatible metadata version found: '{}'",
filename.display()));} filename.display())); }
let cvbuf1 = cvbuf.offset(vlen as int); let cvbuf1 = cvbuf.offset(vlen as int);
debug!("inflating {} bytes of compressed metadata", debug!("inflating {} bytes of compressed metadata",
csz - vlen); csz - vlen);
slice::raw::buf_as_slice(cvbuf1, csz-vlen, |bytes| { slice::raw::buf_as_slice(cvbuf1, csz-vlen, |bytes| {
let inflated = flate::inflate_bytes(bytes); match flate::inflate_bytes(bytes) {
found = Ok(MetadataVec(inflated)); Some(inflated) => found = Ok(MetadataVec(inflated)),
None => found = Err(format!("failed to decompress metadata for: '{}'",
filename.display()))
}
}); });
if found.is_ok() { if found.is_ok() {
return found; return found;

View File

@ -54,7 +54,7 @@ pub enum DefIdSource {
RegionParameter, RegionParameter,
} }
pub type conv_did<'a> = pub type conv_did<'a> =
'a |source: DefIdSource, ast::DefId| -> ast::DefId; |source: DefIdSource, ast::DefId|: 'a -> ast::DefId;
pub struct PState<'a> { pub struct PState<'a> {
data: &'a [u8], data: &'a [u8],

View File

@ -503,7 +503,7 @@ fn assert_is_binding_or_wild(bcx: &Block, p: @ast::Pat) {
} }
} }
type enter_pat<'a> = 'a |@ast::Pat| -> Option<Vec<@ast::Pat>>; type enter_pat<'a> = |@ast::Pat|: 'a -> Option<Vec<@ast::Pat>>;
fn enter_match<'r,'b>( fn enter_match<'r,'b>(
bcx: &'b Block<'b>, bcx: &'b Block<'b>,

View File

@ -613,7 +613,7 @@ pub fn compare_scalar_values<'a>(
} }
pub type val_and_ty_fn<'r,'b> = 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. // Iterates through the elements of a structural type.
pub fn iter_structural_ty<'r, pub fn iter_structural_ty<'r,
@ -2236,7 +2236,10 @@ pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec<u8> {
let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item); let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item);
let metadata = encoder::encode_metadata(encode_parms, krate); let metadata = encoder::encode_metadata(encode_parms, krate);
let compressed = encoder::metadata_encoding_version + 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 llmeta = C_bytes(cx, compressed);
let llconst = C_struct(cx, [llmeta], false); let llconst = C_struct(cx, [llmeta], false);
let name = format!("rust_metadata_{}_{}_{}", cx.link_meta.crateid.name, let name = format!("rust_metadata_{}_{}_{}", cx.link_meta.crateid.name,

View File

@ -1802,11 +1802,15 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
RvalueExpr(Rvalue { mode: ByRef }) => { RvalueExpr(Rvalue { mode: ByRef }) => {
let scope = cleanup::temporary_scope(bcx.tcx(), expr.id); let scope = cleanup::temporary_scope(bcx.tcx(), expr.id);
let ptr = Load(bcx, datum.val); 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 }) => { RvalueExpr(Rvalue { mode: ByValue }) => {
let scope = cleanup::temporary_scope(bcx.tcx(), expr.id); 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 => { } LvalueExpr => { }
} }

View File

@ -525,7 +525,7 @@ pub fn get_base_and_len(bcx: &Block,
} }
pub type iter_vec_block<'r,'b> = 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, pub fn iter_vec_loop<'r,
'b>( 'b>(

View File

@ -217,7 +217,7 @@ pub fn super_fold_trait_store<T:TypeFolder>(this: &mut T,
pub struct BottomUpFolder<'a> { pub struct BottomUpFolder<'a> {
pub tcx: &'a ty::ctxt, 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> { impl<'a> TypeFolder for BottomUpFolder<'a> {
@ -234,14 +234,14 @@ impl<'a> TypeFolder for BottomUpFolder<'a> {
pub struct RegionFolder<'a> { pub struct RegionFolder<'a> {
tcx: &'a ty::ctxt, tcx: &'a ty::ctxt,
fld_t: 'a |ty::t| -> ty::t, fld_t: |ty::t|: 'a -> ty::t,
fld_r: 'a |ty::Region| -> ty::Region, fld_r: |ty::Region|: 'a -> ty::Region,
} }
impl<'a> RegionFolder<'a> { impl<'a> RegionFolder<'a> {
pub fn general(tcx: &'a ty::ctxt, pub fn general(tcx: &'a ty::ctxt,
fld_r: 'a |ty::Region| -> ty::Region, fld_r: |ty::Region|: 'a -> ty::Region,
fld_t: 'a |ty::t| -> ty::t) fld_t: |ty::t|: 'a -> ty::t)
-> RegionFolder<'a> { -> RegionFolder<'a> {
RegionFolder { RegionFolder {
tcx: tcx, 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> { -> RegionFolder<'a> {
fn noop(t: ty::t) -> ty::t { t } fn noop(t: ty::t) -> ty::t { t }

View File

@ -86,7 +86,7 @@ pub fn relate_nested_regions(tcx: &ty::ctxt,
struct RegionRelator<'a> { struct RegionRelator<'a> {
tcx: &'a ty::ctxt, tcx: &'a ty::ctxt,
stack: Vec<ty::Region>, stack: Vec<ty::Region>,
relate_op: 'a |ty::Region, ty::Region|, relate_op: |ty::Region, ty::Region|: 'a,
} }
// FIXME(#10151) -- Define more precisely when a region is // FIXME(#10151) -- Define more precisely when a region is

View File

@ -54,7 +54,7 @@ pub trait LatticeValue {
} }
pub type LatticeOp<'a, T> = pub type LatticeOp<'a, T> =
'a |cf: &CombineFields, a: &T, b: &T| -> cres<T>; |cf: &CombineFields, a: &T, b: &T|: 'a -> cres<T>;
impl LatticeValue for ty::t { impl LatticeValue for ty::t {
fn sub(cf: &CombineFields, a: &ty::t, b: &ty::t) -> ures { fn sub(cf: &CombineFields, a: &ty::t, b: &ty::t) -> ures {
@ -407,7 +407,7 @@ pub fn super_lattice_tys<L:LatticeDir+TyLatticeDir+Combine>(this: &L,
} }
} }
pub type LatticeDirOp<'a, T> = 'a |a: &T, b: &T| -> cres<T>; pub type LatticeDirOp<'a, T> = |a: &T, b: &T|: 'a -> cres<T>;
#[deriving(Clone)] #[deriving(Clone)]
pub enum LatticeVarResult<V,T> { pub enum LatticeVarResult<V,T> {

View File

@ -64,7 +64,7 @@ pub fn indenter() -> _indenter {
} }
struct LoopQueryVisitor<'a> { struct LoopQueryVisitor<'a> {
p: 'a |&ast::Expr_| -> bool, p: |&ast::Expr_|: 'a -> bool,
flag: bool, flag: bool,
} }
@ -92,7 +92,7 @@ pub fn loop_query(b: &ast::Block, p: |&ast::Expr_| -> bool) -> bool {
} }
struct BlockQueryVisitor<'a> { struct BlockQueryVisitor<'a> {
p: 'a |&ast::Expr| -> bool, p: |&ast::Expr|: 'a -> bool,
flag: bool, flag: bool,
} }

View File

@ -120,7 +120,7 @@ impl Drop for Addrinfo {
} }
fn each_ai_flag(_f: |c_int, ai::Flag|) { 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 { unsafe {
f(uvll::rust_AI_ADDRCONFIG(), ai::AddrConfig); f(uvll::rust_AI_ADDRCONFIG(), ai::AddrConfig);
f(uvll::rust_AI_ALL(), ai::All); 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 { let protocol = match (*addr).ai_protocol {
p if p == uvll::rust_IPPROTO_UDP() => Some(ai::UDP), p if p == uvll::rust_IPPROTO_UDP() => Some(ai::UDP),
p if p == uvll::rust_IPPROTO_TCP() => Some(ai::TCP), p if p == uvll::rust_IPPROTO_TCP() => Some(ai::TCP),

View File

@ -46,7 +46,7 @@ use raw;
pub struct CVec<T> { pub struct CVec<T> {
base: *mut T, base: *mut T,
len: uint, len: uint,
dtor: Option<proc:Send()>, dtor: Option<proc():Send>,
} }
#[unsafe_destructor] #[unsafe_destructor]
@ -90,7 +90,7 @@ impl<T> CVec<T> {
/// * dtor - A proc to run when the value is destructed, useful /// * dtor - A proc to run when the value is destructed, useful
/// for freeing the buffer, etc. /// for freeing the buffer, etc.
pub unsafe fn new_with_dtor(base: *mut T, len: uint, pub unsafe fn new_with_dtor(base: *mut T, len: uint,
dtor: proc:Send()) -> CVec<T> { dtor: proc():Send) -> CVec<T> {
assert!(base != ptr::mut_null()); assert!(base != ptr::mut_null());
CVec { CVec {
base: base, base: base,

View File

@ -632,28 +632,28 @@ pub trait Reader {
/// Reads a little-endian unsigned integer. /// 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<uint> { fn read_le_uint(&mut self) -> IoResult<uint> {
self.read_le_uint_n(uint::BYTES).map(|i| i as uint) self.read_le_uint_n(uint::BYTES).map(|i| i as uint)
} }
/// Reads a little-endian integer. /// 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<int> { fn read_le_int(&mut self) -> IoResult<int> {
self.read_le_int_n(int::BYTES).map(|i| i as int) self.read_le_int_n(int::BYTES).map(|i| i as int)
} }
/// Reads a big-endian unsigned integer. /// 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<uint> { fn read_be_uint(&mut self) -> IoResult<uint> {
self.read_be_uint_n(uint::BYTES).map(|i| i as uint) self.read_be_uint_n(uint::BYTES).map(|i| i as uint)
} }
/// Reads a big-endian integer. /// 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<int> { fn read_be_int(&mut self) -> IoResult<int> {
self.read_be_int_n(int::BYTES).map(|i| i as int) self.read_be_int_n(int::BYTES).map(|i| i as int)
} }

View File

@ -141,7 +141,7 @@ mod tests {
use io::*; use io::*;
use io::test::*; 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 path1 = next_test_unix();
let path2 = path1.clone(); let path2 = path1.clone();

View File

@ -99,7 +99,15 @@ fn src<T>(fd: libc::c_int, readable: bool, f: |StdSource| -> T) -> T {
/// ///
/// See `stdout()` for more notes about this function. /// See `stdout()` for more notes about this function.
pub fn stdin() -> BufferedReader<StdReader> { pub fn stdin() -> BufferedReader<StdReader> {
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. /// Creates a new non-blocking handle to the stdin of the current process.

View File

@ -156,7 +156,7 @@ pub trait Iterator<A> {
/// assert!(it.next().is_none()); /// assert!(it.next().is_none());
/// ``` /// ```
#[inline] #[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} Map{iter: self, f: f}
} }
@ -173,7 +173,7 @@ pub trait Iterator<A> {
/// assert!(it.next().is_none()); /// assert!(it.next().is_none());
/// ``` /// ```
#[inline] #[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} Filter{iter: self, predicate: predicate}
} }
@ -190,7 +190,7 @@ pub trait Iterator<A> {
/// assert!(it.next().is_none()); /// assert!(it.next().is_none());
/// ``` /// ```
#[inline] #[inline]
fn filter_map<'r, B>(self, f: 'r |A| -> Option<B>) -> FilterMap<'r, A, B, Self> { fn filter_map<'r, B>(self, f: |A|: 'r -> Option<B>) -> FilterMap<'r, A, B, Self> {
FilterMap { iter: self, f: f } FilterMap { iter: self, f: f }
} }
@ -249,7 +249,7 @@ pub trait Iterator<A> {
/// assert!(it.next().is_none()); /// assert!(it.next().is_none());
/// ``` /// ```
#[inline] #[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} SkipWhile{iter: self, flag: false, predicate: predicate}
} }
@ -267,7 +267,7 @@ pub trait Iterator<A> {
/// assert!(it.next().is_none()); /// assert!(it.next().is_none());
/// ``` /// ```
#[inline] #[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} TakeWhile{iter: self, flag: false, predicate: predicate}
} }
@ -327,7 +327,7 @@ pub trait Iterator<A> {
/// assert!(it.next().is_none()); /// assert!(it.next().is_none());
/// ``` /// ```
#[inline] #[inline]
fn scan<'r, St, B>(self, initial_state: St, f: 'r |&mut St, A| -> Option<B>) fn scan<'r, St, B>(self, initial_state: St, f: |&mut St, A|: 'r -> Option<B>)
-> Scan<'r, A, B, Self, St> { -> Scan<'r, A, B, Self, St> {
Scan{iter: self, f: f, state: initial_state} Scan{iter: self, f: f, state: initial_state}
} }
@ -351,7 +351,7 @@ pub trait Iterator<A> {
/// } /// }
/// ``` /// ```
#[inline] #[inline]
fn flat_map<'r, B, U: Iterator<B>>(self, f: 'r |A| -> U) fn flat_map<'r, B, U: Iterator<B>>(self, f: |A|: 'r -> U)
-> FlatMap<'r, A, Self, U> { -> FlatMap<'r, A, Self, U> {
FlatMap{iter: self, f: f, frontiter: None, backiter: None } FlatMap{iter: self, f: f, frontiter: None, backiter: None }
} }
@ -405,7 +405,7 @@ pub trait Iterator<A> {
/// println!("{}", sum); /// println!("{}", sum);
/// ``` /// ```
#[inline] #[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} Inspect{iter: self, f: f}
} }
@ -1235,7 +1235,7 @@ RandomAccessIterator<(A, B)> for Zip<T, U> {
/// An iterator which maps the values of `iter` with `f` /// An iterator which maps the values of `iter` with `f`
pub struct Map<'a, A, B, T> { pub struct Map<'a, A, B, T> {
iter: T, iter: T,
f: 'a |A| -> B f: |A|: 'a -> B
} }
impl<'a, A, B, T> Map<'a, A, B, T> { impl<'a, A, B, T> Map<'a, A, B, T> {
@ -1284,7 +1284,7 @@ impl<'a, A, B, T: RandomAccessIterator<A>> RandomAccessIterator<B> for Map<'a, A
/// An iterator which filters the elements of `iter` with `predicate` /// An iterator which filters the elements of `iter` with `predicate`
pub struct Filter<'a, A, T> { pub struct Filter<'a, A, T> {
iter: T, iter: T,
predicate: 'a |&A| -> bool predicate: |&A|: 'a -> bool
} }
impl<'a, A, T: Iterator<A>> Iterator<A> for Filter<'a, A, T> { impl<'a, A, T: Iterator<A>> Iterator<A> for Filter<'a, A, T> {
@ -1328,7 +1328,7 @@ impl<'a, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for Filter<'a, A,
/// An iterator which uses `f` to both filter and map elements from `iter` /// An iterator which uses `f` to both filter and map elements from `iter`
pub struct FilterMap<'a, A, B, T> { pub struct FilterMap<'a, A, B, T> {
iter: T, iter: T,
f: 'a |A| -> Option<B> f: |A|: 'a -> Option<B>
} }
impl<'a, A, B, T: Iterator<A>> Iterator<B> for FilterMap<'a, A, B, T> { impl<'a, A, B, T: Iterator<A>> Iterator<B> for FilterMap<'a, A, B, T> {
@ -1477,7 +1477,7 @@ impl<'a, A, T: Iterator<A>> Peekable<A, T> {
pub struct SkipWhile<'a, A, T> { pub struct SkipWhile<'a, A, T> {
iter: T, iter: T,
flag: bool, flag: bool,
predicate: 'a |&A| -> bool predicate: |&A|: 'a -> bool
} }
impl<'a, A, T: Iterator<A>> Iterator<A> for SkipWhile<'a, A, T> { impl<'a, A, T: Iterator<A>> Iterator<A> for SkipWhile<'a, A, T> {
@ -1515,7 +1515,7 @@ impl<'a, A, T: Iterator<A>> Iterator<A> for SkipWhile<'a, A, T> {
pub struct TakeWhile<'a, A, T> { pub struct TakeWhile<'a, A, T> {
iter: T, iter: T,
flag: bool, flag: bool,
predicate: 'a |&A| -> bool predicate: |&A|: 'a -> bool
} }
impl<'a, A, T: Iterator<A>> Iterator<A> for TakeWhile<'a, A, T> { impl<'a, A, T: Iterator<A>> Iterator<A> for TakeWhile<'a, A, T> {
@ -1662,7 +1662,7 @@ impl<A, T: RandomAccessIterator<A>> RandomAccessIterator<A> for Take<T> {
/// An iterator to maintain state while iterating another iterator /// An iterator to maintain state while iterating another iterator
pub struct Scan<'a, A, B, T, St> { pub struct Scan<'a, A, B, T, St> {
iter: T, iter: T,
f: 'a |&mut St, A| -> Option<B>, f: |&mut St, A|: 'a -> Option<B>,
/// The current internal state to be passed to the closure next. /// The current internal state to be passed to the closure next.
pub state: St, pub state: St,
@ -1686,7 +1686,7 @@ impl<'a, A, B, T: Iterator<A>, St> Iterator<B> for Scan<'a, A, B, T, St> {
/// ///
pub struct FlatMap<'a, A, T, U> { pub struct FlatMap<'a, A, T, U> {
iter: T, iter: T,
f: 'a |A| -> U, f: |A|: 'a -> U,
frontiter: Option<U>, frontiter: Option<U>,
backiter: Option<U>, backiter: Option<U>,
} }
@ -1817,7 +1817,7 @@ impl<T> Fuse<T> {
/// element before yielding it. /// element before yielding it.
pub struct Inspect<'a, A, T> { pub struct Inspect<'a, A, T> {
iter: T, iter: T,
f: 'a |&A| f: |&A|: 'a
} }
impl<'a, A, T> Inspect<'a, A, T> { 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. /// An iterator which just modifies the contained state throughout iteration.
pub struct Unfold<'a, A, St> { pub struct Unfold<'a, A, St> {
f: 'a |&mut St| -> Option<A>, f: |&mut St|: 'a -> Option<A>,
/// Internal state that will be yielded on the next iteration /// Internal state that will be yielded on the next iteration
pub state: St, 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 /// Creates a new iterator with the specified closure as the "iterator
/// function" and an initial state to eventually pass to the iterator /// function" and an initial state to eventually pass to the iterator
#[inline] #[inline]
pub fn new<'a>(initial_state: St, f: 'a |&mut St| -> Option<A>) pub fn new<'a>(initial_state: St, f: |&mut St|: 'a -> Option<A>)
-> Unfold<'a, A, St> { -> Unfold<'a, A, St> {
Unfold { Unfold {
f: f, f: f,

View File

@ -58,7 +58,6 @@
#![no_std] #![no_std]
#![deny(missing_doc)] #![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 // 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 // things and all of the std::io tests have an I/O interface to run on top

View File

@ -273,7 +273,8 @@ macro_rules! vec(
let mut _temp = ::std::vec::Vec::new(); let mut _temp = ::std::vec::Vec::new();
$(_temp.push($e);)* $(_temp.push($e);)*
_temp _temp
}) });
($($e:expr),+,) => (vec!($($e),+))
) )

View File

@ -8,7 +8,87 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // 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::<int>() 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 cast;
use clone::Clone; use clone::Clone;
@ -51,31 +131,97 @@ pub unsafe fn position<T>(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] #[inline]
pub fn null<T>() -> *T { 0 as *T } pub fn null<T>() -> *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] #[inline]
pub fn mut_null<T>() -> *mut T { 0 as *mut T } pub fn mut_null<T>() -> *mut T { 0 as *mut T }
/** /// Copies data from one location to another.
* Copies data from one location to another. ///
* /// Copies `count` elements (not bytes) from `src` to `dst`. The source
* Copies `count` elements (not bytes) from `src` to `dst`. The source /// and destination may overlap.
* 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<T>(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] #[inline]
pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) { pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
intrinsics::copy_memory(dst, src, count) intrinsics::copy_memory(dst, src, count)
} }
/** /// Copies data from one location to another.
* Copies data from one location to another. ///
* /// Copies `count` elements (not bytes) from `src` to `dst`. The source
* Copies `count` elements (not bytes) from `src` to `dst`. The source /// and destination may *not* overlap.
* 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<T>(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] #[inline]
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
src: *T, src: *T,
@ -83,27 +229,21 @@ pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
intrinsics::copy_nonoverlapping_memory(dst, src, count) intrinsics::copy_nonoverlapping_memory(dst, src, count)
} }
/** /// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
* Invokes memset on the specified pointer, setting `count * size_of::<T>()` /// bytes of memory starting at `dst` to `c`.
* bytes of memory starting at `dst` to `c`.
*/
#[inline] #[inline]
pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) { pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
intrinsics::set_memory(dst, c, count) intrinsics::set_memory(dst, c, count)
} }
/** /// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
* Zeroes out `count * size_of::<T>` bytes of memory at `dst`
*/
#[inline] #[inline]
pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) { pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
set_memory(dst, 0, count); set_memory(dst, 0, count);
} }
/** /// Swap the values at two mutable locations of the same type, without
* Swap the values at two mutable locations of the same type, without /// deinitialising either. They may overlap.
* deinitialising either. They may overlap.
*/
#[inline] #[inline]
pub unsafe fn swap<T>(x: *mut T, y: *mut T) { pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
// Give ourselves some scratch space to work with // Give ourselves some scratch space to work with
@ -120,19 +260,15 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
cast::forget(tmp); cast::forget(tmp);
} }
/** /// Replace the value at a mutable location with a new one, returning the old
* Replace the value at a mutable location with a new one, returning the old /// value, without deinitialising either.
* value, without deinitialising either.
*/
#[inline] #[inline]
pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T { pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
mem::swap(cast::transmute(dest), &mut src); // cannot overlap mem::swap(cast::transmute(dest), &mut src); // cannot overlap
src src
} }
/** /// Reads the value from `*src` and returns it.
* Reads the value from `*src` and returns it.
*/
#[inline(always)] #[inline(always)]
pub unsafe fn read<T>(src: *T) -> T { pub unsafe fn read<T>(src: *T) -> T {
let mut tmp: T = mem::uninit(); let mut tmp: T = mem::uninit();
@ -140,10 +276,8 @@ pub unsafe fn read<T>(src: *T) -> T {
tmp tmp
} }
/** /// Reads the value from `*src` and nulls it out.
* Reads the value from `*src` and nulls it out. /// This currently prevents destructors from executing.
* This currently prevents destructors from executing.
*/
#[inline(always)] #[inline(always)]
pub unsafe fn read_and_zero<T>(dest: *mut T) -> T { pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
// Copy the data out from `dest`: // Copy the data out from `dest`:
@ -155,13 +289,9 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
tmp tmp
} }
/** /// Given a **T (pointer to an array of pointers),
Given a **T (pointer to an array of pointers), /// iterate through each *T, up to the provided `len`,
iterate through each *T, up to the provided `len`, /// passing to the provided callback function
passing to the provided callback function
SAFETY NOTE: Pointer-arithmetic. Dragons be here.
*/
pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) { pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
if arr.is_null() { if arr.is_null() {
fail!("ptr::array_each_with_len failure: arr input is null pointer"); fail!("ptr::array_each_with_len failure: arr input is null pointer");
@ -173,15 +303,14 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
} }
} }
/** /// Given a null-pointer-terminated **T (pointer to
Given a null-pointer-terminated **T (pointer to /// an array of pointers), iterate through each *T,
an array of pointers), iterate through each *T, /// passing to the provided callback function
passing to the provided callback function ///
/// # Safety Note
SAFETY NOTE: This will only work with a null-terminated ///
pointer array. Barely less-dodgy Pointer Arithmetic. /// This will only work with a null-terminated
Dragons be here. /// pointer array.
*/
pub unsafe fn array_each<T>(arr: **T, cb: |*T|) { pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
if arr.is_null() { if arr.is_null() {
fail!("ptr::array_each_with_len failure: arr input is null pointer"); fail!("ptr::array_each_with_len failure: arr input is null pointer");

View File

@ -21,7 +21,7 @@ use ptr::RawPtr;
use unstable::sync::Exclusive; use unstable::sync::Exclusive;
use slice::OwnedVector; 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 // 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 // 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 { unsafe {
rtassert!(!RUNNING); rtassert!(!RUNNING);
rtassert!(!QUEUE.is_null()); rtassert!(!QUEUE.is_null());

View File

@ -12,7 +12,7 @@
//! //!
//! The runtime will use this for storing ~Task. //! 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. //! and for overwriting an existing pointer.
#![allow(dead_code)] #![allow(dead_code)]

View File

@ -157,7 +157,7 @@ pub trait Runtime {
// Miscellaneous calls which are very different depending on what context // Miscellaneous calls which are very different depending on what context
// you're in. // 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<rtio::LocalIo<'a>>; fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>>;
/// The (low, high) edges of the current stack. /// The (low, high) edges of the current stack.
fn stack_bounds(&self) -> (uint, uint); // (lo, hi) 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 /// It is forbidden for procedures to register more `at_exit` handlers when they
/// are running, and doing so will lead to a process abort. /// 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); at_exit_imp::push(f);
} }

View File

@ -36,7 +36,7 @@ pub trait Callback {
pub trait EventLoop { pub trait EventLoop {
fn run(&mut self); fn run(&mut self);
fn callback(&mut self, arg: proc:Send()); fn callback(&mut self, arg: proc():Send);
fn pausable_idle_callback(&mut self, fn pausable_idle_callback(&mut self,
~Callback:Send) -> ~PausableIdleCallback:Send; ~Callback:Send) -> ~PausableIdleCallback:Send;
fn remote_callback(&mut self, ~Callback:Send) -> ~RemoteCallback:Send; fn remote_callback(&mut self, ~Callback:Send) -> ~RemoteCallback:Send;

View File

@ -70,7 +70,7 @@ pub enum BlockedTask {
pub enum DeathAction { pub enum DeathAction {
/// Action to be done with the exit code. If set, also makes the task wait /// 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. /// 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 /// A channel to send the result of the task on when the task exits
SendMessage(Sender<TaskResult>), SendMessage(Sender<TaskResult>),
} }
@ -236,7 +236,7 @@ impl Task {
/// Spawns a sibling to this task. The newly spawned task is configured with /// 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. /// 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(); let ops = self.imp.take_unwrap();
ops.spawn_sibling(self, opts, f) ops.spawn_sibling(self, opts, f)
} }

View File

@ -68,13 +68,13 @@ impl Thread<()> {
/// to finish executing. This means that even if `join` is not explicitly /// to finish executing. This means that even if `join` is not explicitly
/// called, when the `Thread` falls out of scope its destructor will block /// called, when the `Thread` falls out of scope its destructor will block
/// waiting for the OS thread. /// waiting for the OS thread.
pub fn start<T: Send>(main: proc:Send() -> T) -> Thread<T> { pub fn start<T: Send>(main: proc():Send -> T) -> Thread<T> {
Thread::start_stack(DEFAULT_STACK_SIZE, main) Thread::start_stack(DEFAULT_STACK_SIZE, main)
} }
/// Performs the same functionality as `start`, but specifies an explicit /// Performs the same functionality as `start`, but specifies an explicit
/// stack size for the new thread. /// stack size for the new thread.
pub fn start_stack<T: Send>(stack: uint, main: proc:Send() -> T) -> Thread<T> { pub fn start_stack<T: Send>(stack: uint, main: proc():Send -> T) -> Thread<T> {
// We need the address of the packet to fill in to be stable so when // 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 // `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 /// This corresponds to creating threads in the 'detached' state on unix
/// systems. Note that platforms may not keep the main program alive even if /// systems. Note that platforms may not keep the main program alive even if
/// there are detached thread still running around. /// 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) Thread::spawn_stack(DEFAULT_STACK_SIZE, main)
} }
/// Performs the same functionality as `spawn`, but explicitly specifies a /// Performs the same functionality as `spawn`, but explicitly specifies a
/// stack size for the new thread. /// 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 { unsafe {
let handle = imp::create(stack, ~main); let handle = imp::create(stack, ~main);
imp::detach(handle); imp::detach(handle);
@ -156,7 +156,7 @@ mod imp {
pub type rust_thread = HANDLE; pub type rust_thread = HANDLE;
pub type rust_thread_return = DWORD; 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); let arg: *mut libc::c_void = cast::transmute(p);
// FIXME On UNIX, we guard against stack sizes that are too small but // FIXME On UNIX, we guard against stack sizes that are too small but
// that's because pthreads enforces that stacks are at least // 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 = libc::pthread_t;
pub type rust_thread_return = *u8; 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 native: libc::pthread_t = mem::uninit();
let mut attr: libc::pthread_attr_t = mem::uninit(); let mut attr: libc::pthread_attr_t = mem::uninit();
assert_eq!(pthread_attr_init(&mut attr), 0); assert_eq!(pthread_attr_init(&mut attr), 0);

View File

@ -235,7 +235,7 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
pub struct Splits<'a, T> { pub struct Splits<'a, T> {
v: &'a [T], v: &'a [T],
n: uint, n: uint,
pred: 'a |t: &T| -> bool, pred: |t: &T|: 'a -> bool,
finished: bool finished: bool
} }
@ -284,7 +284,7 @@ impl<'a, T> Iterator<&'a [T]> for Splits<'a, T> {
pub struct RevSplits<'a, T> { pub struct RevSplits<'a, T> {
v: &'a [T], v: &'a [T],
n: uint, n: uint,
pred: 'a |t: &T| -> bool, pred: |t: &T|: 'a -> bool,
finished: bool finished: bool
} }
@ -810,23 +810,23 @@ pub trait ImmutableVector<'a, T> {
/// Returns an iterator over the subslices of the vector which are /// Returns an iterator over the subslices of the vector which are
/// separated by elements that match `pred`. The matched element /// separated by elements that match `pred`. The matched element
/// is not contained in the subslices. /// 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 /// Returns an iterator over the subslices of the vector which are
/// separated by elements that match `pred`, limited to splitting /// separated by elements that match `pred`, limited to splitting
/// at most `n` times. The matched element is not contained in /// at most `n` times. The matched element is not contained in
/// the subslices. /// 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 /// Returns an iterator over the subslices of the vector which are
/// separated by elements that match `pred`. This starts at the /// separated by elements that match `pred`. This starts at the
/// end of the vector and works backwards. The matched element is /// end of the vector and works backwards. The matched element is
/// not contained in the subslices. /// 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 /// Returns an iterator over the subslices of the vector which are
/// separated by elements that match `pred` limited to splitting /// separated by elements that match `pred` limited to splitting
/// at most `n` times. This starts at the end of the vector and /// at most `n` times. This starts at the end of the vector and
/// works backwards. The matched element is not contained in the /// works backwards. The matched element is not contained in the
/// subslices. /// 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 * Returns an iterator over all contiguous windows of length
@ -1003,12 +1003,12 @@ impl<'a,T> ImmutableVector<'a, T> for &'a [T] {
} }
#[inline] #[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) self.splitn(uint::MAX, pred)
} }
#[inline] #[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 { Splits {
v: self, v: self,
n: n, n: n,
@ -1018,12 +1018,12 @@ impl<'a,T> ImmutableVector<'a, T> for &'a [T] {
} }
#[inline] #[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) self.rsplitn(uint::MAX, pred)
} }
#[inline] #[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 { RevSplits {
v: self, v: self,
n: n, n: n,
@ -2027,7 +2027,7 @@ pub trait MutableVector<'a, T> {
/// Returns an iterator over the mutable subslices of the vector /// Returns an iterator over the mutable subslices of the vector
/// which are separated by elements that match `pred`. The /// which are separated by elements that match `pred`. The
/// matched element is not contained in the subslices. /// 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. * 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] #[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 } MutSplits { v: self, pred: pred, finished: false }
} }
@ -2736,7 +2736,7 @@ pub type RevMutItems<'a, T> = Rev<MutItems<'a, T>>;
/// by elements that match `pred`. /// by elements that match `pred`.
pub struct MutSplits<'a, T> { pub struct MutSplits<'a, T> {
v: &'a mut [T], v: &'a mut [T],
pred: 'a |t: &T| -> bool, pred: |t: &T|: 'a -> bool,
finished: bool finished: bool
} }

View File

@ -241,7 +241,7 @@ impl CharEq for char {
fn only_ascii(&self) -> bool { (*self as uint) < 128 } fn only_ascii(&self) -> bool { (*self as uint) < 128 }
} }
impl<'a> CharEq for 'a |char| -> bool { impl<'a> CharEq for |char|: 'a -> bool {
#[inline] #[inline]
fn matches(&self, c: char) -> bool { (*self)(c) } fn matches(&self, c: char) -> bool { (*self)(c) }

View File

@ -86,7 +86,7 @@ pub struct TaskOpts {
pub struct TaskBuilder { pub struct TaskBuilder {
/// Options to spawn the new task with /// Options to spawn the new task with
pub opts: TaskOpts, pub opts: TaskOpts,
gen_body: Option<proc:Send(v: proc:Send()) -> proc:Send()>, gen_body: Option<proc(v: proc():Send):Send -> proc():Send>,
nocopy: Option<marker::NoCopy>, nocopy: Option<marker::NoCopy>,
} }
@ -151,7 +151,7 @@ impl TaskBuilder {
* existing body generator to the new body generator. * existing body generator to the new body generator.
*/ */
pub fn with_wrapper(mut self, pub fn with_wrapper(mut self,
wrapper: proc:Send(v: proc:Send()) -> proc:Send()) wrapper: proc(v: proc():Send):Send -> proc():Send)
-> TaskBuilder -> TaskBuilder
{ {
self.gen_body = match self.gen_body.take() { 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 * the provided unique closure. The task has the properties and behavior
* specified by the task_builder. * 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 gen_body = self.gen_body.take();
let f = match gen_body { let f = match gen_body {
Some(gen) => gen(f), Some(gen) => gen(f),
@ -191,7 +191,7 @@ impl TaskBuilder {
* # Failure * # Failure
* Fails if a future_result was already set for this task. * Fails if a future_result was already set for this task.
*/ */
pub fn try<T:Send>(mut self, f: proc:Send() -> T) -> Result<T, ~Any:Send> { pub fn try<T:Send>(mut self, f: proc():Send -> T) -> Result<T, ~Any:Send> {
let (tx, rx) = channel(); let (tx, rx) = channel();
let result = self.future_result(); let result = self.future_result();
@ -233,12 +233,12 @@ impl TaskOpts {
/// the provided unique closure. /// the provided unique closure.
/// ///
/// This function is equivalent to `task().spawn(f)`. /// This function is equivalent to `task().spawn(f)`.
pub fn spawn(f: proc:Send()) { pub fn spawn(f: proc():Send) {
let task = task(); let task = task();
task.spawn(f) task.spawn(f)
} }
pub fn try<T:Send>(f: proc:Send() -> T) -> Result<T, ~Any:Send> { pub fn try<T:Send>(f: proc():Send -> T) -> Result<T, ~Any:Send> {
/*! /*!
* Execute a function in another task and return either the return value * Execute a function in another task and return either the return value
* of the function or result::err. * of the function or result::err.
@ -338,7 +338,7 @@ fn test_run_basic() {
fn test_with_wrapper() { fn test_with_wrapper() {
let (tx, rx) = channel(); let (tx, rx) = channel();
task().with_wrapper(proc(body) { task().with_wrapper(proc(body) {
let result: proc:Send() = proc() { let result: proc():Send = proc() {
body(); body();
tx.send(()); tx.send(());
}; };
@ -424,7 +424,7 @@ fn test_spawn_sched_childs_on_default_sched() {
} }
#[cfg(test)] #[cfg(test)]
fn avoid_copying_the_body(spawnfn: |v: proc:Send()|) { fn avoid_copying_the_body(spawnfn: |v: proc():Send|) {
let (tx, rx) = channel::<uint>(); let (tx, rx) = channel::<uint>();
let x = ~1; 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 // (well, it would if the constant were 8000+ - I lowered it to be more
// valgrind-friendly. try this at home, instead..!) // valgrind-friendly. try this at home, instead..!)
static generations: uint = 16; static generations: uint = 16;
fn child_no(x: uint) -> proc:Send() { fn child_no(x: uint) -> proc():Send {
return proc() { return proc() {
if x < generations { if x < generations {
task().spawn(child_no(x+1)); task().spawn(child_no(x+1));

View File

@ -39,7 +39,7 @@ pub trait Finally<T> {
fn finally(&self, dtor: ||) -> T; fn finally(&self, dtor: ||) -> T;
} }
impl<'a,T> Finally<T> for 'a || -> T { impl<'a,T> Finally<T> for ||: 'a -> T {
fn finally(&self, dtor: ||) -> T { fn finally(&self, dtor: ||) -> T {
try_finally(&mut (), (), try_finally(&mut (), (),
|_, _| (*self)(), |_, _| (*self)(),
@ -101,7 +101,7 @@ pub fn try_finally<T,U,R>(mutate: &mut T,
struct Finallyalizer<'a,A> { struct Finallyalizer<'a,A> {
mutate: &'a mut A, mutate: &'a mut A,
dtor: 'a |&mut A| dtor: |&mut A|: 'a
} }
#[unsafe_destructor] #[unsafe_destructor]

View File

@ -28,7 +28,7 @@ for it to terminate.
The executing thread has no access to a task pointer and will be using The executing thread has no access to a task pointer and will be using
a normal large stack. 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; use rt::thread::Thread;
Thread::start(f).join() Thread::start(f).join()
} }

View File

@ -1574,6 +1574,7 @@ mod tests {
assert_eq!(v, three) assert_eq!(v, three)
} }
#[test]
fn test_grow_fn() { fn test_grow_fn() {
let mut v = Vec::from_slice([0u, 1]); let mut v = Vec::from_slice([0u, 1]);
v.grow_fn(3, |i| i); v.grow_fn(3, |i| i);

View File

@ -124,12 +124,10 @@ impl<T: Share + Send> Clone for Arc<T> {
} }
} }
// FIXME(#13042): this should have T: Send, and use self.inner() impl<T: Send + Share> Deref<T> for Arc<T> {
impl<T> Deref<T> for Arc<T> {
#[inline] #[inline]
fn deref<'a>(&'a self) -> &'a T { fn deref<'a>(&'a self) -> &'a T {
let inner = unsafe { &*self.x }; &self.inner().data
&inner.data
} }
} }

View File

@ -34,7 +34,7 @@ pub struct Future<A> {
} }
enum FutureState<A> { enum FutureState<A> {
Pending(proc:Send() -> A), Pending(proc():Send -> A),
Evaluating, Evaluating,
Forced(A) Forced(A)
} }
@ -90,7 +90,7 @@ impl<A> Future<A> {
Future {state: Forced(val)} Future {state: Forced(val)}
} }
pub fn from_fn(f: proc:Send() -> A) -> Future<A> { pub fn from_fn(f: proc():Send -> A) -> Future<A> {
/*! /*!
* Create a future from a function. * Create a future from a function.
* *
@ -117,7 +117,7 @@ impl<A:Send> Future<A> {
}) })
} }
pub fn spawn(blk: proc:Send() -> A) -> Future<A> { pub fn spawn(blk: proc():Send -> A) -> Future<A> {
/*! /*!
* Create a future from a unique closure. * Create a future from a unique closure.
* *

View File

@ -231,11 +231,10 @@ impl<T: Send> Mutex<T> {
} }
} }
// FIXME(#13042): these should both have T: Send impl<'a, T: Send> Deref<T> for MutexGuard<'a, T> {
impl<'a, T> Deref<T> for MutexGuard<'a, T> {
fn deref<'a>(&'a self) -> &'a T { &*self.data } fn deref<'a>(&'a self) -> &'a T { &*self.data }
} }
impl<'a, T> DerefMut<T> for MutexGuard<'a, T> { impl<'a, T: Send> DerefMut<T> for MutexGuard<'a, T> {
fn deref_mut<'a>(&'a mut self) -> &'a mut T { &mut *self.data } 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: Send + Share> Deref<T> for RWLockReadGuard<'a, T> {
impl<'a, T> Deref<T> for RWLockReadGuard<'a, T> {
fn deref<'a>(&'a self) -> &'a T { self.data } fn deref<'a>(&'a self) -> &'a T { self.data }
} }
impl<'a, T> Deref<T> for RWLockWriteGuard<'a, T> { impl<'a, T: Send + Share> Deref<T> for RWLockWriteGuard<'a, T> {
fn deref<'a>(&'a self) -> &'a T { &*self.data } fn deref<'a>(&'a self) -> &'a T { &*self.data }
} }
impl<'a, T> DerefMut<T> for RWLockWriteGuard<'a, T> { impl<'a, T: Send + Share> DerefMut<T> for RWLockWriteGuard<'a, T> {
fn deref_mut<'a>(&'a mut self) -> &'a mut T { &mut *self.data } fn deref_mut<'a>(&'a mut self) -> &'a mut T { &mut *self.data }
} }

View File

@ -16,7 +16,7 @@
use std::task; use std::task;
enum Msg<T> { enum Msg<T> {
Execute(proc:Send(&T)), Execute(proc(&T):Send),
Quit Quit
} }
@ -41,7 +41,7 @@ impl<T> TaskPool<T> {
/// returns a function which, given the index of the task, should return /// returns a function which, given the index of the task, should return
/// local data to be kept around in that task. /// local data to be kept around in that task.
pub fn new(n_tasks: uint, pub fn new(n_tasks: uint,
init_fn_factory: || -> proc:Send(uint) -> T) init_fn_factory: || -> proc(uint):Send -> T)
-> TaskPool<T> { -> TaskPool<T> {
assert!(n_tasks >= 1); assert!(n_tasks >= 1);
@ -73,7 +73,7 @@ impl<T> TaskPool<T> {
/// Executes the function `f` on a task in the pool. The function /// Executes the function `f` on a task in the pool. The function
/// receives a reference to the local data returned by the `init_fn`. /// 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.channels.get(self.next_index).send(Execute(f));
self.next_index += 1; self.next_index += 1;
if self.next_index == self.channels.len() { self.next_index = 0; } if self.next_index == self.channels.len() { self.next_index = 0; }
@ -82,8 +82,8 @@ impl<T> TaskPool<T> {
#[test] #[test]
fn test_task_pool() { fn test_task_pool() {
let f: || -> proc:Send(uint) -> uint = || { let f: || -> proc(uint):Send -> uint = || {
let g: proc:Send(uint) -> uint = proc(i) i; let g: proc(uint):Send -> uint = proc(i) i;
g g
}; };
let mut pool = TaskPool::new(4, f); let mut pool = TaskPool::new(4, f);

View File

@ -613,7 +613,7 @@ pub trait EachViewItem {
} }
struct EachViewItemData<'a> { struct EachViewItemData<'a> {
callback: 'a |&ast::ViewItem| -> bool, callback: |&ast::ViewItem|: 'a -> bool,
} }
impl<'a> Visitor<()> for EachViewItemData<'a> { impl<'a> Visitor<()> for EachViewItemData<'a> {

View File

@ -293,13 +293,12 @@ pub fn syntax_expander_table() -> SyntaxEnv {
pub struct MacroCrate { pub struct MacroCrate {
pub lib: Option<Path>, pub lib: Option<Path>,
pub cnum: ast::CrateNum, pub macros: Vec<~str>,
pub registrar_symbol: Option<~str>,
} }
pub trait CrateLoader { pub trait CrateLoader {
fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate; 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; // One of these is made during expansion and incrementally updated as we go;

View File

@ -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. all the fields of all the structures, see above for details.
*/ */
pub type CombineSubstructureFunc<'a> = 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 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 [variant fields]), and a list of the nonself args of the type
*/ */
pub type EnumNonMatchFunc<'a> = pub type EnumNonMatchFunc<'a> =
'a |&mut ExtCtxt, |&mut ExtCtxt,
Span, Span,
&[(uint, P<ast::Variant>, Vec<(Span, Option<Ident>, @Expr)> )], &[(uint, P<ast::Variant>, Vec<(Span, Option<Ident>, @Expr)> )],
&[@Expr]| &[@Expr]|: 'a
-> @Expr; -> @Expr;

View File

@ -487,7 +487,8 @@ pub fn expand_view_item(vi: &ast::ViewItem,
} }
fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) { 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 { let crate_name = match krate.node {
ast::ViewItemExternCrate(name, _, _) => name, 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 name = format!("<{} macros>", token::get_ident(crate_name));
let exported_macros = fld.cx.ecfg.loader.get_exported_macros(cnum); for source in macros.iter() {
for source in exported_macros.iter() {
let item = parse::parse_item_from_source_str(name.clone(), let item = parse::parse_item_from_source_str(name.clone(),
(*source).clone(), (*source).clone(),
fld.cx.cfg(), 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. // Make sure the path contains a / or the linker will search for it.
let path = os::make_absolute(&path); 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, Some(registrar) => registrar,
None => return None => return
}; };
@ -1019,14 +1019,6 @@ mod test {
fn load_crate(&mut self, _: &ast::ViewItem) -> MacroCrate { fn load_crate(&mut self, _: &ast::ViewItem) -> MacroCrate {
fail!("lolwut") 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 // these following tests are quite fragile, in that they don't test what

View File

@ -905,31 +905,23 @@ impl<'a> Parser<'a> {
*/ */
// NOTE: remove after the next stage0 snap let lifetimes = if self.eat(&token::LT) {
let (decl, lifetimes, bounds) = if self.token == token::COLON { let lifetimes = self.parse_lifetimes();
let (_, bounds) = self.parse_optional_ty_param_bounds(false); self.expect_gt();
let (decl, lifetimes) = self.parse_ty_fn_decl(false); lifetimes
(decl, lifetimes, bounds)
} else { } else {
let lifetimes = if self.eat(&token::LT) { Vec::new()
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)
}; };
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 { TyClosure(@ClosureTy {
sigil: OwnedSigil, sigil: OwnedSigil,
region: None, 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 purity = self.parse_unsafety();
let onceness = if self.eat_keyword(keywords::Once) {Once} else {Many}; let onceness = if self.eat_keyword(keywords::Once) {Once} else {Many};
@ -982,10 +972,7 @@ impl<'a> Parser<'a> {
inputs inputs
}; };
let (new_region, bounds) = self.parse_optional_ty_param_bounds(true); let (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 (return_style, output) = self.parse_ret_ty(); let (return_style, output) = self.parse_ret_ty();
let decl = P(FnDecl { let decl = P(FnDecl {
@ -1246,9 +1233,7 @@ impl<'a> Parser<'a> {
} else if self.token_is_closure_keyword() || } else if self.token_is_closure_keyword() ||
self.token == token::BINOP(token::OR) || self.token == token::BINOP(token::OR) ||
self.token == token::OROR || self.token == token::OROR ||
self.token == token::LT || self.token == token::LT {
// NOTE: remove this clause after a stage0 snap
Parser::token_is_lifetime(&self.token) {
// CLOSURE // CLOSURE
// //
// FIXME(pcwalton): Eventually `token::LT` will not unambiguously // FIXME(pcwalton): Eventually `token::LT` will not unambiguously

View File

@ -123,7 +123,7 @@ pub enum TestFn {
StaticTestFn(fn()), StaticTestFn(fn()),
StaticBenchFn(fn(&mut BenchHarness)), StaticBenchFn(fn(&mut BenchHarness)),
StaticMetricFn(proc(&mut MetricMap)), StaticMetricFn(proc(&mut MetricMap)),
DynTestFn(proc:Send()), DynTestFn(proc():Send),
DynMetricFn(proc(&mut MetricMap)), DynMetricFn(proc(&mut MetricMap)),
DynBenchFn(~TDynBenchFn) DynBenchFn(~TDynBenchFn)
} }
@ -948,7 +948,7 @@ pub fn run_test(force_ignore: bool,
#[allow(deprecated_owned_vector)] #[allow(deprecated_owned_vector)]
fn run_test_inner(desc: TestDesc, fn run_test_inner(desc: TestDesc,
monitor_ch: Sender<MonitorMsg>, monitor_ch: Sender<MonitorMsg>,
testfn: proc:Send()) { testfn: proc():Send) {
spawn(proc() { spawn(proc() {
let (tx, rx) = channel(); let (tx, rx) = channel();
let mut reader = ChanReader::new(rx); let mut reader = ChanReader::new(rx);

View File

@ -394,14 +394,14 @@ impl<'a> Prep<'a> {
pub fn exec<'a, T:Send + pub fn exec<'a, T:Send +
Encodable<json::Encoder<'a>, io::IoError> + Encodable<json::Encoder<'a>, io::IoError> +
Decodable<json::Decoder, json::Error>>( Decodable<json::Decoder, json::Error>>(
&'a self, blk: proc:Send(&mut Exec) -> T) -> T { &'a self, blk: proc(&mut Exec):Send -> T) -> T {
self.exec_work(blk).unwrap() self.exec_work(blk).unwrap()
} }
fn exec_work<'a, T:Send + fn exec_work<'a, T:Send +
Encodable<json::Encoder<'a>, io::IoError> + Encodable<json::Encoder<'a>, io::IoError> +
Decodable<json::Decoder, json::Error>>( // FIXME(#5121) Decodable<json::Decoder, json::Error>>( // 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); let mut bo = Some(blk);
debug!("exec_work: looking up {} and {:?}", self.fn_name, debug!("exec_work: looking up {} and {:?}", self.fn_name,

View File

@ -16,7 +16,7 @@
DEPDIR=depends DEPDIR=depends
# "Machine-dependant" options # "Machine-dependent" options
#MFLAGS=-fPIC #MFLAGS=-fPIC
CFLAGS=-c -g -O3 -fPIC -Wall -Werror -Wsign-compare -Isrc -Ihtml CFLAGS=-c -g -O3 -fPIC -Wall -Werror -Wsign-compare -Isrc -Ihtml

View File

@ -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 S 2014-04-03 e7fe207
freebsd-x86_64 6d40f547d13896ab9d9dd4a4fdf2e72be553b01b freebsd-x86_64 6d40f547d13896ab9d9dd4a4fdf2e72be553b01b
linux-i386 875a8f6956f7d703f7206db91ca2a9b67c244cf8 linux-i386 875a8f6956f7d703f7206db91ca2a9b67c244cf8

View File

@ -13,7 +13,7 @@
// part of issue-6919.rs // part of issue-6919.rs
struct C<'a> { struct C<'a> {
pub k: 'a ||, pub k: ||: 'a,
} }
fn no_op() { } fn no_op() { }

View File

@ -15,7 +15,7 @@ use std::os;
fn start(n_tasks: int, token: int) { fn start(n_tasks: int, token: int) {
let (tx, mut rx) = channel(); let (tx, mut rx) = channel();
tx.send(token); 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; let mut i = 2;
while i <= n_tasks { while i <= n_tasks {
let (tx, next_rx) = channel(); let (tx, next_rx) = channel();

View File

@ -9,11 +9,11 @@
// except according to those terms. // except according to those terms.
struct X { struct X {
field: 'static ||:Send, field: ||:'static + Send,
} }
fn foo(blk: 'static ||:) -> X { fn foo(blk: ||:'static) -> X {
return X { field: blk }; //~ ERROR expected bounds `Send` but found no bounds return X { field: blk }; //~ ERROR expected bounds `'static+Send`
} }
fn main() { fn main() {

View File

@ -10,7 +10,7 @@
fn id<T>(t: T) -> T { t } fn id<T>(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 id(|| *v) //~ ERROR cannot infer
} }

View File

@ -10,7 +10,7 @@
fn foopy() {} fn foopy() {}
static f: 'static || = foopy; //~ ERROR found extern fn static f: ||: 'static = foopy; //~ ERROR found extern fn
fn main () { fn main () {
f(); f();

View File

@ -14,8 +14,8 @@ fn foo(_x: @uint) {}
fn main() { fn main() {
let x = @3u; 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); let _: proc() = proc() foo(x);
} }

View File

@ -16,7 +16,7 @@ struct R<'a> {
// This struct is needed to create the // This struct is needed to create the
// otherwise infinite type of a fn that // otherwise infinite type of a fn that
// accepts itself as argument: // accepts itself as argument:
c: 'a |&R, bool| c: |&R, bool|: 'a
} }
fn innocent_looking_victim() { fn innocent_looking_victim() {

View File

@ -13,13 +13,13 @@ fn is_freeze<T: Share>() {}
fn is_static<T: 'static>() {} fn is_static<T: 'static>() {}
fn main() { fn main() {
is_send::<proc:()>(); is_send::<proc()>();
//~^ ERROR: instantiating a type parameter with an incompatible type //~^ ERROR: instantiating a type parameter with an incompatible type
is_freeze::<proc:()>(); is_freeze::<proc()>();
//~^ ERROR: instantiating a type parameter with an incompatible type //~^ ERROR: instantiating a type parameter with an incompatible type
is_static::<proc:()>(); is_static::<proc()>();
//~^ ERROR: instantiating a type parameter with an incompatible type //~^ ERROR: instantiating a type parameter with an incompatible type
} }

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // 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 // Test that the closure here cannot be assigned
// the lifetime `'a`, which outlives the current // the lifetime `'a`, which outlives the current
// block. // block.
@ -21,7 +21,7 @@ fn env<'a>(_: &'a uint, blk: |p: 'a |||) {
blk(|| *statep = 1); //~ ERROR cannot infer 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 // Test that a closure with no free variables CAN
// outlive the block in which it is created. // outlive the block in which it is created.
// //

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
fn wants_static_fn(_x: 'static ||) {} fn wants_static_fn(_x: ||: 'static) {}
fn main() { fn main() {
let i = 3; let i = 3;

View File

@ -9,15 +9,15 @@
// except according to those terms. // except according to those terms.
struct parameterized1<'a> { struct parameterized1<'a> {
g: 'a || g: ||: 'a
} }
struct not_parameterized1 { struct not_parameterized1 {
g: 'static || g: ||: 'static
} }
struct not_parameterized2 { struct not_parameterized2 {
g: 'static || g: ||: 'static
} }
fn take1(p: parameterized1) -> parameterized1 { p } fn take1(p: parameterized1) -> parameterized1 { p }

View File

@ -11,7 +11,7 @@
#![feature(managed_boxes)] #![feature(managed_boxes)]
struct invariant<'a> { struct invariant<'a> {
f: 'static |x: &mut &'a int| f: |x: &mut &'a int|: 'static
} }
fn to_same_lifetime<'r>(bi: invariant<'r>) { fn to_same_lifetime<'r>(bi: invariant<'r>) {

View File

@ -11,7 +11,7 @@
#![feature(managed_boxes)] #![feature(managed_boxes)]
struct invariant<'a> { struct invariant<'a> {
f: 'static || -> &mut &'a int f: ||: 'static -> &mut &'a int
} }
fn to_same_lifetime<'r>(bi: invariant<'r>) { fn to_same_lifetime<'r>(bi: invariant<'r>) {

View File

@ -14,12 +14,12 @@ struct direct<'a> {
struct indirect1 { struct indirect1 {
// Here the lifetime parameter of direct is bound by the fn() // Here the lifetime parameter of direct is bound by the fn()
g: 'static |direct| g: |direct|: 'static
} }
struct indirect2<'a> { struct indirect2<'a> {
// But here it is set to '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 fn take_direct(p: direct) -> direct { p } //~ ERROR mismatched types

View File

@ -9,10 +9,10 @@
// except according to those terms. // except according to those terms.
struct closure_box<'a> { 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} closure_box {cl: x}
} }

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub fn main() {
vec!(,); //~ ERROR unexpected token
}

View File

@ -26,7 +26,7 @@ struct WindowCallbacks<'a> {
pos_callback: Option<WindowPosCallback<'a>>, pos_callback: Option<WindowPosCallback<'a>>,
} }
pub type WindowPosCallback<'a> = 'a |&Window, i32, i32|; pub type WindowPosCallback<'a> = |&Window, i32, i32|: 'a;
fn main() { fn main() {
let x = WindowCallbacks { pos_callback: None }; let x = WindowCallbacks { pos_callback: None };

View File

@ -18,7 +18,7 @@ fn failfn() {
fn main() { fn main() {
let y = ~0; let y = ~0;
let x: @proc:Send() = @(proc() { let x: @proc():Send = @(proc() {
println!("{:?}", y.clone()); println!("{:?}", y.clone());
}); });
failfn(); failfn();

View File

@ -16,7 +16,7 @@ fn main() {
let cheese = ~"roquefort"; let cheese = ~"roquefort";
let carrots = @~"crunchy"; let carrots = @~"crunchy";
let result: 'static |@~str, |~str|| = (|tasties, macerate| { let result: |@~str, |~str||: 'static = (|tasties, macerate| {
macerate((*tasties).clone()); macerate((*tasties).clone());
}); });
result(carrots, |food| { result(carrots, |food| {

View File

@ -18,7 +18,7 @@ struct Pair {
pub fn main() { pub fn main() {
let z = ~Pair { a : 10, b : 12}; 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.a, 10);
assert_eq!(z.b, 12); assert_eq!(z.b, 12);
}; };

View File

@ -61,7 +61,7 @@ fn bar<'b>() {
foo::<proc<'a>(int, f32, &'a int):'static + Share -> &'a int>(); foo::<proc<'a>(int, f32, &'a int):'static + Share -> &'a int>();
// issue #11209 // issue #11209
let _: 'b ||; // for comparison let _: ||: 'b; // for comparison
let _: <'a> ||; let _: <'a> ||;
let _: Option<||:'b>; let _: Option<||:'b>;
@ -69,7 +69,7 @@ fn bar<'b>() {
let _: Option< <'a>||>; let _: Option< <'a>||>;
// issue #11210 // issue #11210
let _: 'static ||; let _: ||: 'static;
} }
pub fn main() { pub fn main() {

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub fn main() {
let x = *~();
}

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<json::Encoder<'a>,
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<writer::Encoder<'a, MemWriter>,
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)
}
}

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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());
}
}

View File

@ -9,5 +9,5 @@
// except according to those terms. // except according to those terms.
pub fn main() { pub fn main() {
let early_error: 'static |&str| -> ! = |_msg| { fail!() }; let early_error: |&str|: 'static -> ! = |_msg| { fail!() };
} }

View File

@ -12,13 +12,13 @@ use std::task;
static generations: uint = 1024+256+128+49; static generations: uint = 1024+256+128+49;
fn spawn(f: proc:Send()) { fn spawn(f: proc():Send) {
let mut t = task::task(); let mut t = task::task();
t.opts.stack_size = Some(32 * 1024); t.opts.stack_size = Some(32 * 1024);
t.spawn(f); t.spawn(f);
} }
fn child_no(x: uint) -> proc:Send() { fn child_no(x: uint) -> proc():Send {
proc() { proc() {
if x < generations { if x < generations {
spawn(child_no(x+1)); spawn(child_no(x+1));

View File

@ -11,7 +11,7 @@
use std::task; use std::task;
type RingBuffer = Vec<f64> ; type RingBuffer = Vec<f64> ;
type SamplesFn = proc:Send(samples: &RingBuffer); type SamplesFn = proc(samples: &RingBuffer):Send;
enum Msg enum Msg
{ {

View File

@ -12,10 +12,10 @@
struct A { a: ~int } struct A { a: ~int }
fn foo() -> 'static || -> int { fn foo() -> ||: 'static -> int {
let k = ~22; let k = ~22;
let _u = A {a: k.clone()}; let _u = A {a: k.clone()};
let result: 'static || -> int = || 22; let result: ||: 'static -> int = || 22;
result result
} }

View File

@ -17,18 +17,18 @@ fn is_static<T: 'static>() {}
pub fn main() { pub fn main() {
foo::<proc()>(); foo::<proc()>();
foo::<proc:()>(); foo::<proc()>();
foo::<proc:Send()>(); foo::<proc():Send>();
foo::<proc:Send + Share()>(); foo::<proc():Send + Share>();
foo::<proc:'static + Send + Share()>(); foo::<proc():'static + Send + Share>();
is_send::<proc:Send()>(); is_send::<proc():Send>();
is_freeze::<proc:Share()>(); is_freeze::<proc():Share>();
is_static::<proc:'static()>(); is_static::<proc():'static>();
let a = 3; let a = 3;
bar::<proc:()>(proc() { bar::<proc():>(proc() {
let b = &a; let b = &a;
println!("{}", *b); println!("{}", *b);
}); });

View File

@ -18,7 +18,7 @@ fn test05_start(f: proc(int)) {
fn test05() { fn test05() {
let three = ~3; 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 println!("{}", *three + n); // will copy x into the closure
assert_eq!(*three, 3); assert_eq!(*three, 3);
}; };

View File

@ -35,7 +35,7 @@ fn test_tempdir() {
fn test_rm_tempdir() { fn test_rm_tempdir() {
let (tx, rx) = channel(); let (tx, rx) = channel();
let f: proc:Send() = proc() { let f: proc():Send = proc() {
let tmp = TempDir::new("test_rm_tempdir").unwrap(); let tmp = TempDir::new("test_rm_tempdir").unwrap();
tx.send(tmp.path().clone()); tx.send(tmp.path().clone());
fail!("fail to unwind past `tmp`"); fail!("fail to unwind past `tmp`");
@ -46,7 +46,7 @@ fn test_rm_tempdir() {
let tmp = TempDir::new("test_rm_tempdir").unwrap(); let tmp = TempDir::new("test_rm_tempdir").unwrap();
let path = tmp.path().clone(); let path = tmp.path().clone();
let f: proc:Send() = proc() { let f: proc():Send = proc() {
let _tmp = tmp; let _tmp = tmp;
fail!("fail to unwind past `tmp`"); fail!("fail to unwind past `tmp`");
}; };

View File

@ -19,10 +19,10 @@ enum maybe_pointy {
struct Pointy { struct Pointy {
a : maybe_pointy, a : maybe_pointy,
d : proc:Send() -> uint, d : proc():Send -> uint,
} }
fn make_uniq_closure<A:Send>(a: A) -> proc:Send() -> uint { fn make_uniq_closure<A:Send>(a: A) -> proc():Send -> uint {
proc() { &a as *A as uint } proc() { &a as *A as uint }
} }

Some files were not shown because too many files have changed in this diff Show More