Auto merge of - alexcrichton:rollup, r=alexcrichton

This commit is contained in:
bors 2015-02-10 19:52:04 +00:00
commit bc87efef2c
92 changed files with 1029 additions and 433 deletions

3
configure vendored

@ -525,6 +525,7 @@ opt verify-install 1 "verify installed binaries work"
opt dist-host-only 0 "only install bins for the host architecture"
opt inject-std-version 1 "inject the current compiler version of libstd into programs"
opt jemalloc 1 "build liballoc with jemalloc"
opt llvm-version-check 1 "don't check if the LLVM version is supported, build anyway"
valopt localstatedir "/var/lib" "local state directory"
valopt sysconfdir "/etc" "install system configuration files"
@ -796,7 +797,7 @@ then
putvar CFG_ENABLE_CLANG
fi
if [ ! -z "$CFG_LLVM_ROOT" -a -e "$CFG_LLVM_ROOT/bin/llvm-config" ]
if [ ! -z "$CFG_LLVM_ROOT" -a -z "$CFG_DISABLE_LLVM_VERSION_CHECK" -a -e "$CFG_LLVM_ROOT/bin/llvm-config" ]
then
step_msg "using custom LLVM at $CFG_LLVM_ROOT"

@ -12,7 +12,6 @@
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
#![feature(int_uint)]
#![feature(io)]
#![feature(os)]

@ -157,7 +157,7 @@ token : simple_token | ident | literal | symbol | whitespace token ;
| | | | | |
|----------|----------|----------|----------|--------|
| abstract | alignof | as | be | box |
| abstract | alignof | as | become | box |
| break | const | continue | crate | do |
| else | enum | extern | false | final |
| fn | for | if | impl | in |

