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

This passed `make check` locally, so hopefully it passes on bors!
This commit is contained in:
bors 2014-02-13 15:17:21 -08:00
commit 94d453e459
50 changed files with 651 additions and 398 deletions

View File

@ -125,10 +125,7 @@ ifdef TRACE
CFG_RUSTC_FLAGS += -Z trace
endif
ifdef CFG_DISABLE_RPATH
# NOTE: make this CFG_RUSTC_FLAGS after stage0 snapshot
RUSTFLAGS_STAGE1 += -C no-rpath
RUSTFLAGS_STAGE2 += -C no-rpath
RUSTFLAGS_STAGE3 += -C no-rpath
CFG_RUSTC_FLAGS += -C no-rpath
endif
# The executables crated during this compilation process have no need to include
@ -140,8 +137,7 @@ endif
# snapshot will be generated with a statically linked rustc so we only have to
# worry about the distribution of one file (with its native dynamic
# dependencies)
#
# NOTE: after a snapshot (stage0), put this on stage0 as well
RUSTFLAGS_STAGE0 += -C prefer-dynamic
RUSTFLAGS_STAGE1 += -C prefer-dynamic
# platform-specific auto-configuration

View File

@ -12,7 +12,7 @@ PKG_ICO = $(S)src/etc/pkg/rust-logo.ico
PKG_EXE = $(PKG_DIR)-install.exe
endif
PKG_GITMODULES := $(S)src/libuv $(S)src/llvm $(S)src/gyp
PKG_GITMODULES := $(S)src/libuv $(S)src/llvm $(S)src/gyp $(S)src/compiler-rt
PKG_FILES := \
$(S)COPYRIGHT \

View File

@ -333,21 +333,22 @@ $(foreach host,$(CFG_HOST), \
define TEST_RUNNER
# If NO_REBUILD is set then break the dependencies on extra so we can
# test crates without rebuilding std and extra first
# If NO_REBUILD is set then break the dependencies on everything but
# the source files so we can test crates without rebuilding any of the
# parent crates.
ifeq ($(NO_REBUILD),)
STDTESTDEP_$(1)_$(2)_$(3)_$(4) = $$(SREQ$(1)_T_$(2)_H_$(3)) \
TESTDEP_$(1)_$(2)_$(3)_$(4) = $$(SREQ$(1)_T_$(2)_H_$(3)) \
$$(foreach crate,$$(TARGET_CRATES),\
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(crate))
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(crate)) \
$$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4))
else
STDTESTDEP_$(1)_$(2)_$(3)_$(4) =
TESTDEP_$(1)_$(2)_$(3)_$(4) = $$(RSINPUTS_$(4))
endif
$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2)): CFG_COMPILER = $(2)
$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2)): \
$$(CRATEFILE_$(4)) \
$$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4)) \
$$(STDTESTDEP_$(1)_$(2)_$(3)_$(4))
$$(CRATEFILE_$(4)) \
$$(TESTDEP_$(1)_$(2)_$(3)_$(4))
@$$(call E, oxidize: $$@)
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test \
-L "$$(RT_OUTPUT_DIR_$(2))" \
@ -684,13 +685,22 @@ $(foreach host,$(CFG_HOST), \
define DEF_CRATE_DOC_TEST
# If NO_REBUILD is set then break the dependencies on everything but
# the source files so we can test crate documentation without
# rebuilding any of the parent crates.
ifeq ($(NO_REBUILD),)
DOCTESTDEP_$(1)_$(2)_$(3)_$(4) = \
$$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
$$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4)) \
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3))
else
DOCTESTDEP_$(1)_$(2)_$(3)_$(4) = $$(RSINPUTS_$(4))
endif
check-stage$(1)-T-$(2)-H-$(3)-doc-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4))
ifeq ($(2),$$(CFG_BUILD))
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)): \
$$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
$$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4)) \
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3))
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)): $$(DOCTESTDEP_$(1)_$(2)_$(3)_$(4))
@$$(call E, run doc-$(4) [$(2)])
$$(Q)$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) --test \
$$(CRATEFILE_$(4)) --test-args "$$(TESTARGS)" && touch $$@

View File

