mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 01:34:21 +00:00
auto merge of #13397 : alexcrichton/rust/rollup, r=alexcrichton
This commit is contained in:
commit
02f51211ed
32
mk/dist.mk
32
mk/dist.mk
@ -203,19 +203,17 @@ distcheck-osx: dist-osx
|
||||
# Unix binary installer tarballs
|
||||
######################################################################
|
||||
|
||||
define DEF_INSTALLER
|
||||
define DEF_PREPARE_DIST_DIR
|
||||
|
||||
$$(eval $$(call DEF_PREPARE,dir-$(1)))
|
||||
|
||||
dist-install-dir-$(1): PREPARE_HOST=$(1)
|
||||
dist-install-dir-$(1): PREPARE_TARGETS=$(1)
|
||||
dist-install-dir-$(1): PREPARE_DEST_DIR=tmp/dist/$$(PKG_NAME)-$(1)
|
||||
dist-install-dir-$(1): PREPARE_DIR_CMD=$(DEFAULT_PREPARE_DIR_CMD)
|
||||
dist-install-dir-$(1): PREPARE_BIN_CMD=$(DEFAULT_PREPARE_BIN_CMD)
|
||||
dist-install-dir-$(1): PREPARE_LIB_CMD=$(DEFAULT_PREPARE_LIB_CMD)
|
||||
dist-install-dir-$(1): PREPARE_MAN_CMD=$(DEFAULT_PREPARE_MAN_CMD)
|
||||
dist-install-dir-$(1): PREPARE_CLEAN=true
|
||||
dist-install-dir-$(1): prepare-base-dir-$(1) docs compiler-docs
|
||||
dist-install-dir-$(1)$(3): PREPARE_HOST=$(1)
|
||||
dist-install-dir-$(1)$(3): PREPARE_TARGETS=$(2)
|
||||
dist-install-dir-$(1)$(3): PREPARE_DEST_DIR=tmp/dist/$$(PKG_NAME)-$(1)
|
||||
dist-install-dir-$(1)$(3): PREPARE_DIR_CMD=$(DEFAULT_PREPARE_DIR_CMD)
|
||||
dist-install-dir-$(1)$(3): PREPARE_BIN_CMD=$(DEFAULT_PREPARE_BIN_CMD)
|
||||
dist-install-dir-$(1)$(3): PREPARE_LIB_CMD=$(DEFAULT_PREPARE_LIB_CMD)
|
||||
dist-install-dir-$(1)$(3): PREPARE_MAN_CMD=$(DEFAULT_PREPARE_MAN_CMD)
|
||||
dist-install-dir-$(1)$(3): PREPARE_CLEAN=true
|
||||
dist-install-dir-$(1)$(3): prepare-base-dir-$(1) docs compiler-docs
|
||||
$$(Q)(cd $$(PREPARE_DEST_DIR)/ && find . -type f | sed 's/^\.\///') \
|
||||
> tmp/dist/manifest-$(1).in
|
||||
$$(Q)mv tmp/dist/manifest-$(1).in $$(PREPARE_DEST_DIR)/$$(CFG_LIBDIR_RELATIVE)/rustlib/manifest.in
|
||||
@ -227,6 +225,16 @@ dist-install-dir-$(1): prepare-base-dir-$(1) docs compiler-docs
|
||||
$$(Q)cp -r doc $$(PREPARE_DEST_DIR)
|
||||
$$(Q)$$(PREPARE_BIN_CMD) $$(S)src/etc/install.sh $$(PREPARE_DEST_DIR)
|
||||
|
||||
endef
|
||||
|
||||
define DEF_INSTALLER
|
||||
|
||||
$$(eval $$(call DEF_PREPARE,dir-$(1)))
|
||||
|
||||
$$(eval $$(call DEF_PREPARE_DIST_DIR,$(1),$(1),))
|
||||
|
||||
$$(eval $$(call DEF_PREPARE_DIST_DIR,$(1),$(CFG_TARGET),-with-target-libs))
|
||||
|
||||
dist/$$(PKG_NAME)-$(1).tar.gz: dist-install-dir-$(1)
|
||||
@$(call E, build: $$@)
|
||||
$$(Q)tar -czf dist/$$(PKG_NAME)-$(1).tar.gz -C tmp/dist $$(PKG_NAME)-$(1)
|
||||
|
@ -14,12 +14,12 @@ else
|
||||
MAYBE_DISABLE_VERIFY=
|
||||
endif
|
||||
|
||||
install: dist-install-dir-$(CFG_BUILD)
|
||||
install: dist-install-dir-$(CFG_BUILD)-with-target-libs
|
||||
$(Q)sh tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)" "$(MAYBE_DISABLE_VERIFY)"
|
||||
# Remove tmp files while we can because they may have been created under sudo
|
||||
$(Q)rm -R tmp/dist
|
||||
|
||||
uninstall: dist-install-dir-$(CFG_BUILD)
|
||||
uninstall: dist-install-dir-$(CFG_BUILD)-with-target-libs
|
||||
$(Q)sh tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --uninstall --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)"
|
||||
# Remove tmp files while we can because they may have been created under sudo
|
||||
$(Q)rm -R tmp/dist
|
||||
|
@ -152,7 +152,7 @@ struct Foo {
|
||||
}
|
||||
|
||||
struct FooClosure<'a> {
|
||||
myfunc: 'a |int, uint| -> i32
|
||||
myfunc: |int, uint|: 'a -> i32
|
||||
}
|
||||
|
||||
fn a(a: int, b: uint) -> i32 {
|
||||
|
@ -432,7 +432,7 @@ operators](#binary-operator-expressions), or [keywords](#keywords).
|
||||
## Paths
|
||||
|
||||
~~~~ {.notrust .ebnf .gram}
|
||||
expr_path : ident [ "::" expr_path_tail ] + ;
|
||||
expr_path : [ "::" ] ident [ "::" expr_path_tail ] + ;
|
||||
expr_path_tail : '<' type_expr [ ',' type_expr ] + '>'
|
||||
| expr_path ;
|
||||
|
||||
@ -475,6 +475,51 @@ let x = id::<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
|
||||
|
||||
A number of minor features of Rust are not central enough to have their own
|
||||
@ -3415,7 +3460,7 @@ fn add(x: int, y: int) -> int {
|
||||
|
||||
let mut x = add(5,7);
|
||||
|
||||
type Binop<'a> = 'a |int,int| -> int;
|
||||
type Binop<'a> = |int,int|: 'a -> int;
|
||||
let bo: Binop = add;
|
||||
x = bo(5,7);
|
||||
~~~~
|
||||
|
@ -65,10 +65,11 @@ try:
|
||||
check_tab = False
|
||||
if line.find(linelength_flag) != -1:
|
||||
check_linelength = False
|
||||
if line.find("// XXX") != -1:
|
||||
report_err("XXX is no longer necessary, use FIXME")
|
||||
if line.find("TODO") != -1:
|
||||
report_err("TODO is deprecated; use FIXME")
|
||||
match = re.match(r'^.*/(\*|/!?)\s*XXX', line)
|
||||
if match:
|
||||
report_err("XXX is no longer necessary, use FIXME")
|
||||
match = re.match(r'^.*//\s*(NOTE.*)$', line)
|
||||
if match:
|
||||
m = match.group(1)
|
||||
|
@ -96,7 +96,7 @@ pub mod bench {
|
||||
map.insert(*k, 1);
|
||||
}
|
||||
|
||||
rng.shuffle_mut(keys);
|
||||
rng.shuffle(keys);
|
||||
|
||||
// measure
|
||||
let mut i = 0;
|
||||
|
@ -54,43 +54,49 @@ static LZ_NORM : c_int = 0x80; // LZ with 128 probes, "normal"
|
||||
static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adler32 checksum
|
||||
static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum
|
||||
|
||||
fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> CVec<u8> {
|
||||
fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
|
||||
unsafe {
|
||||
let mut outsz : size_t = 0;
|
||||
let res = rustrt::tdefl_compress_mem_to_heap(bytes.as_ptr() as *c_void,
|
||||
bytes.len() as size_t,
|
||||
&mut outsz,
|
||||
flags);
|
||||
assert!(!res.is_null());
|
||||
CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res))
|
||||
if !res.is_null() {
|
||||
Some(CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deflate_bytes(bytes: &[u8]) -> CVec<u8> {
|
||||
pub fn deflate_bytes(bytes: &[u8]) -> Option<CVec<u8>> {
|
||||
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)
|
||||
}
|
||||
|
||||
fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> CVec<u8> {
|
||||
fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
|
||||
unsafe {
|
||||
let mut outsz : size_t = 0;
|
||||
let res = rustrt::tinfl_decompress_mem_to_heap(bytes.as_ptr() as *c_void,
|
||||
bytes.len() as size_t,
|
||||
&mut outsz,
|
||||
flags);
|
||||
assert!(!res.is_null());
|
||||
CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res))
|
||||
if !res.is_null() {
|
||||
Some(CVec::new_with_dtor(res as *mut u8, outsz as uint, proc() libc::free(res)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inflate_bytes(bytes: &[u8]) -> CVec<u8> {
|
||||
pub fn inflate_bytes(bytes: &[u8]) -> Option<CVec<u8>> {
|
||||
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)
|
||||
}
|
||||
|
||||
@ -117,8 +123,8 @@ mod tests {
|
||||
}
|
||||
debug!("de/inflate of {} bytes of random word-sequences",
|
||||
input.len());
|
||||
let cmp = deflate_bytes(input);
|
||||
let out = inflate_bytes(cmp.as_slice());
|
||||
let cmp = deflate_bytes(input).expect("deflation failed");
|
||||
let out = inflate_bytes(cmp.as_slice()).expect("inflation failed");
|
||||
debug!("{} bytes deflated to {} ({:.1f}% size)",
|
||||
input.len(), cmp.len(),
|
||||
100.0 * ((cmp.len() as f64) / (input.len() as f64)));
|
||||
@ -129,8 +135,8 @@ mod tests {
|
||||
#[test]
|
||||
fn test_zlib_flate() {
|
||||
let bytes = vec!(1, 2, 3, 4, 5);
|
||||
let deflated = deflate_bytes(bytes.as_slice());
|
||||
let inflated = inflate_bytes(deflated.as_slice());
|
||||
let deflated = deflate_bytes(bytes.as_slice()).expect("deflation failed");
|
||||
let inflated = inflate_bytes(deflated.as_slice()).expect("inflation failed");
|
||||
assert_eq!(inflated.as_slice(), bytes.as_slice());
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ pub fn event_loop() -> ~EventLoop:Send {
|
||||
}
|
||||
|
||||
struct BasicLoop {
|
||||
work: ~[proc:Send()], // pending work
|
||||
work: ~[proc():Send], // pending work
|
||||
idle: Option<*mut BasicPausable>, // only one is allowed
|
||||
remotes: ~[(uint, ~Callback:Send)],
|
||||
next_remote: uint,
|
||||
@ -135,7 +135,7 @@ impl EventLoop for BasicLoop {
|
||||
}
|
||||
}
|
||||
|
||||
fn callback(&mut self, f: proc:Send()) {
|
||||
fn callback(&mut self, f: proc():Send) {
|
||||
self.work.push(f);
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(globs)]
|
||||
#![crate_id = "libc#0.10-pre"]
|
||||
#![crate_id = "libc#0.11-pre"]
|
||||
#![experimental]
|
||||
#![no_std] // we don't need std, and we can't have std, since it doesn't exist
|
||||
// yet. std depends on us.
|
||||
@ -75,8 +75,6 @@
|
||||
#![allow(missing_doc)]
|
||||
#![allow(uppercase_variables)]
|
||||
|
||||
#![feature(link_args)] // NOTE: remove after stage0
|
||||
|
||||
#[cfg(test)] extern crate std;
|
||||
#[cfg(test)] extern crate test;
|
||||
#[cfg(test)] extern crate native;
|
||||
@ -199,11 +197,6 @@ pub use funcs::posix88::unistd::{rmdir, unlink, write};
|
||||
#[link(name = "m")]
|
||||
extern {}
|
||||
|
||||
// NOTE: remove this after a stage0 snap
|
||||
#[cfg(stage0, windows)]
|
||||
#[link_args = "-Wl,--enable-long-section-names"]
|
||||
extern {}
|
||||
|
||||
/// A wrapper for a nullable pointer. Don't use this except for interacting
|
||||
/// with libc. Basically Option, but without the dependance on libstd.
|
||||
// If/when libprim happens, this can be removed in favor of that
|
||||
|
0
src/libnative/io/p
Normal file
0
src/libnative/io/p
Normal file
@ -639,7 +639,7 @@ fn spawn_process_os(config: p::ProcessConfig,
|
||||
}
|
||||
|
||||
#[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;
|
||||
|
||||
// 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)]
|
||||
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;
|
||||
|
||||
// On posixy systems we can pass a char** for envp, which is a
|
||||
|
@ -50,13 +50,13 @@ fn ops() -> ~Ops {
|
||||
}
|
||||
|
||||
/// Spawns a function with the default configuration
|
||||
pub fn spawn(f: proc:Send()) {
|
||||
pub fn spawn(f: proc():Send) {
|
||||
spawn_opts(TaskOpts::new(), f)
|
||||
}
|
||||
|
||||
/// Spawns a new task given the configuration options and a procedure to run
|
||||
/// inside the task.
|
||||
pub fn spawn_opts(opts: TaskOpts, f: proc:Send()) {
|
||||
pub fn spawn_opts(opts: TaskOpts, f: proc():Send) {
|
||||
let TaskOpts {
|
||||
notify_chan, name, stack_size,
|
||||
stderr, stdout,
|
||||
@ -238,7 +238,7 @@ impl rt::Runtime for Ops {
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_sibling(~self, mut cur_task: ~Task, opts: TaskOpts, f: proc:Send()) {
|
||||
fn spawn_sibling(~self, mut cur_task: ~Task, opts: TaskOpts, f: proc():Send) {
|
||||
cur_task.put_runtime(self);
|
||||
Local::put(cur_task);
|
||||
|
||||
|
@ -209,8 +209,8 @@ fn ziggurat<R:Rng>(
|
||||
symmetric: bool,
|
||||
x_tab: ziggurat_tables::ZigTable,
|
||||
f_tab: ziggurat_tables::ZigTable,
|
||||
pdf: 'static |f64| -> f64,
|
||||
zero_case: 'static |&mut R, f64| -> f64)
|
||||
pdf: |f64|: 'static -> f64,
|
||||
zero_case: |&mut R, f64|: 'static -> f64)
|
||||
-> f64 {
|
||||
static SCALE: f64 = (1u64 << 53) as f64;
|
||||
loop {
|
||||
|
@ -801,7 +801,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_shuffle() {
|
||||
let mut r = task_rng();
|
||||
let mut empty: &mut [int] = &mut [];
|
||||
let empty: &mut [int] = &mut [];
|
||||
r.shuffle(empty);
|
||||
let mut one = [1];
|
||||
r.shuffle(one);
|
||||
|
@ -945,11 +945,14 @@ fn link_rlib<'a>(sess: &'a Session,
|
||||
let bc_deflated = obj_filename.with_extension("bc.deflate");
|
||||
match fs::File::open(&bc).read_to_end().and_then(|data| {
|
||||
fs::File::create(&bc_deflated)
|
||||
.write(flate::deflate_bytes(data.as_slice()).as_slice())
|
||||
.write(match flate::deflate_bytes(data.as_slice()) {
|
||||
Some(compressed) => compressed,
|
||||
None => sess.fatal("failed to compress bytecode")
|
||||
}.as_slice())
|
||||
}) {
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
sess.err(format!("failed to compress bytecode: {}", e));
|
||||
sess.err(format!("failed to write compressed bytecode: {}", e));
|
||||
sess.abort_if_errors()
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,10 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
|
||||
archive.read(format!("{}.bc.deflate", name)));
|
||||
let bc = bc.expect("missing compressed bytecode in archive!");
|
||||
let bc = time(sess.time_passes(), format!("inflate {}.bc", name), (), |_|
|
||||
flate::inflate_bytes(bc));
|
||||
match flate::inflate_bytes(bc) {
|
||||
Some(bc) => bc,
|
||||
None => sess.fatal(format!("failed to decompress bc of `{}`", name))
|
||||
});
|
||||
let ptr = bc.as_slice().as_ptr();
|
||||
debug!("linking {}", name);
|
||||
time(sess.time_passes(), format!("ll link {}", name), (), |()| unsafe {
|
||||
|
@ -241,8 +241,6 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
||||
cfg,
|
||||
krate)
|
||||
});
|
||||
// dump the syntax-time crates
|
||||
sess.cstore.reset();
|
||||
|
||||
// strip again, in case expansion added anything with a #[cfg].
|
||||
krate = time(time_passes, "configuration 2", krate, |krate|
|
||||
|
@ -13,7 +13,7 @@ use syntax::{ast, fold, attr};
|
||||
use syntax::codemap;
|
||||
|
||||
struct Context<'a> {
|
||||
in_cfg: 'a |attrs: &[ast::Attribute]| -> bool,
|
||||
in_cfg: |attrs: &[ast::Attribute]|: 'a -> bool,
|
||||
}
|
||||
|
||||
// Support conditional compilation by transforming the AST, stripping out
|
||||
|
@ -364,7 +364,7 @@ fn parse_crate_attrs(sess: &session::Session, input: &d::Input) ->
|
||||
///
|
||||
/// The diagnostic emitter yielded to the procedure should be used for reporting
|
||||
/// errors of the compiler.
|
||||
pub fn monitor(f: proc:Send()) {
|
||||
pub fn monitor(f: proc():Send) {
|
||||
// FIXME: This is a hack for newsched since it doesn't support split stacks.
|
||||
// rustc needs a lot of stack! When optimizations are disabled, it needs
|
||||
// even *more* stack than usual as well.
|
||||
|
@ -18,6 +18,7 @@ use driver::{driver, session};
|
||||
use driver::session::Session;
|
||||
use metadata::csearch;
|
||||
use metadata::cstore;
|
||||
use metadata::cstore::CStore;
|
||||
use metadata::decoder;
|
||||
use metadata::loader;
|
||||
use metadata::loader::Os;
|
||||
@ -38,6 +39,13 @@ use syntax::parse::token;
|
||||
use syntax::crateid::CrateId;
|
||||
use syntax::visit;
|
||||
|
||||
struct Env<'a> {
|
||||
sess: &'a Session,
|
||||
os: loader::Os,
|
||||
next_crate_num: ast::CrateNum,
|
||||
intr: Rc<IdentInterner>
|
||||
}
|
||||
|
||||
// Traverses an AST, reading all the information about use'd crates and extern
|
||||
// libraries necessary for later resolving, typechecking, linking, etc.
|
||||
pub fn read_crates(sess: &Session,
|
||||
@ -47,16 +55,13 @@ pub fn read_crates(sess: &Session,
|
||||
let mut e = Env {
|
||||
sess: sess,
|
||||
os: os,
|
||||
crate_cache: @RefCell::new(Vec::new()),
|
||||
next_crate_num: 1,
|
||||
next_crate_num: sess.cstore.next_crate_num(),
|
||||
intr: intr
|
||||
};
|
||||
visit_crate(&e, krate);
|
||||
visit::walk_crate(&mut e, krate, ());
|
||||
dump_crates(e.crate_cache.borrow().as_slice());
|
||||
warn_if_multiple_versions(&mut e,
|
||||
sess.diagnostic(),
|
||||
e.crate_cache.borrow().as_slice());
|
||||
dump_crates(&sess.cstore);
|
||||
warn_if_multiple_versions(sess.diagnostic(), &sess.cstore)
|
||||
}
|
||||
|
||||
impl<'a> visit::Visitor<()> for Env<'a> {
|
||||
@ -70,55 +75,36 @@ impl<'a> visit::Visitor<()> for Env<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
struct cache_entry {
|
||||
cnum: ast::CrateNum,
|
||||
span: Span,
|
||||
hash: Svh,
|
||||
crate_id: CrateId,
|
||||
}
|
||||
|
||||
fn dump_crates(crate_cache: &[cache_entry]) {
|
||||
fn dump_crates(cstore: &CStore) {
|
||||
debug!("resolved crates:");
|
||||
for entry in crate_cache.iter() {
|
||||
debug!("cnum: {:?}", entry.cnum);
|
||||
debug!("span: {:?}", entry.span);
|
||||
debug!("hash: {:?}", entry.hash);
|
||||
}
|
||||
cstore.iter_crate_data(|_, data| {
|
||||
debug!("crate_id: {}", data.crate_id());
|
||||
debug!(" cnum: {}", data.cnum);
|
||||
debug!(" hash: {}", data.hash());
|
||||
})
|
||||
}
|
||||
|
||||
fn warn_if_multiple_versions(e: &mut Env,
|
||||
diag: &SpanHandler,
|
||||
crate_cache: &[cache_entry]) {
|
||||
if crate_cache.len() != 0u {
|
||||
let name = crate_cache[crate_cache.len() - 1].crate_id.name.clone();
|
||||
fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) {
|
||||
let mut map = HashMap::new();
|
||||
|
||||
let (matches, non_matches) = crate_cache.partitioned(|entry|
|
||||
name == entry.crate_id.name);
|
||||
cstore.iter_crate_data(|cnum, data| {
|
||||
let crateid = data.crate_id();
|
||||
let key = (crateid.name.clone(), crateid.path.clone());
|
||||
map.find_or_insert_with(key, |_| Vec::new()).push(cnum);
|
||||
});
|
||||
|
||||
assert!(!matches.is_empty());
|
||||
|
||||
if matches.len() != 1u {
|
||||
diag.handler().warn(
|
||||
format!("using multiple versions of crate `{}`", name));
|
||||
for match_ in matches.iter() {
|
||||
diag.span_note(match_.span, "used here");
|
||||
loader::note_crateid_attr(diag, &match_.crate_id);
|
||||
}
|
||||
for ((name, _), dupes) in map.move_iter() {
|
||||
if dupes.len() == 1 { continue }
|
||||
diag.handler().warn(
|
||||
format!("using multiple versions of crate `{}`", name));
|
||||
for dupe in dupes.move_iter() {
|
||||
let data = cstore.get_crate_data(dupe);
|
||||
diag.span_note(data.span, "used here");
|
||||
loader::note_crateid_attr(diag, &data.crate_id());
|
||||
}
|
||||
|
||||
warn_if_multiple_versions(e, diag, non_matches);
|
||||
}
|
||||
}
|
||||
|
||||
struct Env<'a> {
|
||||
sess: &'a Session,
|
||||
os: loader::Os,
|
||||
crate_cache: @RefCell<Vec<cache_entry>>,
|
||||
next_crate_num: ast::CrateNum,
|
||||
intr: Rc<IdentInterner>
|
||||
}
|
||||
|
||||
fn visit_crate(e: &Env, c: &ast::Crate) {
|
||||
for a in c.attrs.iter().filter(|m| m.name().equiv(&("link_args"))) {
|
||||
match a.value_str() {
|
||||
@ -128,22 +114,25 @@ fn visit_crate(e: &Env, c: &ast::Crate) {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
|
||||
let should_load = i.attrs.iter().all(|attr| {
|
||||
fn should_link(i: &ast::ViewItem) -> bool {
|
||||
i.attrs.iter().all(|attr| {
|
||||
attr.name().get() != "phase" ||
|
||||
attr.meta_item_list().map_or(false, |phases| {
|
||||
attr::contains_name(phases.as_slice(), "link")
|
||||
})
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
if !should_load {
|
||||
fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
|
||||
if !should_link(i) {
|
||||
return;
|
||||
}
|
||||
|
||||
match extract_crate_info(e, i) {
|
||||
Some(info) => {
|
||||
let cnum = resolve_crate(e, &None, info.ident, &info.crate_id, None,
|
||||
i.span);
|
||||
let (cnum, _, _) = resolve_crate(e, &None, info.ident,
|
||||
&info.crate_id, None, true,
|
||||
i.span);
|
||||
e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
|
||||
}
|
||||
None => ()
|
||||
@ -154,6 +143,7 @@ struct CrateInfo {
|
||||
ident: ~str,
|
||||
crate_id: CrateId,
|
||||
id: ast::NodeId,
|
||||
should_link: bool,
|
||||
}
|
||||
|
||||
fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
|
||||
@ -179,6 +169,7 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
|
||||
ident: ident.get().to_str(),
|
||||
crate_id: crate_id,
|
||||
id: id,
|
||||
should_link: should_link(i),
|
||||
})
|
||||
}
|
||||
_ => None
|
||||
@ -269,14 +260,18 @@ fn visit_item(e: &Env, i: &ast::Item) {
|
||||
|
||||
fn existing_match(e: &Env, crate_id: &CrateId,
|
||||
hash: Option<&Svh>) -> Option<ast::CrateNum> {
|
||||
for c in e.crate_cache.borrow().iter() {
|
||||
if !crate_id.matches(&c.crate_id) { continue }
|
||||
match hash {
|
||||
Some(hash) if *hash != c.hash => {}
|
||||
Some(..) | None => return Some(c.cnum)
|
||||
let mut ret = None;
|
||||
e.sess.cstore.iter_crate_data(|cnum, data| {
|
||||
let other_id = data.crate_id();
|
||||
if crate_id.matches(&other_id) {
|
||||
let other_hash = data.hash();
|
||||
match hash {
|
||||
Some(hash) if *hash != other_hash => {}
|
||||
Some(..) | None => { ret = Some(cnum); }
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
fn resolve_crate<'a>(e: &mut Env,
|
||||
@ -284,8 +279,10 @@ fn resolve_crate<'a>(e: &mut Env,
|
||||
ident: &str,
|
||||
crate_id: &CrateId,
|
||||
hash: Option<&Svh>,
|
||||
should_link: bool,
|
||||
span: Span)
|
||||
-> ast::CrateNum {
|
||||
-> (ast::CrateNum, @cstore::crate_metadata,
|
||||
cstore::CrateSource) {
|
||||
match existing_match(e, crate_id, hash) {
|
||||
None => {
|
||||
let id_hash = link::crate_id_hash(crate_id);
|
||||
@ -304,17 +301,8 @@ fn resolve_crate<'a>(e: &mut Env,
|
||||
dylib, rlib, metadata
|
||||
} = load_ctxt.load_library_crate(root);
|
||||
|
||||
let crate_id = decoder::get_crate_id(metadata.as_slice());
|
||||
let hash = decoder::get_crate_hash(metadata.as_slice());
|
||||
|
||||
// Claim this crate number and cache it
|
||||
let cnum = e.next_crate_num;
|
||||
e.crate_cache.borrow_mut().push(cache_entry {
|
||||
cnum: cnum,
|
||||
span: span,
|
||||
hash: hash,
|
||||
crate_id: crate_id,
|
||||
});
|
||||
e.next_crate_num += 1;
|
||||
|
||||
// Stash paths for top-most crate locally if necessary.
|
||||
@ -331,27 +319,35 @@ fn resolve_crate<'a>(e: &mut Env,
|
||||
let root = if root.is_some() { root } else { &crate_paths };
|
||||
|
||||
// Now resolve the crates referenced by this crate
|
||||
let cnum_map = resolve_crate_deps(e,
|
||||
root,
|
||||
metadata.as_slice(),
|
||||
span);
|
||||
let cnum_map = if should_link {
|
||||
resolve_crate_deps(e, root, metadata.as_slice(), span)
|
||||
} else {
|
||||
@RefCell::new(HashMap::new())
|
||||
};
|
||||
|
||||
let cmeta = @cstore::crate_metadata {
|
||||
name: load_ctxt.crate_id.name.to_owned(),
|
||||
data: metadata,
|
||||
cnum_map: cnum_map,
|
||||
cnum: cnum
|
||||
cnum: cnum,
|
||||
span: span,
|
||||
};
|
||||
|
||||
e.sess.cstore.set_crate_data(cnum, cmeta);
|
||||
e.sess.cstore.add_used_crate_source(cstore::CrateSource {
|
||||
let source = cstore::CrateSource {
|
||||
dylib: dylib,
|
||||
rlib: rlib,
|
||||
cnum: cnum,
|
||||
});
|
||||
cnum
|
||||
};
|
||||
|
||||
if should_link {
|
||||
e.sess.cstore.set_crate_data(cnum, cmeta);
|
||||
e.sess.cstore.add_used_crate_source(source.clone());
|
||||
}
|
||||
(cnum, cmeta, source)
|
||||
}
|
||||
Some(cnum) => cnum
|
||||
Some(cnum) => (cnum,
|
||||
e.sess.cstore.get_crate_data(cnum),
|
||||
e.sess.cstore.get_used_crate_source(cnum).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
@ -368,11 +364,12 @@ fn resolve_crate_deps(e: &mut Env,
|
||||
for dep in r.iter() {
|
||||
let extrn_cnum = dep.cnum;
|
||||
debug!("resolving dep crate {} hash: `{}`", dep.crate_id, dep.hash);
|
||||
let local_cnum = resolve_crate(e, root,
|
||||
dep.crate_id.name.as_slice(),
|
||||
&dep.crate_id,
|
||||
Some(&dep.hash),
|
||||
span);
|
||||
let (local_cnum, _, _) = resolve_crate(e, root,
|
||||
dep.crate_id.name.as_slice(),
|
||||
&dep.crate_id,
|
||||
Some(&dep.hash),
|
||||
true,
|
||||
span);
|
||||
cnum_map.insert(extrn_cnum, local_cnum);
|
||||
}
|
||||
return @RefCell::new(cnum_map);
|
||||
@ -390,8 +387,7 @@ impl<'a> Loader<'a> {
|
||||
env: Env {
|
||||
sess: sess,
|
||||
os: os,
|
||||
crate_cache: @RefCell::new(Vec::new()),
|
||||
next_crate_num: 1,
|
||||
next_crate_num: sess.cstore.next_crate_num(),
|
||||
intr: token::get_ident_interner(),
|
||||
}
|
||||
}
|
||||
@ -401,23 +397,17 @@ impl<'a> Loader<'a> {
|
||||
impl<'a> CrateLoader for Loader<'a> {
|
||||
fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate {
|
||||
let info = extract_crate_info(&self.env, krate).unwrap();
|
||||
let cnum = resolve_crate(&mut self.env, &None, info.ident,
|
||||
&info.crate_id, None, krate.span);
|
||||
let library = self.env.sess.cstore.get_used_crate_source(cnum).unwrap();
|
||||
let (cnum, data, library) = resolve_crate(&mut self.env, &None,
|
||||
info.ident, &info.crate_id,
|
||||
None, true, krate.span);
|
||||
let macros = decoder::get_exported_macros(data);
|
||||
let cstore = &self.env.sess.cstore;
|
||||
let registrar = csearch::get_macro_registrar_fn(cstore, cnum)
|
||||
.map(|did| csearch::get_symbol(cstore, did));
|
||||
MacroCrate {
|
||||
lib: library.dylib,
|
||||
cnum: cnum
|
||||
macros: macros.move_iter().collect(),
|
||||
registrar_symbol: registrar,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_exported_macros(&mut self, cnum: ast::CrateNum) -> Vec<~str> {
|
||||
csearch::get_exported_macros(&self.env.sess.cstore, cnum).move_iter()
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn get_registrar_symbol(&mut self, cnum: ast::CrateNum) -> Option<~str> {
|
||||
let cstore = &self.env.sess.cstore;
|
||||
csearch::get_macro_registrar_fn(cstore, cnum)
|
||||
.map(|did| csearch::get_symbol(cstore, did))
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ use std::c_vec::CVec;
|
||||
use std::rc::Rc;
|
||||
use collections::HashMap;
|
||||
use syntax::ast;
|
||||
use syntax::crateid::CrateId;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token::IdentInterner;
|
||||
|
||||
// A map from external crate numbers (as decoded from some crate file) to
|
||||
@ -40,6 +42,7 @@ pub struct crate_metadata {
|
||||
pub data: MetadataBlob,
|
||||
pub cnum_map: cnum_map,
|
||||
pub cnum: ast::CrateNum,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[deriving(Eq)]
|
||||
@ -88,6 +91,10 @@ impl CStore {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next_crate_num(&self) -> ast::CrateNum {
|
||||
self.metas.borrow().len() as ast::CrateNum + 1
|
||||
}
|
||||
|
||||
pub fn get_crate_data(&self, cnum: ast::CrateNum) -> @crate_metadata {
|
||||
*self.metas.borrow().get(&cnum)
|
||||
}
|
||||
@ -121,6 +128,9 @@ impl CStore {
|
||||
.map(|source| source.clone())
|
||||
}
|
||||
|
||||
pub fn dump_phase_syntax_crates(&self) {
|
||||
}
|
||||
|
||||
pub fn reset(&self) {
|
||||
self.metas.borrow_mut().clear();
|
||||
self.extern_mod_crate_map.borrow_mut().clear();
|
||||
@ -202,6 +212,8 @@ impl CStore {
|
||||
|
||||
impl crate_metadata {
|
||||
pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() }
|
||||
pub fn crate_id(&self) -> CrateId { decoder::get_crate_id(self.data()) }
|
||||
pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) }
|
||||
}
|
||||
|
||||
impl MetadataBlob {
|
||||
|
@ -76,7 +76,7 @@ fn lookup_hash<'a>(d: ebml::Doc<'a>, eq_fn: |&[u8]| -> bool,
|
||||
ret
|
||||
}
|
||||
|
||||
pub type GetCrateDataCb<'a> = 'a |ast::CrateNum| -> Cmd;
|
||||
pub type GetCrateDataCb<'a> = |ast::CrateNum|: 'a -> Cmd;
|
||||
|
||||
pub fn maybe_find_item<'a>(item_id: ast::NodeId,
|
||||
items: ebml::Doc<'a>) -> Option<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()))
|
||||
}
|
||||
|
||||
pub type DecodeInlinedItem<'a> = 'a |cdata: @cstore::crate_metadata,
|
||||
tcx: &ty::ctxt,
|
||||
path: Vec<ast_map::PathElem>,
|
||||
par_doc: ebml::Doc|
|
||||
-> Result<ast::InlinedItem, Vec<ast_map::PathElem> >;
|
||||
pub type DecodeInlinedItem<'a> = |cdata: @cstore::crate_metadata,
|
||||
tcx: &ty::ctxt,
|
||||
path: Vec<ast_map::PathElem>,
|
||||
par_doc: ebml::Doc|: 'a
|
||||
-> Result<ast::InlinedItem, Vec<ast_map::PathElem> >;
|
||||
|
||||
pub fn maybe_get_item_ast(cdata: Cmd, tcx: &ty::ctxt, id: ast::NodeId,
|
||||
decode_inlined_item: DecodeInlinedItem)
|
||||
|
@ -64,9 +64,9 @@ pub enum InlinedItemRef<'a> {
|
||||
|
||||
pub type Encoder<'a> = writer::Encoder<'a, MemWriter>;
|
||||
|
||||
pub type EncodeInlinedItem<'a> = 'a |ecx: &EncodeContext,
|
||||
ebml_w: &mut Encoder,
|
||||
ii: InlinedItemRef|;
|
||||
pub type EncodeInlinedItem<'a> = |ecx: &EncodeContext,
|
||||
ebml_w: &mut Encoder,
|
||||
ii: InlinedItemRef|: 'a;
|
||||
|
||||
pub struct EncodeParams<'a> {
|
||||
pub diag: &'a SpanHandler,
|
||||
|
@ -23,7 +23,7 @@ pub enum FileMatch { FileMatches, FileDoesntMatch }
|
||||
|
||||
/// Functions with type `pick` take a parent directory as well as
|
||||
/// a file found in that directory.
|
||||
pub type pick<'a> = 'a |path: &Path| -> FileMatch;
|
||||
pub type pick<'a> = |path: &Path|: 'a -> FileMatch;
|
||||
|
||||
pub struct FileSearch<'a> {
|
||||
pub sysroot: &'a Path,
|
||||
|
@ -317,15 +317,23 @@ impl<'a> Context<'a> {
|
||||
// read the metadata from it if `*slot` is `None`. If the metadata couldn't
|
||||
// be read, it is assumed that the file isn't a valid rust library (no
|
||||
// errors are emitted).
|
||||
//
|
||||
// FIXME(#10786): for an optimization, we only read one of the library's
|
||||
// metadata sections. In theory we should read both, but
|
||||
// reading dylib metadata is quite slow.
|
||||
fn extract_one(&mut self, m: HashSet<Path>, flavor: &str,
|
||||
slot: &mut Option<MetadataBlob>) -> Option<Path> {
|
||||
let mut ret = None::<Path>;
|
||||
let mut error = 0;
|
||||
|
||||
if slot.is_some() {
|
||||
// FIXME(#10786): for an optimization, we only read one of the
|
||||
// library's metadata sections. In theory we should
|
||||
// read both, but reading dylib metadata is quite
|
||||
// slow.
|
||||
if m.len() == 0 {
|
||||
return None
|
||||
} else if m.len() == 1 {
|
||||
return Some(m.move_iter().next().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
for lib in m.move_iter() {
|
||||
info!("{} reading metadata from: {}", flavor, lib.display());
|
||||
let metadata = match get_metadata_section(self.os, &lib) {
|
||||
@ -494,14 +502,17 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Result<MetadataBlob, ~st
|
||||
let version_ok = slice::raw::buf_as_slice(cvbuf, minsz,
|
||||
|buf0| buf0 == encoder::metadata_encoding_version);
|
||||
if !version_ok { return Err(format!("incompatible metadata version found: '{}'",
|
||||
filename.display()));}
|
||||
filename.display())); }
|
||||
|
||||
let cvbuf1 = cvbuf.offset(vlen as int);
|
||||
debug!("inflating {} bytes of compressed metadata",
|
||||
csz - vlen);
|
||||
slice::raw::buf_as_slice(cvbuf1, csz-vlen, |bytes| {
|
||||
let inflated = flate::inflate_bytes(bytes);
|
||||
found = Ok(MetadataVec(inflated));
|
||||
match flate::inflate_bytes(bytes) {
|
||||
Some(inflated) => found = Ok(MetadataVec(inflated)),
|
||||
None => found = Err(format!("failed to decompress metadata for: '{}'",
|
||||
filename.display()))
|
||||
}
|
||||
});
|
||||
if found.is_ok() {
|
||||
return found;
|
||||
|
@ -54,7 +54,7 @@ pub enum DefIdSource {
|
||||
RegionParameter,
|
||||
}
|
||||
pub type conv_did<'a> =
|
||||
'a |source: DefIdSource, ast::DefId| -> ast::DefId;
|
||||
|source: DefIdSource, ast::DefId|: 'a -> ast::DefId;
|
||||
|
||||
pub struct PState<'a> {
|
||||
data: &'a [u8],
|
||||
|
@ -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>(
|
||||
bcx: &'b Block<'b>,
|
||||
|
@ -613,7 +613,7 @@ pub fn compare_scalar_values<'a>(
|
||||
}
|
||||
|
||||
pub type val_and_ty_fn<'r,'b> =
|
||||
'r |&'b Block<'b>, ValueRef, ty::t| -> &'b Block<'b>;
|
||||
|&'b Block<'b>, ValueRef, ty::t|: 'r -> &'b Block<'b>;
|
||||
|
||||
// Iterates through the elements of a structural type.
|
||||
pub fn iter_structural_ty<'r,
|
||||
@ -2236,7 +2236,10 @@ pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec<u8> {
|
||||
let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item);
|
||||
let metadata = encoder::encode_metadata(encode_parms, krate);
|
||||
let compressed = encoder::metadata_encoding_version +
|
||||
flate::deflate_bytes(metadata.as_slice()).as_slice();
|
||||
match flate::deflate_bytes(metadata.as_slice()) {
|
||||
Some(compressed) => compressed,
|
||||
None => cx.sess().fatal(format!("failed to compress metadata", ))
|
||||
}.as_slice();
|
||||
let llmeta = C_bytes(cx, compressed);
|
||||
let llconst = C_struct(cx, [llmeta], false);
|
||||
let name = format!("rust_metadata_{}_{}_{}", cx.link_meta.crateid.name,
|
||||
|
@ -1802,11 +1802,15 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
|
||||
RvalueExpr(Rvalue { mode: ByRef }) => {
|
||||
let scope = cleanup::temporary_scope(bcx.tcx(), expr.id);
|
||||
let ptr = Load(bcx, datum.val);
|
||||
bcx.fcx.schedule_free_value(scope, ptr, cleanup::HeapExchange);
|
||||
if !type_is_zero_size(bcx.ccx(), content_ty) {
|
||||
bcx.fcx.schedule_free_value(scope, ptr, cleanup::HeapExchange);
|
||||
}
|
||||
}
|
||||
RvalueExpr(Rvalue { mode: ByValue }) => {
|
||||
let scope = cleanup::temporary_scope(bcx.tcx(), expr.id);
|
||||
bcx.fcx.schedule_free_value(scope, datum.val, cleanup::HeapExchange);
|
||||
if !type_is_zero_size(bcx.ccx(), content_ty) {
|
||||
bcx.fcx.schedule_free_value(scope, datum.val, cleanup::HeapExchange);
|
||||
}
|
||||
}
|
||||
LvalueExpr => { }
|
||||
}
|
||||
|
@ -525,7 +525,7 @@ pub fn get_base_and_len(bcx: &Block,
|
||||
}
|
||||
|
||||
pub type iter_vec_block<'r,'b> =
|
||||
'r |&'b Block<'b>, ValueRef, ty::t| -> &'b Block<'b>;
|
||||
|&'b Block<'b>, ValueRef, ty::t|: 'r -> &'b Block<'b>;
|
||||
|
||||
pub fn iter_vec_loop<'r,
|
||||
'b>(
|
||||
|
@ -217,7 +217,7 @@ pub fn super_fold_trait_store<T:TypeFolder>(this: &mut T,
|
||||
|
||||
pub struct BottomUpFolder<'a> {
|
||||
pub tcx: &'a ty::ctxt,
|
||||
pub fldop: 'a |ty::t| -> ty::t,
|
||||
pub fldop: |ty::t|: 'a -> ty::t,
|
||||
}
|
||||
|
||||
impl<'a> TypeFolder for BottomUpFolder<'a> {
|
||||
@ -234,14 +234,14 @@ impl<'a> TypeFolder for BottomUpFolder<'a> {
|
||||
|
||||
pub struct RegionFolder<'a> {
|
||||
tcx: &'a ty::ctxt,
|
||||
fld_t: 'a |ty::t| -> ty::t,
|
||||
fld_r: 'a |ty::Region| -> ty::Region,
|
||||
fld_t: |ty::t|: 'a -> ty::t,
|
||||
fld_r: |ty::Region|: 'a -> ty::Region,
|
||||
}
|
||||
|
||||
impl<'a> RegionFolder<'a> {
|
||||
pub fn general(tcx: &'a ty::ctxt,
|
||||
fld_r: 'a |ty::Region| -> ty::Region,
|
||||
fld_t: 'a |ty::t| -> ty::t)
|
||||
fld_r: |ty::Region|: 'a -> ty::Region,
|
||||
fld_t: |ty::t|: 'a -> ty::t)
|
||||
-> RegionFolder<'a> {
|
||||
RegionFolder {
|
||||
tcx: tcx,
|
||||
@ -250,7 +250,7 @@ impl<'a> RegionFolder<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn regions(tcx: &'a ty::ctxt, fld_r: 'a |ty::Region| -> ty::Region)
|
||||
pub fn regions(tcx: &'a ty::ctxt, fld_r: |ty::Region|: 'a -> ty::Region)
|
||||
-> RegionFolder<'a> {
|
||||
fn noop(t: ty::t) -> ty::t { t }
|
||||
|
||||
|
@ -86,7 +86,7 @@ pub fn relate_nested_regions(tcx: &ty::ctxt,
|
||||
struct RegionRelator<'a> {
|
||||
tcx: &'a ty::ctxt,
|
||||
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
|
||||
|
@ -54,7 +54,7 @@ pub trait LatticeValue {
|
||||
}
|
||||
|
||||
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 {
|
||||
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)]
|
||||
pub enum LatticeVarResult<V,T> {
|
||||
|
@ -64,7 +64,7 @@ pub fn indenter() -> _indenter {
|
||||
}
|
||||
|
||||
struct LoopQueryVisitor<'a> {
|
||||
p: 'a |&ast::Expr_| -> bool,
|
||||
p: |&ast::Expr_|: 'a -> bool,
|
||||
flag: bool,
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ pub fn loop_query(b: &ast::Block, p: |&ast::Expr_| -> bool) -> bool {
|
||||
}
|
||||
|
||||
struct BlockQueryVisitor<'a> {
|
||||
p: 'a |&ast::Expr| -> bool,
|
||||
p: |&ast::Expr|: 'a -> bool,
|
||||
flag: bool,
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ impl Drop for Addrinfo {
|
||||
}
|
||||
|
||||
fn each_ai_flag(_f: |c_int, ai::Flag|) {
|
||||
/* XXX: do we really want to support these?
|
||||
/* FIXME: do we really want to support these?
|
||||
unsafe {
|
||||
f(uvll::rust_AI_ADDRCONFIG(), ai::AddrConfig);
|
||||
f(uvll::rust_AI_ALL(), ai::All);
|
||||
@ -150,7 +150,7 @@ pub fn accum_addrinfo(addr: &Addrinfo) -> ~[ai::Info] {
|
||||
}
|
||||
});
|
||||
|
||||
/* XXX: do we really want to support these
|
||||
/* FIXME: do we really want to support these
|
||||
let protocol = match (*addr).ai_protocol {
|
||||
p if p == uvll::rust_IPPROTO_UDP() => Some(ai::UDP),
|
||||
p if p == uvll::rust_IPPROTO_TCP() => Some(ai::TCP),
|
||||
|
@ -46,7 +46,7 @@ use raw;
|
||||
pub struct CVec<T> {
|
||||
base: *mut T,
|
||||
len: uint,
|
||||
dtor: Option<proc:Send()>,
|
||||
dtor: Option<proc():Send>,
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
@ -90,7 +90,7 @@ impl<T> CVec<T> {
|
||||
/// * dtor - A proc to run when the value is destructed, useful
|
||||
/// for freeing the buffer, etc.
|
||||
pub unsafe fn new_with_dtor(base: *mut T, len: uint,
|
||||
dtor: proc:Send()) -> CVec<T> {
|
||||
dtor: proc():Send) -> CVec<T> {
|
||||
assert!(base != ptr::mut_null());
|
||||
CVec {
|
||||
base: base,
|
||||
|
@ -632,28 +632,28 @@ pub trait Reader {
|
||||
|
||||
/// Reads a little-endian unsigned integer.
|
||||
///
|
||||
/// The number of bytes returned is system-dependant.
|
||||
/// The number of bytes returned is system-dependent.
|
||||
fn read_le_uint(&mut self) -> IoResult<uint> {
|
||||
self.read_le_uint_n(uint::BYTES).map(|i| i as uint)
|
||||
}
|
||||
|
||||
/// Reads a little-endian integer.
|
||||
///
|
||||
/// The number of bytes returned is system-dependant.
|
||||
/// The number of bytes returned is system-dependent.
|
||||
fn read_le_int(&mut self) -> IoResult<int> {
|
||||
self.read_le_int_n(int::BYTES).map(|i| i as int)
|
||||
}
|
||||
|
||||
/// Reads a big-endian unsigned integer.
|
||||
///
|
||||
/// The number of bytes returned is system-dependant.
|
||||
/// The number of bytes returned is system-dependent.
|
||||
fn read_be_uint(&mut self) -> IoResult<uint> {
|
||||
self.read_be_uint_n(uint::BYTES).map(|i| i as uint)
|
||||
}
|
||||
|
||||
/// Reads a big-endian integer.
|
||||
///
|
||||
/// The number of bytes returned is system-dependant.
|
||||
/// The number of bytes returned is system-dependent.
|
||||
fn read_be_int(&mut self) -> IoResult<int> {
|
||||
self.read_be_int_n(int::BYTES).map(|i| i as int)
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ mod tests {
|
||||
use io::*;
|
||||
use io::test::*;
|
||||
|
||||
pub fn smalltest(server: proc:Send(UnixStream), client: proc:Send(UnixStream)) {
|
||||
pub fn smalltest(server: proc(UnixStream):Send, client: proc(UnixStream):Send) {
|
||||
let path1 = next_test_unix();
|
||||
let path2 = path1.clone();
|
||||
|
||||
|
@ -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.
|
||||
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.
|
||||
|
@ -156,7 +156,7 @@ pub trait Iterator<A> {
|
||||
/// assert!(it.next().is_none());
|
||||
/// ```
|
||||
#[inline]
|
||||
fn map<'r, B>(self, f: 'r |A| -> B) -> Map<'r, A, B, Self> {
|
||||
fn map<'r, B>(self, f: |A|: 'r -> B) -> Map<'r, A, B, Self> {
|
||||
Map{iter: self, f: f}
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ pub trait Iterator<A> {
|
||||
/// assert!(it.next().is_none());
|
||||
/// ```
|
||||
#[inline]
|
||||
fn filter<'r>(self, predicate: 'r |&A| -> bool) -> Filter<'r, A, Self> {
|
||||
fn filter<'r>(self, predicate: |&A|: 'r -> bool) -> Filter<'r, A, Self> {
|
||||
Filter{iter: self, predicate: predicate}
|
||||
}
|
||||
|
||||
@ -190,7 +190,7 @@ pub trait Iterator<A> {
|
||||
/// assert!(it.next().is_none());
|
||||
/// ```
|
||||
#[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 }
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ pub trait Iterator<A> {
|
||||
/// assert!(it.next().is_none());
|
||||
/// ```
|
||||
#[inline]
|
||||
fn skip_while<'r>(self, predicate: 'r |&A| -> bool) -> SkipWhile<'r, A, Self> {
|
||||
fn skip_while<'r>(self, predicate: |&A|: 'r -> bool) -> SkipWhile<'r, A, Self> {
|
||||
SkipWhile{iter: self, flag: false, predicate: predicate}
|
||||
}
|
||||
|
||||
@ -267,7 +267,7 @@ pub trait Iterator<A> {
|
||||
/// assert!(it.next().is_none());
|
||||
/// ```
|
||||
#[inline]
|
||||
fn take_while<'r>(self, predicate: 'r |&A| -> bool) -> TakeWhile<'r, A, Self> {
|
||||
fn take_while<'r>(self, predicate: |&A|: 'r -> bool) -> TakeWhile<'r, A, Self> {
|
||||
TakeWhile{iter: self, flag: false, predicate: predicate}
|
||||
}
|
||||
|
||||
@ -327,7 +327,7 @@ pub trait Iterator<A> {
|
||||
/// assert!(it.next().is_none());
|
||||
/// ```
|
||||
#[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{iter: self, f: f, state: initial_state}
|
||||
}
|
||||
@ -351,7 +351,7 @@ pub trait Iterator<A> {
|
||||
/// }
|
||||
/// ```
|
||||
#[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{iter: self, f: f, frontiter: None, backiter: None }
|
||||
}
|
||||
@ -405,7 +405,7 @@ pub trait Iterator<A> {
|
||||
/// println!("{}", sum);
|
||||
/// ```
|
||||
#[inline]
|
||||
fn inspect<'r>(self, f: 'r |&A|) -> Inspect<'r, A, Self> {
|
||||
fn inspect<'r>(self, f: |&A|: 'r) -> Inspect<'r, A, Self> {
|
||||
Inspect{iter: self, f: f}
|
||||
}
|
||||
|
||||
@ -1235,7 +1235,7 @@ RandomAccessIterator<(A, B)> for Zip<T, U> {
|
||||
/// An iterator which maps the values of `iter` with `f`
|
||||
pub struct Map<'a, A, B, T> {
|
||||
iter: T,
|
||||
f: 'a |A| -> B
|
||||
f: |A|: 'a -> B
|
||||
}
|
||||
|
||||
impl<'a, A, B, T> Map<'a, A, B, T> {
|
||||
@ -1284,7 +1284,7 @@ impl<'a, A, B, T: RandomAccessIterator<A>> RandomAccessIterator<B> for Map<'a, A
|
||||
/// An iterator which filters the elements of `iter` with `predicate`
|
||||
pub struct Filter<'a, A, T> {
|
||||
iter: T,
|
||||
predicate: 'a |&A| -> bool
|
||||
predicate: |&A|: 'a -> bool
|
||||
}
|
||||
|
||||
impl<'a, A, T: Iterator<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`
|
||||
pub struct FilterMap<'a, A, B, 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> {
|
||||
@ -1477,7 +1477,7 @@ impl<'a, A, T: Iterator<A>> Peekable<A, T> {
|
||||
pub struct SkipWhile<'a, A, T> {
|
||||
iter: T,
|
||||
flag: bool,
|
||||
predicate: 'a |&A| -> bool
|
||||
predicate: |&A|: 'a -> bool
|
||||
}
|
||||
|
||||
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> {
|
||||
iter: T,
|
||||
flag: bool,
|
||||
predicate: 'a |&A| -> bool
|
||||
predicate: |&A|: 'a -> bool
|
||||
}
|
||||
|
||||
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
|
||||
pub struct Scan<'a, A, B, T, St> {
|
||||
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.
|
||||
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> {
|
||||
iter: T,
|
||||
f: 'a |A| -> U,
|
||||
f: |A|: 'a -> U,
|
||||
frontiter: Option<U>,
|
||||
backiter: Option<U>,
|
||||
}
|
||||
@ -1817,7 +1817,7 @@ impl<T> Fuse<T> {
|
||||
/// element before yielding it.
|
||||
pub struct Inspect<'a, A, T> {
|
||||
iter: T,
|
||||
f: 'a |&A|
|
||||
f: |&A|: 'a
|
||||
}
|
||||
|
||||
impl<'a, A, T> Inspect<'a, A, T> {
|
||||
@ -1869,7 +1869,7 @@ for Inspect<'a, A, T> {
|
||||
|
||||
/// An iterator which just modifies the contained state throughout iteration.
|
||||
pub struct Unfold<'a, A, St> {
|
||||
f: 'a |&mut St| -> Option<A>,
|
||||
f: |&mut St|: 'a -> Option<A>,
|
||||
/// Internal state that will be yielded on the next iteration
|
||||
pub state: St,
|
||||
}
|
||||
@ -1878,7 +1878,7 @@ impl<'a, A, St> Unfold<'a, A, St> {
|
||||
/// Creates a new iterator with the specified closure as the "iterator
|
||||
/// function" and an initial state to eventually pass to the iterator
|
||||
#[inline]
|
||||
pub fn new<'a>(initial_state: St, f: 'a |&mut St| -> Option<A>)
|
||||
pub fn new<'a>(initial_state: St, f: |&mut St|: 'a -> Option<A>)
|
||||
-> Unfold<'a, A, St> {
|
||||
Unfold {
|
||||
f: f,
|
||||
|
@ -58,7 +58,6 @@
|
||||
#![no_std]
|
||||
|
||||
#![deny(missing_doc)]
|
||||
#![allow(unknown_features)] // NOTE: remove after a stage0 snap
|
||||
|
||||
// When testing libstd, bring in libuv as the I/O backend so tests can print
|
||||
// things and all of the std::io tests have an I/O interface to run on top
|
||||
|
@ -273,7 +273,8 @@ macro_rules! vec(
|
||||
let mut _temp = ::std::vec::Vec::new();
|
||||
$(_temp.push($e);)*
|
||||
_temp
|
||||
})
|
||||
});
|
||||
($($e:expr),+,) => (vec!($($e),+))
|
||||
)
|
||||
|
||||
|
||||
|
@ -8,7 +8,87 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Unsafe pointer utility functions
|
||||
//! Conveniences for working with unsafe pointers, the `*T`, and `*mut T` types.
|
||||
//!
|
||||
//! Working with unsafe pointers in Rust is fairly uncommon,
|
||||
//! and often limited to some narrow use cases: holding
|
||||
//! an unsafe pointer when safe pointers are unsuitable;
|
||||
//! checking for null; and converting back to safe pointers.
|
||||
//! As a result, there is not yet an abundance of library code
|
||||
//! for working with unsafe poniters, and in particular,
|
||||
//! since pointer math is fairly uncommon in Rust, it is not
|
||||
//! all that convenient.
|
||||
//!
|
||||
//! Use the [`null` function](fn.null.html) to create null pointers,
|
||||
//! the [`is_null`](trait.RawPtr.html#tymethod.is_null)
|
||||
//! and [`is_not_null`](trait.RawPtr.html#method.is_not_null)
|
||||
//! methods of the [`RawPtr` trait](trait.RawPtr.html) to check for null.
|
||||
//! The `RawPtr` trait is imported by the prelude, so `is_null` etc.
|
||||
//! work everywhere.
|
||||
//!
|
||||
//! # Common ways to create unsafe pointers
|
||||
//!
|
||||
//! ## 1. Coerce a reference (`&T`) or mutable reference (`&mut T`).
|
||||
//!
|
||||
//! ```
|
||||
//! let my_num: int = 10;
|
||||
//! let my_num_ptr: *int = &my_num;
|
||||
//! let mut my_speed: int = 88;
|
||||
//! let my_speed_ptr: *mut int = &mut my_speed;
|
||||
//! ```
|
||||
//!
|
||||
//! This does not take ownership of the original allocation
|
||||
//! and requires no resource management later,
|
||||
//! but you must not use the pointer after its lifetime.
|
||||
//!
|
||||
//! ## 2. Transmute an owned box (`~T`).
|
||||
//!
|
||||
//! The `transmute` function takes, by value, whatever it's given
|
||||
//! and returns it as whatever type is requested, as long as the
|
||||
//! types are the same size. Because `~T` and `*T` have the same
|
||||
//! representation they can be trivially,
|
||||
//! though unsafely, transformed from one type to the other.
|
||||
//!
|
||||
//! ```
|
||||
//! use std::cast;
|
||||
//!
|
||||
//! unsafe {
|
||||
//! let my_num: ~int = ~10;
|
||||
//! let my_num: *int = cast::transmute(my_num);
|
||||
//! let my_speed: ~int = ~88;
|
||||
//! let my_speed: *mut int = cast::transmute(my_speed);
|
||||
//!
|
||||
//! // By taking ownership of the original `~T` though
|
||||
//! // we are obligated to transmute it back later to be destroyed.
|
||||
//! drop(cast::transmute::<_, ~int>(my_speed));
|
||||
//! drop(cast::transmute::<_, ~int>(my_num));
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! Note that here the call to `drop` is for clarity - it indicates
|
||||
//! that we are done with the given value and it should be destroyed.
|
||||
//!
|
||||
//! ## 3. Get it from C.
|
||||
//!
|
||||
//! ```
|
||||
//! extern crate libc;
|
||||
//!
|
||||
//! use std::mem;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! unsafe {
|
||||
//! let my_num: *mut int = libc::malloc(mem::size_of::<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 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]
|
||||
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]
|
||||
pub fn mut_null<T>() -> *mut T { 0 as *mut T }
|
||||
|
||||
/**
|
||||
* Copies data from one location to another.
|
||||
*
|
||||
* Copies `count` elements (not bytes) from `src` to `dst`. The source
|
||||
* and destination may overlap.
|
||||
*/
|
||||
/// Copies data from one location to another.
|
||||
///
|
||||
/// Copies `count` elements (not bytes) from `src` to `dst`. The source
|
||||
/// and destination may overlap.
|
||||
///
|
||||
/// `copy_memory` is semantically equivalent to C's `memmove`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Efficiently create a Rust vector from an unsafe buffer:
|
||||
///
|
||||
/// ```
|
||||
/// use std::ptr;
|
||||
/// use std::slice;
|
||||
///
|
||||
/// unsafe fn from_buf_raw<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]
|
||||
pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
|
||||
intrinsics::copy_memory(dst, src, count)
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies data from one location to another.
|
||||
*
|
||||
* Copies `count` elements (not bytes) from `src` to `dst`. The source
|
||||
* and destination may *not* overlap.
|
||||
*/
|
||||
/// Copies data from one location to another.
|
||||
///
|
||||
/// Copies `count` elements (not bytes) from `src` to `dst`. The source
|
||||
/// and destination may *not* overlap.
|
||||
///
|
||||
/// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// A safe swap function:
|
||||
///
|
||||
/// ```
|
||||
/// use std::cast;
|
||||
/// use std::mem;
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// fn swap<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]
|
||||
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
|
||||
src: *T,
|
||||
@ -83,27 +229,21 @@ pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
|
||||
intrinsics::copy_nonoverlapping_memory(dst, src, count)
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes memset on the specified pointer, setting `count * size_of::<T>()`
|
||||
* bytes of memory starting at `dst` to `c`.
|
||||
*/
|
||||
/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
|
||||
/// bytes of memory starting at `dst` to `c`.
|
||||
#[inline]
|
||||
pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
|
||||
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]
|
||||
pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
|
||||
set_memory(dst, 0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap the values at two mutable locations of the same type, without
|
||||
* deinitialising either. They may overlap.
|
||||
*/
|
||||
/// Swap the values at two mutable locations of the same type, without
|
||||
/// deinitialising either. They may overlap.
|
||||
#[inline]
|
||||
pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
|
||||
// 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the value at a mutable location with a new one, returning the old
|
||||
* value, without deinitialising either.
|
||||
*/
|
||||
/// Replace the value at a mutable location with a new one, returning the old
|
||||
/// value, without deinitialising either.
|
||||
#[inline]
|
||||
pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
|
||||
mem::swap(cast::transmute(dest), &mut src); // cannot overlap
|
||||
src
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the value from `*src` and returns it.
|
||||
*/
|
||||
/// Reads the value from `*src` and returns it.
|
||||
#[inline(always)]
|
||||
pub unsafe fn read<T>(src: *T) -> T {
|
||||
let mut tmp: T = mem::uninit();
|
||||
@ -140,10 +276,8 @@ pub unsafe fn read<T>(src: *T) -> T {
|
||||
tmp
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the value from `*src` and nulls it out.
|
||||
* This currently prevents destructors from executing.
|
||||
*/
|
||||
/// Reads the value from `*src` and nulls it out.
|
||||
/// This currently prevents destructors from executing.
|
||||
#[inline(always)]
|
||||
pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
|
||||
// Copy the data out from `dest`:
|
||||
@ -155,13 +289,9 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
|
||||
tmp
|
||||
}
|
||||
|
||||
/**
|
||||
Given a **T (pointer to an array of pointers),
|
||||
iterate through each *T, up to the provided `len`,
|
||||
passing to the provided callback function
|
||||
|
||||
SAFETY NOTE: Pointer-arithmetic. Dragons be here.
|
||||
*/
|
||||
/// Given a **T (pointer to an array of pointers),
|
||||
/// iterate through each *T, up to the provided `len`,
|
||||
/// passing to the provided callback function
|
||||
pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
|
||||
if arr.is_null() {
|
||||
fail!("ptr::array_each_with_len failure: arr input is null pointer");
|
||||
@ -173,15 +303,14 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Given a null-pointer-terminated **T (pointer to
|
||||
an array of pointers), iterate through each *T,
|
||||
passing to the provided callback function
|
||||
|
||||
SAFETY NOTE: This will only work with a null-terminated
|
||||
pointer array. Barely less-dodgy Pointer Arithmetic.
|
||||
Dragons be here.
|
||||
*/
|
||||
/// Given a null-pointer-terminated **T (pointer to
|
||||
/// an array of pointers), iterate through each *T,
|
||||
/// passing to the provided callback function
|
||||
///
|
||||
/// # Safety Note
|
||||
///
|
||||
/// This will only work with a null-terminated
|
||||
/// pointer array.
|
||||
pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
|
||||
if arr.is_null() {
|
||||
fail!("ptr::array_each_with_len failure: arr input is null pointer");
|
||||
|
@ -21,7 +21,7 @@ use ptr::RawPtr;
|
||||
use unstable::sync::Exclusive;
|
||||
use slice::OwnedVector;
|
||||
|
||||
type Queue = Exclusive<~[proc:Send()]>;
|
||||
type Queue = Exclusive<~[proc():Send]>;
|
||||
|
||||
// You'll note that these variables are *not* atomic, and this is done on
|
||||
// purpose. This module is designed to have init() called *once* in a
|
||||
@ -40,7 +40,7 @@ pub fn init() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push(f: proc:Send()) {
|
||||
pub fn push(f: proc():Send) {
|
||||
unsafe {
|
||||
rtassert!(!RUNNING);
|
||||
rtassert!(!QUEUE.is_null());
|
||||
|
@ -12,7 +12,7 @@
|
||||
//!
|
||||
//! The runtime will use this for storing ~Task.
|
||||
//!
|
||||
//! XXX: Add runtime checks for usage of inconsistent pointer types.
|
||||
//! FIXME: Add runtime checks for usage of inconsistent pointer types.
|
||||
//! and for overwriting an existing pointer.
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
@ -157,7 +157,7 @@ pub trait Runtime {
|
||||
|
||||
// Miscellaneous calls which are very different depending on what context
|
||||
// you're in.
|
||||
fn spawn_sibling(~self, cur_task: ~Task, opts: TaskOpts, f: proc:Send());
|
||||
fn spawn_sibling(~self, cur_task: ~Task, opts: TaskOpts, f: proc():Send);
|
||||
fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>>;
|
||||
/// The (low, high) edges of the current stack.
|
||||
fn stack_bounds(&self) -> (uint, uint); // (lo, hi)
|
||||
@ -196,7 +196,7 @@ pub fn init(argc: int, argv: **u8) {
|
||||
///
|
||||
/// It is forbidden for procedures to register more `at_exit` handlers when they
|
||||
/// are running, and doing so will lead to a process abort.
|
||||
pub fn at_exit(f: proc:Send()) {
|
||||
pub fn at_exit(f: proc():Send) {
|
||||
at_exit_imp::push(f);
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ pub trait Callback {
|
||||
|
||||
pub trait EventLoop {
|
||||
fn run(&mut self);
|
||||
fn callback(&mut self, arg: proc:Send());
|
||||
fn callback(&mut self, arg: proc():Send);
|
||||
fn pausable_idle_callback(&mut self,
|
||||
~Callback:Send) -> ~PausableIdleCallback:Send;
|
||||
fn remote_callback(&mut self, ~Callback:Send) -> ~RemoteCallback:Send;
|
||||
|
@ -70,7 +70,7 @@ pub enum BlockedTask {
|
||||
pub enum DeathAction {
|
||||
/// Action to be done with the exit code. If set, also makes the task wait
|
||||
/// until all its watched children exit before collecting the status.
|
||||
Execute(proc:Send(TaskResult)),
|
||||
Execute(proc(TaskResult):Send),
|
||||
/// A channel to send the result of the task on when the task exits
|
||||
SendMessage(Sender<TaskResult>),
|
||||
}
|
||||
@ -236,7 +236,7 @@ impl Task {
|
||||
|
||||
/// Spawns a sibling to this task. The newly spawned task is configured with
|
||||
/// the `opts` structure and will run `f` as the body of its code.
|
||||
pub fn spawn_sibling(mut ~self, opts: TaskOpts, f: proc:Send()) {
|
||||
pub fn spawn_sibling(mut ~self, opts: TaskOpts, f: proc():Send) {
|
||||
let ops = self.imp.take_unwrap();
|
||||
ops.spawn_sibling(self, opts, f)
|
||||
}
|
||||
|
@ -68,13 +68,13 @@ impl Thread<()> {
|
||||
/// to finish executing. This means that even if `join` is not explicitly
|
||||
/// called, when the `Thread` falls out of scope its destructor will block
|
||||
/// waiting for the OS thread.
|
||||
pub fn start<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)
|
||||
}
|
||||
|
||||
/// Performs the same functionality as `start`, but specifies an explicit
|
||||
/// 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
|
||||
// `main` fills it in it's still valid, so allocate an extra ~ box to do
|
||||
@ -99,13 +99,13 @@ impl Thread<()> {
|
||||
/// This corresponds to creating threads in the 'detached' state on unix
|
||||
/// systems. Note that platforms may not keep the main program alive even if
|
||||
/// there are detached thread still running around.
|
||||
pub fn spawn(main: proc:Send()) {
|
||||
pub fn spawn(main: proc():Send) {
|
||||
Thread::spawn_stack(DEFAULT_STACK_SIZE, main)
|
||||
}
|
||||
|
||||
/// Performs the same functionality as `spawn`, but explicitly specifies a
|
||||
/// stack size for the new thread.
|
||||
pub fn spawn_stack(stack: uint, main: proc:Send()) {
|
||||
pub fn spawn_stack(stack: uint, main: proc():Send) {
|
||||
unsafe {
|
||||
let handle = imp::create(stack, ~main);
|
||||
imp::detach(handle);
|
||||
@ -156,7 +156,7 @@ mod imp {
|
||||
pub type rust_thread = HANDLE;
|
||||
pub type rust_thread_return = DWORD;
|
||||
|
||||
pub unsafe fn create(stack: uint, p: ~proc:Send()) -> rust_thread {
|
||||
pub unsafe fn create(stack: uint, p: ~proc():Send) -> rust_thread {
|
||||
let arg: *mut libc::c_void = cast::transmute(p);
|
||||
// FIXME On UNIX, we guard against stack sizes that are too small but
|
||||
// that's because pthreads enforces that stacks are at least
|
||||
@ -215,7 +215,7 @@ mod imp {
|
||||
pub type rust_thread = libc::pthread_t;
|
||||
pub type rust_thread_return = *u8;
|
||||
|
||||
pub unsafe fn create(stack: uint, p: ~proc:Send()) -> rust_thread {
|
||||
pub unsafe fn create(stack: uint, p: ~proc():Send) -> rust_thread {
|
||||
let mut native: libc::pthread_t = mem::uninit();
|
||||
let mut attr: libc::pthread_attr_t = mem::uninit();
|
||||
assert_eq!(pthread_attr_init(&mut attr), 0);
|
||||
|
@ -235,7 +235,7 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
|
||||
pub struct Splits<'a, T> {
|
||||
v: &'a [T],
|
||||
n: uint,
|
||||
pred: 'a |t: &T| -> bool,
|
||||
pred: |t: &T|: 'a -> bool,
|
||||
finished: bool
|
||||
}
|
||||
|
||||
@ -284,7 +284,7 @@ impl<'a, T> Iterator<&'a [T]> for Splits<'a, T> {
|
||||
pub struct RevSplits<'a, T> {
|
||||
v: &'a [T],
|
||||
n: uint,
|
||||
pred: 'a |t: &T| -> bool,
|
||||
pred: |t: &T|: 'a -> bool,
|
||||
finished: bool
|
||||
}
|
||||
|
||||
@ -810,23 +810,23 @@ pub trait ImmutableVector<'a, T> {
|
||||
/// Returns an iterator over the subslices of the vector which are
|
||||
/// separated by elements that match `pred`. The matched element
|
||||
/// is not contained in the subslices.
|
||||
fn split(self, pred: 'a |&T| -> bool) -> Splits<'a, T>;
|
||||
fn split(self, pred: |&T|: 'a -> bool) -> Splits<'a, T>;
|
||||
/// Returns an iterator over the subslices of the vector which are
|
||||
/// separated by elements that match `pred`, limited to splitting
|
||||
/// at most `n` times. The matched element is not contained in
|
||||
/// the subslices.
|
||||
fn splitn(self, n: uint, pred: 'a |&T| -> bool) -> Splits<'a, T>;
|
||||
fn splitn(self, n: uint, pred: |&T|: 'a -> bool) -> Splits<'a, T>;
|
||||
/// Returns an iterator over the subslices of the vector which are
|
||||
/// separated by elements that match `pred`. This starts at the
|
||||
/// end of the vector and works backwards. The matched element is
|
||||
/// not contained in the subslices.
|
||||
fn rsplit(self, pred: 'a |&T| -> bool) -> RevSplits<'a, T>;
|
||||
fn rsplit(self, pred: |&T|: 'a -> bool) -> RevSplits<'a, T>;
|
||||
/// Returns an iterator over the subslices of the vector which are
|
||||
/// separated by elements that match `pred` limited to splitting
|
||||
/// at most `n` times. This starts at the end of the vector and
|
||||
/// works backwards. The matched element is not contained in the
|
||||
/// subslices.
|
||||
fn rsplitn(self, n: uint, pred: 'a |&T| -> bool) -> RevSplits<'a, T>;
|
||||
fn rsplitn(self, n: uint, pred: |&T|: 'a -> bool) -> RevSplits<'a, T>;
|
||||
|
||||
/**
|
||||
* Returns an iterator over all contiguous windows of length
|
||||
@ -1003,12 +1003,12 @@ impl<'a,T> ImmutableVector<'a, T> for &'a [T] {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn split(self, pred: 'a |&T| -> bool) -> Splits<'a, T> {
|
||||
fn split(self, pred: |&T|: 'a -> bool) -> Splits<'a, T> {
|
||||
self.splitn(uint::MAX, pred)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn splitn(self, n: uint, pred: 'a |&T| -> bool) -> Splits<'a, T> {
|
||||
fn splitn(self, n: uint, pred: |&T|: 'a -> bool) -> Splits<'a, T> {
|
||||
Splits {
|
||||
v: self,
|
||||
n: n,
|
||||
@ -1018,12 +1018,12 @@ impl<'a,T> ImmutableVector<'a, T> for &'a [T] {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rsplit(self, pred: 'a |&T| -> bool) -> RevSplits<'a, T> {
|
||||
fn rsplit(self, pred: |&T|: 'a -> bool) -> RevSplits<'a, T> {
|
||||
self.rsplitn(uint::MAX, pred)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rsplitn(self, n: uint, pred: 'a |&T| -> bool) -> RevSplits<'a, T> {
|
||||
fn rsplitn(self, n: uint, pred: |&T|: 'a -> bool) -> RevSplits<'a, T> {
|
||||
RevSplits {
|
||||
v: self,
|
||||
n: n,
|
||||
@ -2027,7 +2027,7 @@ pub trait MutableVector<'a, T> {
|
||||
/// Returns an iterator over the mutable subslices of the vector
|
||||
/// which are separated by elements that match `pred`. The
|
||||
/// matched element is not contained in the subslices.
|
||||
fn mut_split(self, pred: 'a |&T| -> bool) -> MutSplits<'a, T>;
|
||||
fn mut_split(self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T>;
|
||||
|
||||
/**
|
||||
* Returns an iterator over `size` elements of the vector at a time.
|
||||
@ -2299,7 +2299,7 @@ impl<'a,T> MutableVector<'a, T> for &'a mut [T] {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn mut_split(self, pred: 'a |&T| -> bool) -> MutSplits<'a, T> {
|
||||
fn mut_split(self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T> {
|
||||
MutSplits { v: self, pred: pred, finished: false }
|
||||
}
|
||||
|
||||
@ -2736,7 +2736,7 @@ pub type RevMutItems<'a, T> = Rev<MutItems<'a, T>>;
|
||||
/// by elements that match `pred`.
|
||||
pub struct MutSplits<'a, T> {
|
||||
v: &'a mut [T],
|
||||
pred: 'a |t: &T| -> bool,
|
||||
pred: |t: &T|: 'a -> bool,
|
||||
finished: bool
|
||||
}
|
||||
|
||||
|
@ -241,7 +241,7 @@ impl CharEq for char {
|
||||
fn only_ascii(&self) -> bool { (*self as uint) < 128 }
|
||||
}
|
||||
|
||||
impl<'a> CharEq for 'a |char| -> bool {
|
||||
impl<'a> CharEq for |char|: 'a -> bool {
|
||||
#[inline]
|
||||
fn matches(&self, c: char) -> bool { (*self)(c) }
|
||||
|
||||
|
@ -86,7 +86,7 @@ pub struct TaskOpts {
|
||||
pub struct TaskBuilder {
|
||||
/// Options to spawn the new task with
|
||||
pub opts: TaskOpts,
|
||||
gen_body: Option<proc:Send(v: proc:Send()) -> proc:Send()>,
|
||||
gen_body: Option<proc(v: proc():Send):Send -> proc():Send>,
|
||||
nocopy: Option<marker::NoCopy>,
|
||||
}
|
||||
|
||||
@ -151,7 +151,7 @@ impl TaskBuilder {
|
||||
* existing body generator to the new body generator.
|
||||
*/
|
||||
pub fn with_wrapper(mut self,
|
||||
wrapper: proc:Send(v: proc:Send()) -> proc:Send())
|
||||
wrapper: proc(v: proc():Send):Send -> proc():Send)
|
||||
-> TaskBuilder
|
||||
{
|
||||
self.gen_body = match self.gen_body.take() {
|
||||
@ -168,7 +168,7 @@ impl TaskBuilder {
|
||||
* the provided unique closure. The task has the properties and behavior
|
||||
* specified by the task_builder.
|
||||
*/
|
||||
pub fn spawn(mut self, f: proc:Send()) {
|
||||
pub fn spawn(mut self, f: proc():Send) {
|
||||
let gen_body = self.gen_body.take();
|
||||
let f = match gen_body {
|
||||
Some(gen) => gen(f),
|
||||
@ -191,7 +191,7 @@ impl TaskBuilder {
|
||||
* # Failure
|
||||
* Fails if a future_result was already set for this task.
|
||||
*/
|
||||
pub fn try<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 result = self.future_result();
|
||||
@ -233,12 +233,12 @@ impl TaskOpts {
|
||||
/// the provided unique closure.
|
||||
///
|
||||
/// This function is equivalent to `task().spawn(f)`.
|
||||
pub fn spawn(f: proc:Send()) {
|
||||
pub fn spawn(f: proc():Send) {
|
||||
let task = task();
|
||||
task.spawn(f)
|
||||
}
|
||||
|
||||
pub fn try<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
|
||||
* of the function or result::err.
|
||||
@ -338,7 +338,7 @@ fn test_run_basic() {
|
||||
fn test_with_wrapper() {
|
||||
let (tx, rx) = channel();
|
||||
task().with_wrapper(proc(body) {
|
||||
let result: proc:Send() = proc() {
|
||||
let result: proc():Send = proc() {
|
||||
body();
|
||||
tx.send(());
|
||||
};
|
||||
@ -424,7 +424,7 @@ fn test_spawn_sched_childs_on_default_sched() {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn avoid_copying_the_body(spawnfn: |v: proc:Send()|) {
|
||||
fn avoid_copying_the_body(spawnfn: |v: proc():Send|) {
|
||||
let (tx, rx) = channel::<uint>();
|
||||
|
||||
let x = ~1;
|
||||
@ -470,7 +470,7 @@ fn test_child_doesnt_ref_parent() {
|
||||
// (well, it would if the constant were 8000+ - I lowered it to be more
|
||||
// valgrind-friendly. try this at home, instead..!)
|
||||
static generations: uint = 16;
|
||||
fn child_no(x: uint) -> proc:Send() {
|
||||
fn child_no(x: uint) -> proc():Send {
|
||||
return proc() {
|
||||
if x < generations {
|
||||
task().spawn(child_no(x+1));
|
||||
|
@ -39,7 +39,7 @@ pub trait Finally<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 {
|
||||
try_finally(&mut (), (),
|
||||
|_, _| (*self)(),
|
||||
@ -101,7 +101,7 @@ pub fn try_finally<T,U,R>(mutate: &mut T,
|
||||
|
||||
struct Finallyalizer<'a,A> {
|
||||
mutate: &'a mut A,
|
||||
dtor: 'a |&mut A|
|
||||
dtor: |&mut A|: 'a
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
|
@ -28,7 +28,7 @@ for it to terminate.
|
||||
The executing thread has no access to a task pointer and will be using
|
||||
a normal large stack.
|
||||
*/
|
||||
pub fn run_in_bare_thread(f: proc:Send()) {
|
||||
pub fn run_in_bare_thread(f: proc():Send) {
|
||||
use rt::thread::Thread;
|
||||
Thread::start(f).join()
|
||||
}
|
||||
|
@ -1574,6 +1574,7 @@ mod tests {
|
||||
assert_eq!(v, three)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_grow_fn() {
|
||||
let mut v = Vec::from_slice([0u, 1]);
|
||||
v.grow_fn(3, |i| i);
|
||||
|
@ -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> Deref<T> for Arc<T> {
|
||||
impl<T: Send + Share> Deref<T> for Arc<T> {
|
||||
#[inline]
|
||||
fn deref<'a>(&'a self) -> &'a T {
|
||||
let inner = unsafe { &*self.x };
|
||||
&inner.data
|
||||
&self.inner().data
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ pub struct Future<A> {
|
||||
}
|
||||
|
||||
enum FutureState<A> {
|
||||
Pending(proc:Send() -> A),
|
||||
Pending(proc():Send -> A),
|
||||
Evaluating,
|
||||
Forced(A)
|
||||
}
|
||||
@ -90,7 +90,7 @@ impl<A> Future<A> {
|
||||
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.
|
||||
*
|
||||
@ -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.
|
||||
*
|
||||
|
@ -231,11 +231,10 @@ impl<T: Send> Mutex<T> {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(#13042): these should both have T: Send
|
||||
impl<'a, T> Deref<T> for MutexGuard<'a, T> {
|
||||
impl<'a, T: Send> Deref<T> for MutexGuard<'a, T> {
|
||||
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 }
|
||||
}
|
||||
|
||||
@ -363,14 +362,13 @@ impl<'a, T: Send + Share> RWLockWriteGuard<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(#13042): these should all have T: Send + Share
|
||||
impl<'a, T> Deref<T> for RWLockReadGuard<'a, T> {
|
||||
impl<'a, T: Send + Share> Deref<T> for RWLockReadGuard<'a, T> {
|
||||
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 }
|
||||
}
|
||||
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 }
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
use std::task;
|
||||
|
||||
enum Msg<T> {
|
||||
Execute(proc:Send(&T)),
|
||||
Execute(proc(&T):Send),
|
||||
Quit
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ impl<T> TaskPool<T> {
|
||||
/// returns a function which, given the index of the task, should return
|
||||
/// local data to be kept around in that task.
|
||||
pub fn new(n_tasks: uint,
|
||||
init_fn_factory: || -> proc:Send(uint) -> T)
|
||||
init_fn_factory: || -> proc(uint):Send -> T)
|
||||
-> TaskPool<T> {
|
||||
assert!(n_tasks >= 1);
|
||||
|
||||
@ -73,7 +73,7 @@ impl<T> TaskPool<T> {
|
||||
|
||||
/// Executes the function `f` on a task in the pool. The function
|
||||
/// receives a reference to the local data returned by the `init_fn`.
|
||||
pub fn execute(&mut self, f: proc:Send(&T)) {
|
||||
pub fn execute(&mut self, f: proc(&T):Send) {
|
||||
self.channels.get(self.next_index).send(Execute(f));
|
||||
self.next_index += 1;
|
||||
if self.next_index == self.channels.len() { self.next_index = 0; }
|
||||
@ -82,8 +82,8 @@ impl<T> TaskPool<T> {
|
||||
|
||||
#[test]
|
||||
fn test_task_pool() {
|
||||
let f: || -> proc:Send(uint) -> uint = || {
|
||||
let g: proc:Send(uint) -> uint = proc(i) i;
|
||||
let f: || -> proc(uint):Send -> uint = || {
|
||||
let g: proc(uint):Send -> uint = proc(i) i;
|
||||
g
|
||||
};
|
||||
let mut pool = TaskPool::new(4, f);
|
||||
|
@ -613,7 +613,7 @@ pub trait EachViewItem {
|
||||
}
|
||||
|
||||
struct EachViewItemData<'a> {
|
||||
callback: 'a |&ast::ViewItem| -> bool,
|
||||
callback: |&ast::ViewItem|: 'a -> bool,
|
||||
}
|
||||
|
||||
impl<'a> Visitor<()> for EachViewItemData<'a> {
|
||||
|
@ -293,13 +293,12 @@ pub fn syntax_expander_table() -> SyntaxEnv {
|
||||
|
||||
pub struct MacroCrate {
|
||||
pub lib: Option<Path>,
|
||||
pub cnum: ast::CrateNum,
|
||||
pub macros: Vec<~str>,
|
||||
pub registrar_symbol: Option<~str>,
|
||||
}
|
||||
|
||||
pub trait CrateLoader {
|
||||
fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate;
|
||||
fn get_exported_macros(&mut self, crate_num: ast::CrateNum) -> Vec<~str> ;
|
||||
fn get_registrar_symbol(&mut self, crate_num: ast::CrateNum) -> Option<~str>;
|
||||
}
|
||||
|
||||
// One of these is made during expansion and incrementally updated as we go;
|
||||
|
@ -303,7 +303,7 @@ Combine the values of all the fields together. The last argument is
|
||||
all the fields of all the structures, see above for details.
|
||||
*/
|
||||
pub type CombineSubstructureFunc<'a> =
|
||||
'a |&mut ExtCtxt, Span, &Substructure| -> @Expr;
|
||||
|&mut ExtCtxt, Span, &Substructure|: 'a -> @Expr;
|
||||
|
||||
/**
|
||||
Deal with non-matching enum variants, the arguments are a list
|
||||
@ -311,10 +311,10 @@ representing each variant: (variant index, ast::Variant instance,
|
||||
[variant fields]), and a list of the nonself args of the type
|
||||
*/
|
||||
pub type EnumNonMatchFunc<'a> =
|
||||
'a |&mut ExtCtxt,
|
||||
|&mut ExtCtxt,
|
||||
Span,
|
||||
&[(uint, P<ast::Variant>, Vec<(Span, Option<Ident>, @Expr)> )],
|
||||
&[@Expr]|
|
||||
&[@Expr]|: 'a
|
||||
-> @Expr;
|
||||
|
||||
|
||||
|
@ -487,7 +487,8 @@ pub fn expand_view_item(vi: &ast::ViewItem,
|
||||
}
|
||||
|
||||
fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
|
||||
let MacroCrate { lib, cnum } = fld.cx.ecfg.loader.load_crate(krate);
|
||||
let MacroCrate { lib, macros, registrar_symbol } =
|
||||
fld.cx.ecfg.loader.load_crate(krate);
|
||||
|
||||
let crate_name = match krate.node {
|
||||
ast::ViewItemExternCrate(name, _, _) => name,
|
||||
@ -495,8 +496,7 @@ fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
|
||||
};
|
||||
let name = format!("<{} macros>", token::get_ident(crate_name));
|
||||
|
||||
let exported_macros = fld.cx.ecfg.loader.get_exported_macros(cnum);
|
||||
for source in exported_macros.iter() {
|
||||
for source in macros.iter() {
|
||||
let item = parse::parse_item_from_source_str(name.clone(),
|
||||
(*source).clone(),
|
||||
fld.cx.cfg(),
|
||||
@ -512,7 +512,7 @@ fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) {
|
||||
// Make sure the path contains a / or the linker will search for it.
|
||||
let path = os::make_absolute(&path);
|
||||
|
||||
let registrar = match fld.cx.ecfg.loader.get_registrar_symbol(cnum) {
|
||||
let registrar = match registrar_symbol {
|
||||
Some(registrar) => registrar,
|
||||
None => return
|
||||
};
|
||||
@ -1019,14 +1019,6 @@ mod test {
|
||||
fn load_crate(&mut self, _: &ast::ViewItem) -> MacroCrate {
|
||||
fail!("lolwut")
|
||||
}
|
||||
|
||||
fn get_exported_macros(&mut self, _: ast::CrateNum) -> Vec<~str> {
|
||||
fail!("lolwut")
|
||||
}
|
||||
|
||||
fn get_registrar_symbol(&mut self, _: ast::CrateNum) -> Option<~str> {
|
||||
fail!("lolwut")
|
||||
}
|
||||
}
|
||||
|
||||
// these following tests are quite fragile, in that they don't test what
|
||||
|
@ -905,31 +905,23 @@ impl<'a> Parser<'a> {
|
||||
|
||||
*/
|
||||
|
||||
// NOTE: remove after the next stage0 snap
|
||||
let (decl, lifetimes, bounds) = if self.token == token::COLON {
|
||||
let (_, bounds) = self.parse_optional_ty_param_bounds(false);
|
||||
let (decl, lifetimes) = self.parse_ty_fn_decl(false);
|
||||
(decl, lifetimes, bounds)
|
||||
let lifetimes = if self.eat(&token::LT) {
|
||||
let lifetimes = self.parse_lifetimes();
|
||||
self.expect_gt();
|
||||
lifetimes
|
||||
} else {
|
||||
let lifetimes = if self.eat(&token::LT) {
|
||||
let lifetimes = self.parse_lifetimes();
|
||||
self.expect_gt();
|
||||
lifetimes
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
let (inputs, variadic) = self.parse_fn_args(false, false);
|
||||
let (_, bounds) = self.parse_optional_ty_param_bounds(false);
|
||||
let (ret_style, ret_ty) = self.parse_ret_ty();
|
||||
let decl = P(FnDecl {
|
||||
inputs: inputs,
|
||||
output: ret_ty,
|
||||
cf: ret_style,
|
||||
variadic: variadic
|
||||
});
|
||||
(decl, lifetimes, bounds)
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
let (inputs, variadic) = self.parse_fn_args(false, false);
|
||||
let (_, bounds) = self.parse_optional_ty_param_bounds(false);
|
||||
let (ret_style, ret_ty) = self.parse_ret_ty();
|
||||
let decl = P(FnDecl {
|
||||
inputs: inputs,
|
||||
output: ret_ty,
|
||||
cf: ret_style,
|
||||
variadic: variadic
|
||||
});
|
||||
TyClosure(@ClosureTy {
|
||||
sigil: OwnedSigil,
|
||||
region: None,
|
||||
@ -957,8 +949,6 @@ impl<'a> Parser<'a> {
|
||||
|
||||
*/
|
||||
|
||||
// NOTE: remove 'let region' after a stage0 snap
|
||||
let region = self.parse_opt_lifetime();
|
||||
let purity = self.parse_unsafety();
|
||||
let onceness = if self.eat_keyword(keywords::Once) {Once} else {Many};
|
||||
|
||||
@ -982,10 +972,7 @@ impl<'a> Parser<'a> {
|
||||
inputs
|
||||
};
|
||||
|
||||
let (new_region, bounds) = self.parse_optional_ty_param_bounds(true);
|
||||
|
||||
// NOTE: this should be removed after a stage0 snap
|
||||
let region = new_region.or(region);
|
||||
let (region, bounds) = self.parse_optional_ty_param_bounds(true);
|
||||
|
||||
let (return_style, output) = self.parse_ret_ty();
|
||||
let decl = P(FnDecl {
|
||||
@ -1246,9 +1233,7 @@ impl<'a> Parser<'a> {
|
||||
} else if self.token_is_closure_keyword() ||
|
||||
self.token == token::BINOP(token::OR) ||
|
||||
self.token == token::OROR ||
|
||||
self.token == token::LT ||
|
||||
// NOTE: remove this clause after a stage0 snap
|
||||
Parser::token_is_lifetime(&self.token) {
|
||||
self.token == token::LT {
|
||||
// CLOSURE
|
||||
//
|
||||
// FIXME(pcwalton): Eventually `token::LT` will not unambiguously
|
||||
|
@ -123,7 +123,7 @@ pub enum TestFn {
|
||||
StaticTestFn(fn()),
|
||||
StaticBenchFn(fn(&mut BenchHarness)),
|
||||
StaticMetricFn(proc(&mut MetricMap)),
|
||||
DynTestFn(proc:Send()),
|
||||
DynTestFn(proc():Send),
|
||||
DynMetricFn(proc(&mut MetricMap)),
|
||||
DynBenchFn(~TDynBenchFn)
|
||||
}
|
||||
@ -948,7 +948,7 @@ pub fn run_test(force_ignore: bool,
|
||||
#[allow(deprecated_owned_vector)]
|
||||
fn run_test_inner(desc: TestDesc,
|
||||
monitor_ch: Sender<MonitorMsg>,
|
||||
testfn: proc:Send()) {
|
||||
testfn: proc():Send) {
|
||||
spawn(proc() {
|
||||
let (tx, rx) = channel();
|
||||
let mut reader = ChanReader::new(rx);
|
||||
|
@ -394,14 +394,14 @@ impl<'a> Prep<'a> {
|
||||
pub fn exec<'a, T:Send +
|
||||
Encodable<json::Encoder<'a>, io::IoError> +
|
||||
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()
|
||||
}
|
||||
|
||||
fn exec_work<'a, T:Send +
|
||||
Encodable<json::Encoder<'a>, io::IoError> +
|
||||
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);
|
||||
|
||||
debug!("exec_work: looking up {} and {:?}", self.fn_name,
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
DEPDIR=depends
|
||||
|
||||
# "Machine-dependant" options
|
||||
# "Machine-dependent" options
|
||||
#MFLAGS=-fPIC
|
||||
|
||||
CFLAGS=-c -g -O3 -fPIC -Wall -Werror -Wsign-compare -Isrc -Ihtml
|
||||
|
@ -1,3 +1,11 @@
|
||||
S 2014-04-07 c7fac44
|
||||
freebsd-x86_64 3c01e2a52a1487c360a8e075df0d4fd412d84fe9
|
||||
linux-i386 145f83ec557db77160a207aa2a17e2db8e254b84
|
||||
linux-x86_64 647d2922311a497280d49e91e4946a271d44a232
|
||||
macos-i386 fa19ebca45f83e224911bad13475e40d531e6515
|
||||
macos-x86_64 c0b4df5eed015c527a2a23ca3f2755a44782f61d
|
||||
winnt-i386 e93af6e5ce88e1220f8b4b4cce14436af0b4279a
|
||||
|
||||
S 2014-04-03 e7fe207
|
||||
freebsd-x86_64 6d40f547d13896ab9d9dd4a4fdf2e72be553b01b
|
||||
linux-i386 875a8f6956f7d703f7206db91ca2a9b67c244cf8
|
||||
|
@ -13,7 +13,7 @@
|
||||
// part of issue-6919.rs
|
||||
|
||||
struct C<'a> {
|
||||
pub k: 'a ||,
|
||||
pub k: ||: 'a,
|
||||
}
|
||||
|
||||
fn no_op() { }
|
||||
|
@ -15,7 +15,7 @@ use std::os;
|
||||
fn start(n_tasks: int, token: int) {
|
||||
let (tx, mut rx) = channel();
|
||||
tx.send(token);
|
||||
// XXX could not get this to work with a range closure
|
||||
// FIXME could not get this to work with a range closure
|
||||
let mut i = 2;
|
||||
while i <= n_tasks {
|
||||
let (tx, next_rx) = channel();
|
||||
|
@ -9,11 +9,11 @@
|
||||
// except according to those terms.
|
||||
|
||||
struct X {
|
||||
field: 'static ||:Send,
|
||||
field: ||:'static + Send,
|
||||
}
|
||||
|
||||
fn foo(blk: 'static ||:) -> X {
|
||||
return X { field: blk }; //~ ERROR expected bounds `Send` but found no bounds
|
||||
fn foo(blk: ||:'static) -> X {
|
||||
return X { field: blk }; //~ ERROR expected bounds `'static+Send`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
fn foopy() {}
|
||||
|
||||
static f: 'static || = foopy; //~ ERROR found extern fn
|
||||
static f: ||: 'static = foopy; //~ ERROR found extern fn
|
||||
|
||||
fn main () {
|
||||
f();
|
||||
|
@ -14,8 +14,8 @@ fn foo(_x: @uint) {}
|
||||
|
||||
fn main() {
|
||||
let x = @3u;
|
||||
let _: proc:Send() = proc() foo(x); //~ ERROR does not fulfill `Send`
|
||||
let _: proc:Send() = proc() foo(x); //~ ERROR does not fulfill `Send`
|
||||
let _: proc:Send() = proc() foo(x); //~ ERROR does not fulfill `Send`
|
||||
let _: proc():Send = proc() foo(x); //~ ERROR does not fulfill `Send`
|
||||
let _: proc():Send = proc() foo(x); //~ ERROR does not fulfill `Send`
|
||||
let _: proc():Send = proc() foo(x); //~ ERROR does not fulfill `Send`
|
||||
let _: proc() = proc() foo(x);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ struct R<'a> {
|
||||
// This struct is needed to create the
|
||||
// otherwise infinite type of a fn that
|
||||
// accepts itself as argument:
|
||||
c: 'a |&R, bool|
|
||||
c: |&R, bool|: 'a
|
||||
}
|
||||
|
||||
fn innocent_looking_victim() {
|
||||
|
@ -13,13 +13,13 @@ fn is_freeze<T: Share>() {}
|
||||
fn is_static<T: 'static>() {}
|
||||
|
||||
fn main() {
|
||||
is_send::<proc:()>();
|
||||
is_send::<proc()>();
|
||||
//~^ ERROR: instantiating a type parameter with an incompatible type
|
||||
|
||||
is_freeze::<proc:()>();
|
||||
is_freeze::<proc()>();
|
||||
//~^ ERROR: instantiating a type parameter with an incompatible type
|
||||
|
||||
is_static::<proc:()>();
|
||||
is_static::<proc()>();
|
||||
//~^ ERROR: instantiating a type parameter with an incompatible type
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn env<'a>(_: &'a uint, blk: |p: 'a |||) {
|
||||
fn env<'a>(_: &'a uint, blk: |p: ||: 'a|) {
|
||||
// Test that the closure here cannot be assigned
|
||||
// the lifetime `'a`, which outlives the current
|
||||
// block.
|
||||
@ -21,7 +21,7 @@ fn env<'a>(_: &'a uint, blk: |p: 'a |||) {
|
||||
blk(|| *statep = 1); //~ ERROR cannot infer
|
||||
}
|
||||
|
||||
fn no_env_no_for<'a>(_: &'a uint, blk: |p: 'a |||) {
|
||||
fn no_env_no_for<'a>(_: &'a uint, blk: |p: |||: 'a) {
|
||||
// Test that a closure with no free variables CAN
|
||||
// outlive the block in which it is created.
|
||||
//
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn wants_static_fn(_x: 'static ||) {}
|
||||
fn wants_static_fn(_x: ||: 'static) {}
|
||||
|
||||
fn main() {
|
||||
let i = 3;
|
||||
|
@ -9,15 +9,15 @@
|
||||
// except according to those terms.
|
||||
|
||||
struct parameterized1<'a> {
|
||||
g: 'a ||
|
||||
g: ||: 'a
|
||||
}
|
||||
|
||||
struct not_parameterized1 {
|
||||
g: 'static ||
|
||||
g: ||: 'static
|
||||
}
|
||||
|
||||
struct not_parameterized2 {
|
||||
g: 'static ||
|
||||
g: ||: 'static
|
||||
}
|
||||
|
||||
fn take1(p: parameterized1) -> parameterized1 { p }
|
||||
|
@ -11,7 +11,7 @@
|
||||
#![feature(managed_boxes)]
|
||||
|
||||
struct invariant<'a> {
|
||||
f: 'static |x: &mut &'a int|
|
||||
f: |x: &mut &'a int|: 'static
|
||||
}
|
||||
|
||||
fn to_same_lifetime<'r>(bi: invariant<'r>) {
|
||||
|
@ -11,7 +11,7 @@
|
||||
#![feature(managed_boxes)]
|
||||
|
||||
struct invariant<'a> {
|
||||
f: 'static || -> &mut &'a int
|
||||
f: ||: 'static -> &mut &'a int
|
||||
}
|
||||
|
||||
fn to_same_lifetime<'r>(bi: invariant<'r>) {
|
||||
|
@ -14,12 +14,12 @@ struct direct<'a> {
|
||||
|
||||
struct indirect1 {
|
||||
// Here the lifetime parameter of direct is bound by the fn()
|
||||
g: 'static |direct|
|
||||
g: |direct|: 'static
|
||||
}
|
||||
|
||||
struct indirect2<'a> {
|
||||
// But here it is set to 'a
|
||||
g: 'static |direct<'a>|
|
||||
g: |direct<'a>|: 'static
|
||||
}
|
||||
|
||||
fn take_direct(p: direct) -> direct { p } //~ ERROR mismatched types
|
||||
|
@ -9,10 +9,10 @@
|
||||
// except according to those terms.
|
||||
|
||||
struct closure_box<'a> {
|
||||
cl: 'a ||
|
||||
cl: ||: 'a
|
||||
}
|
||||
|
||||
fn box_it<'r>(x: 'r ||) -> closure_box<'r> {
|
||||
fn box_it<'r>(x: ||: 'r) -> closure_box<'r> {
|
||||
closure_box {cl: x}
|
||||
}
|
||||
|
||||
|
13
src/test/compile-fail/vec-macro-with-comma-only.rs
Normal file
13
src/test/compile-fail/vec-macro-with-comma-only.rs
Normal 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
|
||||
}
|
@ -26,7 +26,7 @@ struct WindowCallbacks<'a> {
|
||||
pos_callback: Option<WindowPosCallback<'a>>,
|
||||
}
|
||||
|
||||
pub type WindowPosCallback<'a> = 'a |&Window, i32, i32|;
|
||||
pub type WindowPosCallback<'a> = |&Window, i32, i32|: 'a;
|
||||
|
||||
fn main() {
|
||||
let x = WindowCallbacks { pos_callback: None };
|
||||
|
@ -18,7 +18,7 @@ fn failfn() {
|
||||
|
||||
fn main() {
|
||||
let y = ~0;
|
||||
let x: @proc:Send() = @(proc() {
|
||||
let x: @proc():Send = @(proc() {
|
||||
println!("{:?}", y.clone());
|
||||
});
|
||||
failfn();
|
||||
|
@ -16,7 +16,7 @@ fn main() {
|
||||
let cheese = ~"roquefort";
|
||||
let carrots = @~"crunchy";
|
||||
|
||||
let result: 'static |@~str, |~str|| = (|tasties, macerate| {
|
||||
let result: |@~str, |~str||: 'static = (|tasties, macerate| {
|
||||
macerate((*tasties).clone());
|
||||
});
|
||||
result(carrots, |food| {
|
||||
|
@ -18,7 +18,7 @@ struct Pair {
|
||||
pub fn main() {
|
||||
let z = ~Pair { a : 10, b : 12};
|
||||
|
||||
let f: proc:Send() = proc() {
|
||||
let f: proc():Send = proc() {
|
||||
assert_eq!(z.a, 10);
|
||||
assert_eq!(z.b, 12);
|
||||
};
|
||||
|
@ -61,7 +61,7 @@ fn bar<'b>() {
|
||||
foo::<proc<'a>(int, f32, &'a int):'static + Share -> &'a int>();
|
||||
|
||||
// issue #11209
|
||||
let _: 'b ||; // for comparison
|
||||
let _: ||: 'b; // for comparison
|
||||
let _: <'a> ||;
|
||||
|
||||
let _: Option<||:'b>;
|
||||
@ -69,7 +69,7 @@ fn bar<'b>() {
|
||||
let _: Option< <'a>||>;
|
||||
|
||||
// issue #11210
|
||||
let _: 'static ||;
|
||||
let _: ||: 'static;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
|
13
src/test/run-pass/empty-allocation-rvalue-non-null.rs
Normal file
13
src/test/run-pass/empty-allocation-rvalue-non-null.rs
Normal 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 = *~();
|
||||
}
|
60
src/test/run-pass/issue-11881.rs
Normal file
60
src/test/run-pass/issue-11881.rs
Normal 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)
|
||||
}
|
||||
}
|
63
src/test/run-pass/issue-13304.rs
Normal file
63
src/test/run-pass/issue-13304.rs
Normal 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());
|
||||
}
|
||||
}
|
@ -9,5 +9,5 @@
|
||||
// except according to those terms.
|
||||
|
||||
pub fn main() {
|
||||
let early_error: 'static |&str| -> ! = |_msg| { fail!() };
|
||||
let early_error: |&str|: 'static -> ! = |_msg| { fail!() };
|
||||
}
|
||||
|
@ -12,13 +12,13 @@ use std::task;
|
||||
|
||||
static generations: uint = 1024+256+128+49;
|
||||
|
||||
fn spawn(f: proc:Send()) {
|
||||
fn spawn(f: proc():Send) {
|
||||
let mut t = task::task();
|
||||
t.opts.stack_size = Some(32 * 1024);
|
||||
t.spawn(f);
|
||||
}
|
||||
|
||||
fn child_no(x: uint) -> proc:Send() {
|
||||
fn child_no(x: uint) -> proc():Send {
|
||||
proc() {
|
||||
if x < generations {
|
||||
spawn(child_no(x+1));
|
||||
|
@ -11,7 +11,7 @@
|
||||
use std::task;
|
||||
|
||||
type RingBuffer = Vec<f64> ;
|
||||
type SamplesFn = proc:Send(samples: &RingBuffer);
|
||||
type SamplesFn = proc(samples: &RingBuffer):Send;
|
||||
|
||||
enum Msg
|
||||
{
|
||||
|
@ -12,10 +12,10 @@
|
||||
|
||||
struct A { a: ~int }
|
||||
|
||||
fn foo() -> 'static || -> int {
|
||||
fn foo() -> ||: 'static -> int {
|
||||
let k = ~22;
|
||||
let _u = A {a: k.clone()};
|
||||
let result: 'static || -> int = || 22;
|
||||
let result: ||: 'static -> int = || 22;
|
||||
result
|
||||
}
|
||||
|
||||
|
@ -17,18 +17,18 @@ fn is_static<T: 'static>() {}
|
||||
|
||||
pub fn main() {
|
||||
foo::<proc()>();
|
||||
foo::<proc:()>();
|
||||
foo::<proc:Send()>();
|
||||
foo::<proc:Send + Share()>();
|
||||
foo::<proc:'static + Send + Share()>();
|
||||
foo::<proc()>();
|
||||
foo::<proc():Send>();
|
||||
foo::<proc():Send + Share>();
|
||||
foo::<proc():'static + Send + Share>();
|
||||
|
||||
is_send::<proc:Send()>();
|
||||
is_freeze::<proc:Share()>();
|
||||
is_static::<proc:'static()>();
|
||||
is_send::<proc():Send>();
|
||||
is_freeze::<proc():Share>();
|
||||
is_static::<proc():'static>();
|
||||
|
||||
|
||||
let a = 3;
|
||||
bar::<proc:()>(proc() {
|
||||
bar::<proc():>(proc() {
|
||||
let b = &a;
|
||||
println!("{}", *b);
|
||||
});
|
||||
|
@ -18,7 +18,7 @@ fn test05_start(f: proc(int)) {
|
||||
|
||||
fn test05() {
|
||||
let three = ~3;
|
||||
let fn_to_send: proc:Send(int) = proc(n) {
|
||||
let fn_to_send: proc(int):Send = proc(n) {
|
||||
println!("{}", *three + n); // will copy x into the closure
|
||||
assert_eq!(*three, 3);
|
||||
};
|
||||
|
@ -35,7 +35,7 @@ fn test_tempdir() {
|
||||
|
||||
fn test_rm_tempdir() {
|
||||
let (tx, rx) = channel();
|
||||
let f: proc:Send() = proc() {
|
||||
let f: proc():Send = proc() {
|
||||
let tmp = TempDir::new("test_rm_tempdir").unwrap();
|
||||
tx.send(tmp.path().clone());
|
||||
fail!("fail to unwind past `tmp`");
|
||||
@ -46,7 +46,7 @@ fn test_rm_tempdir() {
|
||||
|
||||
let tmp = TempDir::new("test_rm_tempdir").unwrap();
|
||||
let path = tmp.path().clone();
|
||||
let f: proc:Send() = proc() {
|
||||
let f: proc():Send = proc() {
|
||||
let _tmp = tmp;
|
||||
fail!("fail to unwind past `tmp`");
|
||||
};
|
||||
|
@ -19,10 +19,10 @@ enum maybe_pointy {
|
||||
|
||||
struct Pointy {
|
||||
a : maybe_pointy,
|
||||
d : proc:Send() -> uint,
|
||||
d : proc():Send -> uint,
|
||||
}
|
||||
|
||||
fn make_uniq_closure<A:Send>(a: A) -> proc:Send() -> uint {
|
||||
fn make_uniq_closure<A:Send>(a: A) -> proc():Send -> uint {
|
||||
proc() { &a as *A as uint }
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user