@ -59,8 +59,7 @@ tools we have are really nice.
[Cargo](http://crates.io) is Rust's package manager, and its website contains
lots of good documentation.
[The `rustdoc` manual](rustdoc.html) contains information about Rust's
documentation tool.
[`rustdoc`](book/documentation.html) is used to generate documentation for Rust code.
# FAQs

@ -189,7 +189,7 @@ grammar as double-quoted strings. Other tokens have exact rules given.
| | | | | |
|----------|----------|----------|----------|---------|
| abstract | alignof | as | be | box |
| abstract | alignof | as | become | box |
| break | const | continue | crate | do |
| else | enum | extern | false | final |
| fn | for | if | impl | in |
@ -381,11 +381,13 @@ character (`\`), or a single _escape_. It is equivalent to a `u8` unsigned
##### Byte string literals
A _byte string literal_ is a sequence of ASCII characters and _escapes_
enclosed within two `U+0022` (double-quote) characters, with the exception of
`U+0022` itself, which must be _escaped_ by a preceding `U+005C` character
(`\`), or a _raw byte string literal_. It is equivalent to a `&'static [u8]`
borrowed array of unsigned 8-bit integers.
A non-raw _byte string literal_ is a sequence of ASCII characters and _escapes_,
preceded by the characters `U+0062` (`b`) and `U+0022` (double-quote), and
followed by the character `U+0022`. If the character `U+0022` is present within
the literal, it must be _escaped_ by a preceding `U+005C` (`\`) character.
Alternatively, a byte string literal can be a _raw byte string literal_, defined
below. A byte string literal is equivalent to a `&'static [u8]` borrowed array
of unsigned 8-bit integers.
Some additional _escapes_ are available in either byte or non-raw byte string
literals. An escape starts with a `U+005C` (`\`) and continues with one of the
@ -1253,9 +1255,7 @@ fn my_err(s: &str) -> ! {
We call such functions "diverging" because they never return a value to the
caller. Every control path in a diverging function must end with a `panic!()` or
a call to another diverging function on every control path. The `!` annotation
does *not* denote a type. Rather, the result type of a diverging function is a
special type called ⊥ ("bottom") that unifies with any type. Rust has no
syntax for ⊥.
does *not* denote a type.
It might be necessary to declare a diverging function because as mentioned
previously, the typechecker checks that every control path in a function ends
@ -2354,8 +2354,8 @@ Supported traits for `derive` are:
* `FromPrimitive`, to create an instance from a numeric primitive.
* `Hash`, to iterate over the bytes in a data type.
* `Rand`, to create a random instance of a data type.
* `Show`, to format a value using the `{}` formatter.
* `Zero`, to create a zero instance of a numeric data type.
* `Debug`, to format a value using the `{:?}` formatter.
* `Copy`, for "Plain Old Data" types which can be copied by simply moving bits.
### Compiler Features

@ -58,7 +58,7 @@
body {
margin: 0 auto;
padding: 0 15px;
font-family: "Source Serif Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-family: "Source Serif Pro", Georgia, Times, "Times New Roman", serif;
font-size: 18px;
color: #333;
line-height: 1.428571429;

@ -27,6 +27,7 @@
* [Iterators](iterators.md)
* [Generics](generics.md)
* [Traits](traits.md)
* [Static and Dynamic Dispatch](static-and-dynamic-dispatch.md)
* [Concurrency](concurrency.md)
* [Error Handling](error-handling.md)
* [Documentation](documentation.md)

@ -9,7 +9,7 @@ arguments, really powerful things are possible.
Let's make a closure:
```{rust}
let add_one = |&: x| { 1 + x };
let add_one = |x| { 1 + x };
println!("The sum of 5 plus 1 is {}.", add_one(5));
```
@ -21,8 +21,8 @@ binding name and two parentheses, just like we would for a named function.
Let's compare syntax. The two are pretty close:
```{rust}
let add_one = |&: x: i32| -> i32 { 1 + x };
fn add_one (x: i32) -> i32 { 1 + x }
let add_one = |x: i32| -> i32 { 1 + x };
fn add_one (x: i32) -> i32 { 1 + x }
```
As you may have noticed, closures infer their argument and return types, so you
@ -37,7 +37,7 @@ this:
fn main() {
let x: i32 = 5;
let printer = |&:| { println!("x is: {}", x); };
let printer = || { println!("x is: {}", x); };
printer(); // prints "x is: 5"
}
@ -53,7 +53,7 @@ defined. The closure borrows any variables it uses, so this will error:
fn main() {
let mut x: i32 = 5;
let printer = |&:| { println!("x is: {}", x); };
let printer = || { println!("x is: {}", x); };
x = 6; // error: cannot assign to `x` because it is borrowed
}
@ -80,7 +80,7 @@ fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 {
}
fn main() {
let square = |&: x: i32| { x * x };
let square = |x: i32| { x * x };
twice(5, square); // evaluates to 50
}
@ -89,7 +89,7 @@ fn main() {
Let's break the example down, starting with `main`:
```{rust}
let square = |&: x: i32| { x * x };
let square = |x: i32| { x * x };
```
We've seen this before. We make a closure that takes an integer, and returns
@ -97,7 +97,7 @@ its square.
```{rust}
# fn twice<F: Fn(i32) -> i32>(x: i32, f: F) -> i32 { f(x) + f(x) }
# let square = |&: x: i32| { x * x };
# let square = |x: i32| { x * x };
twice(5, square); // evaluates to 50
```
@ -184,8 +184,8 @@ fn compose<F, G>(x: i32, f: F, g: G) -> i32
fn main() {
compose(5,
|&: n: i32| { n + 42 },
|&: n: i32| { n * 2 }); // evaluates to 94
|n: i32| { n + 42 },
|n: i32| { n * 2 }); // evaluates to 94
}
```

@ -72,6 +72,20 @@ if x == y {
This will print `no`, because some of the values aren't equal.
Note that the order of the values is considered when checking for equality,
so the following example will also print `no`.
```rust
let x = (1, 2, 3);
let y = (2, 1, 3);
if x == y {
println!("yes");
} else {
println!("no");
}
```
One other use of tuples is to return multiple values from a function:
```rust

@ -0,0 +1,286 @@
% Static and Dynamic Dispatch
When code involves polymorphism, there needs to be a mechanism to determine
which specific version is actually run. This is called 'dispatch.' There are
two major forms of dispatch: static dispatch and dynamic dispatch. While Rust
favors static dispatch, it also supports dynamic dispatch through a mechanism
called 'trait objects.'
## Background
For the rest of this chapter, we'll need a trait and some implementations.
Let's make a simple one, `Foo`. It has one method that is expected to return a
`String`.
```rust
trait Foo {
fn method(&self) -> String;
}
```
We'll also implement this trait for `u8` and `String`:
```rust
# trait Foo { fn method(&self) -> String; }
impl Foo for u8 {
fn method(&self) -> String { format!("u8: {}", *self) }
}
impl Foo for String {
fn method(&self) -> String { format!("string: {}", *self) }
}
```
## Static dispatch
We can use this trait to perform static dispatch with trait bounds:
```rust
# trait Foo { fn method(&self) -> String; }
# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }
fn do_something<T: Foo>(x: T) {
x.method();
}
fn main() {
let x = 5u8;
let y = "Hello".to_string();
do_something(x);
do_something(y);
}
```
Rust uses 'monomorphization' to perform static dispatch here. This means that
Rust will create a special version of `do_something()` for both `u8` and
`String`, and then replace the call sites with calls to these specialized
functions. In other words, Rust generates something like this:
```rust
# trait Foo { fn method(&self) -> String; }
# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }
fn do_something_u8(x: u8) {
x.method();
}
fn do_something_string(x: String) {
x.method();
}
fn main() {
let x = 5u8;
let y = "Hello".to_string();
do_something_u8(x);
do_something_string(y);
}
```
This has some upsides: static dispatching of any method calls, allowing for
inlining and hence usually higher performance. It also has some downsides:
causing code bloat due to many copies of the same function existing in the
binary, one for each type.
Furthermore, compilers arent perfect and may “optimise” code to become slower.
For example, functions inlined too eagerly will bloat the instruction cache
(cache rules everything around us). This is part of the reason that `#[inline]`
and `#[inline(always)]` should be used carefully, and one reason why using a
dynamic dispatch is sometimes more efficient.
However, the common case is that it is more efficient to use static dispatch,
and one can always have a thin statically-dispatched wrapper function that does
a dynamic, but not vice versa, meaning static calls are more flexible. The
standard library tries to be statically dispatched where possible for this
reason.
## Dynamic dispatch
Rust provides dynamic dispatch through a feature called 'trait objects.' Trait
objects, like `&Foo` or `Box<Foo>`, are normal values that store a value of
*any* type that implements the given trait, where the precise type can only be
known at runtime. The methods of the trait can be called on a trait object via
a special record of function pointers (created and managed by the compiler).
A function that takes a trait object is not specialised to each of the types
that implements `Foo`: only one copy is generated, often (but not always)
resulting in less code bloat. However, this comes at the cost of requiring
slower virtual function calls, and effectively inhibiting any chance of
inlining and related optimisations from occurring.
Trait objects are both simple and complicated: their core representation and
layout is quite straight-forward, but there are some curly error messages and
surprising behaviours to discover.
### Obtaining a trait object
There's two similar ways to get a trait object value: casts and coercions. If
`T` is a type that implements a trait `Foo` (e.g. `u8` for the `Foo` above),
then the two ways to get a `Foo` trait object out of a pointer to `T` look
like:
```{rust,ignore}
let ref_to_t: &T = ...;
// `as` keyword for casting
let cast = ref_to_t as &Foo;
// using a `&T` in a place that has a known type of `&Foo` will implicitly coerce:
let coerce: &Foo = ref_to_t;
fn also_coerce(_unused: &Foo) {}
also_coerce(ref_to_t);
```
These trait object coercions and casts also work for pointers like `&mut T` to
`&mut Foo` and `Box<T>` to `Box<Foo>`, but that's all at the moment. Coercions
and casts are identical.
This operation can be seen as "erasing" the compiler's knowledge about the
specific type of the pointer, and hence trait objects are sometimes referred to
"type erasure".
### Representation
Let's start simple, with the runtime representation of a trait object. The
`std::raw` module contains structs with layouts that are the same as the
complicated build-in types, [including trait objects][stdraw]:
```rust
# mod foo {
pub struct TraitObject {
pub data: *mut (),
pub vtable: *mut (),
}
# }
```
[stdraw]: ../std/raw/struct.TraitObject.html
That is, a trait object like `&Foo` consists of a "data" pointer and a "vtable"
pointer.
The data pointer addresses the data (of some unknown type `T`) that the trait
object is storing, and the vtable pointer points to the vtable ("virtual method
table") corresponding to the implementation of `Foo` for `T`.
A vtable is essentially a struct of function pointers, pointing to the concrete
piece of machine code for each method in the implementation. A method call like
`trait_object.method()` will retrieve the correct pointer out of the vtable and
then do a dynamic call of it. For example:
```{rust,ignore}
struct FooVtable {
destructor: fn(*mut ()),
size: usize,
align: usize,
method: fn(*const ()) -> String,
}
// u8:
fn call_method_on_u8(x: *const ()) -> String {
// the compiler guarantees that this function is only called
// with `x` pointing to a u8
let byte: &u8 = unsafe { &*(x as *const u8) };
byte.method()
}
static Foo_for_u8_vtable: FooVtable = FooVtable {
destructor: /* compiler magic */,
size: 1,
align: 1,
// cast to a function pointer
method: call_method_on_u8 as fn(*const ()) -> String,
};
// String:
fn call_method_on_String(x: *const ()) -> String {
// the compiler guarantees that this function is only called
// with `x` pointing to a String
let string: &String = unsafe { &*(x as *const String) };
string.method()
}
static Foo_for_String_vtable: FooVtable = FooVtable {
destructor: /* compiler magic */,
// values for a 64-bit computer, halve them for 32-bit ones
size: 24,
align: 8,
method: call_method_on_String as fn(*const ()) -> String,
};
```
The `destructor` field in each vtable points to a function that will clean up
any resources of the vtable's type, for `u8` it is trivial, but for `String` it
will free the memory. This is necessary for owning trait objects like
`Box<Foo>`, which need to clean-up both the `Box` allocation and as well as the
internal type when they go out of scope. The `size` and `align` fields store
the size of the erased type, and its alignment requirements; these are
essentially unused at the moment since the information is embedded in the
destructor, but will be used in future, as trait objects are progressively made
more flexible.
Suppose we've got some values that implement `Foo`, the explicit form of
construction and use of `Foo` trait objects might look a bit like (ignoring the
type mismatches: they're all just pointers anyway):
```{rust,ignore}
let a: String = "foo".to_string();
let x: u8 = 1;
// let b: &Foo = &a;
let b = TraitObject {
// store the data
data: &a,
// store the methods
vtable: &Foo_for_String_vtable
};
// let y: &Foo = x;
let y = TraitObject {
// store the data
data: &x,
// store the methods
vtable: &Foo_for_u8_vtable
};
// b.method();
(b.vtable.method)(b.data);
// y.method();
(y.vtable.method)(y.data);
```
If `b` or `y` were owning trait objects (`Box<Foo>`), there would be a
`(b.vtable.destructor)(b.data)` (respectively `y`) call when they went out of
scope.
### Why pointers?
The use of language like "fat pointer" implies that a trait object is
always a pointer of some form, but why?
Rust does not put things behind a pointer by default, unlike many managed
languages, so types can have different sizes. Knowing the size of the value at
compile time is important for things like passing it as an argument to a
function, moving it about on the stack and allocating (and deallocating) space
on the heap to store it.
For `Foo`, we would need to have a value that could be at least either a
`String` (24 bytes) or a `u8` (1 byte), as well as any other type for which
dependent crates may implement `Foo` (any number of bytes at all). There's no
way to guarantee that this last point can work if the values are stored without
a pointer, because those other types can be arbitrarily large.
Putting the value behind a pointer means the size of the value is not relevant
when we are tossing a trait object around, only the size of the pointer itself.

@ -270,51 +270,8 @@ not, because both the trait and the type aren't in our crate.
One last thing about traits: generic functions with a trait bound use
*monomorphization* (*mono*: one, *morph*: form), so they are statically
dispatched. What's that mean? Well, let's take a look at `print_area` again:
```{rust,ignore}
fn print_area<T: HasArea>(shape: T) {
println!("This shape has an area of {}", shape.area());
}
fn main() {
let c = Circle { ... };
let s = Square { ... };
print_area(c);
print_area(s);
}
```
When we use this trait with `Circle` and `Square`, Rust ends up generating
two different functions with the concrete type, and replacing the call sites with
calls to the concrete implementations. In other words, you get something like
this:
```{rust,ignore}
fn __print_area_circle(shape: Circle) {
println!("This shape has an area of {}", shape.area());
}
fn __print_area_square(shape: Square) {
println!("This shape has an area of {}", shape.area());
}
fn main() {
let c = Circle { ... };
let s = Square { ... };
__print_area_circle(c);
__print_area_square(s);
}
```
The names don't actually change to this, it's just for illustration. But
as you can see, there's no overhead of deciding which version to call here,
hence *statically dispatched*. The downside is that we have two copies of
the same function, so our binary is a little bit larger.
dispatched. What's that mean? Check out the chapter on [static and dynamic
dispatch](static-and-dynamic-dispatch.html) for more.
## Our `inverse` Example

@ -206,12 +206,12 @@ impl<T> Arc<T> {
/// Get the number of weak references to this value.
#[inline]
#[unstable(feature = "alloc")]
pub fn weak_count<T>(this: &Arc<T>) -> uint { this.inner().weak.load(SeqCst) - 1 }
pub fn weak_count<T>(this: &Arc<T>) -> usize { this.inner().weak.load(SeqCst) - 1 }
/// Get the number of strong references to this value.
#[inline]
#[unstable(feature = "alloc")]
pub fn strong_count<T>(this: &Arc<T>) -> uint { this.inner().strong.load(SeqCst) }
pub fn strong_count<T>(this: &Arc<T>) -> usize { this.inner().strong.load(SeqCst) }
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Clone for Arc<T> {
@ -649,7 +649,7 @@ mod tests {
let (tx, rx) = channel();
let _t = Thread::spawn(move || {
let arc_v: Arc<Vec<int>> = rx.recv().unwrap();
let arc_v: Arc<Vec<i32>> = rx.recv().unwrap();
assert_eq!((*arc_v)[3], 4);
});
@ -818,5 +818,5 @@ mod tests {
// Make sure deriving works with Arc<T>
#[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)]
struct Foo { inner: Arc<int> }
struct Foo { inner: Arc<i32> }
}

@ -22,7 +22,7 @@ use std::boxed::BoxAny;
#[test]
fn test_owned_clone() {
let a = Box::new(5);
let b: Box<int> = a.clone();
let b: Box<i32> = a.clone();
assert!(a == b);
}
@ -31,11 +31,11 @@ struct Test;
#[test]
fn any_move() {
let a = Box::new(8us) as Box<Any>;
let a = Box::new(8) as Box<Any>;
let b = Box::new(Test) as Box<Any>;
match a.downcast::<uint>() {
Ok(a) => { assert!(a == Box::new(8us)); }
match a.downcast::<i32>() {
Ok(a) => { assert!(a == Box::new(8)); }
Err(..) => panic!()
}
match b.downcast::<Test>() {
@ -47,7 +47,7 @@ fn any_move() {
let b = Box::new(Test) as Box<Any>;
assert!(a.downcast::<Box<Test>>().is_err());
assert!(b.downcast::<Box<uint>>().is_err());
assert!(b.downcast::<Box<i32>>().is_err());
}
#[test]

@ -21,7 +21,7 @@ use core::ptr::PtrExt;
/// power of 2. The alignment must be no larger than the largest supported page
/// size on the platform.
#[inline]
pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
imp::allocate(size, align)
}
@ -37,7 +37,7 @@ pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
/// create the allocation referenced by `ptr`. The `old_size` parameter may be
/// any value in range_inclusive(requested_size, usable_size).
#[inline]
pub unsafe fn reallocate(ptr: *mut u8, old_size: uint, size: uint, align: uint) -> *mut u8 {
pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
imp::reallocate(ptr, old_size, size, align)
}
@ -54,7 +54,8 @@ pub unsafe fn reallocate(ptr: *mut u8, old_size: uint, size: uint, align: uint)
/// create the allocation referenced by `ptr`. The `old_size` parameter may be
/// any value in range_inclusive(requested_size, usable_size).
#[inline]
pub unsafe fn reallocate_inplace(ptr: *mut u8, old_size: uint, size: uint, align: uint) -> uint {
pub unsafe fn reallocate_inplace(ptr: *mut u8, old_size: usize, size: usize,
align: usize) -> usize {
imp::reallocate_inplace(ptr, old_size, size, align)
}
@ -66,14 +67,14 @@ pub unsafe fn reallocate_inplace(ptr: *mut u8, old_size: uint, size: uint, align
/// create the allocation referenced by `ptr`. The `old_size` parameter may be
/// any value in range_inclusive(requested_size, usable_size).
#[inline]
pub unsafe fn deallocate(ptr: *mut u8, old_size: uint, align: uint) {
pub unsafe fn deallocate(ptr: *mut u8, old_size: usize, align: usize) {
imp::deallocate(ptr, old_size, align)
}
/// Returns the usable size of an allocation created with the specified the
/// `size` and `align`.
#[inline]
pub fn usable_size(size: uint, align: uint) -> uint {
pub fn usable_size(size: usize, align: usize) -> usize {
imp::usable_size(size, align)
}
@ -96,7 +97,7 @@ pub const EMPTY: *mut () = 0x1 as *mut ();
#[cfg(not(test))]
#[lang="exchange_malloc"]
#[inline]
unsafe fn exchange_malloc(size: uint, align: uint) -> *mut u8 {
unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
if size == 0 {
EMPTY as *mut u8
} else {
@ -109,7 +110,7 @@ unsafe fn exchange_malloc(size: uint, align: uint) -> *mut u8 {
#[cfg(not(test))]
#[lang="exchange_free"]
#[inline]
unsafe fn exchange_free(ptr: *mut u8, old_size: uint, align: uint) {
unsafe fn exchange_free(ptr: *mut u8, old_size: usize, align: usize) {
deallocate(ptr, old_size, align);
}
@ -122,49 +123,49 @@ unsafe fn exchange_free(ptr: *mut u8, old_size: uint, align: uint) {
target_arch = "mips",
target_arch = "mipsel",
target_arch = "powerpc")))]
const MIN_ALIGN: uint = 8;
const MIN_ALIGN: usize = 8;
#[cfg(all(not(feature = "external_funcs"),
not(feature = "external_crate"),
any(target_arch = "x86",
target_arch = "x86_64",
target_arch = "aarch64")))]
const MIN_ALIGN: uint = 16;
const MIN_ALIGN: usize = 16;
#[cfg(feature = "external_funcs")]
mod imp {
extern {
fn rust_allocate(size: uint, align: uint) -> *mut u8;
fn rust_deallocate(ptr: *mut u8, old_size: uint, align: uint);
fn rust_reallocate(ptr: *mut u8, old_size: uint, size: uint, align: uint) -> *mut u8;
fn rust_reallocate_inplace(ptr: *mut u8, old_size: uint, size: uint,
align: uint) -> uint;
fn rust_usable_size(size: uint, align: uint) -> uint;
fn rust_allocate(size: usize, align: usize) -> *mut u8;
fn rust_deallocate(ptr: *mut u8, old_size: usize, align: usize);
fn rust_reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8;
fn rust_reallocate_inplace(ptr: *mut u8, old_size: usize, size: usize,
align: usize) -> usize;
fn rust_usable_size(size: usize, align: usize) -> usize;
fn rust_stats_print();
}
#[inline]
pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
rust_allocate(size, align)
}
#[inline]
pub unsafe fn deallocate(ptr: *mut u8, old_size: uint, align: uint) {
pub unsafe fn deallocate(ptr: *mut u8, old_size: usize, align: usize) {
rust_deallocate(ptr, old_size, align)
}
#[inline]
pub unsafe fn reallocate(ptr: *mut u8, old_size: uint, size: uint, align: uint) -> *mut u8 {
pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
rust_reallocate(ptr, old_size, size, align)
}
#[inline]
pub unsafe fn reallocate_inplace(ptr: *mut u8, old_size: uint, size: uint,
align: uint) -> uint {
pub unsafe fn reallocate_inplace(ptr: *mut u8, old_size: usize, size: usize,
align: usize) -> usize {
rust_reallocate_inplace(ptr, old_size, size, align)
}
#[inline]
pub fn usable_size(size: uint, align: uint) -> uint {
pub fn usable_size(size: usize, align: usize) -> usize {
unsafe { rust_usable_size(size, align) }
}
@ -215,42 +216,42 @@ mod imp {
// MALLOCX_ALIGN(a) macro
#[inline(always)]
fn mallocx_align(a: uint) -> c_int { a.trailing_zeros() as c_int }
fn mallocx_align(a: usize) -> c_int { a.trailing_zeros() as c_int }
#[inline(always)]
fn align_to_flags(align: uint) -> c_int {
fn align_to_flags(align: usize) -> c_int {
if align <= MIN_ALIGN { 0 } else { mallocx_align(align) }
}
#[inline]
pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
let flags = align_to_flags(align);
je_mallocx(size as size_t, flags) as *mut u8
}
#[inline]
pub unsafe fn reallocate(ptr: *mut u8, _old_size: uint, size: uint, align: uint) -> *mut u8 {
pub unsafe fn reallocate(ptr: *mut u8, _old_size: usize, size: usize, align: usize) -> *mut u8 {
let flags = align_to_flags(align);
je_rallocx(ptr as *mut c_void, size as size_t, flags) as *mut u8
}
#[inline]
pub unsafe fn reallocate_inplace(ptr: *mut u8, _old_size: uint, size: uint,
align: uint) -> uint {
pub unsafe fn reallocate_inplace(ptr: *mut u8, _old_size: usize, size: usize,
align: usize) -> usize {
let flags = align_to_flags(align);
je_xallocx(ptr as *mut c_void, size as size_t, 0, flags) as uint
je_xallocx(ptr as *mut c_void, size as size_t, 0, flags) as usize
}
#[inline]
pub unsafe fn deallocate(ptr: *mut u8, old_size: uint, align: uint) {
pub unsafe fn deallocate(ptr: *mut u8, old_size: usize, align: usize) {
let flags = align_to_flags(align);
je_sdallocx(ptr as *mut c_void, old_size as size_t, flags)
}
#[inline]
pub fn usable_size(size: uint, align: uint) -> uint {
pub fn usable_size(size: usize, align: usize) -> usize {
let flags = align_to_flags(align);
unsafe { je_nallocx(size as size_t, flags) as uint }
unsafe { je_nallocx(size as size_t, flags) as usize }
}
pub fn stats_print() {
@ -277,7 +278,7 @@ mod imp {
}
#[inline]
pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
if align <= MIN_ALIGN {
libc::malloc(size as libc::size_t) as *mut u8
} else {
@ -294,7 +295,7 @@ mod imp {
}
#[inline]
pub unsafe fn reallocate(ptr: *mut u8, old_size: uint, size: uint, align: uint) -> *mut u8 {
pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
if align <= MIN_ALIGN {
libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
} else {
@ -306,18 +307,18 @@ mod imp {
}
#[inline]
pub unsafe fn reallocate_inplace(_ptr: *mut u8, old_size: uint, _size: uint,
_align: uint) -> uint {
pub unsafe fn reallocate_inplace(_ptr: *mut u8, old_size: usize, _size: usize,
_align: usize) -> usize {
old_size
}
#[inline]
pub unsafe fn deallocate(ptr: *mut u8, _old_size: uint, _align: uint) {
pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, _align: usize) {
libc::free(ptr as *mut libc::c_void)
}
#[inline]
pub fn usable_size(size: uint, _align: uint) -> uint {
pub fn usable_size(size: usize, _align: usize) -> usize {
size
}
@ -341,7 +342,7 @@ mod imp {
}
#[inline]
pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
if align <= MIN_ALIGN {
libc::malloc(size as size_t) as *mut u8
} else {
@ -350,7 +351,7 @@ mod imp {
}
#[inline]
pub unsafe fn reallocate(ptr: *mut u8, _old_size: uint, size: uint, align: uint) -> *mut u8 {
pub unsafe fn reallocate(ptr: *mut u8, _old_size: usize, size: usize, align: usize) -> *mut u8 {
if align <= MIN_ALIGN {
libc::realloc(ptr as *mut c_void, size as size_t) as *mut u8
} else {
@ -359,13 +360,13 @@ mod imp {
}
#[inline]
pub unsafe fn reallocate_inplace(_ptr: *mut u8, old_size: uint, _size: uint,
_align: uint) -> uint {
pub unsafe fn reallocate_inplace(_ptr: *mut u8, old_size: usize, _size: usize,
_align: usize) -> usize {
old_size
}
#[inline]
pub unsafe fn deallocate(ptr: *mut u8, _old_size: uint, align: uint) {
pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, align: usize) {
if align <= MIN_ALIGN {
libc::free(ptr as *mut libc::c_void)
} else {
@ -374,7 +375,7 @@ mod imp {
}
#[inline]
pub fn usable_size(size: uint, _align: uint) -> uint {
pub fn usable_size(size: usize, _align: usize) -> usize {
size
}

@ -70,7 +70,6 @@
#![feature(lang_items, unsafe_destructor)]
#![feature(box_syntax)]
#![feature(optin_builtin_traits)]
#![feature(int_uint)]
#![feature(unboxed_closures)]
#![feature(core)]
#![feature(hash)]

@ -40,7 +40,7 @@
//! }
//!
//! struct Gadget {
//! id: int,
//! id: i32,
//! owner: Rc<Owner>
//! // ...other fields
//! }
@ -99,7 +99,7 @@
//! }
//!
//! struct Gadget {
//! id: int,
//! id: i32,
//! owner: Rc<Owner>
//! // ...other fields
//! }
@ -166,8 +166,8 @@ use heap::deallocate;
struct RcBox<T> {
value: T,
strong: Cell<uint>,
weak: Cell<uint>
strong: Cell<usize>,
weak: Cell<usize>
}
/// An immutable reference-counted pointer type.
@ -233,12 +233,12 @@ impl<T> Rc<T> {
/// Get the number of weak references to this value.
#[inline]
#[unstable(feature = "alloc")]
pub fn weak_count<T>(this: &Rc<T>) -> uint { this.weak() - 1 }
pub fn weak_count<T>(this: &Rc<T>) -> usize { this.weak() - 1 }
/// Get the number of strong references to this value.
#[inline]
#[unstable(feature = "alloc")]
pub fn strong_count<T>(this: &Rc<T>) -> uint { this.strong() }
pub fn strong_count<T>(this: &Rc<T>) -> usize { this.strong() }
/// Returns true if there are no other `Rc` or `Weak<T>` values that share the same inner value.
///
@ -447,7 +447,7 @@ impl<T: Default> Default for Rc<T> {
/// use std::rc::Rc;
/// use std::default::Default;
///
/// let x: Rc<int> = Default::default();
/// let x: Rc<i32> = Default::default();
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
@ -750,7 +750,7 @@ trait RcBoxPtr<T> {
fn inner(&self) -> &RcBox<T>;
#[inline]
fn strong(&self) -> uint { self.inner().strong.get() }
fn strong(&self) -> usize { self.inner().strong.get() }
#[inline]
fn inc_strong(&self) { self.inner().strong.set(self.strong() + 1); }
@ -759,7 +759,7 @@ trait RcBoxPtr<T> {
fn dec_strong(&self) { self.inner().strong.set(self.strong() - 1); }
#[inline]
fn weak(&self) -> uint { self.inner().weak.get() }
fn weak(&self) -> usize { self.inner().weak.get() }
#[inline]
fn inc_weak(&self) { self.inner().weak.set(self.weak() + 1); }

@ -31,7 +31,6 @@
#![feature(alloc)]
#![feature(box_syntax)]
#![feature(core)]
#![feature(int_uint)]
#![feature(staged_api)]
#![feature(unboxed_closures)]
#![feature(unsafe_destructor)]
@ -55,12 +54,12 @@ use std::rt::heap::{allocate, deallocate};
#[derive(Clone, PartialEq)]
struct Chunk {
data: Rc<RefCell<Vec<u8>>>,
fill: Cell<uint>,
fill: Cell<usize>,
is_copy: Cell<bool>,
}
impl Chunk {
fn capacity(&self) -> uint {
fn capacity(&self) -> usize {
self.data.borrow().capacity()
}
@ -105,7 +104,7 @@ impl Arena {
}
/// Allocates a new Arena with `initial_size` bytes preallocated.
pub fn new_with_size(initial_size: uint) -> Arena {
pub fn new_with_size(initial_size: usize) -> Arena {
Arena {
head: RefCell::new(chunk(initial_size, false)),
copy_head: RefCell::new(chunk(initial_size, true)),
@ -114,7 +113,7 @@ impl Arena {
}
}
fn chunk(size: uint, is_copy: bool) -> Chunk {
fn chunk(size: usize, is_copy: bool) -> Chunk {
Chunk {
data: Rc::new(RefCell::new(Vec::with_capacity(size))),
fill: Cell::new(0),
@ -137,7 +136,7 @@ impl Drop for Arena {
}
#[inline]
fn round_up(base: uint, align: uint) -> uint {
fn round_up(base: usize, align: usize) -> usize {
(base.checked_add(align - 1)).unwrap() & !(align - 1)
}
@ -149,7 +148,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
let fill = chunk.fill.get();
while idx < fill {
let tydesc_data: *const uint = mem::transmute(buf.offset(idx as int));
let tydesc_data: *const usize = mem::transmute(buf.offset(idx as isize));
let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
let (size, align) = ((*tydesc).size, (*tydesc).align);
@ -160,7 +159,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)(buf.offset(start as int) as *const i8);
((*tydesc).drop_glue)(buf.offset(start as isize) as *const i8);
}
// Find where the next tydesc lives
@ -173,21 +172,21 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
// is necessary in order to properly do cleanup if a panic occurs
// during an initializer.
#[inline]
fn bitpack_tydesc_ptr(p: *const TyDesc, is_done: bool) -> uint {
p as uint | (is_done as uint)
fn bitpack_tydesc_ptr(p: *const TyDesc, is_done: bool) -> usize {
p as usize | (is_done as usize)
}
#[inline]
fn un_bitpack_tydesc_ptr(p: uint) -> (*const TyDesc, bool) {
fn un_bitpack_tydesc_ptr(p: usize) -> (*const TyDesc, bool) {
((p & !1) as *const TyDesc, p & 1 == 1)
}
impl Arena {
fn chunk_size(&self) -> uint {
fn chunk_size(&self) -> usize {
self.copy_head.borrow().capacity()
}
// Functions for the POD part of the arena
fn alloc_copy_grow(&self, n_bytes: uint, align: uint) -> *const u8 {
fn alloc_copy_grow(&self, n_bytes: usize, align: usize) -> *const u8 {
// Allocate a new chunk.
let new_min_chunk_size = cmp::max(n_bytes, self.chunk_size());
self.chunks.borrow_mut().push(self.copy_head.borrow().clone());
@ -199,7 +198,7 @@ impl Arena {
}
#[inline]
fn alloc_copy_inner(&self, n_bytes: uint, align: uint) -> *const u8 {
fn alloc_copy_inner(&self, n_bytes: usize, align: usize) -> *const u8 {
let start = round_up(self.copy_head.borrow().fill.get(), align);
let end = start + n_bytes;
@ -211,7 +210,7 @@ impl Arena {
copy_head.fill.set(end);
unsafe {
copy_head.as_ptr().offset(start as int)
copy_head.as_ptr().offset(start as isize)
}
}
@ -227,8 +226,8 @@ impl Arena {
}
// Functions for the non-POD part of the arena
fn alloc_noncopy_grow(&self, n_bytes: uint,
align: uint) -> (*const u8, *const u8) {
fn alloc_noncopy_grow(&self, n_bytes: usize,
align: usize) -> (*const u8, *const u8) {
// Allocate a new chunk.
let new_min_chunk_size = cmp::max(n_bytes, self.chunk_size());
self.chunks.borrow_mut().push(self.head.borrow().clone());
@ -240,8 +239,8 @@ impl Arena {
}
#[inline]
fn alloc_noncopy_inner(&self, n_bytes: uint,
align: uint) -> (*const u8, *const u8) {
fn alloc_noncopy_inner(&self, n_bytes: usize,
align: usize) -> (*const u8, *const u8) {
// Be careful to not maintain any `head` borrows active, because
// `alloc_noncopy_grow` borrows it mutably.
let (start, end, tydesc_start, head_capacity) = {
@ -265,7 +264,7 @@ impl Arena {
unsafe {
let buf = head.as_ptr();
return (buf.offset(tydesc_start as int), buf.offset(start as int));
return (buf.offset(tydesc_start as isize), buf.offset(start as isize));
}
}
@ -276,7 +275,7 @@ impl Arena {
let (ty_ptr, ptr) =
self.alloc_noncopy_inner(mem::size_of::<T>(),
mem::min_align_of::<T>());
let ty_ptr = ty_ptr as *mut uint;
let ty_ptr = ty_ptr as *mut usize;
let ptr = ptr as *mut T;
// Write in our tydesc along with a bit indicating that it
// has *not* been initialized yet.
@ -320,7 +319,7 @@ fn test_arena_destructors() {
#[test]
fn test_arena_alloc_nested() {
struct Inner { value: uint }
struct Inner { value: usize }
struct Outer<'a> { inner: &'a Inner }
let arena = Arena::new();
@ -343,10 +342,10 @@ fn test_arena_destructors_fail() {
arena.alloc(|| { Rc::new(i) });
// Allocate something with funny size and alignment, to keep
// things interesting.
arena.alloc(|| { [0u8, 1u8, 2u8] });
arena.alloc(|| { [0u8, 1, 2] });
}
// Now, panic while allocating
arena.alloc::<Rc<int>, _>(|| {
arena.alloc::<Rc<i32>, _>(|| {
panic!();
});
}
@ -373,12 +372,12 @@ struct TypedArenaChunk<T> {
next: *mut TypedArenaChunk<T>,
/// The number of elements that this chunk can hold.
capacity: uint,
capacity: usize,
// Objects follow here, suitably aligned.
}
fn calculate_size<T>(capacity: uint) -> uint {
fn calculate_size<T>(capacity: usize) -> usize {
let mut size = mem::size_of::<TypedArenaChunk<T>>();
size = round_up(size, mem::min_align_of::<T>());
let elem_size = mem::size_of::<T>();
@ -389,7 +388,7 @@ fn calculate_size<T>(capacity: uint) -> uint {
impl<T> TypedArenaChunk<T> {
#[inline]
unsafe fn new(next: *mut TypedArenaChunk<T>, capacity: uint)
unsafe fn new(next: *mut TypedArenaChunk<T>, capacity: usize)
-> *mut TypedArenaChunk<T> {
let size = calculate_size::<T>(capacity);
let chunk = allocate(size, mem::min_align_of::<TypedArenaChunk<T>>())
@ -403,13 +402,13 @@ impl<T> TypedArenaChunk<T> {
/// Destroys this arena chunk. If the type descriptor is supplied, the
/// drop glue is called; otherwise, drop glue is not called.
#[inline]
unsafe fn destroy(&mut self, len: uint) {
unsafe fn destroy(&mut self, len: usize) {
// Destroy all the allocated objects.
if intrinsics::needs_drop::<T>() {
let mut start = self.start();
for _ in 0..len {
ptr::read(start as *const T); // run the destructor on the pointer
start = start.offset(mem::size_of::<T>() as int)
start = start.offset(mem::size_of::<T>() as isize)
}
}
@ -429,7 +428,7 @@ impl<T> TypedArenaChunk<T> {
fn start(&self) -> *const u8 {
let this: *const TypedArenaChunk<T> = self;
unsafe {
mem::transmute(round_up(this.offset(1) as uint,
mem::transmute(round_up(this.offset(1) as usize,
mem::min_align_of::<T>()))
}
}
@ -439,7 +438,7 @@ impl<T> TypedArenaChunk<T> {
fn end(&self) -> *const u8 {
unsafe {
let size = mem::size_of::<T>().checked_mul(self.capacity).unwrap();
self.start().offset(size as int)
self.start().offset(size as isize)
}
}
}
@ -454,7 +453,7 @@ impl<T> TypedArena<T> {
/// Creates a new `TypedArena` with preallocated space for the given number of
/// objects.
#[inline]
pub fn with_capacity(capacity: uint) -> TypedArena<T> {
pub fn with_capacity(capacity: usize) -> TypedArena<T> {
unsafe {
let chunk = TypedArenaChunk::<T>::new(ptr::null_mut(), capacity);
TypedArena {
@ -501,8 +500,8 @@ impl<T> Drop for TypedArena<T> {
fn drop(&mut self) {
unsafe {
// Determine how much was filled.
let start = self.first.borrow().as_ref().unwrap().start() as uint;
let end = self.ptr.get() as uint;
let start = self.first.borrow().as_ref().unwrap().start() as usize;
let end = self.ptr.get() as usize;
let diff = (end - start) / mem::size_of::<T>();
// Pass that to the `destroy` method.
@ -519,9 +518,9 @@ mod tests {
#[allow(dead_code)]
struct Point {
x: int,
y: int,
z: int,
x: i32,
y: i32,
z: i32,
}
#[test]
@ -576,7 +575,7 @@ mod tests {
#[allow(dead_code)]
struct Noncopy {
string: String,
array: Vec<int>,
array: Vec<i32>,
}
#[test]

@ -656,7 +656,7 @@ impl<T: Ord> FromIterator<T> for BinaryHeap<T> {
}
impl<T: Ord> IntoIterator for BinaryHeap<T> {
type Iter = IntoIter<T>;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
self.into_iter()
@ -664,7 +664,7 @@ impl<T: Ord> IntoIterator for BinaryHeap<T> {
}
impl<'a, T> IntoIterator for &'a BinaryHeap<T> where T: Ord {
type Iter = Iter<'a, T>;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()

@ -1071,7 +1071,7 @@ impl<'a> RandomAccessIterator for Iter<'a> {
}
impl<'a> IntoIterator for &'a Bitv {
type Iter = Iter<'a>;
type IntoIter = Iter<'a>;
fn into_iter(self) -> Iter<'a> {
self.iter()
@ -1883,7 +1883,7 @@ impl<'a> Iterator for SymmetricDifference<'a> {
}
impl<'a> IntoIterator for &'a BitvSet {
type Iter = SetIter<'a>;
type IntoIter = SetIter<'a>;
fn into_iter(self) -> SetIter<'a> {
self.iter()

@ -463,7 +463,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
}
impl<K, V> IntoIterator for BTreeMap<K, V> {
type Iter = IntoIter<K, V>;
type IntoIter = IntoIter<K, V>;
fn into_iter(self) -> IntoIter<K, V> {
self.into_iter()
@ -471,7 +471,7 @@ impl<K, V> IntoIterator for BTreeMap<K, V> {
}
impl<'a, K, V> IntoIterator for &'a BTreeMap<K, V> {
type Iter = Iter<'a, K, V>;
type IntoIter = Iter<'a, K, V>;
fn into_iter(self) -> Iter<'a, K, V> {
self.iter()
@ -479,7 +479,7 @@ impl<'a, K, V> IntoIterator for &'a BTreeMap<K, V> {
}
impl<'a, K, V> IntoIterator for &'a mut BTreeMap<K, V> {
type Iter = IterMut<'a, K, V>;
type IntoIter = IterMut<'a, K, V>;
fn into_iter(mut self) -> IterMut<'a, K, V> {
self.iter_mut()

@ -481,7 +481,7 @@ impl<T: Ord> FromIterator<T> for BTreeSet<T> {
}
impl<T> IntoIterator for BTreeSet<T> {
type Iter = IntoIter<T>;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
self.into_iter()
@ -489,7 +489,7 @@ impl<T> IntoIterator for BTreeSet<T> {
}
impl<'a, T> IntoIterator for &'a BTreeSet<T> {
type Iter = Iter<'a, T>;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()

@ -831,7 +831,7 @@ impl<A> FromIterator<A> for DList<A> {
}
impl<T> IntoIterator for DList<T> {
type Iter = IntoIter<T>;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
self.into_iter()
@ -839,7 +839,7 @@ impl<T> IntoIterator for DList<T> {
}
impl<'a, T> IntoIterator for &'a DList<T> {
type Iter = Iter<'a, T>;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
@ -847,7 +847,7 @@ impl<'a, T> IntoIterator for &'a DList<T> {
}
impl<'a, T> IntoIterator for &'a mut DList<T> {
type Iter = IterMut<'a, T>;
type IntoIter = IterMut<'a, T>;
fn into_iter(mut self) -> IterMut<'a, T> {
self.iter_mut()

@ -258,7 +258,7 @@ impl<E:CLike> FromIterator<E> for EnumSet<E> {
}
impl<'a, E> IntoIterator for &'a EnumSet<E> where E: CLike {
type Iter = Iter<E>;
type IntoIter = Iter<E>;
fn into_iter(self) -> Iter<E> {
self.iter()

@ -30,7 +30,7 @@
#![feature(unboxed_closures)]
#![feature(unicode)]
#![feature(unsafe_destructor, slicing_syntax)]
#![cfg_attr(test, feature(test))]
#![cfg_attr(test, feature(rand, rustc_private, test))]
#![cfg_attr(test, allow(deprecated))] // rand
#![feature(no_std)]

@ -1608,7 +1608,7 @@ impl<A> FromIterator<A> for RingBuf<A> {
}
impl<T> IntoIterator for RingBuf<T> {
type Iter = IntoIter<T>;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
self.into_iter()
@ -1616,7 +1616,7 @@ impl<T> IntoIterator for RingBuf<T> {
}
impl<'a, T> IntoIterator for &'a RingBuf<T> {
type Iter = Iter<'a, T>;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
@ -1624,7 +1624,7 @@ impl<'a, T> IntoIterator for &'a RingBuf<T> {
}
impl<'a, T> IntoIterator for &'a mut RingBuf<T> {
type Iter = IterMut<'a, T>;
type IntoIter = IterMut<'a, T>;
fn into_iter(mut self) -> IterMut<'a, T> {
self.iter_mut()

@ -1388,7 +1388,7 @@ impl<T> FromIterator<T> for Vec<T> {
}
impl<T> IntoIterator for Vec<T> {
type Iter = IntoIter<T>;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
self.into_iter()
@ -1396,7 +1396,7 @@ impl<T> IntoIterator for Vec<T> {
}
impl<'a, T> IntoIterator for &'a Vec<T> {
type Iter = slice::Iter<'a, T>;
type IntoIter = slice::Iter<'a, T>;
fn into_iter(self) -> slice::Iter<'a, T> {
self.iter()
@ -1404,7 +1404,7 @@ impl<'a, T> IntoIterator for &'a Vec<T> {
}
impl<'a, T> IntoIterator for &'a mut Vec<T> {
type Iter = slice::IterMut<'a, T>;
type IntoIter = slice::IterMut<'a, T>;
fn into_iter(mut self) -> slice::IterMut<'a, T> {
self.iter_mut()

@ -669,7 +669,7 @@ impl<V> FromIterator<(usize, V)> for VecMap<V> {
}
impl<T> IntoIterator for VecMap<T> {
type Iter = IntoIter<T>;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
self.into_iter()
@ -677,7 +677,7 @@ impl<T> IntoIterator for VecMap<T> {
}
impl<'a, T> IntoIterator for &'a VecMap<T> {
type Iter = Iter<'a, T>;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
@ -685,7 +685,7 @@ impl<'a, T> IntoIterator for &'a VecMap<T> {
}
impl<'a, T> IntoIterator for &'a mut VecMap<T> {
type Iter = IterMut<'a, T>;
type IntoIter = IterMut<'a, T>;
fn into_iter(mut self) -> IterMut<'a, T> {
self.iter_mut()

@ -27,7 +27,7 @@
//! # Examples
//!
//! Consider a situation where we want to log out a value passed to a function.
//! We know the value we're working on implements Show, but we don't know its
//! We know the value we're working on implements Debug, but we don't know its
//! concrete type. We want to give special treatment to certain types: in this
//! case printing out the length of String values prior to their value.
//! We don't know the concrete type of our value at compile time, so we need to

@ -49,7 +49,7 @@ macro_rules! array_impls {
}
impl<'a, T> IntoIterator for &'a [T; $N] {
type Iter = Iter<'a, T>;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
@ -57,7 +57,7 @@ macro_rules! array_impls {
}
impl<'a, T> IntoIterator for &'a mut [T; $N] {
type Iter = IterMut<'a, T>;
type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> IterMut<'a, T> {
self.iter_mut()

@ -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.
//
@ -151,7 +151,7 @@ use option::Option::{None, Some};
/// A mutable memory location that admits only `Copy` data.
///
/// See the [module-level documentation](../index.html) for more.
/// See the [module-level documentation](index.html) for more.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Cell<T> {
value: UnsafeCell<T>,
@ -259,7 +259,7 @@ impl<T:PartialEq + Copy> PartialEq for Cell<T> {
/// A mutable memory location with dynamically checked borrow rules
///
/// See the [module-level documentation](../index.html) for more.
/// See the [module-level documentation](index.html) for more.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct RefCell<T> {
value: UnsafeCell<T>,
@ -534,7 +534,7 @@ impl<'b> Clone for BorrowRef<'b> {
/// Wraps a borrowed reference to a value in a `RefCell` box.
/// A wrapper type for an immutably borrowed value from a `RefCell<T>`.
///
/// See the [module-level documentation](../index.html) for more.
/// See the [module-level documentation](index.html) for more.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Ref<'b, T:'b> {
// FIXME #12808: strange name to try to avoid interfering with
@ -595,7 +595,7 @@ impl<'b> BorrowRefMut<'b> {
/// A wrapper type for a mutably borrowed value from a `RefCell<T>`.
///
/// See the [module-level documentation](../index.html) for more.
/// See the [module-level documentation](index.html) for more.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct RefMut<'b, T:'b> {
// FIXME #12808: strange name to try to avoid interfering with

@ -222,12 +222,11 @@ extern "rust-intrinsic" {
/// Unsafely transforms a value of one type into a value of another type.
///
/// Both types must have the same size and alignment, and this guarantee
/// is enforced at compile-time.
/// Both types must have the same size.
///
/// # Examples
///
/// ```rust
/// ```
/// use std::mem;
///
/// let v: &[u8] = unsafe { mem::transmute("L") };

@ -120,14 +120,15 @@ pub trait FromIterator<A> {
/// Conversion into an `Iterator`
pub trait IntoIterator {
type Iter: Iterator;
type IntoIter: Iterator;
/// Consumes `Self` and returns an iterator over it
fn into_iter(self) -> Self::Iter;
#[stable(feature = "rust1", since = "1.0.0")]
fn into_iter(self) -> Self::IntoIter;
}
impl<I> IntoIterator for I where I: Iterator {
type Iter = I;
type IntoIter = I;
fn into_iter(self) -> I {
self
@ -967,10 +968,9 @@ pub trait IteratorExt: Iterator + Sized {
/// Creates an iterator that clones the elements it yields. Useful for converting an
/// Iterator<&T> to an Iterator<T>.
#[unstable(feature = "core", reason = "recent addition")]
fn cloned<T, D>(self) -> Cloned<Self> where
Self: Iterator<Item=D>,
D: Deref<Target=T>,
T: Clone,
fn cloned(self) -> Cloned<Self> where
Self::Item: Deref,
<Self::Item as Deref>::Output: Clone,
{
Cloned { it: self }
}
@ -2646,13 +2646,7 @@ impl<A: Int> Iterator for RangeStepInclusive<A> {
macro_rules! range_exact_iter_impl {
($($t:ty)*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]
impl ExactSizeIterator for ::ops::Range<$t> {
#[inline]
fn len(&self) -> usize {
debug_assert!(self.end >= self.start);
(self.end - self.start) as usize
}
}
impl ExactSizeIterator for ::ops::Range<$t> { }
)*)
}
@ -2673,9 +2667,12 @@ impl<A: Int> Iterator for ::ops::Range<A> {
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
debug_assert!(self.end >= self.start);
let hint = (self.end - self.start).to_uint();
(hint.unwrap_or(0), hint)
if self.start >= self.end {
(0, Some(0))
} else {
let length = (self.end - self.start).to_uint();
(length.unwrap_or(0), length)
}
}
}

@ -141,6 +141,10 @@ pub mod hash;
pub mod fmt;
pub mod error;
#[doc(primitive = "bool")]
mod bool {
}
// note: does not need to be public
mod tuple;
mod array;

@ -522,21 +522,21 @@ impl<T> PartialOrd for *mut T {
/// Useful for building abstractions like `Vec<T>` or `Box<T>`, which
/// internally use raw pointers to manage the memory that they own.
#[unstable(feature = "core", reason = "recently added to this module")]
pub struct Unique<T>(pub *mut T);
pub struct Unique<T: ?Sized>(pub *mut T);
/// `Unique` pointers are `Send` if `T` is `Send` because the data they
/// reference is unaliased. Note that this aliasing invariant is
/// unenforced by the type system; the abstraction using the
/// `Unique` must enforce it.
#[unstable(feature = "core", reason = "recently added to this module")]
unsafe impl<T:Send> Send for Unique<T> { }
unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they
/// reference is unaliased. Note that this aliasing invariant is
/// unenforced by the type system; the abstraction using the
/// `Unique` must enforce it.
#[unstable(feature = "core", reason = "recently added to this module")]
unsafe impl<T:Sync> Sync for Unique<T> { }
unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
impl<T> Unique<T> {
/// Returns a null Unique.

@ -628,7 +628,7 @@ impl<'a, T> Default for &'a [T] {
//
impl<'a, T> IntoIterator for &'a [T] {
type Iter = Iter<'a, T>;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
@ -636,7 +636,7 @@ impl<'a, T> IntoIterator for &'a [T] {
}
impl<'a, T> IntoIterator for &'a mut [T] {
type Iter = IterMut<'a, T>;
type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> IterMut<'a, T> {
self.iter_mut()

@ -34,6 +34,7 @@
//! * `Default`
#![stable(feature = "rust1", since = "1.0.0")]
#![doc(primitive = "tuple")]
use clone::Clone;
use cmp::*;

@ -756,6 +756,7 @@ fn test_range() {
// this test is only meaningful when sizeof uint < sizeof u64
assert_eq!((uint::MAX - 1..uint::MAX).size_hint(), (1, Some(1)));
assert_eq!((-10..-1).size_hint(), (9, Some(9)));
assert_eq!((-1..-10).size_hint(), (0, Some(0)));
}
#[test]

@ -167,3 +167,12 @@ fn test_set_memory() {
unsafe { set_memory(ptr, 5u8, xs.len()); }
assert!(xs == [5u8; 20]);
}
#[test]
fn test_unsized_unique() {
let xs: &mut [_] = &mut [1, 2, 3];
let ptr = Unique(xs as *mut [_]);
let ys = unsafe { &mut *ptr.0 };
let zs: &mut [_] = &mut [1, 2, 3];
assert!(ys == zs);
}

@ -90,7 +90,6 @@
#![deny(missing_docs)]
#![feature(collections)]
#![feature(core)]
#![feature(int_uint)]
#![feature(slicing_syntax)]
#![feature(staged_api)]
@ -195,7 +194,7 @@ pub struct Matches {
}
/// The type returned when the command line does not conform to the
/// expected format. Use the `Show` implementation to output detailed
/// expected format. Use the `Debug` implementation to output detailed
/// information.
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum Fail {
@ -545,7 +544,7 @@ impl Fail {
/// Convert a `Fail` enum into an error string.
#[unstable(feature = "rustc_private")]
#[deprecated(since = "1.0.0",
reason = "use `fmt::String` (`{}` format specifier)")]
reason = "use `fmt::Display` (`{}` format specifier)")]
pub fn to_err_msg(self) -> String {
self.to_string()
}
@ -579,7 +578,7 @@ impl fmt::Display for Fail {
/// `opt_str`, etc. to interrogate results.
/// # Panics
///
/// Returns `Err(Fail)` on failure: use the `Show` implementation of `Fail` to display
/// Returns `Err(Fail)` on failure: use the `Debug` implementation of `Fail` to display
/// information about it.
pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
let opts: Vec<Opt> = optgrps.iter().map(|x| x.long_to_short()).collect();

@ -15,7 +15,6 @@
#![cfg_attr(not(feature = "cargo-build"), feature(staged_api))]
#![cfg_attr(not(feature = "cargo-build"), staged_api)]
#![cfg_attr(not(feature = "cargo-build"), feature(core))]
#![feature(int_uint)]
#![feature(no_std)]
#![no_std]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
@ -1905,7 +1904,7 @@ pub mod types {
#[repr(C)]
#[derive(Copy)] pub struct WSAPROTOCOLCHAIN {
pub ChainLen: c_int,
pub ChainEntries: [DWORD; MAX_PROTOCOL_CHAIN as uint],
pub ChainEntries: [DWORD; MAX_PROTOCOL_CHAIN as usize],
}
pub type LPWSAPROTOCOLCHAIN = *mut WSAPROTOCOLCHAIN;
@ -1931,7 +1930,7 @@ pub mod types {
pub iSecurityScheme: c_int,
pub dwMessageSize: DWORD,
pub dwProviderReserved: DWORD,
pub szProtocol: [u8; (WSAPROTOCOL_LEN as uint) + 1us],
pub szProtocol: [u8; WSAPROTOCOL_LEN as usize + 1us],
}
pub type LPWSAPROTOCOL_INFO = *mut WSAPROTOCOL_INFO;

@ -50,7 +50,10 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
let any_exe = session.crate_types.borrow().iter().any(|ty| {
*ty == config::CrateTypeExecutable
});
if !any_exe {
let emit_link = session.opts.output_types.iter().any(|ty| {
*ty == config::OutputTypeExe
});
if !any_exe || !emit_link {
// No need to find a main function
return
}

@ -1549,6 +1549,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return Ok(ParameterBuiltin);
}
// Upvars are always local variables or references to
// local variables, and local variables cannot be
// unsized, so the closure struct as a whole must be
// Sized.
if bound == ty::BoundSized {
return Ok(If(Vec::new()));
}
match self.closure_typer.closure_upvars(def_id, substs) {
Some(upvars) => {
Ok(If(upvars.iter().map(|c| c.ty).collect()))

@ -70,7 +70,7 @@ use arena::TypedArena;
use std::borrow::{BorrowFrom, Cow};
use std::cell::{Cell, RefCell};
use std::cmp;
use std::fmt::{self, Show};
use std::fmt;
use std::hash::{Hash, Writer, SipHasher, Hasher};
use std::mem;
use std::ops;

@ -83,7 +83,7 @@ pub struct Options {
pub debuginfo: DebugInfoLevel,
pub lint_opts: Vec<(String, lint::Level)>,
pub describe_lints: bool,
pub output_types: Vec<OutputType> ,
pub output_types: Vec<OutputType>,
// This was mutable for rustpkg, which updates search paths based on the
// parsed code. It remains mutable in case its replacements wants to use
// this.
@ -1076,7 +1076,9 @@ pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateTy
part));
}
};
crate_types.push(new_part)
if !crate_types.contains(&new_part) {
crate_types.push(new_part)
}
}
}

@ -118,6 +118,7 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
match move_from.cat {
mc::cat_deref(_, _, mc::BorrowedPtr(..)) |
mc::cat_deref(_, _, mc::Implicit(..)) |
mc::cat_deref(_, _, mc::UnsafePtr(..)) |
mc::cat_static_item => {
bccx.span_err(move_from.span,
&format!("cannot move out of {}",

@ -390,8 +390,8 @@ enum PrivacyResult {
enum FieldName {
UnnamedField(uint), // index
// FIXME #6993: change type (and name) from Ident to Name
NamedField(ast::Ident),
// (Name, not Ident, because struct fields are not macro-hygienic)
NamedField(ast::Name),
}
impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
@ -665,9 +665,9 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
name: FieldName) {
let fields = ty::lookup_struct_fields(self.tcx, id);
let field = match name {
NamedField(ident) => {
debug!("privacy - check named field {} in struct {:?}", ident.name, id);
fields.iter().find(|f| f.name == ident.name).unwrap()
NamedField(f_name) => {
debug!("privacy - check named field {} in struct {:?}", f_name, id);
fields.iter().find(|f| f.name == f_name).unwrap()
}
UnnamedField(idx) => &fields[idx]
};
@ -686,7 +686,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
};
let msg = match name {
NamedField(name) => format!("field `{}` of {} is private",
token::get_ident(name), struct_desc),
token::get_name(name), struct_desc),
UnnamedField(idx) => format!("field #{} of {} is private",
idx + 1, struct_desc),
};
@ -873,7 +873,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
match expr.node {
ast::ExprField(ref base, ident) => {
if let ty::ty_struct(id, _) = ty::expr_ty_adjusted(self.tcx, &**base).sty {
self.check_field(expr.span, id, NamedField(ident.node));
self.check_field(expr.span, id, NamedField(ident.node.name));
}
}
ast::ExprTupField(ref base, idx) => {
@ -897,10 +897,14 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
}
ast::ExprStruct(_, ref fields, _) => {
match ty::expr_ty(self.tcx, expr).sty {
ty::ty_struct(id, _) => {
for field in &(*fields) {
self.check_field(expr.span, id,
NamedField(field.ident.node));
ty::ty_struct(ctor_id, _) => {
// RFC 736: ensure all unmentioned fields are visible.
// Rather than computing the set of unmentioned fields
// (i.e. `all_fields - fields`), just check them all.
let all_fields = ty::lookup_struct_fields(self.tcx, ctor_id);
for field in all_fields {
self.check_field(expr.span, ctor_id,
NamedField(field.name));
}
}
ty::ty_enum(_, _) => {
@ -908,7 +912,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
def::DefVariant(_, variant_id, _) => {
for field in fields {
self.check_field(expr.span, variant_id,
NamedField(field.ident.node));
NamedField(field.ident.node.name));
}
}
_ => self.tcx.sess.span_bug(expr.span,
@ -973,7 +977,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
ty::ty_struct(id, _) => {
for field in fields {
self.check_field(pattern.span, id,
NamedField(field.node.ident));
NamedField(field.node.ident.name));
}
}
ty::ty_enum(_, _) => {
@ -981,7 +985,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
Some(&def::DefVariant(_, variant_id, _)) => {
for field in fields {
self.check_field(pattern.span, variant_id,
NamedField(field.node.ident));
NamedField(field.node.ident.name));
}
}
_ => self.tcx.sess.span_bug(pattern.span,

@ -9,11 +9,11 @@
// except according to those terms.
use check::{FnCtxt, structurally_resolved_type};
use check::demand;
use middle::traits::{self, ObjectSafetyViolation, MethodViolationCode};
use middle::traits::{Obligation, ObligationCause};
use middle::traits::report_fulfillment_errors;
use middle::ty::{self, Ty, AsPredicate};
use middle::infer;
use syntax::ast;
use syntax::codemap::Span;
use util::nodemap::FnvHashSet;
@ -24,71 +24,63 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
source_expr: &ast::Expr,
target_object_ty: Ty<'tcx>)
{
let tcx = fcx.tcx();
debug!("check_object_cast(cast_expr={}, target_object_ty={})",
cast_expr.repr(fcx.tcx()),
target_object_ty.repr(fcx.tcx()));
cast_expr.repr(tcx),
target_object_ty.repr(tcx));
// Look up vtables for the type we're casting to,
// passing in the source and target type. The source
// must be a pointer type suitable to the object sigil,
// e.g.: `&x as &Trait` or `box x as Box<Trait>`
let source_ty = fcx.expr_ty(source_expr);
let source_ty = structurally_resolved_type(fcx, source_expr.span, source_ty);
debug!("source_ty={}", source_ty.repr(fcx.tcx()));
match (&source_ty.sty, &target_object_ty.sty) {
(&ty::ty_uniq(referent_ty), &ty::ty_uniq(object_trait_ty)) => {
let object_trait = object_trait(&object_trait_ty);
// Ensure that if ~T is cast to ~Trait, then T : Trait
push_cast_obligation(fcx, cast_expr, object_trait, referent_ty);
check_object_safety(fcx.tcx(), object_trait, source_expr.span);
// First, construct a fresh type that we can feed into `<expr>`
// within `<expr> as <type>` to inform type inference (e.g. to
// tell it that we are expecting a `Box<_>` or an `&_`).
let fresh_ty = fcx.infcx().next_ty_var();
let (object_trait_ty, source_expected_ty) = match target_object_ty.sty {
ty::ty_uniq(object_trait_ty) => {
(object_trait_ty, ty::mk_uniq(fcx.tcx(), fresh_ty))
}
(&ty::ty_rptr(referent_region, ty::mt { ty: referent_ty,
mutbl: referent_mutbl }),
&ty::ty_rptr(target_region, ty::mt { ty: object_trait_ty,
mutbl: target_mutbl })) =>
{
let object_trait = object_trait(&object_trait_ty);
if !mutability_allowed(referent_mutbl, target_mutbl) {
span_err!(fcx.tcx().sess, source_expr.span, E0188,
"types differ in mutability");
} else {
// Ensure that if &'a T is cast to &'b Trait, then T : Trait
push_cast_obligation(fcx, cast_expr,
object_trait,
referent_ty);
// Ensure that if &'a T is cast to &'b Trait, then 'b <= 'a
infer::mk_subr(fcx.infcx(),
infer::RelateObjectBound(source_expr.span),
*target_region,
*referent_region);
check_object_safety(fcx.tcx(), object_trait, source_expr.span);
}
ty::ty_rptr(target_region, ty::mt { ty: object_trait_ty,
mutbl: target_mutbl }) => {
(object_trait_ty,
ty::mk_rptr(fcx.tcx(),
target_region, ty::mt { ty: fresh_ty,
mutbl: target_mutbl }))
}
(_, &ty::ty_uniq(..)) => {
span_err!(fcx.ccx.tcx.sess, source_expr.span, E0189,
"can only cast a boxed pointer \
to a boxed object, not a {}",
ty::ty_sort_string(fcx.tcx(), source_ty));
}
(_, &ty::ty_rptr(..)) => {
span_err!(fcx.ccx.tcx.sess, source_expr.span, E0190,
"can only cast a &-pointer \
to an &-object, not a {}",
ty::ty_sort_string(fcx.tcx(), source_ty));
}
_ => {
fcx.tcx().sess.span_bug(
source_expr.span,
"expected object type");
fcx.tcx().sess.span_bug(source_expr.span, "expected object type");
}
}
};
let source_ty = fcx.expr_ty(source_expr);
debug!("check_object_cast pre unify source_ty={}", source_ty.repr(tcx));
// This ensures that the source_ty <: source_expected_ty, which
// will ensure e.g. that &'a T <: &'b T when doing `&'a T as &'b Trait`
//
// FIXME (pnkfelix): do we need to use suptype_with_fn in order to
// override the error message emitted when the types do not work
// out in the manner desired?
demand::suptype(fcx, source_expr.span, source_expected_ty, source_ty);
debug!("check_object_cast postunify source_ty={}", source_ty.repr(tcx));
let source_ty = structurally_resolved_type(fcx, source_expr.span, source_ty);
debug!("check_object_cast resolveto source_ty={}", source_ty.repr(tcx));
let object_trait = object_trait(&object_trait_ty);
let referent_ty = match source_ty.sty {
ty::ty_uniq(ty) => ty,
ty::ty_rptr(_, ty::mt { ty, mutbl: _ }) => ty,
_ => fcx.tcx().sess.span_bug(source_expr.span,
"expected appropriate reference type"),
};
// Ensure that if Ptr<T> is cast to Ptr<Trait>, then T : Trait.
push_cast_obligation(fcx, cast_expr, object_trait, referent_ty);
check_object_safety(tcx, object_trait, source_expr.span);
fn object_trait<'a, 'tcx>(t: &'a Ty<'tcx>) -> &'a ty::TyTrait<'tcx> {
match t.sty {
@ -97,13 +89,6 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
}
}
fn mutability_allowed(a_mutbl: ast::Mutability,
b_mutbl: ast::Mutability)
-> bool {
a_mutbl == b_mutbl ||
(a_mutbl == ast::MutMutable && b_mutbl == ast::MutImmutable)
}
fn push_cast_obligation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
cast_expr: &ast::Expr,
object_trait: &ty::TyTrait<'tcx>,

@ -10,7 +10,7 @@
//! HTML formatting module
//!
//! This module contains a large number of `fmt::String` implementations for
//! This module contains a large number of `fmt::Display` implementations for
//! various types in `rustdoc::clean`. These implementations all currently
//! assume that HTML output is desired, although it may be possible to redesign
//! them in the future to instead emit any format desired.

@ -64,7 +64,7 @@
body {
color: #333;
font: 16px/1.4 "Source Serif Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
font: 16px/1.4 "Source Serif Pro", Georgia, Times, "Times New Roman", serif;
margin: 0;
position: relative;
padding: 10px 15px 20px 15px;

@ -24,11 +24,8 @@ use rustc::session::{self, config};
use rustc::session::config::get_unstable_features_setting;
use rustc::session::search_paths::{SearchPaths, PathKind};
use rustc_driver::{driver, Compilation};
use syntax::ast;
use syntax::codemap::{CodeMap, dummy_spanned};
use syntax::codemap::CodeMap;
use syntax::diagnostic;
use syntax::parse::token;
use syntax::ptr::P;
use core;
use clean;
@ -67,10 +64,7 @@ pub fn run(input: &str,
span_diagnostic_handler);
let mut cfg = config::build_configuration(&sess);
cfg.extend(cfgs.into_iter().map(|cfg_| {
let cfg_ = token::intern_and_get_ident(&cfg_);
P(dummy_spanned(ast::MetaWord(cfg_)))
}));
cfg.extend(config::parse_cfgspecs(cfgs).into_iter());
let krate = driver::phase_1_parse_input(&sess, cfg, &input);
let krate = driver::phase_2_configure_and_expand(&sess, krate,
"rustdoc-test", None)

@ -1032,7 +1032,7 @@ pub fn as_pretty_json<T>(t: &T) -> AsPrettyJson<T> {
impl Json {
/// Borrow this json object as a pretty object to generate a pretty
/// representation for it via `Show`.
/// representation for it via `Display`.
pub fn pretty(&self) -> PrettyJson {
PrettyJson { inner: self }
}
@ -3540,7 +3540,7 @@ mod tests {
fn test_hashmap_with_enum_key() {
use std::collections::HashMap;
use json;
#[derive(RustcEncodable, Eq, Hash, PartialEq, RustcDecodable, Show)]
#[derive(RustcEncodable, Eq, Hash, PartialEq, RustcDecodable, Debug)]
enum Enum {
Foo,
#[allow(dead_code)]

@ -338,7 +338,6 @@ mod tests {
assert!("".is_ascii());
assert!("a".is_ascii());
assert!(!"\u{2009}".is_ascii());
}
#[test]
@ -346,13 +345,11 @@ mod tests {
assert_eq!("url()URL()uRl()ürl".to_ascii_uppercase(), "URL()URL()URL()üRL");
assert_eq!("hıß".to_ascii_uppercase(), "Hıß");
let mut i = 0;
while i <= 500 {
for i in 0u32..501 {
let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 }
else { i };
assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_uppercase(),
(from_u32(upper).unwrap()).to_string());
i += 1;
}
}
@ -362,13 +359,11 @@ mod tests {
// Dotted capital I, Kelvin sign, Sharp S.
assert_eq!("ß".to_ascii_lowercase(), "ß");
let mut i = 0;
while i <= 500 {
for i in 0u32..501 {
let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
else { i };
assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_lowercase(),
(from_u32(lower).unwrap()).to_string());
i += 1;
}
}
@ -378,13 +373,11 @@ mod tests {
"URL()URL()URL()üRL".to_string());
assert_eq!(("hıß".to_string()).into_ascii_uppercase(), "Hıß");
let mut i = 0;
while i <= 500 {
for i in 0u32..501 {
let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 }
else { i };
assert_eq!((from_u32(i).unwrap()).to_string().into_ascii_uppercase(),
(from_u32(upper).unwrap()).to_string());
i += 1;
}
}
@ -395,13 +388,11 @@ mod tests {
// Dotted capital I, Kelvin sign, Sharp S.
assert_eq!(("ß".to_string()).into_ascii_lowercase(), "ß");
let mut i = 0;
while i <= 500 {
for i in 0u32..501 {
let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
else { i };
assert_eq!((from_u32(i).unwrap()).to_string().into_ascii_lowercase(),
(from_u32(lower).unwrap()).to_string());
i += 1;
}
}
@ -415,14 +406,11 @@ mod tests {
assert!(!"".eq_ignore_ascii_case("k"));
assert!(!"ß".eq_ignore_ascii_case("s"));
let mut i = 0;
while i <= 500 {
let c = i;
let lower = if 'A' as u32 <= c && c <= 'Z' as u32 { c + 'a' as u32 - 'A' as u32 }
else { c };
for i in 0u32..501 {
let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
else { i };
assert!((from_u32(i).unwrap()).to_string().eq_ignore_ascii_case(
&from_u32(lower).unwrap().to_string()));
i += 1;
}
}
}

@ -1377,7 +1377,7 @@ impl<'a, K, V, S, H> IntoIterator for &'a HashMap<K, V, S>
S: HashState<Hasher=H>,
H: hash::Hasher<Output=u64>
{
type Iter = Iter<'a, K, V>;
type IntoIter = Iter<'a, K, V>;
fn into_iter(self) -> Iter<'a, K, V> {
self.iter()
@ -1389,7 +1389,7 @@ impl<'a, K, V, S, H> IntoIterator for &'a mut HashMap<K, V, S>
S: HashState<Hasher=H>,
H: hash::Hasher<Output=u64>
{
type Iter = IterMut<'a, K, V>;
type IntoIter = IterMut<'a, K, V>;
fn into_iter(mut self) -> IterMut<'a, K, V> {
self.iter_mut()
@ -1401,7 +1401,7 @@ impl<K, V, S, H> IntoIterator for HashMap<K, V, S>
S: HashState<Hasher=H>,
H: hash::Hasher<Output=u64>
{
type Iter = IntoIter<K, V>;
type IntoIter = IntoIter<K, V>;
fn into_iter(self) -> IntoIter<K, V> {
self.into_iter()

@ -840,7 +840,7 @@ impl<'a, T, S, H> IntoIterator for &'a HashSet<T, S>
S: HashState<Hasher=H>,
H: hash::Hasher<Output=u64>
{
type Iter = Iter<'a, T>;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
@ -852,7 +852,7 @@ impl<T, S, H> IntoIterator for HashSet<T, S>
S: HashState<Hasher=H>,
H: hash::Hasher<Output=u64>
{
type Iter = IntoIter<T>;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
self.into_iter()

@ -228,7 +228,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
/// ```
fn into_vec(self) -> Vec<u8>;
/// Returns an object that implements `Show` for printing paths
/// Returns an object that implements `Display` for printing paths
///
/// # Example
///
@ -244,7 +244,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
Display{ path: self, filename: false }
}
/// Returns an object that implements `Show` for printing filenames
/// Returns an object that implements `Display` for printing filenames
///
/// If there is no filename, nothing will be printed.
///

@ -723,7 +723,7 @@ extern "system" {
/// println!("{}", argument);
/// }
/// ```
#[deprecated(since = "1.0.0", reason = "use env::args instead")]
#[deprecated(since = "1.0.0", reason = "use std::env::args() instead")]
#[unstable(feature = "os")]
pub fn args() -> Vec<String> {
real_args()

@ -56,10 +56,6 @@ pub fn stack_guard() -> uint {
pub fn set(stack_bounds: (uint, uint), stack_guard: uint, thread: Thread) {
THREAD_INFO.with(|c| assert!(c.borrow().is_none()));
match thread.name() {
Some(name) => unsafe { ::sys::thread::set_name(name); },
None => {}
}
THREAD_INFO.with(move |c| *c.borrow_mut() = Some(ThreadInfo{
stack_bounds: stack_bounds,
stack_guard: stack_guard,

@ -156,6 +156,7 @@ use ops::{Drop, FnOnce};
use option::Option::{self, Some, None};
use result::Result::{Err, Ok};
use sync::{Mutex, Condvar, Arc};
use str::Str;
use string::String;
use rt::{self, unwind};
use old_io::{Writer, stdio};
@ -280,6 +281,10 @@ impl Builder {
unsafe {
stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
}
match their_thread.name() {
Some(name) => unsafe { imp::set_name(name.as_slice()); },
None => {}
}
thread_info::set(
(my_stack_bottom, my_stack_top),
unsafe { imp::guard::current() },

@ -64,7 +64,6 @@ use parse::token;
use ptr::P;
use std::fmt;
use std::fmt::Show;
use std::num::Int;
use std::rc::Rc;
use serialize::{Encodable, Decodable, Encoder, Decoder};

@ -12,7 +12,7 @@ use attr::AttrMetaMethods;
use diagnostic::SpanHandler;
use fold::Folder;
use {ast, fold, attr};
use codemap::Spanned;
use codemap::{Spanned, respan};
use ptr::P;
use util::small_vector::SmallVector;
@ -26,6 +26,7 @@ struct Context<F> where F: FnMut(&[ast::Attribute]) -> bool {
// Support conditional compilation by transforming the AST, stripping out
// any items that do not belong in the current configuration
pub fn strip_unconfigured_items(diagnostic: &SpanHandler, krate: ast::Crate) -> ast::Crate {
let krate = process_cfg_attr(diagnostic, krate);
let config = krate.config.clone();
strip_items(krate, |attrs| in_cfg(diagnostic, &config, attrs))
}
@ -281,3 +282,49 @@ fn in_cfg(diagnostic: &SpanHandler, cfg: &[P<ast::MetaItem>], attrs: &[ast::Attr
attr::cfg_matches(diagnostic, cfg, &*mis[0])
})
}
struct CfgAttrFolder<'a> {
diag: &'a SpanHandler,
config: ast::CrateConfig,
}
// Process `#[cfg_attr]`.
fn process_cfg_attr(diagnostic: &SpanHandler, krate: ast::Crate) -> ast::Crate {
let mut fld = CfgAttrFolder {
diag: diagnostic,
config: krate.config.clone(),
};
fld.fold_crate(krate)
}
impl<'a> fold::Folder for CfgAttrFolder<'a> {
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
if !attr.check_name("cfg_attr") {
return fold::noop_fold_attribute(attr, self);
}
let (cfg, mi) = match attr.meta_item_list() {
Some([ref cfg, ref mi]) => (cfg, mi),
_ => {
self.diag.span_err(attr.span, "expected `#[cfg_attr(<cfg pattern>, <attr>)]`");
return None;
}
};
if attr::cfg_matches(self.diag, &self.config[], &cfg) {
Some(respan(mi.span, ast::Attribute_ {
id: attr::mk_attr_id(),
style: attr.node.style,
value: mi.clone(),
is_sugared_doc: false,
}))
} else {
None
}
}
// Need the ability to run pre-expansion.
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
fold::noop_fold_mac(mac, self)
}
}

@ -518,10 +518,11 @@ fn highlight_lines(err: &mut EmitterWriter,
let count = match lastc {
// Most terminals have a tab stop every eight columns by default
'\t' => 8 - col%8,
_ => lastc.width(false).unwrap_or(1),
_ => lastc.width(false).unwrap_or(0),
};
col += count;
s.extend(::std::iter::repeat('~').take(count - 1));
s.extend(::std::iter::repeat('~').take(count));
let hi = cm.lookup_char_pos(sp.hi);
if hi.col != lo.col {
for (pos, ch) in iter {
@ -534,6 +535,12 @@ fn highlight_lines(err: &mut EmitterWriter,
s.extend(::std::iter::repeat('~').take(count));
}
}
if s.len() > 1 {
// One extra squiggly is replaced by a "^"
s.pop();
}
try!(print_maybe_styled(err,
&format!("{}\n", s)[],
term::attr::ForegroundColor(lvl.color())));

@ -528,8 +528,6 @@ fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv {
syntax_expanders.insert(intern("cfg"),
builtin_normal_expander(
ext::cfg::expand_cfg));
syntax_expanders.insert(intern("cfg_attr"),
Modifier(box ext::cfg_attr::expand));
syntax_expanders.insert(intern("trace_macros"),
builtin_normal_expander(
ext::trace_macros::expand_trace_macros));

@ -40,6 +40,18 @@ pub trait AstBuilder {
bindings: Vec<P<ast::TypeBinding>> )
-> ast::Path;
fn qpath(&self, self_type: P<ast::Ty>,
trait_ref: P<ast::TraitRef>,
ident: ast::Ident )
-> P<ast::QPath>;
fn qpath_all(&self, self_type: P<ast::Ty>,
trait_ref: P<ast::TraitRef>,
ident: ast::Ident,
lifetimes: Vec<ast::Lifetime>,
types: Vec<P<ast::Ty>>,
bindings: Vec<P<ast::TypeBinding>> )
-> P<ast::QPath>;
// types
fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy;
@ -102,6 +114,7 @@ pub trait AstBuilder {
// expressions
fn expr(&self, span: Span, node: ast::Expr_) -> P<ast::Expr>;
fn expr_path(&self, path: ast::Path) -> P<ast::Expr>;
fn expr_qpath(&self, span: Span, qpath: P<ast::QPath>) -> P<ast::Expr>;
fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr>;
fn expr_self(&self, span: Span) -> P<ast::Expr>;
@ -330,6 +343,44 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
}
}
/// Constructs a qualified path.
///
/// Constructs a path like `<self_type as trait_ref>::ident`.
fn qpath(&self,
self_type: P<ast::Ty>,
trait_ref: P<ast::TraitRef>,
ident: ast::Ident)
-> P<ast::QPath> {
self.qpath_all(self_type, trait_ref, ident, Vec::new(), Vec::new(), Vec::new())
}
/// Constructs a qualified path.
///
/// Constructs a path like `<self_type as trait_ref>::ident<a, T, A=Bar>`.
fn qpath_all(&self,
self_type: P<ast::Ty>,
trait_ref: P<ast::TraitRef>,
ident: ast::Ident,
lifetimes: Vec<ast::Lifetime>,
types: Vec<P<ast::Ty>>,
bindings: Vec<P<ast::TypeBinding>> )
-> P<ast::QPath> {
let segment = ast::PathSegment {
identifier: ident,
parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
lifetimes: lifetimes,
types: OwnedSlice::from_vec(types),
bindings: OwnedSlice::from_vec(bindings),
})
};
P(ast::QPath {
self_type: self_type,
trait_ref: trait_ref,
item_path: segment,
})
}
fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy {
ast::MutTy {
ty: ty,
@ -554,6 +605,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.expr(path.span, ast::ExprPath(path))
}
/// Constructs a QPath expression.
fn expr_qpath(&self, span: Span, qpath: P<ast::QPath>) -> P<ast::Expr> {
self.expr(span, ast::ExprQPath(qpath))
}
fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr> {
self.expr_path(self.path_ident(span, id))
}

@ -1,34 +0,0 @@
// 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.
use ast;
use attr;
use codemap::Span;
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
use ptr::P;
pub fn expand(cx: &mut ExtCtxt, sp: Span, mi: &ast::MetaItem, it: P<ast::Item>) -> P<ast::Item> {
let (cfg, attr) = match mi.node {
ast::MetaList(_, ref mis) if mis.len() == 2 => (&mis[0], &mis[1]),
_ => {
cx.span_err(sp, "expected `#[cfg_attr(<cfg pattern>, <attr>)]`");
return it;
}
};
let mut out = (*it).clone();
if attr::cfg_matches(&cx.parse_sess.span_diagnostic, &cx.cfg, &**cfg) {
out.attrs.push(cx.attribute(attr.span, attr.clone()));
}
P(out)
}

@ -844,7 +844,7 @@ fn expand_arm(arm: ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
arm.guard.map(|g| fld.fold_expr(rename_fld.fold_expr(g)));
let rewritten_body = fld.fold_expr(rename_fld.fold_expr(arm.body));
ast::Arm {
attrs: arm.attrs.move_map(|x| fld.fold_attribute(x)),
attrs: fold::fold_attrs(arm.attrs, fld),
pats: rewritten_pats,
guard: rewritten_guard,
body: rewritten_body,
@ -1273,7 +1273,7 @@ fn expand_method(m: P<ast::Method>, fld: &mut MacroExpander) -> SmallVector<P<as
let (rewritten_fn_decl, rewritten_body)
= expand_and_rename_fn_decl_and_block(decl, body, fld);
SmallVector::one(P(ast::Method {
attrs: m.attrs.move_map(|a| fld.fold_attribute(a)),
attrs: fold::fold_attrs(m.attrs, fld),
id: id,
span: fld.new_span(m.span),
node: ast::MethDecl(fld.fold_ident(ident),

@ -223,7 +223,7 @@ pub trait Folder : Sized {
noop_fold_lifetime_def(l, self)
}
fn fold_attribute(&mut self, at: Attribute) -> Attribute {
fn fold_attribute(&mut self, at: Attribute) -> Option<Attribute> {
noop_fold_attribute(at, self)
}
@ -373,9 +373,13 @@ pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<
})
}
pub fn fold_attrs<T: Folder>(attrs: Vec<Attribute>, fld: &mut T) -> Vec<Attribute> {
attrs.into_iter().flat_map(|x| fld.fold_attribute(x).into_iter()).collect()
}
pub fn noop_fold_arm<T: Folder>(Arm {attrs, pats, guard, body}: Arm, fld: &mut T) -> Arm {
Arm {
attrs: attrs.move_map(|x| fld.fold_attribute(x)),
attrs: fold_attrs(attrs, fld),
pats: pats.move_map(|x| fld.fold_pat(x)),
guard: guard.map(|x| fld.fold_expr(x)),
body: fld.fold_expr(body),
@ -475,7 +479,7 @@ pub fn noop_fold_variant<T: Folder>(v: P<Variant>, fld: &mut T) -> P<Variant> {
node: Variant_ {
id: fld.new_id(id),
name: name,
attrs: attrs.move_map(|x| fld.fold_attribute(x)),
attrs: fold_attrs(attrs, fld),
kind: match kind {
TupleVariantKind(variant_args) => {
TupleVariantKind(variant_args.move_map(|x|
@ -553,9 +557,9 @@ pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> {
})
}
pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Attribute {
pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Option<Attribute> {
let Spanned {node: Attribute_ {id, style, value, is_sugared_doc}, span} = at;
Spanned {
Some(Spanned {
node: Attribute_ {
id: id,
style: style,
@ -563,7 +567,7 @@ pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Attribute {
is_sugared_doc: is_sugared_doc
},
span: fld.new_span(span)
}
})
}
pub fn noop_fold_explicit_self_underscore<T: Folder>(es: ExplicitSelf_, fld: &mut T)
@ -845,8 +849,8 @@ pub fn noop_fold_typedef<T>(t: Typedef, folder: &mut T)
where T: Folder {
let new_id = folder.new_id(t.id);
let new_span = folder.new_span(t.span);
let new_attrs = t.attrs.iter().map(|attr| {
folder.fold_attribute((*attr).clone())
let new_attrs = t.attrs.iter().flat_map(|attr| {
folder.fold_attribute((*attr).clone()).into_iter()
}).collect();
let new_ident = folder.fold_ident(t.ident);
let new_type = folder.fold_ty(t.typ);
@ -866,7 +870,7 @@ pub fn noop_fold_associated_type<T>(at: AssociatedType, folder: &mut T)
{
let new_attrs = at.attrs
.iter()
.map(|attr| folder.fold_attribute((*attr).clone()))
.flat_map(|attr| folder.fold_attribute((*attr).clone()).into_iter())
.collect();
let new_param = folder.fold_ty_param(at.ty_param);
ast::AssociatedType {
@ -909,7 +913,7 @@ pub fn noop_fold_struct_field<T: Folder>(f: StructField, fld: &mut T) -> StructF
id: fld.new_id(id),
kind: kind,
ty: fld.fold_ty(ty),
attrs: attrs.move_map(|a| fld.fold_attribute(a))
attrs: fold_attrs(attrs, fld),
},
span: fld.new_span(span)
}
@ -1072,7 +1076,7 @@ pub fn noop_fold_type_method<T: Folder>(m: TypeMethod, fld: &mut T) -> TypeMetho
TypeMethod {
id: fld.new_id(id),
ident: fld.fold_ident(ident),
attrs: attrs.move_map(|a| fld.fold_attribute(a)),
attrs: fold_attrs(attrs, fld),
unsafety: unsafety,
abi: abi,
decl: fld.fold_fn_decl(decl),
@ -1154,7 +1158,7 @@ pub fn noop_fold_item_simple<T: Folder>(Item {id, ident, attrs, node, vis, span}
Item {
id: id,
ident: folder.fold_ident(ident),
attrs: attrs.move_map(|e| folder.fold_attribute(e)),
attrs: fold_attrs(attrs, folder),
node: node,
vis: vis,
span: folder.new_span(span)
@ -1165,7 +1169,7 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) ->
ni.map(|ForeignItem {id, ident, attrs, node, span, vis}| ForeignItem {
id: folder.new_id(id),
ident: folder.fold_ident(ident),
attrs: attrs.move_map(|x| folder.fold_attribute(x)),
attrs: fold_attrs(attrs, folder),
node: match node {
ForeignItemFn(fdec, generics) => {
ForeignItemFn(folder.fold_fn_decl(fdec), folder.fold_generics(generics))
@ -1184,7 +1188,7 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) ->
pub fn noop_fold_method<T: Folder>(m: P<Method>, folder: &mut T) -> SmallVector<P<Method>> {
SmallVector::one(m.map(|Method {id, attrs, node, span}| Method {
id: folder.new_id(id),
attrs: attrs.move_map(|a| folder.fold_attribute(a)),
attrs: fold_attrs(attrs, folder),
node: match node {
MethDecl(ident,
generics,

@ -96,7 +96,6 @@ pub mod ext {
pub mod base;
pub mod build;
pub mod cfg;
pub mod cfg_attr;
pub mod concat;
pub mod concat_idents;
pub mod deriving;

@ -562,7 +562,7 @@ declare_special_idents_and_keywords! {
(45, Where, "where");
'reserved:
(46, Alignof, "alignof");
(47, Be, "be");
(47, Become, "become");
(48, Offsetof, "offsetof");
(49, Priv, "priv");
(50, Pure, "pure");

@ -52,7 +52,6 @@
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
#![feature(int_uint)]
#![feature(io)]
#![feature(path)]

@ -0,0 +1,18 @@
// Copyright 2015 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.
//
// error-pattern: main function not found
// compile-flags: --cfg foo
// main is conditionally compiled, but the conditional compilation
// is conditional too!
#[cfg_attr(foo, cfg(bar))]
fn main() { }

@ -0,0 +1,17 @@
// Copyright 2015 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.
//
// compile-flags: --cfg broken
// https://github.com/rust-lang/rust/issues/21833#issuecomment-72353044
#![cfg_attr(broken, no_std)] //~ ERROR no_std is experimental
fn main() { }

@ -0,0 +1,42 @@
// Copyright 2015 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.
// RFC 736 (and Issue 21407): functional struct update should respect privacy.
// The `foo` module attempts to maintains an invariant that each `S`
// has a unique `u64` id.
use self::foo::S;
mod foo {
use std::cell::{UnsafeCell};
static mut count : UnsafeCell<u64> = UnsafeCell { value: 1 };
pub struct S { pub a: u8, pub b: String, secret_uid: u64 }
pub fn make_secrets(a: u8, b: String) -> S {
let val = unsafe { let p = count.get(); let val = *p; *p = val + 1; val };
println!("creating {}, uid {}", b, val);
S { a: a, b: b, secret_uid: val }
}
impl Drop for S {
fn drop(&mut self) {
println!("dropping {}, uid {}", self.b, self.secret_uid);
}
}
}
fn main() {
let s_1 = foo::make_secrets(3, format!("ess one"));
let s_2 = foo::S { b: format!("ess two"), ..s_1 }; // FRU ...
//~^ ERROR field `secret_uid` of struct `foo::S` is private
println!("main forged an S named: {}", s_2.b);
// at end of scope, ... both s_1 *and* s_2 get dropped. Boom!
}

@ -13,6 +13,6 @@
struct B<T>;
fn main() {
let foo = B;
let closure = || foo; //~ ERROR unable to infer enough type information
let foo = B; //~ ERROR: unable to infer enough type information
let closure = || foo;
}

@ -9,7 +9,6 @@
// except according to those terms.
#![deny(unused_variables)]
#![feature(core)]
fn main() {
for _ in 1..101 {

@ -0,0 +1,47 @@
// Copyright 2015 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.
// We used to ICE when moving out of a `*mut T` or `*const T`.
struct T(u8);
static mut GLOBAL_MUT_T: T = T(0);
static GLOBAL_T: T = T(0);
fn imm_ref() -> &'static T {
unsafe { &GLOBAL_T }
}
fn mut_ref() -> &'static mut T {
unsafe { &mut GLOBAL_MUT_T }
}
fn mut_ptr() -> *mut T {
unsafe { 0u8 as *mut T }
}
fn const_ptr() -> *const T {
unsafe { 0u8 as *const T }
}
pub fn main() {
let a = unsafe { *mut_ref() };
//~^ ERROR cannot move out of borrowed content
let b = unsafe { *imm_ref() };
//~^ ERROR cannot move out of borrowed content
let c = unsafe { *mut_ptr() };
//~^ ERROR cannot move out of dereference of unsafe pointer
let d = unsafe { *const_ptr() };
//~^ ERROR cannot move out of dereference of unsafe pointer
}

@ -11,7 +11,6 @@
#![deny(unreachable_code)]
#![allow(unused_variables)]
#![allow(dead_code)]
#![feature(core)]
fn fail_len(v: Vec<isize> ) -> usize {
let mut i = 3;

@ -11,7 +11,6 @@
#![deny(unused_variables)]
#![deny(unused_assignments)]
#![allow(dead_code, non_camel_case_types)]
#![feature(core)]
fn f1(x: isize) {
//~^ ERROR unused variable: `x`

@ -1,4 +1,4 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -9,6 +9,6 @@
// except according to those terms.
fn main() {
let be = 0;
//~^ ERROR `be` is a reserved keyword
let become = 0;
//~^ ERROR `become` is a reserved keyword
}

@ -1,9 +1,7 @@
-include ../tools.mk
ifndef IS_WINDOWS
ifneq ($(shell uname),Darwin)
EXTRAFLAGS := -lm -lrt -ldl -lpthread
endif
EXTRAFLAGS := $(EXTRACFLAGS)
endif
# FIXME: ignore freebsd

@ -2,3 +2,4 @@ include ../tools.mk
all:
$(RUSTC) --crate-type=rlib foo.rs
$(RUSTC) --crate-type=rlib,rlib foo.rs

@ -0,0 +1,5 @@
-include ../tools.mk
all:
$(RUSTC) --emit=asm,llvm-bc,llvm-ir,obj,dep-info empty.rs
$(RUSTC) --emit=link --crate-type=rlib,dylib,staticlib empty.rs

@ -0,0 +1,7 @@
-include ../tools.mk
all: foo.rs
$(RUSTC) --cfg 'feature="bar"' --crate-type lib foo.rs
$(HOST_RPATH_ENV) $(RUSTDOC) --test --cfg 'feature="bar"' \
-L $(TMPDIR) foo.rs |\
grep --quiet 'test foo_0 ... ok'

@ -0,0 +1,17 @@
// 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.
#![crate_name="foo"]
/// ```rust
/// assert_eq!(foo::foo(), 1);
/// ```
#[cfg(feature = "bar")]
pub fn foo() -> i32 { 1 }

@ -1,6 +1,7 @@
-include ../tools.mk
ifndef IS_WINDOWS
ifneq ($(UNAME),OpenBSD)
all:
$(RUSTC) -O --emit asm attr.rs
! grep -q morestack $(TMPDIR)/attr.s
@ -9,6 +10,10 @@ all:
$(RUSTC) -O --emit asm -C no-stack-check flag.rs
! grep -q morestack $(TMPDIR)/flag.s
else
# On OpenBSD, morestack isn't used as the segmented stacks are disabled
all:
endif
else
# On Windows we use __chkstk and it only appears in functions with large allocations,
# so this test wouldn't be reliable.
all:

@ -10,6 +10,6 @@ OUT=$(TMPDIR)/lib.s
all:
$(RUSTC) lib.rs --emit=asm --crate-type=staticlib
# just check for symbol declarations with the names we're expecting.
grep 'str[0-9]\+:' $(OUT)
grep 'binary[0-9]\+:' $(OUT)
grep 'vtable[0-9]\+' $(OUT)
grep 'str[0-9][0-9]*:' $(OUT)
grep 'binary[0-9][0-9]*:' $(OUT)
grep 'vtable[0-9][0-9]*' $(OUT)

@ -1,11 +1,11 @@
-include ../tools.mk
all:
$(RUSTC) foo.rs --target=my-awesome-platform.json --crate-type=lib --emit=asm
grep --quiet --invert-match morestack < $(TMPDIR)/foo.s
grep -q -v morestack < $(TMPDIR)/foo.s
$(RUSTC) foo.rs --target=my-invalid-platform.json 2>&1 | grep --quiet "Error loading target specification"
$(RUSTC) foo.rs --target=my-incomplete-platform.json 2>&1 | grep 'Field llvm-target'
RUST_TARGET_PATH=. $(RUSTC) foo.rs --target=my-awesome-platform --crate-type=lib --emit=asm
RUST_TARGET_PATH=. $(RUSTC) foo.rs --target=x86_64-unknown-linux-gnu --crate-type=lib --emit=asm
# The built-in target *should* override the one we have here, and thus we
# should have morestack
grep --quiet morestack < $(TMPDIR)/foo.s
grep -q morestack < $(TMPDIR)/foo.s

@ -1,5 +1,6 @@
-include ../tools.mk
ifneq ($(UNAME),OpenBSD)
HOST := $(shell $(RUSTC) -vV | grep 'host:' | sed 's/host: //')
ifeq ($(findstring i686,$(HOST)),i686)
TARGET := $(subst i686,x86_64,$(HOST))
@ -11,3 +12,7 @@ all:
$(RUSTC) foo.rs -C extra-filename=-host
$(RUSTC) bar.rs -C extra-filename=-targ --target $(TARGET)
$(RUSTC) baz.rs --extern a=$(TMPDIR)/liba-targ.rlib --target $(TARGET)
else
# OpenBSD support only x86_64 architecture for now
all:
endif

@ -0,0 +1,15 @@
// Copyright 2015 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.
// main is conditionally compiled, but the conditional compilation
// is conditional too!
#[cfg_attr(foo, cfg(bar))]
fn main() { }

@ -0,0 +1,15 @@
// Copyright 2015 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.
// https://github.com/rust-lang/rust/issues/21833#issuecomment-72353044
#![cfg_attr(not_used, no_std)]
fn main() { }

@ -0,0 +1,59 @@
// Copyright 2015 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.
// Given `<expr> as Box<Trait>`, we should be able to infer that a
// `Box<_>` is the expected type.
trait Foo { fn foo(&self) -> u32; }
impl Foo for u32 { fn foo(&self) -> u32 { *self } }
// (another impl to ensure trait-matching cannot just choose from a singleton set)
impl Foo for () { fn foo(&self) -> u32 { -176 } }
trait Boxed { fn make() -> Self; }
impl Boxed for Box<u32> { fn make() -> Self { Box::new(7) } }
// (another impl to ensure trait-matching cannot just choose from a singleton set)
impl Boxed for () { fn make() -> Self { () } }
fn boxed_foo() {
let b7 = Boxed::make() as Box<Foo>;
assert_eq!(b7.foo(), 7);
}
trait Refed<'a,T> { fn make(&'a T) -> Self; }
impl<'a> Refed<'a, u32> for &'a u32 { fn make(x: &'a u32) -> Self { x } }
// (another impl to ensure trait-matching cannot just choose from a singleton set)
impl<'a,'b> Refed<'a, ()> for &'b () { fn make(_: &'a ()) -> Self { static U: () = (); &U } }
fn refed_foo() {
let a = 8;
let b7 = Refed::make(&a) as &Foo;
assert_eq!(b7.foo(), 8);
}
fn check_subtyping_works() {
fn inner<'short, 'long:'short>(_s: &'short u32,
l: &'long u32) -> &'short (Foo+'short) {
Refed::make(l) as &Foo
}
let a = 9;
let b = 10;
let r = inner(&b, &a);
assert_eq!(r.foo(), 9);
}
pub fn main() {
boxed_foo();
refed_foo();
check_subtyping_works();
}

@ -0,0 +1,22 @@
// Copyright 2015 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.
// Test that the type variable in the type(`Vec<_>`) of a closed over
// variable does not interfere with type inference.
fn f<F: FnMut()>(mut f: F) {
f();
}
fn main() {
let mut v: Vec<_> = vec![];
f(|| v.push(0));
assert_eq!(v, vec![0]);
}