@ -195,7 +195,7 @@ impl<T: Send> Unique<T> {
pub fn new(value: T) -> Unique<T> {
unsafe {
let ptr = malloc(std::mem::size_of::<T>() as size_t) as *mut T;
assert!(!ptr::is_null(ptr));
assert!(!ptr.is_null());
// `*ptr` is uninitialized, and `*ptr = value` would attempt to destroy it
// move_val_init moves a value into this memory without
// attempting to drop the original value.

View File

@ -1725,14 +1725,17 @@ mod bar {
pub type int8_t = i8;
~~~~
> **Note:** In future versions of Rust, user-provided extensions to the compiler will be able to interpret attributes.
> When this facility is provided, the compiler will distinguish between language-reserved and user-available attributes.
> **Note:** In future versions of Rust, user-provided extensions to the compiler
> will be able to interpret attributes. When this facility is provided, the
> compiler will distinguish between language-reserved and user-available
> attributes.
At present, only the Rust compiler interprets attributes, so all attribute
names are effectively reserved. Some significant attributes include:
At present, only the Rust compiler interprets attributes, so all attribute names
are effectively reserved. Some significant attributes include:
* The `doc` attribute, for documenting code in-place.
* The `cfg` attribute, for conditional-compilation by build-configuration.
* The `cfg` attribute, for conditional-compilation by build-configuration (see
[Conditional compilation](#conditional-compilation)).
* The `crate_id` attribute, for describing the package ID of a crate.
* The `lang` attribute, for custom definitions of traits and functions that are
known to the Rust compiler (see [Language items](#language-items)).
@ -1740,16 +1743,77 @@ names are effectively reserved. Some significant attributes include:
* The `test` attribute, for marking functions as unit tests.
* The `allow`, `warn`, `forbid`, and `deny` attributes, for
controlling lint checks (see [Lint check attributes](#lint-check-attributes)).
* The `deriving` attribute, for automatically generating
implementations of certain traits.
* The `deriving` attribute, for automatically generating implementations of
certain traits.
* The `inline` attribute, for expanding functions at caller location (see
[Inline attributes](#inline-attributes)).
* The `static_assert` attribute, for asserting that a static bool is true at compiletime
* The `thread_local` attribute, for defining a `static mut` as a thread-local. Note that this is
only a low-level building block, and is not local to a *task*, nor does it provide safety.
* The `static_assert` attribute, for asserting that a static bool is true at
compiletime.
* The `thread_local` attribute, for defining a `static mut` as a thread-local.
Note that this is only a low-level building block, and is not local to a
*task*, nor does it provide safety.
Other attributes may be added or removed during development of the language.
### Conditional compilation
Sometimes one wants to have different compiler outputs from the same code,
depending on build target, such as targeted operating system, or to enable
release builds.
There are two kinds of configuration options, one that is either defined or not
(`#[cfg(foo)]`), and the other that contains a string that can be checked
against (`#[cfg(bar = "baz")]` (currently only compiler-defined configuration
options can have the latter form).
~~~~
// The function is only included in the build when compiling for OSX
#[cfg(target_os = "macos")]
fn macos_only() {
// ...
}
// This function is only included when either foo or bar is defined
#[cfg(foo)]
#[cfg(bar)]
fn needs_foo_or_bar() {
// ...
}
// This function is only included when compiling for a unixish OS with a 32-bit
// architecture
#[cfg(unix, target_word_size = "32")]
fn on_32bit_unix() {
// ...
}
~~~~
This illustrates some conditional compilation can be achieved using the
`#[cfg(...)]` attribute. Note that `#[cfg(foo, bar)]` is a condition that needs
both `foo` and `bar` to be defined while `#[cfg(foo)] #[cfg(bar)]` only needs
one of `foo` and `bar` to be defined (this resembles in the disjunctive normal
form). Additionally, one can reverse a condition by enclosing it in a
`not(...)`, like e. g. `#[cfg(not(target_os = "win32"))]`.
To pass a configuration option which triggers a `#[cfg(identifier)]` one can use
`rustc --cfg identifier`. In addition to that, the following configurations are
pre-defined by the compiler:
* `target_arch = "..."`. Target CPU architecture, such as `"x86"`, `"x86_64"`
`"mips"`, or `"arm"`.
* `target_endian = "..."`. Endianness of the target CPU, either `"little"` or
`"big"`.
* `target_family = "..."`. Operating system family of the target, e. g.
`"unix"` or `"windows"`. The value of this configuration option is defined as
a configuration itself, like `unix` or `windows`.
* `target_os = "..."`. Operating system of the target, examples include
`"win32"`, `"macos"`, `"linux"`, `"android"` or `"freebsd"`.
* `target_word_size = "..."`. Target word size in bits. This is set to `"32"`
for 32-bit CPU targets, and likewise set to `"64"` for 64-bit CPU targets.
* `test`. Only set in test builds (`rustc --test`).
* `unix`. See `target_family`.
* `windows`. See `target_family`.
### Lint check attributes
A lint check names a potentially undesirable coding pattern, such as

View File

@ -34,7 +34,6 @@ use std::cast;
use std::cell::{Cell, RefCell};
use std::mem;
use std::num;
use std::ptr;
use std::kinds::marker;
use std::rc::Rc;
use std::rt::global_heap;
@ -144,7 +143,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
let fill = chunk.fill.get();
while idx < fill {
let tydesc_data: *uint = transmute(ptr::offset(buf, idx as int));
let tydesc_data: *uint = transmute(buf.offset(idx as int));
let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
let (size, align) = ((*tydesc).size, (*tydesc).align);
@ -155,7 +154,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
//debug!("freeing object: idx = {}, size = {}, align = {}, done = {}",
// start, size, align, is_done);
if is_done {
((*tydesc).drop_glue)(ptr::offset(buf, start as int) as *i8);
((*tydesc).drop_glue)(buf.offset(start as int) as *i8);
}
// Find where the next tydesc lives
@ -261,7 +260,7 @@ impl Arena {
// start, n_bytes, align, head.fill);
let buf = self.head.as_ptr();
return (ptr::offset(buf, tydesc_start as int), ptr::offset(buf, start as int));
return (buf.offset(tydesc_start as int), buf.offset(start as int));
}
}

View File

@ -119,7 +119,7 @@ impl <T> CVec<T> {
pub fn get<'a>(&'a self, ofs: uint) -> &'a T {
assert!(ofs < self.len);
unsafe {
&*ptr::mut_offset(self.base, ofs as int)
&*self.base.offset(ofs as int)
}
}
@ -131,7 +131,7 @@ impl <T> CVec<T> {
pub fn get_mut<'a>(&'a mut self, ofs: uint) -> &'a mut T {
assert!(ofs < self.len);
unsafe {
&mut *ptr::mut_offset(self.base, ofs as int)
&mut *self.base.offset(ofs as int)
}
}

View File

@ -35,20 +35,10 @@ Rust extras are part of the standard Rust distribution.
#[deny(missing_doc)];
extern mod sync;
#[cfg(not(stage0))]
extern mod serialize;
extern mod collections;
#[cfg(stage0)]
pub mod serialize {
#[allow(missing_doc)];
// Temp re-export until after a snapshot
extern mod serialize = "serialize";
pub use self::serialize::{Encoder, Decoder, Encodable, Decodable,
EncoderHelpers, DecoderHelpers};
}
// Utility modules
pub mod c_vec;
@ -59,11 +49,9 @@ pub mod url;
pub mod json;
pub mod tempfile;
pub mod time;
pub mod base64;
pub mod workcache;
pub mod enum_set;
pub mod stats;
pub mod hex;
#[cfg(unicode)]
mod unicode;

View File

@ -784,11 +784,12 @@ impl BigUint {
if n_bits == 0 || self.data.is_empty() { return (*self).clone(); }
let mut borrow = 0;
let mut shifted = ~[];
let mut shifted_rev = vec::with_capacity(self.data.len());
for elem in self.data.rev_iter() {
shifted = ~[(*elem >> n_bits) | borrow] + shifted;
shifted_rev.push((*elem >> n_bits) | borrow);
borrow = *elem << (BigDigit::bits - n_bits);
}
let shifted = { shifted_rev.reverse(); shifted_rev };
return BigUint::new(shifted);
}
@ -2637,4 +2638,15 @@ mod bench {
fib.to_str();
});
}
#[bench]
fn shr(bh: &mut BenchHarness) {
let n = { let one : BigUint = One::one(); one << 1000 };
bh.iter(|| {
let mut m = n.clone();
for _ in range(0, 10) {
m = m >> 1;
}
})
}
}

View File

@ -34,7 +34,7 @@ use std::run;
use std::str;
use std::io;
use std::io::fs;
use extra::hex::ToHex;
use serialize::hex::ToHex;
use extra::tempfile::TempDir;
use syntax::abi;
use syntax::ast;

View File

@ -30,7 +30,6 @@ use std::io;
use std::num;
use std::option;
use std::os::consts::{macos, freebsd, linux, android, win32};
use std::ptr;
use std::str;
use std::vec;
use flate;
@ -340,7 +339,7 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Option<MetadataBlob> {
});
if !version_ok { return None; }
let cvbuf1 = ptr::offset(cvbuf, vlen as int);
let cvbuf1 = cvbuf.offset(vlen as int);
debug!("inflating {} bytes of compressed metadata",
csz - vlen);
vec::raw::buf_as_slice(cvbuf1, csz-vlen, |bytes| {

View File

@ -21,7 +21,6 @@ use std::cast;
use std::hashmap::HashMap;
use std::libc::{c_uint, c_ulonglong, c_char};
use syntax::codemap::Span;
use std::ptr::is_not_null;
pub struct Builder<'a> {
llbuilder: BuilderRef,
@ -492,7 +491,7 @@ impl<'a> Builder<'a> {
debug!("Store {} -> {}",
self.ccx.tn.val_to_str(val),
self.ccx.tn.val_to_str(ptr));
assert!(is_not_null(self.llbuilder));
assert!(self.llbuilder.is_not_null());
self.count_insn("store");
unsafe {
llvm::LLVMBuildStore(self.llbuilder, val, ptr);
@ -503,7 +502,7 @@ impl<'a> Builder<'a> {
debug!("Store {} -> {}",
self.ccx.tn.val_to_str(val),
self.ccx.tn.val_to_str(ptr));
assert!(is_not_null(self.llbuilder));
assert!(self.llbuilder.is_not_null());
self.count_insn("store.volatile");
unsafe {
let insn = llvm::LLVMBuildStore(self.llbuilder, val, ptr);

View File

@ -3035,6 +3035,7 @@ pub fn check_expr_with_unifier(fcx: @FnCtxt,
if type_is_c_like_enum(fcx, expr.span, t_e) && t_1_is_trivial {
// casts from C-like enums are allowed
} else if t_1_is_char {
let te = fcx.infcx().resolve_type_vars_if_possible(te);
if ty::get(te).sty != ty::ty_uint(ast::TyU8) {
fcx.type_error_message(expr.span, |actual| {
format!("only `u8` can be cast as `char`, not `{}`", actual)

View File

@ -16,7 +16,7 @@ use std::iter::range_step;
use std::num::Zero;
use std::vec;
use std::vec::bytes::{MutableByteVector, copy_memory};
use extra::hex::ToHex;
use serialize::hex::ToHex;
/// Write a u32 into a vector, which must be 4 bytes long. The value is written in big-endian
/// format.
@ -529,7 +529,7 @@ mod tests {
use std::vec;
use std::rand::isaac::IsaacRng;
use std::rand::Rng;
use extra::hex::FromHex;
use serialize::hex::FromHex;
// A normal addition - no overflow occurs
#[test]

View File

@ -342,7 +342,9 @@ impl Clean<Item> for ast::Method {
_ => self.decl.inputs.slice_from(1)
};
let decl = FnDecl {
inputs: inputs.iter().map(|x| x.clean()).collect(),
inputs: Arguments {
values: inputs.iter().map(|x| x.clean()).collect(),
},
output: (self.decl.output.clean()),
cf: self.decl.cf.clean(),
attrs: ~[]
@ -378,7 +380,9 @@ impl Clean<Item> for ast::TypeMethod {
_ => self.decl.inputs.slice_from(1)
};
let decl = FnDecl {
inputs: inputs.iter().map(|x| x.clean()).collect(),
inputs: Arguments {
values: inputs.iter().map(|x| x.clean()).collect(),
},
output: (self.decl.output.clean()),
cf: self.decl.cf.clean(),
attrs: ~[]
@ -472,16 +476,23 @@ impl Clean<ClosureDecl> for ast::ClosureTy {
#[deriving(Clone, Encodable, Decodable)]
pub struct FnDecl {
inputs: ~[Argument],
inputs: Arguments,
output: Type,
cf: RetStyle,
attrs: ~[Attribute]
}
#[deriving(Clone, Encodable, Decodable)]
pub struct Arguments {
values: ~[Argument],
}
impl Clean<FnDecl> for ast::FnDecl {
fn clean(&self) -> FnDecl {
FnDecl {
inputs: self.inputs.iter().map(|x| x.clean()).collect(),
inputs: Arguments {
values: self.inputs.iter().map(|x| x.clean()).collect(),
},
output: (self.output.clean()),
cf: self.cf.clean(),
attrs: ~[]

View File

@ -404,6 +404,19 @@ impl fmt::Show for clean::Type {
}
}
impl fmt::Show for clean::Arguments {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for (i, input) in self.values.iter().enumerate() {
if i > 0 { if_ok!(write!(f.buf, ", ")); }
if input.name.len() > 0 {
if_ok!(write!(f.buf, "{}: ", input.name));
}
if_ok!(write!(f.buf, "{}", input.type_));
}
Ok(())
}
}
impl fmt::Show for clean::FnDecl {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f.buf, "({args}){arrow, select, yes{ -&gt; {ret}} other{}}",
@ -413,20 +426,6 @@ impl fmt::Show for clean::FnDecl {
}
}
impl fmt::Show for ~[clean::Argument] {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut args = ~"";
for (i, input) in self.iter().enumerate() {
if i > 0 { args.push_str(", "); }
if input.name.len() > 0 {
args.push_str(format!("{}: ", input.name));
}
args.push_str(format!("{}", input.type_));
}
f.buf.write(args.as_bytes())
}
}
impl<'a> fmt::Show for Method<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let Method(selfty, d) = *self;
@ -448,7 +447,7 @@ impl<'a> fmt::Show for Method<'a> {
args.push_str("&amp;self");
}
}
for (i, input) in d.inputs.iter().enumerate() {
for (i, input) in d.inputs.values.iter().enumerate() {
if i > 0 || args.len() > 0 { args.push_str(", "); }
if input.name.len() > 0 {
args.push_str(format!("{}: ", input.name));

View File

@ -426,7 +426,7 @@ mod test {
unsafe {
let base = transmute::<*u8, *mut u8>(buf.base);
(*base) = 1;
(*ptr::mut_offset(base, 1)) = 2;
(*base.offset(1)) = 2;
}
assert!(slice[0] == 1);

View File

@ -63,8 +63,8 @@ impl<'a> ToBase64 for &'a [u8] {
* # Example
*
* ```rust
* extern mod extra;
* use extra::base64::{ToBase64, STANDARD};
* extern mod serialize;
* use serialize::base64::{ToBase64, STANDARD};
*
* fn main () {
* let str = [52,32].to_base64(STANDARD);
@ -189,8 +189,8 @@ impl<'a> FromBase64 for &'a str {
* This converts a string literal to base64 and back.
*
* ```rust
* extern mod extra;
* use extra::base64::{ToBase64, FromBase64, STANDARD};
* extern mod serialize;
* use serialize::base64::{ToBase64, FromBase64, STANDARD};
* use std::str;
*
* fn main () {
@ -261,8 +261,8 @@ impl<'a> FromBase64 for &'a str {
#[cfg(test)]
mod test {
use test::BenchHarness;
use base64::*;
use extra::test::BenchHarness;
use base64::{Config, FromBase64, ToBase64, STANDARD, URL_SAFE};
#[test]
fn test_to_base64_basic() {

View File

@ -131,7 +131,6 @@ pub mod reader {
}
pub fn vuint_at(data: &[u8], start: uint) -> Res {
use std::ptr::offset;
use std::mem::from_be32;
if data.len() - start < 4 {
@ -163,7 +162,7 @@ pub mod reader {
unsafe {
let (ptr, _): (*u8, uint) = transmute(data);
let ptr = offset(ptr, start as int);
let ptr = ptr.offset(start as int);
let ptr: *i32 = transmute(ptr);
let val = from_be32(*ptr) as u32;

View File

@ -28,7 +28,8 @@ impl<'a> ToHex for &'a [u8] {
* # Example
*
* ```rust
* use extra::hex::ToHex;
* extern mod serialize;
* use serialize::hex::ToHex;
*
* fn main () {
* let str = [52,32].to_hex();
@ -88,7 +89,8 @@ impl<'a> FromHex for &'a str {
* This converts a string literal to hexadecimal and back.
*
* ```rust
* use extra::hex::{FromHex, ToHex};
* extern mod serialize;
* use serialize::hex::{FromHex, ToHex};
* use std::str;
*
* fn main () {
@ -137,8 +139,8 @@ impl<'a> FromHex for &'a str {
#[cfg(test)]
mod tests {
use test::BenchHarness;
use hex::*;
use extra::test::BenchHarness;
use hex::{FromHex, ToHex};
#[test]
pub fn test_to_hex() {

View File

@ -30,4 +30,8 @@ pub use self::serialize::{Decoder, Encoder, Decodable, Encodable,
DecoderHelpers, EncoderHelpers};
mod serialize;
pub mod base64;
pub mod ebml;
pub mod hex;

View File

@ -21,6 +21,7 @@
//! extension traits (`*Ext`) for the full details.
use cast::transmute;
use fmt;
use option::{Option, Some, None};
use result::{Result, Ok, Err};
use to_str::ToStr;
@ -158,6 +159,18 @@ impl<'a> ToStr for &'a Any {
fn to_str(&self) -> ~str { ~"&Any" }
}
impl fmt::Show for ~Any {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("~Any")
}
}
impl<'a> fmt::Show for &'a Any {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("&Any")
}
}
#[cfg(test)]
mod tests {
use prelude::*;
@ -377,4 +390,17 @@ mod tests {
assert!(a.move::<~Test>().is_err());
assert!(b.move::<~uint>().is_err());
}
#[test]
fn test_show() {
let a = ~8u as ~Any;
let b = ~Test as ~Any;
assert_eq!(format!("{}", a), ~"~Any");
assert_eq!(format!("{}", b), ~"~Any");
let a = &8u as &Any;
let b = &Test as &Any;
assert_eq!(format!("{}", a), ~"&Any");
assert_eq!(format!("{}", b), ~"&Any");
}
}

View File

@ -17,6 +17,7 @@ use str::StrSlice;
use str::OwnedStr;
use container::Container;
use cast;
use fmt;
use iter::Iterator;
use vec::{ImmutableVector, MutableVector, Vector};
use to_bytes::IterBytes;
@ -134,6 +135,12 @@ impl ToStr for Ascii {
}
}
impl<'a> fmt::Show for Ascii {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
(self.chr as char).fmt(f)
}
}
/// Trait for converting into an ascii type.
pub trait AsciiCast<T> {
/// Convert to an ascii type, fail on non-ASCII input.
@ -698,5 +705,9 @@ mod tests {
assert_eq!(s, ~"t");
}
#[test]
fn test_show() {
let c = Ascii { chr: 't' as u8 };
assert_eq!(format!("{}", c), ~"t");
}
}

View File

@ -310,7 +310,7 @@ impl<'a> ToCStr for &'a [u8] {
let buf = malloc_raw(self_len + 1);
ptr::copy_memory(buf, self.as_ptr(), self_len);
*ptr::mut_offset(buf, self_len as int) = 0;
*buf.offset(self_len as int) = 0;
CString::new(buf as *libc::c_char, true)
}
@ -368,7 +368,7 @@ impl<'a> Iterator<libc::c_char> for CChars<'a> {
if ch == 0 {
None
} else {
self.ptr = unsafe { ptr::offset(self.ptr, 1) };
self.ptr = unsafe { self.ptr.offset(1) };
Some(ch)
}
}
@ -429,18 +429,18 @@ mod tests {
fn test_str_to_c_str() {
"".to_c_str().with_ref(|buf| {
unsafe {
assert_eq!(*ptr::offset(buf, 0), 0);
assert_eq!(*buf.offset(0), 0);
}
});
"hello".to_c_str().with_ref(|buf| {
unsafe {
assert_eq!(*ptr::offset(buf, 0), 'h' as libc::c_char);
assert_eq!(*ptr::offset(buf, 1), 'e' as libc::c_char);
assert_eq!(*ptr::offset(buf, 2), 'l' as libc::c_char);
assert_eq!(*ptr::offset(buf, 3), 'l' as libc::c_char);
assert_eq!(*ptr::offset(buf, 4), 'o' as libc::c_char);
assert_eq!(*ptr::offset(buf, 5), 0);
assert_eq!(*buf.offset(0), 'h' as libc::c_char);
assert_eq!(*buf.offset(1), 'e' as libc::c_char);
assert_eq!(*buf.offset(2), 'l' as libc::c_char);
assert_eq!(*buf.offset(3), 'l' as libc::c_char);
assert_eq!(*buf.offset(4), 'o' as libc::c_char);
assert_eq!(*buf.offset(5), 0);
}
})
}
@ -450,28 +450,28 @@ mod tests {
let b: &[u8] = [];
b.to_c_str().with_ref(|buf| {
unsafe {
assert_eq!(*ptr::offset(buf, 0), 0);
assert_eq!(*buf.offset(0), 0);
}
});
let _ = bytes!("hello").to_c_str().with_ref(|buf| {
unsafe {
assert_eq!(*ptr::offset(buf, 0), 'h' as libc::c_char);
assert_eq!(*ptr::offset(buf, 1), 'e' as libc::c_char);
assert_eq!(*ptr::offset(buf, 2), 'l' as libc::c_char);
assert_eq!(*ptr::offset(buf, 3), 'l' as libc::c_char);
assert_eq!(*ptr::offset(buf, 4), 'o' as libc::c_char);
assert_eq!(*ptr::offset(buf, 5), 0);
assert_eq!(*buf.offset(0), 'h' as libc::c_char);
assert_eq!(*buf.offset(1), 'e' as libc::c_char);
assert_eq!(*buf.offset(2), 'l' as libc::c_char);
assert_eq!(*buf.offset(3), 'l' as libc::c_char);
assert_eq!(*buf.offset(4), 'o' as libc::c_char);
assert_eq!(*buf.offset(5), 0);
}
});
let _ = bytes!("foo", 0xff).to_c_str().with_ref(|buf| {
unsafe {
assert_eq!(*ptr::offset(buf, 0), 'f' as libc::c_char);
assert_eq!(*ptr::offset(buf, 1), 'o' as libc::c_char);
assert_eq!(*ptr::offset(buf, 2), 'o' as libc::c_char);
assert_eq!(*ptr::offset(buf, 3), 0xff as i8);
assert_eq!(*ptr::offset(buf, 4), 0);
assert_eq!(*buf.offset(0), 'f' as libc::c_char);
assert_eq!(*buf.offset(1), 'o' as libc::c_char);
assert_eq!(*buf.offset(2), 'o' as libc::c_char);
assert_eq!(*buf.offset(3), 0xff as i8);
assert_eq!(*buf.offset(4), 0);
}
});
}
@ -634,7 +634,6 @@ mod bench {
use extra::test::BenchHarness;
use libc;
use prelude::*;
use ptr;
#[inline]
fn check(s: &str, c_str: *libc::c_char) {
@ -642,8 +641,8 @@ mod bench {
for i in range(0, s.len()) {
unsafe {
assert_eq!(
*ptr::offset(s_buf, i as int) as libc::c_char,
*ptr::offset(c_str, i as int));
*s_buf.offset(i as int) as libc::c_char,
*c_str.offset(i as int));
}
}
}

View File

@ -57,53 +57,6 @@ fn debug_mem() -> bool {
}
/// Destroys all managed memory (i.e. @ boxes) held by the current task.
#[cfg(stage0)]
pub unsafe fn annihilate() {
use rt::local_heap::local_free;
let mut n_total_boxes = 0u;
// Pass 1: Make all boxes immortal.
//
// In this pass, nothing gets freed, so it does not matter whether
// we read the next field before or after the callback.
each_live_alloc(true, |alloc| {
n_total_boxes += 1;
(*alloc).ref_count = RC_IMMORTAL;
true
});
// Pass 2: Drop all boxes.
//
// In this pass, unique-managed boxes may get freed, but not
// managed boxes, so we must read the `next` field *after* the
// callback, as the original value may have been freed.
each_live_alloc(false, |alloc| {
let tydesc = (*alloc).type_desc;
let data = &(*alloc).data as *();
((*tydesc).drop_glue)(data as *i8);
true
});
// Pass 3: Free all boxes.
//
// In this pass, managed boxes may get freed (but not
// unique-managed boxes, though I think that none of those are
// left), so we must read the `next` field before, since it will
// not be valid after.
each_live_alloc(true, |alloc| {
local_free(alloc as *u8);
true
});
if debug_mem() {
// We do logging here w/o allocation.
debug!("total boxes annihilated: {}", n_total_boxes);
}
}
/// Destroys all managed memory (i.e. @ boxes) held by the current task.
#[cfg(not(stage0))]
pub unsafe fn annihilate() {
use rt::local_heap::local_free;

View File

@ -60,21 +60,17 @@ use uint;
macro_rules! select {
(
$name1:pat = $port1:ident.$meth1:ident() => $code1:expr,
$($name:pat = $port:ident.$meth:ident() => $code:expr),*
$($name:pat = $port:ident.$meth:ident() => $code:expr),+
) => ({
use std::comm::Select;
let sel = Select::new();
let mut $port1 = sel.handle(&$port1);
$( let mut $port = sel.handle(&$port); )*
$( let mut $port = sel.handle(&$port); )+
unsafe {
$port1.add();
$( $port.add(); )*
$( $port.add(); )+
}
let ret = sel.wait();
if ret == $port1.id { let $name1 = $port1.$meth1(); $code1 }
$( else if ret == $port.id { let $name = $port.$meth(); $code } )*
else { unreachable!() }
$( if ret == $port.id() { let $name = $port.$meth(); $code } else )+
{ unreachable!() }
})
}
@ -94,7 +90,7 @@ pub struct Select {
pub struct Handle<'port, T> {
/// The ID of this handle, used to compare against the return value of
/// `Select::wait()`
id: uint,
priv id: uint,
priv selector: &'port Select,
priv next: *mut Handle<'static, ()>,
priv prev: *mut Handle<'static, ()>,
@ -150,11 +146,16 @@ impl Select {
/// Waits for an event on this port set. The returned valus is *not* and
/// index, but rather an id. This id can be queried against any active
/// `Handle` structures (each one has a public `id` field). The handle with
/// `Handle` structures (each one has an `id` method). The handle with
/// the matching `id` will have some sort of event available on it. The
/// event could either be that data is available or the corresponding
/// channel has been closed.
pub fn wait(&self) -> uint {
self.wait2(false)
}
/// Helper method for skipping the preflight checks during testing
fn wait2(&self, do_preflight_checks: bool) -> uint {
// Note that this is currently an inefficient implementation. We in
// theory have knowledge about all ports in the set ahead of time, so
// this method shouldn't really have to iterate over all of them yet
@ -179,7 +180,7 @@ impl Select {
let mut amt = 0;
for p in self.iter() {
amt += 1;
if (*p).packet.can_recv() {
if do_preflight_checks && (*p).packet.can_recv() {
return (*p).id;
}
}
@ -242,6 +243,10 @@ impl Select {
}
impl<'port, T: Send> Handle<'port, T> {
/// Retrieve the id of this handle.
#[inline]
pub fn id(&self) -> uint { self.id }
/// Receive a value on the underlying port. Has the same semantics as
/// `Port.recv`
pub fn recv(&mut self) -> T { self.port.recv() }
@ -355,7 +360,7 @@ mod test {
)
drop(c2);
select! (
bar = p2.recv_opt() => { assert_eq!(bar, None); },
bar = p2.recv_opt() => { assert_eq!(bar, None); }
)
})
@ -507,7 +512,7 @@ mod test {
let (p2, c2) = Chan::<()>::new();
let (p, c) = Chan::new();
spawn(proc() {
let mut s = Select::new();
let s = Select::new();
let mut h1 = s.handle(&p1);
let mut h2 = s.handle(&p2);
unsafe { h2.add(); }
@ -521,4 +526,91 @@ mod test {
c2.send(());
p.recv();
})
test!(fn preflight1() {
let (p, c) = Chan::new();
c.send(());
select!(
() = p.recv() => {}
)
})
test!(fn preflight2() {
let (p, c) = Chan::new();
c.send(());
c.send(());
select!(
() = p.recv() => {}
)
})
test!(fn preflight3() {
let (p, c) = Chan::new();
drop(c.clone());
c.send(());
select!(
() = p.recv() => {}
)
})
test!(fn preflight4() {
let (p, c) = Chan::new();
c.send(());
let s = Select::new();
let mut h = s.handle(&p);
unsafe { h.add(); }
assert_eq!(s.wait2(false), h.id);
})
test!(fn preflight5() {
let (p, c) = Chan::new();
c.send(());
c.send(());
let s = Select::new();
let mut h = s.handle(&p);
unsafe { h.add(); }
assert_eq!(s.wait2(false), h.id);
})
test!(fn preflight6() {
let (p, c) = Chan::new();
drop(c.clone());
c.send(());
let s = Select::new();
let mut h = s.handle(&p);
unsafe { h.add(); }
assert_eq!(s.wait2(false), h.id);
})
test!(fn preflight7() {
let (p, c) = Chan::<()>::new();
drop(c);
let s = Select::new();
let mut h = s.handle(&p);
unsafe { h.add(); }
assert_eq!(s.wait2(false), h.id);
})
test!(fn preflight8() {
let (p, c) = Chan::new();
c.send(());
drop(c);
p.recv();
let s = Select::new();
let mut h = s.handle(&p);
unsafe { h.add(); }
assert_eq!(s.wait2(false), h.id);
})
test!(fn preflight9() {
let (p, c) = Chan::new();
drop(c.clone());
c.send(());
drop(c);
p.recv();
let s = Select::new();
let mut h = s.handle(&p);
unsafe { h.add(); }
assert_eq!(s.wait2(false), h.id);
})
}

View File

@ -398,6 +398,17 @@ impl<T: Send> Packet<T> {
cnt == DISCONNECTED || cnt - self.steals > 0
}
// increment the count on the channel (used for selection)
fn bump(&mut self, amt: int) -> int {
match self.cnt.fetch_add(amt, atomics::SeqCst) {
DISCONNECTED => {
self.cnt.store(DISCONNECTED, atomics::SeqCst);
DISCONNECTED
}
n => n
}
}
// Inserts the blocked task for selection on this port, returning it back if
// the port already has data on it.
//
@ -408,8 +419,8 @@ impl<T: Send> Packet<T> {
match self.decrement(task) {
Ok(()) => Ok(()),
Err(task) => {
let prev = self.cnt.fetch_add(1, atomics::SeqCst);
assert!(prev >= 0);
let prev = self.bump(1);
assert!(prev == DISCONNECTED || prev >= 0);
return Err(task);
}
}
@ -440,11 +451,10 @@ impl<T: Send> Packet<T> {
let cnt = self.cnt.load(atomics::SeqCst);
if cnt < 0 && cnt != DISCONNECTED {-cnt} else {0}
};
let prev = self.cnt.fetch_add(steals + 1, atomics::SeqCst);
let prev = self.bump(steals + 1);
if prev == DISCONNECTED {
assert_eq!(self.to_wake.load(atomics::SeqCst), 0);
self.cnt.store(DISCONNECTED, atomics::SeqCst);
true
} else {
let cur = prev + steals + 1;

View File

@ -333,6 +333,17 @@ impl<T: Send> Packet<T> {
}
}
// increment the count on the channel (used for selection)
fn bump(&mut self, amt: int) -> int {
match self.cnt.fetch_add(amt, atomics::SeqCst) {
DISCONNECTED => {
self.cnt.store(DISCONNECTED, atomics::SeqCst);
DISCONNECTED
}
n => n
}
}
// Attempts to start selecting on this port. Like a oneshot, this can fail
// immediately because of an upgrade.
pub fn start_selection(&mut self, task: BlockedTask) -> SelectionResult<T> {
@ -351,8 +362,8 @@ impl<T: Send> Packet<T> {
};
// Undo our decrement above, and we should be guaranteed that the
// previous value is positive because we're not going to sleep
let prev = self.cnt.fetch_add(1, atomics::SeqCst);
assert!(prev >= 0);
let prev = self.bump(1);
assert!(prev == DISCONNECTED || prev >= 0);
return ret;
}
}
@ -384,13 +395,12 @@ impl<T: Send> Packet<T> {
// and in the stream case we can have at most one steal, so just assume
// that we had one steal.
let steals = 1;
let prev = self.cnt.fetch_add(steals + 1, atomics::SeqCst);
let prev = self.bump(steals + 1);
// If we were previously disconnected, then we know for sure that there
// is no task in to_wake, so just keep going
let has_data = if prev == DISCONNECTED {
assert_eq!(self.to_wake.load(atomics::SeqCst), 0);
self.cnt.store(DISCONNECTED, atomics::SeqCst);
true // there is data, that data is that we're disconnected
} else {
let cur = prev + steals + 1;

View File

@ -56,6 +56,7 @@ use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
use clone::Clone;
use cmp::{Eq, Equiv};
use default::Default;
#[cfg(not(stage0))] use fmt;
use hash::Hash;
use iter;
use iter::{Iterator, FromIterator, Extendable};
@ -65,6 +66,7 @@ use num;
use option::{None, Option, Some};
use rand::Rng;
use rand;
#[cfg(not(stage0))] use result::{Ok, Err};
use vec::{ImmutableVector, MutableVector, OwnedVector, Items, MutItems};
use vec_ng;
use vec_ng::Vec;
@ -595,6 +597,23 @@ impl<K:Hash + Eq + Clone,V:Clone> Clone for HashMap<K,V> {
}
}
#[cfg(not(stage0))]
impl<A: fmt::Show + Hash + Eq, B: fmt::Show> fmt::Show for HashMap<A, B> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if_ok!(write!(f.buf, r"\{"))
let mut first = true;
for (key, value) in self.iter() {
if first {
first = false;
} else {
if_ok!(write!(f.buf, ", "));
}
if_ok!(write!(f.buf, "{}: {}", *key, *value));
}
write!(f.buf, r"\}")
}
}
/// HashMap iterator
#[deriving(Clone)]
pub struct Entries<'a, K, V> {
@ -857,6 +876,23 @@ impl<T:Hash + Eq + Clone> Clone for HashSet<T> {
}
}
#[cfg(not(stage0))]
impl<A: fmt::Show + Hash + Eq> fmt::Show for HashSet<A> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if_ok!(write!(f.buf, r"\{"))
let mut first = true;
for x in self.iter() {
if first {
first = false;
} else {
if_ok!(write!(f.buf, ", "));
}
if_ok!(write!(f.buf, "{}", *x));
}
write!(f.buf, r"\}")
}
}
impl<K: Eq + Hash> FromIterator<K> for HashSet<K> {
fn from_iterator<T: Iterator<K>>(iter: &mut T) -> HashSet<K> {
let (lower, _) = iter.size_hint();
@ -890,6 +926,7 @@ pub type SetAlgebraItems<'a, T> =
mod test_map {
use prelude::*;
use super::*;
use fmt;
#[test]
fn test_create_capacity_zero() {
@ -1121,6 +1158,30 @@ mod test_map {
assert_eq!(map.find(&k), Some(&v));
}
}
struct ShowableStruct {
value: int,
}
impl fmt::Show for ShowableStruct {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f.buf, r"s{}", self.value)
}
}
#[test]
fn test_show() {
let mut table: HashMap<int, ShowableStruct> = HashMap::new();
let empty: HashMap<int, ShowableStruct> = HashMap::new();
table.insert(3, ShowableStruct { value: 4 });
table.insert(1, ShowableStruct { value: 2 });
let table_str = format!("{}", table);
assert!(table_str == ~"{1: s2, 3: s4}" || table_str == ~"{3: s4, 1: s2}");
assert_eq!(format!("{}", empty), ~"{}");
}
}
#[cfg(test)]
@ -1346,4 +1407,18 @@ mod test_set {
assert_eq!(s1, s2);
}
#[test]
fn test_show() {
let mut set: HashSet<int> = HashSet::new();
let empty: HashSet<int> = HashSet::new();
set.insert(1);
set.insert(2);
let set_str = format!("{}", set);
assert!(set_str == ~"{1, 2}" || set_str == ~"{2, 1}");
assert_eq!(format!("{}", empty), ~"{}");
}
}

View File

@ -18,6 +18,7 @@ use iter::Iterator;
use option::Option;
use io::Reader;
use vec::{OwnedVector, ImmutableVector};
use ptr::RawPtr;
/// An iterator that reads a single byte on each iteration,
/// until `.read_byte()` returns `None`.
@ -104,7 +105,7 @@ pub fn u64_from_be_bytes(data: &[u8],
start: uint,
size: uint)
-> u64 {
use ptr::{copy_nonoverlapping_memory, offset, mut_offset};
use ptr::{copy_nonoverlapping_memory};
use mem::from_be64;
use vec::MutableVector;
@ -116,9 +117,9 @@ pub fn u64_from_be_bytes(data: &[u8],
let mut buf = [0u8, ..8];
unsafe {
let ptr = offset(data.as_ptr(), start as int);
let ptr = data.as_ptr().offset(start as int);
let out = buf.as_mut_ptr();
copy_nonoverlapping_memory(mut_offset(out, (8 - size) as int), ptr, size);
copy_nonoverlapping_memory(out.offset((8 - size) as int), ptr, size);
from_be64(*(out as *i64)) as u64
}
}

View File

@ -145,16 +145,18 @@ macro_rules! format(
#[macro_export]
macro_rules! write(
($dst:expr, $($arg:tt)*) => (
format_args!(|args| { ::std::fmt::write($dst, args) }, $($arg)*)
)
($dst:expr, $($arg:tt)*) => ({
let dst: &mut ::std::io::Writer = $dst;
format_args!(|args| { ::std::fmt::write(dst, args) }, $($arg)*)
})
)
#[macro_export]
macro_rules! writeln(
($dst:expr, $($arg:tt)*) => (
format_args!(|args| { ::std::fmt::writeln($dst, args) }, $($arg)*)
)
($dst:expr, $($arg:tt)*) => ({
let dst: &mut ::std::io::Writer = $dst;
format_args!(|args| { ::std::fmt::writeln(dst, args) }, $($arg)*)
})
)
#[macro_export]

View File

@ -21,23 +21,6 @@ use unstable::intrinsics;
#[cfg(not(test))] use cmp::{Eq, Ord};
/// Calculate the offset from a pointer.
/// The `count` argument is in units of T; e.g. a `count` of 3
/// represents a pointer offset of `3 * sizeof::<T>()` bytes.
#[inline]
pub unsafe fn offset<T>(ptr: *T, count: int) -> *T {
intrinsics::offset(ptr, count)
}
/// Calculate the offset from a mut pointer. The count *must* be in bounds or
/// otherwise the loads of this address are undefined.
/// The `count` argument is in units of T; e.g. a `count` of 3
/// represents a pointer offset of `3 * sizeof::<T>()` bytes.
#[inline]
pub unsafe fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
intrinsics::offset(ptr as *T, count) as *mut T
}
/// Return the offset of the first null pointer in `buf`.
#[inline]
pub unsafe fn buf_len<T>(buf: **T) -> uint {
@ -63,7 +46,7 @@ impl<T> Clone for *mut T {
pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
let mut i = 0;
loop {
if f(&(*offset(buf, i as int))) { return i; }
if f(&(*buf.offset(i as int))) { return i; }
else { i += 1; }
}
}
@ -76,14 +59,6 @@ pub fn null<T>() -> *T { 0 as *T }
#[inline]
pub fn mut_null<T>() -> *mut T { 0 as *mut T }
/// Returns true if the pointer is equal to the null pointer.
#[inline]
pub fn is_null<T,P:RawPtr<T>>(ptr: P) -> bool { ptr.is_null() }
/// Returns true if the pointer is not equal to the null pointer.
#[inline]
pub fn is_not_null<T,P:RawPtr<T>>(ptr: P) -> bool { ptr.is_not_null() }
/**
* Copies data from one location to another.
*
@ -206,7 +181,7 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
}
//let start_ptr = *arr;
for e in range(0, len) {
let n = offset(arr, e as int);
let n = arr.offset(e as int);
cb(*n);
}
debug!("array_each_with_len: after iterate");
@ -278,7 +253,7 @@ impl<T> RawPtr<T> for *T {
/// Calculates the offset from a pointer. The offset *must* be in-bounds of
/// the object, or one-byte-past-the-end.
#[inline]
unsafe fn offset(self, count: int) -> *T { offset(self, count) }
unsafe fn offset(self, count: int) -> *T { intrinsics::offset(self, count) }
}
/// Extension methods for mutable pointers
@ -323,7 +298,7 @@ impl<T> RawPtr<T> for *mut T {
/// This method should be preferred over `offset` when the guarantee can be
/// satisfied, to enable better optimization.
#[inline]
unsafe fn offset(self, count: int) -> *mut T { mut_offset(self, count) }
unsafe fn offset(self, count: int) -> *mut T { intrinsics::offset(self as *T, count) as *mut T }
}
// Equality for pointers
@ -478,14 +453,14 @@ pub mod ptr_tests {
let v0 = ~[32000u16, 32001u16, 32002u16];
let mut v1 = ~[0u16, 0u16, 0u16];
copy_memory(mut_offset(v1.as_mut_ptr(), 1),
offset(v0.as_ptr(), 1), 1);
copy_memory(v1.as_mut_ptr().offset(1),
v0.as_ptr().offset(1), 1);
assert!((v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16));
copy_memory(v1.as_mut_ptr(),
offset(v0.as_ptr(), 2), 1);
v0.as_ptr().offset(2), 1);
assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
v1[2] == 0u16));
copy_memory(mut_offset(v1.as_mut_ptr(), 2),
copy_memory(v1.as_mut_ptr().offset(2),
v0.as_ptr(), 1u);
assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
v1[2] == 32000u16));
@ -525,7 +500,7 @@ pub mod ptr_tests {
assert!(p.is_null());
assert!(!p.is_not_null());
let q = unsafe { offset(p, 1) };
let q = unsafe { p.offset(1) };
assert!(!q.is_null());
assert!(q.is_not_null());

View File

@ -441,11 +441,4 @@ impl<V:TyVisitor + MovePtr> TyVisitor for MovePtrAdaptor<V> {
self.align_to::<&'static u8>();
true
}
// NOTE Remove after next snapshot.
#[cfg(stage0)]
fn visit_type(&mut self) -> bool {
if ! self.inner.visit_type() { return false; }
true
}
}

View File

@ -23,6 +23,7 @@ use io;
use iter::Iterator;
use option::{Some, None, Option};
use ptr;
use ptr::RawPtr;
use reflect;
use reflect::{MovePtr, align};
use result::{Ok, Err};
@ -221,7 +222,7 @@ impl<'a> ReprVisitor<'a> {
if_ok!(self, self.writer.write(", ".as_bytes()));
}
self.visit_ptr_inner(p as *u8, inner);
p = align(unsafe { ptr::offset(p, sz as int) as uint }, al) as *u8;
p = align(unsafe { p.offset(sz as int) as uint }, al) as *u8;
left -= dec;
}
if_ok!(self, self.writer.write([']' as u8]));
@ -601,10 +602,6 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
fn visit_param(&mut self, _i: uint) -> bool { true }
fn visit_self(&mut self) -> bool { true }
// NOTE Remove after next snapshot.
#[cfg(stage0)]
fn visit_type(&mut self) -> bool { true }
}
pub fn write_repr<T>(writer: &mut io::Writer, object: &T) -> io::IoResult<()> {

View File

@ -10,8 +10,6 @@
use libc::{c_void, size_t, free, malloc, realloc};
use ptr::{RawPtr, mut_null};
#[cfg(stage0)]
use unstable::intrinsics::TyDesc;
use unstable::intrinsics::abort;
use unstable::raw;
use mem::size_of;
@ -75,15 +73,7 @@ pub unsafe fn exchange_malloc(size: uint) -> *u8 {
}
// FIXME: #7496
#[cfg(not(test), stage0)]
#[lang="closure_exchange_malloc"]
#[inline]
pub unsafe fn closure_exchange_malloc_(td: *u8, size: uint) -> *u8 {
closure_exchange_malloc(td, size)
}
// FIXME: #7496
#[cfg(not(test), not(stage0))]
#[cfg(not(test))]
#[lang="closure_exchange_malloc"]
#[inline]
pub unsafe fn closure_exchange_malloc_(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 {
@ -91,24 +81,6 @@ pub unsafe fn closure_exchange_malloc_(drop_glue: fn(*mut u8), size: uint, align
}
#[inline]
#[cfg(stage0)]
pub unsafe fn closure_exchange_malloc(td: *u8, size: uint) -> *u8 {
let td = td as *TyDesc;
let size = size;
assert!(td.is_not_null());
let total_size = get_box_size(size, (*td).align);
let p = malloc_raw(total_size);
let alloc = p as *mut raw::Box<()>;
(*alloc).type_desc = td;
alloc as *u8
}
#[inline]
#[cfg(not(stage0))]
pub unsafe fn closure_exchange_malloc(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 {
let total_size = get_box_size(size, align);
let p = malloc_raw(total_size);

View File

@ -21,8 +21,6 @@ use rt::env;
use rt::global_heap;
use rt::local::Local;
use rt::task::Task;
#[cfg(stage0)]
use unstable::intrinsics::TyDesc;
use unstable::raw;
use vec::ImmutableVector;
@ -61,29 +59,6 @@ impl LocalHeap {
}
#[inline]
#[cfg(stage0)]
pub fn alloc(&mut self, td: *TyDesc, size: uint) -> *mut Box {
let total_size = global_heap::get_box_size(size, unsafe { (*td).align });
let alloc = self.memory_region.malloc(total_size);
{
// Make sure that we can't use `mybox` outside of this scope
let mybox: &mut Box = unsafe { cast::transmute(alloc) };
// Clear out this box, and move it to the front of the live
// allocations list
mybox.type_desc = td;
mybox.ref_count = 1;
mybox.prev = ptr::mut_null();
mybox.next = self.live_allocs;
if !self.live_allocs.is_null() {
unsafe { (*self.live_allocs).prev = alloc; }
}
self.live_allocs = alloc;
}
return alloc;
}
#[inline]
#[cfg(not(stage0))]
pub fn alloc(&mut self, drop_glue: fn(*mut u8), size: uint, align: uint) -> *mut Box {
let total_size = global_heap::get_box_size(size, align);
let alloc = self.memory_region.malloc(total_size);
@ -126,41 +101,6 @@ impl LocalHeap {
}
#[inline]
#[cfg(stage0)]
pub fn free(&mut self, alloc: *mut Box) {
{
// Make sure that we can't use `mybox` outside of this scope
let mybox: &mut Box = unsafe { cast::transmute(alloc) };
assert!(!mybox.type_desc.is_null());
// Unlink it from the linked list
if !mybox.prev.is_null() {
unsafe { (*mybox.prev).next = mybox.next; }
}
if !mybox.next.is_null() {
unsafe { (*mybox.next).prev = mybox.prev; }
}
if self.live_allocs == alloc {
self.live_allocs = mybox.next;
}
// Destroy the box memory-wise
if self.poison_on_free {
unsafe {
let ptr: *mut u8 = cast::transmute(&mybox.data);
ptr::set_memory(ptr, 0xab, (*mybox.type_desc).size);
}
}
mybox.prev = ptr::mut_null();
mybox.next = ptr::mut_null();
mybox.type_desc = ptr::null();
}
self.memory_region.free(alloc);
}
#[inline]
#[cfg(not(stage0))]
pub fn free(&mut self, alloc: *mut Box) {
{
// Make sure that we can't use `mybox` outside of this scope
@ -339,20 +279,6 @@ impl Drop for MemoryRegion {
}
#[inline]
#[cfg(stage0)]
pub unsafe fn local_malloc(td: *u8, size: uint) -> *u8 {
// FIXME: Unsafe borrow for speed. Lame.
let task: Option<*mut Task> = Local::try_unsafe_borrow();
match task {
Some(task) => {
(*task).heap.alloc(td as *TyDesc, size) as *u8
}
None => rtabort!("local malloc outside of task")
}
}
#[inline]
#[cfg(not(stage0))]
pub unsafe fn local_malloc(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 {
// FIXME: Unsafe borrow for speed. Lame.
let task: Option<*mut Task> = Local::try_unsafe_borrow();

View File

@ -1242,7 +1242,7 @@ pub mod raw {
let mut i = 0;
while *curr != 0 {
i += 1;
curr = ptr::offset(buf, i);
curr = buf.offset(i);
}
from_buf_len(buf as *u8, i as uint)
}
@ -1272,7 +1272,7 @@ pub mod raw {
let mut len = 0u;
while *curr != 0u8 {
len += 1u;
curr = ptr::offset(s, len as int);
curr = s.offset(len as int);
}
let v = Slice { data: s, len: len };
assert!(is_utf8(::cast::transmute(v)));
@ -2921,7 +2921,6 @@ impl Default for ~str {
mod tests {
use iter::AdditiveIterator;
use prelude::*;
use ptr;
use str::*;
#[test]
@ -3549,11 +3548,11 @@ mod tests {
fn test_as_ptr() {
let buf = "hello".as_ptr();
unsafe {
assert_eq!(*ptr::offset(buf, 0), 'h' as u8);
assert_eq!(*ptr::offset(buf, 1), 'e' as u8);
assert_eq!(*ptr::offset(buf, 2), 'l' as u8);
assert_eq!(*ptr::offset(buf, 3), 'l' as u8);
assert_eq!(*ptr::offset(buf, 4), 'o' as u8);
assert_eq!(*buf.offset(0), 'h' as u8);
assert_eq!(*buf.offset(1), 'e' as u8);
assert_eq!(*buf.offset(2), 'l' as u8);
assert_eq!(*buf.offset(3), 'l' as u8);
assert_eq!(*buf.offset(4), 'o' as u8);
}
}
@ -4164,6 +4163,7 @@ mod tests {
assert_eq!(s.len(), 5);
assert_eq!(s.as_slice(), "abcde");
assert_eq!(s.to_str(), ~"abcde");
assert_eq!(format!("{}", s), ~"abcde");
assert!(s.lt(&Owned(~"bcdef")));
assert_eq!(Slice(""), Default::default());
@ -4171,6 +4171,7 @@ mod tests {
assert_eq!(o.len(), 5);
assert_eq!(o.as_slice(), "abcde");
assert_eq!(o.to_str(), ~"abcde");
assert_eq!(format!("{}", o), ~"abcde");
assert!(o.lt(&Slice("bcdef")));
assert_eq!(Owned(~""), Default::default());

View File

@ -14,6 +14,7 @@
use default::Default;
#[cfg(not(test))]
use cmp::{Eq, Equal, Ord, Ordering, TotalEq, TotalOrd};
use fmt;
#[cfg(not(test))]
impl Eq for () {
@ -46,3 +47,9 @@ impl Default for () {
#[inline]
fn default() -> () { () }
}
impl fmt::Show for () {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("()")
}
}

View File

@ -160,10 +160,6 @@ pub trait TyVisitor {
fn visit_trait(&mut self, name: &str) -> bool;
fn visit_param(&mut self, i: uint) -> bool;
fn visit_self(&mut self) -> bool;
// NOTE Remove after next snapshot.
#[cfg(stage0)]
fn visit_type(&mut self) -> bool;
}
extern "rust-intrinsic" {

View File

@ -27,14 +27,6 @@ pub fn fail_bounds_check(file: *u8, line: uint, index: uint, len: uint) -> ! {
}
#[lang="malloc"]
#[cfg(stage0)]
#[inline]
pub unsafe fn local_malloc(td: *u8, size: uint) -> *u8 {
::rt::local_heap::local_malloc(td, size)
}
#[lang="malloc"]
#[cfg(not(stage0))]
#[inline]
pub unsafe fn local_malloc(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 {
::rt::local_heap::local_malloc(drop_glue, size, align)

View File

@ -9,21 +9,8 @@
// except according to those terms.
use cast;
#[cfg(stage0)]
use unstable::intrinsics::TyDesc;
/// The representation of a Rust managed box
#[cfg(stage0)]
pub struct Box<T> {
ref_count: uint,
type_desc: *TyDesc,
prev: *mut Box<T>,
next: *mut Box<T>,
data: T
}
/// The representation of a Rust managed box
#[cfg(not(stage0))]
pub struct Box<T> {
ref_count: uint,
drop_glue: fn(ptr: *mut u8),

View File

@ -108,6 +108,7 @@ use container::{Container, Mutable};
use cmp::{Eq, TotalOrd, Ordering, Less, Equal, Greater};
use cmp;
use default::Default;
#[cfg(not(stage0))] use fmt;
use iter::*;
use num::{Integer, CheckedAdd, Saturating, checked_next_power_of_two};
use option::{None, Option, Some};
@ -115,6 +116,7 @@ use ptr::to_unsafe_ptr;
use ptr;
use ptr::RawPtr;
use rt::global_heap::{malloc_raw, realloc_raw, exchange_free};
#[cfg(not(stage0))] use result::{Ok, Err};
use mem;
use mem::size_of;
use kinds::marker;
@ -137,7 +139,7 @@ pub fn from_fn<T>(n_elts: uint, op: |uint| -> T) -> ~[T] {
&mut i, (),
|i, ()| while *i < n_elts {
mem::move_val_init(
&mut(*ptr::mut_offset(p, *i as int)),
&mut(*p.offset(*i as int)),
op(*i));
*i += 1u;
},
@ -165,7 +167,7 @@ pub fn from_elem<T:Clone>(n_elts: uint, t: T) -> ~[T] {
&mut i, (),
|i, ()| while *i < n_elts {
mem::move_val_init(
&mut(*ptr::mut_offset(p, *i as int)),
&mut(*p.offset(*i as int)),
t.clone());
*i += 1u;
},
@ -1495,7 +1497,7 @@ impl<T> OwnedVector<T> for ~[T] {
let fill = (**repr).fill;
(**repr).fill += mem::nonzero_size_of::<T>();
let p = to_unsafe_ptr(&((**repr).data));
let p = ptr::offset(p, fill as int) as *mut T;
let p = p.offset(fill as int) as *mut T;
mem::move_val_init(&mut(*p), t);
}
}
@ -1509,7 +1511,7 @@ impl<T> OwnedVector<T> for ~[T] {
unsafe { // Note: infallible.
let self_p = self.as_mut_ptr();
let rhs_p = rhs.as_ptr();
ptr::copy_memory(ptr::mut_offset(self_p, self_len as int), rhs_p, rhs_len);
ptr::copy_memory(self_p.offset(self_len as int), rhs_p, rhs_len);
self.set_len(new_len);
rhs.set_len(0);
}
@ -1796,11 +1798,11 @@ impl<T:Eq> OwnedEqVector<T> for ~[T] {
let mut w = 1;
while r < ln {
let p_r = ptr::mut_offset(p, r as int);
let p_wm1 = ptr::mut_offset(p, (w - 1) as int);
let p_r = p.offset(r as int);
let p_wm1 = p.offset((w - 1) as int);
if *p_r != *p_wm1 {
if r != w {
let p_w = ptr::mut_offset(p_wm1, 1);
let p_w = p_wm1.offset(1);
mem::swap(&mut *p_r, &mut *p_w);
}
w += 1;
@ -2383,7 +2385,7 @@ impl<'a,T> MutableVector<'a, T> for &'a mut [T] {
#[inline]
unsafe fn unsafe_mut_ref(self, index: uint) -> &'a mut T {
cast::transmute(ptr::mut_offset(self.repr().data as *mut T, index as int))
cast::transmute((self.repr().data as *mut T).offset(index as int))
}
#[inline]
@ -2484,6 +2486,7 @@ pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> ~[T] {
pub mod raw {
use cast;
use ptr;
use ptr::RawPtr;
use vec::{with_capacity, MutableVector, OwnedVector};
use unstable::raw::Slice;
@ -2542,7 +2545,7 @@ pub mod raw {
pub unsafe fn shift_ptr<T>(slice: &mut Slice<T>) -> *T {
if slice.len == 0 { fail!("shift on empty slice"); }
let head: *T = slice.data;
slice.data = ptr::offset(slice.data, 1);
slice.data = slice.data.offset(1);
slice.len -= 1;
head
}
@ -2554,7 +2557,7 @@ pub mod raw {
*/
pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> *T {
if slice.len == 0 { fail!("pop on empty slice"); }
let tail: *T = ptr::offset(slice.data, (slice.len - 1) as int);
let tail: *T = slice.data.offset((slice.len - 1) as int);
slice.len -= 1;
tail
}
@ -2640,6 +2643,30 @@ impl<A: DeepClone> DeepClone for ~[A] {
}
}
#[cfg(not(stage0))]
impl<'a, T: fmt::Show> fmt::Show for &'a [T] {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if_ok!(write!(f.buf, "["));
let mut is_first = true;
for x in self.iter() {
if is_first {
is_first = false;
} else {
if_ok!(write!(f.buf, ", "));
}
if_ok!(write!(f.buf, "{}", *x))
}
write!(f.buf, "]")
}
}
#[cfg(not(stage0))]
impl<T: fmt::Show> fmt::Show for ~[T] {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_slice().fmt(f)
}
}
// This works because every lifetime is a sub-lifetime of 'static
impl<'a, A> Default for &'a [A] {
fn default() -> &'a [A] { &'a [] }
@ -4049,6 +4076,22 @@ mod tests {
assert_eq!(values, [1,4,3,2,5]);
}
#[test]
fn test_show() {
macro_rules! test_show_vec(
($x:expr, $x_str:expr) => ({
let (x, x_str) = ($x, $x_str);
assert_eq!(format!("{}", x), x_str);
assert_eq!(format!("{}", x.as_slice()), x_str);
})
)
let empty: ~[int] = ~[];
test_show_vec!(empty, ~"[]");
test_show_vec!(~[1], ~"[1]");
test_show_vec!(~[1, 2, 3], ~"[1, 2, 3]");
test_show_vec!(~[~[], ~[1u], ~[1u, 1u]], ~"[[], [1], [1, 1]]");
}
#[test]
fn test_vec_default() {
use default::Default;

View File

@ -22,7 +22,8 @@ use cast::{forget, transmute};
use rt::global_heap::{malloc_raw, realloc_raw};
use vec::{ImmutableVector, Items, MutableVector};
use unstable::raw::Slice;
use ptr::{offset, read_ptr};
use ptr::read_ptr;
use ptr::RawPtr;
use libc::{free, c_void};
pub struct Vec<T> {
@ -135,7 +136,7 @@ impl<T> Vec<T> {
}
unsafe {
let end = offset(self.ptr as *T, self.len as int) as *mut T;
let end = (self.ptr as *T).offset(self.len as int) as *mut T;
move_val_init(&mut *end, value);
self.len += 1;
}

View File

@ -20,7 +20,6 @@ use parse::token::{InternedString, intern, str_to_ident};
use util::small_vector::SmallVector;
use std::hashmap::HashMap;
use std::unstable::dynamic_lib::DynamicLibrary;
// new-style macro! tt code:
//
@ -143,8 +142,6 @@ pub struct BlockInfo {
macros_escape : bool,
// what are the pending renames?
pending_renames : RenameList,
// references for crates loaded in this scope
macro_crates: ~[DynamicLibrary],
}
impl BlockInfo {
@ -152,7 +149,6 @@ impl BlockInfo {
BlockInfo {
macros_escape: false,
pending_renames: ~[],
macro_crates: ~[],
}
}
}
@ -551,10 +547,6 @@ impl SyntaxEnv {
self.find_escape_frame().map.insert(k, v);
}
pub fn insert_macro_crate(&mut self, lib: DynamicLibrary) {
self.find_escape_frame().info.macro_crates.push(lib);
}
pub fn info<'a>(&'a mut self) -> &'a mut BlockInfo {
&mut self.chain[self.chain.len()-1].info
}

View File

@ -1,4 +1,4 @@
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -28,6 +28,7 @@ use visit;
use visit::Visitor;
use util::small_vector::SmallVector;
use std::cast;
use std::vec;
use std::unstable::dynamic_lib::DynamicLibrary;
use std::os;
@ -469,9 +470,12 @@ fn load_extern_macros(crate: &ast::ViewItem, fld: &mut MacroExpander) {
};
fld.extsbox.insert(name, extension);
});
}
fld.extsbox.insert_macro_crate(lib);
// Intentionally leak the dynamic library. We can't ever unload it
// since the library can do things that will outlive the expansion
// phase (e.g. make an @-box cycle or launch a task).
cast::forget(lib);
}
}
// expand a stmt

View File

@ -1,3 +1,11 @@
S 2014-02-12 c62f6ce
freebsd-x86_64 737a423c5f803119ff5a692eac432fa9d0c595a8
linux-i386 a7e90e27e8b6a3fa79ddc15f0ed217ccbade875d
linux-x86_64 8f5fdf9f07b2afbc55d8d8c06c60aeb532b5ea83
macos-i386 57bb225f45bc57fef4c34552a2d5814ab4913087
macos-x86_64 d37b62478aa1c1dd1babb19d1df494d2aaf59c4c
winnt-i386 2c5c5f7228140cd79f120201805504a9e07ad245
S 2014-02-03 346d378
freebsd-x86_64 d369c1a83a2be6eb42bd0e550a1adc38ffed0804
linux-i386 a6d4ab441f5b285d7aecbb940fa733526b413f34

View File

@ -0,0 +1,35 @@
// 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.
// force-host
#[feature(macro_registrar)];
extern mod syntax;
use std::any::Any;
use std::local_data;
use syntax::ast::Name;
use syntax::ext::base::SyntaxExtension;
struct Foo {
foo: int
}
impl Drop for Foo {
fn drop(&mut self) {}
}
#[macro_registrar]
pub fn registrar(_: |Name, SyntaxExtension|) {
local_data_key!(foo: ~Any);
local_data::set(foo, ~Foo { foo: 10 } as ~Any);
}

View File

@ -0,0 +1,21 @@
// 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.
// aux-build:macro_crate_outlive_expansion_phase.rs
// ignore-stage1
// ignore-fast
// ignore-android
#[feature(phase)];
#[phase(syntax)]
extern mod macro_crate_outlive_expansion_phase;
pub fn main() {}

View File

@ -0,0 +1,28 @@
// 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.
#[allow(unused_must_use, dead_code)];
use std::io::MemWriter;
struct Foo<'a> {
writer: &'a mut Writer,
other: &'a str,
}
fn borrowing_writer_from_struct_and_formatting_struct_field(foo: Foo) {
write!(foo.writer, "{}", foo.other);
}
pub fn main() {
let mut w = MemWriter::new();
write!(&mut w as &mut Writer, "");
write!(&mut w, ""); // should coerce
}

View File

@ -0,0 +1,13 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub fn main() {
assert_eq!((0 + 0u8) as char, '\0');
}