diff --git a/configure b/configure index a80dafcf047..e6b8d235448 100755 --- a/configure +++ b/configure @@ -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" diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index e6d2a691cf5..3c92fa02f20 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -12,7 +12,6 @@ #![feature(box_syntax)] #![feature(collections)] -#![feature(core)] #![feature(int_uint)] #![feature(io)] #![feature(os)] diff --git a/src/doc/grammar.md b/src/doc/grammar.md index 59a1c8f828b..b4e023c2039 100644 --- a/src/doc/grammar.md +++ b/src/doc/grammar.md @@ -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 | diff --git a/src/doc/index.md b/src/doc/index.md index 252a3125ebd..a4f79412220 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -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 diff --git a/src/doc/reference.md b/src/doc/reference.md index 999efc95c0e..d50c0d6582b 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -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 diff --git a/src/doc/rust.css b/src/doc/rust.css index 3f59f12e74c..c2a25cd7a58 100644 --- a/src/doc/rust.css +++ b/src/doc/rust.css @@ -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; diff --git a/src/doc/trpl/SUMMARY.md b/src/doc/trpl/SUMMARY.md index 9d65f30e723..bfc1247dc3b 100644 --- a/src/doc/trpl/SUMMARY.md +++ b/src/doc/trpl/SUMMARY.md @@ -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) diff --git a/src/doc/trpl/closures.md b/src/doc/trpl/closures.md index bfb1494efc7..8cc6be7387c 100644 --- a/src/doc/trpl/closures.md +++ b/src/doc/trpl/closures.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 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 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(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 } ``` diff --git a/src/doc/trpl/compound-data-types.md b/src/doc/trpl/compound-data-types.md index 8b99278acb1..51a4edbdac8 100644 --- a/src/doc/trpl/compound-data-types.md +++ b/src/doc/trpl/compound-data-types.md @@ -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 diff --git a/src/doc/trpl/static-and-dynamic-dispatch.md b/src/doc/trpl/static-and-dynamic-dispatch.md new file mode 100644 index 00000000000..9421dac7bf6 --- /dev/null +++ b/src/doc/trpl/static-and-dynamic-dispatch.md @@ -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(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 aren’t 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`, 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` to `Box`, 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`, 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`), 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. diff --git a/src/doc/trpl/traits.md b/src/doc/trpl/traits.md index d12480d7dd9..e091878cf86 100644 --- a/src/doc/trpl/traits.md +++ b/src/doc/trpl/traits.md @@ -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(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 diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 24b4abbff4a..0617c604121 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -206,12 +206,12 @@ impl Arc { /// Get the number of weak references to this value. #[inline] #[unstable(feature = "alloc")] -pub fn weak_count(this: &Arc) -> uint { this.inner().weak.load(SeqCst) - 1 } +pub fn weak_count(this: &Arc) -> usize { this.inner().weak.load(SeqCst) - 1 } /// Get the number of strong references to this value. #[inline] #[unstable(feature = "alloc")] -pub fn strong_count(this: &Arc) -> uint { this.inner().strong.load(SeqCst) } +pub fn strong_count(this: &Arc) -> usize { this.inner().strong.load(SeqCst) } #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Arc { @@ -649,7 +649,7 @@ mod tests { let (tx, rx) = channel(); let _t = Thread::spawn(move || { - let arc_v: Arc> = rx.recv().unwrap(); + let arc_v: Arc> = rx.recv().unwrap(); assert_eq!((*arc_v)[3], 4); }); @@ -818,5 +818,5 @@ mod tests { // Make sure deriving works with Arc #[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)] - struct Foo { inner: Arc } + struct Foo { inner: Arc } } diff --git a/src/liballoc/boxed_test.rs b/src/liballoc/boxed_test.rs index 8f65b8c42c9..b7bacaa0cae 100644 --- a/src/liballoc/boxed_test.rs +++ b/src/liballoc/boxed_test.rs @@ -22,7 +22,7 @@ use std::boxed::BoxAny; #[test] fn test_owned_clone() { let a = Box::new(5); - let b: Box = a.clone(); + let b: Box = a.clone(); assert!(a == b); } @@ -31,11 +31,11 @@ struct Test; #[test] fn any_move() { - let a = Box::new(8us) as Box; + let a = Box::new(8) as Box; let b = Box::new(Test) as Box; - match a.downcast::() { - Ok(a) => { assert!(a == Box::new(8us)); } + match a.downcast::() { + Ok(a) => { assert!(a == Box::new(8)); } Err(..) => panic!() } match b.downcast::() { @@ -47,7 +47,7 @@ fn any_move() { let b = Box::new(Test) as Box; assert!(a.downcast::>().is_err()); - assert!(b.downcast::>().is_err()); + assert!(b.downcast::>().is_err()); } #[test] diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index 1d5637a6ad6..d3d86270d1e 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -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 } diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 81391fd63eb..0e6266f9cbc 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -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)] diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 54ff4c18654..ab3c0901bc9 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -40,7 +40,7 @@ //! } //! //! struct Gadget { -//! id: int, +//! id: i32, //! owner: Rc //! // ...other fields //! } @@ -99,7 +99,7 @@ //! } //! //! struct Gadget { -//! id: int, +//! id: i32, //! owner: Rc //! // ...other fields //! } @@ -166,8 +166,8 @@ use heap::deallocate; struct RcBox { value: T, - strong: Cell, - weak: Cell + strong: Cell, + weak: Cell } /// An immutable reference-counted pointer type. @@ -233,12 +233,12 @@ impl Rc { /// Get the number of weak references to this value. #[inline] #[unstable(feature = "alloc")] -pub fn weak_count(this: &Rc) -> uint { this.weak() - 1 } +pub fn weak_count(this: &Rc) -> usize { this.weak() - 1 } /// Get the number of strong references to this value. #[inline] #[unstable(feature = "alloc")] -pub fn strong_count(this: &Rc) -> uint { this.strong() } +pub fn strong_count(this: &Rc) -> usize { this.strong() } /// Returns true if there are no other `Rc` or `Weak` values that share the same inner value. /// @@ -447,7 +447,7 @@ impl Default for Rc { /// use std::rc::Rc; /// use std::default::Default; /// - /// let x: Rc = Default::default(); + /// let x: Rc = Default::default(); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -750,7 +750,7 @@ trait RcBoxPtr { fn inner(&self) -> &RcBox; #[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 { 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); } diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 62d103ae06a..223c5111f8f 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -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>>, - fill: Cell, + fill: Cell, is_copy: Cell, } 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::(), mem::min_align_of::()); - 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::, _>(|| { + arena.alloc::, _>(|| { panic!(); }); } @@ -373,12 +372,12 @@ struct TypedArenaChunk { next: *mut TypedArenaChunk, /// The number of elements that this chunk can hold. - capacity: uint, + capacity: usize, // Objects follow here, suitably aligned. } -fn calculate_size(capacity: uint) -> uint { +fn calculate_size(capacity: usize) -> usize { let mut size = mem::size_of::>(); size = round_up(size, mem::min_align_of::()); let elem_size = mem::size_of::(); @@ -389,7 +388,7 @@ fn calculate_size(capacity: uint) -> uint { impl TypedArenaChunk { #[inline] - unsafe fn new(next: *mut TypedArenaChunk, capacity: uint) + unsafe fn new(next: *mut TypedArenaChunk, capacity: usize) -> *mut TypedArenaChunk { let size = calculate_size::(capacity); let chunk = allocate(size, mem::min_align_of::>()) @@ -403,13 +402,13 @@ impl TypedArenaChunk { /// 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::() { 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::() as int) + start = start.offset(mem::size_of::() as isize) } } @@ -429,7 +428,7 @@ impl TypedArenaChunk { fn start(&self) -> *const u8 { let this: *const TypedArenaChunk = self; unsafe { - mem::transmute(round_up(this.offset(1) as uint, + mem::transmute(round_up(this.offset(1) as usize, mem::min_align_of::())) } } @@ -439,7 +438,7 @@ impl TypedArenaChunk { fn end(&self) -> *const u8 { unsafe { let size = mem::size_of::().checked_mul(self.capacity).unwrap(); - self.start().offset(size as int) + self.start().offset(size as isize) } } } @@ -454,7 +453,7 @@ impl TypedArena { /// Creates a new `TypedArena` with preallocated space for the given number of /// objects. #[inline] - pub fn with_capacity(capacity: uint) -> TypedArena { + pub fn with_capacity(capacity: usize) -> TypedArena { unsafe { let chunk = TypedArenaChunk::::new(ptr::null_mut(), capacity); TypedArena { @@ -501,8 +500,8 @@ impl Drop for TypedArena { 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::(); // 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, + array: Vec, } #[test] diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index 275fc34f813..11576fbb00c 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -656,7 +656,7 @@ impl FromIterator for BinaryHeap { } impl IntoIterator for BinaryHeap { - type Iter = IntoIter; + type IntoIter = IntoIter; fn into_iter(self) -> IntoIter { self.into_iter() @@ -664,7 +664,7 @@ impl IntoIterator for BinaryHeap { } impl<'a, T> IntoIterator for &'a BinaryHeap where T: Ord { - type Iter = Iter<'a, T>; + type IntoIter = Iter<'a, T>; fn into_iter(self) -> Iter<'a, T> { self.iter() diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index 8ba0eb9b7ef..6d15a264172 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -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() diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index aec50d53808..2cef08725a2 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -463,7 +463,7 @@ impl BTreeMap { } impl IntoIterator for BTreeMap { - type Iter = IntoIter; + type IntoIter = IntoIter; fn into_iter(self) -> IntoIter { self.into_iter() @@ -471,7 +471,7 @@ impl IntoIterator for BTreeMap { } impl<'a, K, V> IntoIterator for &'a BTreeMap { - 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 { } impl<'a, K, V> IntoIterator for &'a mut BTreeMap { - type Iter = IterMut<'a, K, V>; + type IntoIter = IterMut<'a, K, V>; fn into_iter(mut self) -> IterMut<'a, K, V> { self.iter_mut() diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index c888a261f9d..7cb31ab1f6d 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -481,7 +481,7 @@ impl FromIterator for BTreeSet { } impl IntoIterator for BTreeSet { - type Iter = IntoIter; + type IntoIter = IntoIter; fn into_iter(self) -> IntoIter { self.into_iter() @@ -489,7 +489,7 @@ impl IntoIterator for BTreeSet { } impl<'a, T> IntoIterator for &'a BTreeSet { - type Iter = Iter<'a, T>; + type IntoIter = Iter<'a, T>; fn into_iter(self) -> Iter<'a, T> { self.iter() diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index 748230c5d24..a080146e0ec 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -831,7 +831,7 @@ impl FromIterator for DList { } impl IntoIterator for DList { - type Iter = IntoIter; + type IntoIter = IntoIter; fn into_iter(self) -> IntoIter { self.into_iter() @@ -839,7 +839,7 @@ impl IntoIterator for DList { } impl<'a, T> IntoIterator for &'a DList { - 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 { } impl<'a, T> IntoIterator for &'a mut DList { - type Iter = IterMut<'a, T>; + type IntoIter = IterMut<'a, T>; fn into_iter(mut self) -> IterMut<'a, T> { self.iter_mut() diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index da146506077..da533d34703 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -258,7 +258,7 @@ impl FromIterator for EnumSet { } impl<'a, E> IntoIterator for &'a EnumSet where E: CLike { - type Iter = Iter; + type IntoIter = Iter; fn into_iter(self) -> Iter { self.iter() diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index f220724c42e..a542ee5d47d 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -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)] diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs index 76849e6ade8..5f1dc1d2ef4 100644 --- a/src/libcollections/ring_buf.rs +++ b/src/libcollections/ring_buf.rs @@ -1608,7 +1608,7 @@ impl FromIterator for RingBuf { } impl IntoIterator for RingBuf { - type Iter = IntoIter; + type IntoIter = IntoIter; fn into_iter(self) -> IntoIter { self.into_iter() @@ -1616,7 +1616,7 @@ impl IntoIterator for RingBuf { } impl<'a, T> IntoIterator for &'a RingBuf { - 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 { } impl<'a, T> IntoIterator for &'a mut RingBuf { - type Iter = IterMut<'a, T>; + type IntoIter = IterMut<'a, T>; fn into_iter(mut self) -> IterMut<'a, T> { self.iter_mut() diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 70097c956cd..1cd2a89ad60 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1388,7 +1388,7 @@ impl FromIterator for Vec { } impl IntoIterator for Vec { - type Iter = IntoIter; + type IntoIter = IntoIter; fn into_iter(self) -> IntoIter { self.into_iter() @@ -1396,7 +1396,7 @@ impl IntoIterator for Vec { } impl<'a, T> IntoIterator for &'a Vec { - 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 { } impl<'a, T> IntoIterator for &'a mut Vec { - type Iter = slice::IterMut<'a, T>; + type IntoIter = slice::IterMut<'a, T>; fn into_iter(mut self) -> slice::IterMut<'a, T> { self.iter_mut() diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 739b8d8ce19..93d02de9b55 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -669,7 +669,7 @@ impl FromIterator<(usize, V)> for VecMap { } impl IntoIterator for VecMap { - type Iter = IntoIter; + type IntoIter = IntoIter; fn into_iter(self) -> IntoIter { self.into_iter() @@ -677,7 +677,7 @@ impl IntoIterator for VecMap { } impl<'a, T> IntoIterator for &'a VecMap { - 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 { } impl<'a, T> IntoIterator for &'a mut VecMap { - type Iter = IterMut<'a, T>; + type IntoIter = IterMut<'a, T>; fn into_iter(mut self) -> IterMut<'a, T> { self.iter_mut() diff --git a/src/libcore/any.rs b/src/libcore/any.rs index 40c2d82bf4b..462b6771b4a 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -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 diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 5c4567e567b..a596fe4a588 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -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() diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index c82d8c531d2..050b34508ff 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -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 { value: UnsafeCell, @@ -259,7 +259,7 @@ impl PartialEq for Cell { /// 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 { value: UnsafeCell, @@ -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`. /// -/// 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`. /// -/// 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 diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 125e8a0e814..5562845e11d 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -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") }; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 5df64cfaada..7740cd6867c 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -120,14 +120,15 @@ pub trait FromIterator { /// 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 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. #[unstable(feature = "core", reason = "recent addition")] - fn cloned(self) -> Cloned where - Self: Iterator, - D: Deref, - T: Clone, + fn cloned(self) -> Cloned where + Self::Item: Deref, + ::Output: Clone, { Cloned { it: self } } @@ -2646,13 +2646,7 @@ impl Iterator for RangeStepInclusive { 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 Iterator for ::ops::Range { #[inline] fn size_hint(&self) -> (usize, Option) { - 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) + } } } diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index df4942b509b..a122bcb2c7a 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -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; diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index ba1eae551ff..bf801a88ca5 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -522,21 +522,21 @@ impl PartialOrd for *mut T { /// Useful for building abstractions like `Vec` or `Box`, which /// internally use raw pointers to manage the memory that they own. #[unstable(feature = "core", reason = "recently added to this module")] -pub struct Unique(pub *mut T); +pub struct Unique(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 Send for Unique { } +unsafe impl Send for Unique { } /// `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 Sync for Unique { } +unsafe impl Sync for Unique { } impl Unique { /// Returns a null Unique. diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index fc51920ec6b..459addb09fd 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -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() diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs index 64c2964eb7c..72b2d5dc188 100644 --- a/src/libcore/tuple.rs +++ b/src/libcore/tuple.rs @@ -34,6 +34,7 @@ //! * `Default` #![stable(feature = "rust1", since = "1.0.0")] +#![doc(primitive = "tuple")] use clone::Clone; use cmp::*; diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index c9cdf50fdbd..3f8e330b332 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -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] diff --git a/src/libcoretest/ptr.rs b/src/libcoretest/ptr.rs index 7f0b97c53d4..2365b907b3f 100644 --- a/src/libcoretest/ptr.rs +++ b/src/libcoretest/ptr.rs @@ -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); +} diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index 1b30bdf230e..a3cae259fd3 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -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 = optgrps.iter().map(|x| x.long_to_short()).collect(); diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 38d5c5eb27a..94e4012c5ee 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -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; diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 0ce9db1c80f..b5904f23ef3 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -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 } diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 1c341df85cb..5323a322436 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -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())) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 95f7ff58524..97e6517a615 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index cd664b7388c..949fee45517 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -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 , + pub output_types: Vec, // 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) -> Result(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 {}", diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index aa9b6c479bb..96e146fc894 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -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, diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs index 19287f19d8d..00f6c6109fa 100644 --- a/src/librustc_typeck/check/vtable.rs +++ b/src/librustc_typeck/check/vtable.rs @@ -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` - 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 `` + // within ` as ` 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 is cast to Ptr, 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>, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index cc2cf21095e..e916b63eb8d 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -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. diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css index 46faa3efc34..7267f95b31f 100644 --- a/src/librustdoc/html/static/main.css +++ b/src/librustdoc/html/static/main.css @@ -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; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index e43c3a6da3a..09df9fc8cbb 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -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) diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index b8383577987..daa358647d8 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -1032,7 +1032,7 @@ pub fn as_pretty_json(t: &T) -> AsPrettyJson { 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)] diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 892747e79ed..ac48481027d 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -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ıKß".to_ascii_uppercase(), "HıKß"); - 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!("HİKß".to_ascii_lowercase(), "hİKß"); - 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ıKß".to_string()).into_ascii_uppercase(), "HıKß"); - 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!(("HİKß".to_string()).into_ascii_lowercase(), "hİKß"); - 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!(!"K".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; } } } diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 710f021d912..18dd122891d 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1377,7 +1377,7 @@ impl<'a, K, V, S, H> IntoIterator for &'a HashMap S: HashState, H: hash::Hasher { - 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 S: HashState, H: hash::Hasher { - 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 IntoIterator for HashMap S: HashState, H: hash::Hasher { - type Iter = IntoIter; + type IntoIter = IntoIter; fn into_iter(self) -> IntoIter { self.into_iter() diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index e40f17f29e8..de3c0424c9a 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -840,7 +840,7 @@ impl<'a, T, S, H> IntoIterator for &'a HashSet S: HashState, H: hash::Hasher { - type Iter = Iter<'a, T>; + type IntoIter = Iter<'a, T>; fn into_iter(self) -> Iter<'a, T> { self.iter() @@ -852,7 +852,7 @@ impl IntoIterator for HashSet S: HashState, H: hash::Hasher { - type Iter = IntoIter; + type IntoIter = IntoIter; fn into_iter(self) -> IntoIter { self.into_iter() diff --git a/src/libstd/old_path/mod.rs b/src/libstd/old_path/mod.rs index 0d80258d7e0..17cfe1c8297 100644 --- a/src/libstd/old_path/mod.rs +++ b/src/libstd/old_path/mod.rs @@ -228,7 +228,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe { /// ``` fn into_vec(self) -> Vec; - /// 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. /// diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 1a617694456..526b5edd4cb 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -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 { real_args() diff --git a/src/libstd/sys/common/thread_info.rs b/src/libstd/sys/common/thread_info.rs index ce67a584a0a..92b936e74f6 100644 --- a/src/libstd/sys/common/thread_info.rs +++ b/src/libstd/sys/common/thread_info.rs @@ -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, diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index eb967c9f4e3..cc9d7492441 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -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() }, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index f8793f81b19..5979d339e17 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -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}; diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index eb845e463a0..7ca0591be50 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -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 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], 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 { + 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(, )]`"); + 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) + } +} diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 454209bdba2..83a4d938bb5 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -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()))); diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 778b2cabea6..64ae6162ef4 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -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)); diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 6d9a2fdb9f1..5bfd4a9f611 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -40,6 +40,18 @@ pub trait AstBuilder { bindings: Vec> ) -> ast::Path; + fn qpath(&self, self_type: P, + trait_ref: P, + ident: ast::Ident ) + -> P; + fn qpath_all(&self, self_type: P, + trait_ref: P, + ident: ast::Ident, + lifetimes: Vec, + types: Vec>, + bindings: Vec> ) + -> P; + // types fn ty_mt(&self, ty: P, mutbl: ast::Mutability) -> ast::MutTy; @@ -102,6 +114,7 @@ pub trait AstBuilder { // expressions fn expr(&self, span: Span, node: ast::Expr_) -> P; fn expr_path(&self, path: ast::Path) -> P; + fn expr_qpath(&self, span: Span, qpath: P) -> P; fn expr_ident(&self, span: Span, id: ast::Ident) -> P; fn expr_self(&self, span: Span) -> P; @@ -330,6 +343,44 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } + /// Constructs a qualified path. + /// + /// Constructs a path like `::ident`. + fn qpath(&self, + self_type: P, + trait_ref: P, + ident: ast::Ident) + -> P { + self.qpath_all(self_type, trait_ref, ident, Vec::new(), Vec::new(), Vec::new()) + } + + /// Constructs a qualified path. + /// + /// Constructs a path like `::ident`. + fn qpath_all(&self, + self_type: P, + trait_ref: P, + ident: ast::Ident, + lifetimes: Vec, + types: Vec>, + bindings: Vec> ) + -> P { + 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, 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) -> P { + self.expr(span, ast::ExprQPath(qpath)) + } + fn expr_ident(&self, span: Span, id: ast::Ident) -> P { self.expr_path(self.path_ident(span, id)) } diff --git a/src/libsyntax/ext/cfg_attr.rs b/src/libsyntax/ext/cfg_attr.rs deleted file mode 100644 index 72eaa3e47be..00000000000 --- a/src/libsyntax/ext/cfg_attr.rs +++ /dev/null @@ -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 or the MIT license -// , 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) -> P { - 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(, )]`"); - 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) -} - diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index fd7593f2a3b..131bbc41005 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -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, fld: &mut MacroExpander) -> SmallVector Attribute { + fn fold_attribute(&mut self, at: Attribute) -> Option { noop_fold_attribute(at, self) } @@ -373,9 +373,13 @@ pub fn noop_fold_view_path(view_path: P, fld: &mut T) -> P< }) } +pub fn fold_attrs(attrs: Vec, fld: &mut T) -> Vec { + attrs.into_iter().flat_map(|x| fld.fold_attribute(x).into_iter()).collect() +} + pub fn noop_fold_arm(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(v: P, fld: &mut T) -> P { 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(l: P, fld: &mut T) -> P { }) } -pub fn noop_fold_attribute(at: Attribute, fld: &mut T) -> Attribute { +pub fn noop_fold_attribute(at: Attribute, fld: &mut T) -> Option { 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(at: Attribute, fld: &mut T) -> Attribute { is_sugared_doc: is_sugared_doc }, span: fld.new_span(span) - } + }) } pub fn noop_fold_explicit_self_underscore(es: ExplicitSelf_, fld: &mut T) @@ -845,8 +849,8 @@ pub fn noop_fold_typedef(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(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(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(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(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(ni: P, 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(ni: P, folder: &mut T) -> pub fn noop_fold_method(m: P, folder: &mut T) -> SmallVector> { 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, diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 08e795ef80d..41850ada3e6 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -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; diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 45f4f044ea4..4c988164528 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -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"); diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 219c9baf4c8..084152f107c 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -52,7 +52,6 @@ #![feature(box_syntax)] #![feature(collections)] -#![feature(core)] #![feature(int_uint)] #![feature(io)] #![feature(path)] diff --git a/src/test/compile-fail/cfg-attr-cfg-2.rs b/src/test/compile-fail/cfg-attr-cfg-2.rs new file mode 100644 index 00000000000..b71a3be5dce --- /dev/null +++ b/src/test/compile-fail/cfg-attr-cfg-2.rs @@ -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 or the MIT license +// , 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() { } diff --git a/src/test/compile-fail/cfg-attr-crate-2.rs b/src/test/compile-fail/cfg-attr-crate-2.rs new file mode 100644 index 00000000000..4867dd8d0b4 --- /dev/null +++ b/src/test/compile-fail/cfg-attr-crate-2.rs @@ -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 or the MIT license +// , 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() { } diff --git a/src/test/compile-fail/functional-struct-update-respects-privacy.rs b/src/test/compile-fail/functional-struct-update-respects-privacy.rs new file mode 100644 index 00000000000..51e23a689a1 --- /dev/null +++ b/src/test/compile-fail/functional-struct-update-respects-privacy.rs @@ -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 or the MIT license +// , 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 = 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! +} diff --git a/src/test/compile-fail/issue-17551.rs b/src/test/compile-fail/issue-17551.rs index b19a7703b85..e037ba92b4a 100644 --- a/src/test/compile-fail/issue-17551.rs +++ b/src/test/compile-fail/issue-17551.rs @@ -13,6 +13,6 @@ struct B; 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; } diff --git a/src/test/compile-fail/issue-17999.rs b/src/test/compile-fail/issue-17999.rs index f4c0a9c38c3..88945f80eae 100644 --- a/src/test/compile-fail/issue-17999.rs +++ b/src/test/compile-fail/issue-17999.rs @@ -9,7 +9,6 @@ // except according to those terms. #![deny(unused_variables)] -#![feature(core)] fn main() { for _ in 1..101 { diff --git a/src/test/compile-fail/issue-20801.rs b/src/test/compile-fail/issue-20801.rs new file mode 100644 index 00000000000..929c8ec0fd6 --- /dev/null +++ b/src/test/compile-fail/issue-20801.rs @@ -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 or the MIT license +// , 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 +} diff --git a/src/test/compile-fail/issue-2150.rs b/src/test/compile-fail/issue-2150.rs index a2711d532d2..79df16c8979 100644 --- a/src/test/compile-fail/issue-2150.rs +++ b/src/test/compile-fail/issue-2150.rs @@ -11,7 +11,6 @@ #![deny(unreachable_code)] #![allow(unused_variables)] #![allow(dead_code)] -#![feature(core)] fn fail_len(v: Vec ) -> usize { let mut i = 3; diff --git a/src/test/compile-fail/liveness-unused.rs b/src/test/compile-fail/liveness-unused.rs index d4238120d06..ac4b8a5f309 100644 --- a/src/test/compile-fail/liveness-unused.rs +++ b/src/test/compile-fail/liveness-unused.rs @@ -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` diff --git a/src/test/parse-fail/reserved-be.rs b/src/test/compile-fail/reserved-become.rs similarity index 75% rename from src/test/parse-fail/reserved-be.rs rename to src/test/compile-fail/reserved-become.rs index 386d53cc16e..82e9ebc10d1 100644 --- a/src/test/parse-fail/reserved-be.rs +++ b/src/test/compile-fail/reserved-become.rs @@ -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 } diff --git a/src/test/run-make/c-link-to-rust-staticlib/Makefile b/src/test/run-make/c-link-to-rust-staticlib/Makefile index 8a6d6e4dd6d..477b85f362a 100644 --- a/src/test/run-make/c-link-to-rust-staticlib/Makefile +++ b/src/test/run-make/c-link-to-rust-staticlib/Makefile @@ -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 diff --git a/src/test/run-make/duplicate-output-flavors/Makefile b/src/test/run-make/duplicate-output-flavors/Makefile index d40b6862a01..e33279966c9 100644 --- a/src/test/run-make/duplicate-output-flavors/Makefile +++ b/src/test/run-make/duplicate-output-flavors/Makefile @@ -2,3 +2,4 @@ include ../tools.mk all: $(RUSTC) --crate-type=rlib foo.rs + $(RUSTC) --crate-type=rlib,rlib foo.rs diff --git a/src/test/run-make/empty-file/Makefile b/src/test/run-make/empty-file/Makefile new file mode 100644 index 00000000000..f55a2cc3bb1 --- /dev/null +++ b/src/test/run-make/empty-file/Makefile @@ -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 diff --git a/src/test/run-make/empty-file/empty.rs b/src/test/run-make/empty-file/empty.rs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/test/run-make/issue-22131/Makefile b/src/test/run-make/issue-22131/Makefile new file mode 100644 index 00000000000..0f927320c4e --- /dev/null +++ b/src/test/run-make/issue-22131/Makefile @@ -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' diff --git a/src/test/run-make/issue-22131/foo.rs b/src/test/run-make/issue-22131/foo.rs new file mode 100644 index 00000000000..0b1f1291df0 --- /dev/null +++ b/src/test/run-make/issue-22131/foo.rs @@ -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 or the MIT license +// , 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 } diff --git a/src/test/run-make/no-stack-check/Makefile b/src/test/run-make/no-stack-check/Makefile index 561056d719e..5fce35e2beb 100644 --- a/src/test/run-make/no-stack-check/Makefile +++ b/src/test/run-make/no-stack-check/Makefile @@ -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: diff --git a/src/test/run-make/symbols-are-reasonable/Makefile b/src/test/run-make/symbols-are-reasonable/Makefile index 42a72f7ca39..89f610dee17 100644 --- a/src/test/run-make/symbols-are-reasonable/Makefile +++ b/src/test/run-make/symbols-are-reasonable/Makefile @@ -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) diff --git a/src/test/run-make/target-specs/Makefile b/src/test/run-make/target-specs/Makefile index a352bc3a8cc..db2b253a6f1 100644 --- a/src/test/run-make/target-specs/Makefile +++ b/src/test/run-make/target-specs/Makefile @@ -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 diff --git a/src/test/run-make/use-extern-for-plugins/Makefile b/src/test/run-make/use-extern-for-plugins/Makefile index 84032b45159..bdce7b7810a 100644 --- a/src/test/run-make/use-extern-for-plugins/Makefile +++ b/src/test/run-make/use-extern-for-plugins/Makefile @@ -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 diff --git a/src/test/run-pass/cfg-attr-cfg.rs b/src/test/run-pass/cfg-attr-cfg.rs new file mode 100644 index 00000000000..09ab7019486 --- /dev/null +++ b/src/test/run-pass/cfg-attr-cfg.rs @@ -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 or the MIT license +// , 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() { } diff --git a/src/test/run-pass/cfg-attr-crate.rs b/src/test/run-pass/cfg-attr-crate.rs new file mode 100644 index 00000000000..e6bd8afad28 --- /dev/null +++ b/src/test/run-pass/cfg-attr-crate.rs @@ -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 or the MIT license +// , 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() { } diff --git a/src/test/run-pass/infer-container-across-object-cast.rs b/src/test/run-pass/infer-container-across-object-cast.rs new file mode 100644 index 00000000000..979e76b1ff9 --- /dev/null +++ b/src/test/run-pass/infer-container-across-object-cast.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Given ` as Box`, 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 { 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; + 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(); +} diff --git a/src/test/run-pass/unboxed-closures-infer-upvar.rs b/src/test/run-pass/unboxed-closures-infer-upvar.rs new file mode 100644 index 00000000000..087ef5dcf05 --- /dev/null +++ b/src/test/run-pass/unboxed-closures-infer-upvar.rs @@ -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 or the MIT license +// , 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(mut f: F) { + f(); +} + +fn main() { + let mut v: Vec<_> = vec![]; + f(|| v.push(0)); + assert_eq!(v, vec![0]); +}