diff --git a/mk/docs.mk b/mk/docs.mk index 2a5a847d2a425..4c2c1243c65a4 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -27,7 +27,7 @@ ###################################################################### DOCS := index intro tutorial complement-bugreport \ complement-lang-faq complement-design-faq complement-project-faq \ - rustdoc reference + rustdoc reference grammar # Legacy guides, preserved for a while to reduce the number of 404s DOCS += guide-crates guide-error-handling guide-ffi guide-macros guide \ diff --git a/mk/main.mk b/mk/main.mk index a6b201a2b7bdf..ef3abebb88f47 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -61,13 +61,16 @@ SPACE := SPACE += ifneq ($(CFG_GIT),) ifneq ($(wildcard $(subst $(SPACE),\$(SPACE),$(CFG_GIT_DIR))),) - CFG_VER_DATE = $(shell git --git-dir='$(CFG_GIT_DIR)' log -1 --pretty=format:'%ci') + CFG_VER_DATE = $(shell git --git-dir='$(CFG_GIT_DIR)' log -1 --date=short --pretty=format:'%cd') CFG_VER_HASH = $(shell git --git-dir='$(CFG_GIT_DIR)' rev-parse HEAD) CFG_SHORT_VER_HASH = $(shell git --git-dir='$(CFG_GIT_DIR)' rev-parse --short=9 HEAD) CFG_VERSION += ($(CFG_SHORT_VER_HASH) $(CFG_VER_DATE)) endif endif +CFG_BUILD_DATE = $(shell date +%F) +CFG_VERSION += (built $(CFG_BUILD_DATE)) + # Windows exe's need numeric versions - don't use anything but # numbers and dots here CFG_VERSION_WIN = $(CFG_RELEASE_NUM) @@ -317,6 +320,7 @@ endif ifdef CFG_VER_HASH export CFG_VER_HASH endif +export CFG_BUILD_DATE export CFG_VERSION export CFG_VERSION_WIN export CFG_RELEASE diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 385f1b9e79154..6b6251a96c944 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -16,7 +16,7 @@ #![feature(io)] #![feature(path)] #![feature(rustc_private)] -#![feature(slicing_syntax, unboxed_closures)] +#![feature(unboxed_closures)] #![feature(std_misc)] #![feature(test)] #![feature(unicode)] diff --git a/src/doc/complement-bugreport.md b/src/doc/complement-bugreport.md index 848c56ee543dd..1a28cd682e70c 100644 --- a/src/doc/complement-bugreport.md +++ b/src/doc/complement-bugreport.md @@ -56,8 +56,6 @@ $ RUST_BACKTRACE=1 rustc ... # I submitted a bug, but nobody has commented on it! -This is sad, but does happen sometimes, since we're short-staffed. If you -submit a bug and you haven't received a comment on it within 3 business days, -it's entirely reasonable to either ask on the #rust IRC channel, -or post on the [rust-dev mailing list](https://mail.mozilla.org/listinfo/rust-dev) -to ask what the status of the bug is. +This is sad, but does happen sometimes, since we're short-staffed. If you submit a +bug and you haven't received a comment on it within 3 business days, it's entirely +reasonable to ask about the status of the bug in #rust on irc.mozilla.org. diff --git a/src/doc/grammar.md b/src/doc/grammar.md index b4e023c203911..9124328b8eee9 100644 --- a/src/doc/grammar.md +++ b/src/doc/grammar.md @@ -1,6 +1,4 @@ -# **This is a work in progress** - -% The Rust Grammar +% Grammar # Introduction diff --git a/src/doc/intro.md b/src/doc/intro.md index 1e343b593df2d..7433c54998520 100644 --- a/src/doc/intro.md +++ b/src/doc/intro.md @@ -224,7 +224,7 @@ segfault when we allocate more memory? The answer is that in the C++ version, `x` is a *reference* to the memory location where the first element of the array is stored. But in Ruby, `x` is a -standalone value, not connected to the underyling array at all. Let's dig into +standalone value, not connected to the underlying array at all. Let's dig into the details for a moment. Your program has access to memory, provided to it by the operating system. Each location in memory has an address. So when we make our vector, `v`, it's stored in a memory location somewhere: @@ -427,7 +427,7 @@ fn main() { let mut numbers = vec![1, 2, 3]; for i in 0..3 { - Thread::spawn(move || { + Thread::scoped(move || { for j in 0..3 { numbers[j] += 1 } }); } @@ -441,7 +441,7 @@ It gives us this error: for j in 0..3 { numbers[j] += 1 } ^~~~~~~ 7:50 note: `numbers` moved into closure environment here - spawn(move || { + scoped(move || { for j in 0..3 { numbers[j] += 1 } }); 6:79 error: cannot assign to immutable dereference (dereference is implicit, due to indexing) @@ -482,7 +482,7 @@ fn main() { for i in 0us..3 { let number = numbers.clone(); - Thread::spawn(move || { + Thread::scoped(move || { let mut array = number.lock().unwrap(); array[i] += 1; println!("numbers[{}] is {}", i, array[i]); @@ -542,7 +542,7 @@ fn main() { let vec = vec![1, 2, 3]; for i in 0us..3 { - Thread::spawn(move || { + Thread::scoped(move || { println!("{}", vec[i]); }); } diff --git a/src/doc/reference.md b/src/doc/reference.md index 73880549ae649..3223e2f262653 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -5,9 +5,7 @@ This document is the primary reference for the Rust programming language. It provides three kinds of material: - - Chapters that formally define the language grammar and, for each - construct, informally describe its semantics and give examples of its - use. + - Chapters that informally describe each language construct and their use. - Chapters that informally describe the memory model, concurrency model, runtime services, linkage model and debugging facilities. - Appendix chapters providing rationale and references to languages that @@ -23,8 +21,11 @@ separately by extracting documentation attributes from their source code. Many of the features that one might expect to be language features are library features in Rust, so what you're looking for may be there, not here. +You may also be interested in the [grammar]. + [book]: book/index.html [standard]: std/index.html +[grammar]: grammar.html # Notation @@ -2377,21 +2378,33 @@ considered off, and using the features will result in a compiler error. The currently implemented features of the reference compiler are: +* `advanced_slice_patterns` - see the [match expressions](#match-expressions) + section for discussion; the exact semantics of + slice patterns are subject to change. + * `asm` - The `asm!` macro provides a means for inline assembly. This is often useful, but the exact syntax for this feature along with its semantics are likely to change, so this macro usage must be opted into. +* `associated_types` - Allows type aliases in traits. Experimental. + +* `box_patterns` - Allows `box` patterns, the exact semantics of which + is subject to change. + +* `box_syntax` - Allows use of `box` expressions, the exact semantics of which + is subject to change. + * `concat_idents` - Allows use of the `concat_idents` macro, which is in many ways insufficient for concatenating identifiers, and may be removed entirely for something more wholesome. -* `default_type_params` - Allows use of default type parameters. The future of - this feature is uncertain. - * `intrinsics` - Allows use of the "rust-intrinsics" ABI. Compiler intrinsics are inherently unstable and no promise about them is made. +* `int_uint` - Allows the use of the `int` and `uint` types, which are deprecated. + Use `isize` and `usize` instead. + * `lang_items` - Allows use of the `#[lang]` attribute. Like `intrinsics`, lang items are inherently unstable and no promise about them is made. @@ -2410,12 +2423,33 @@ The currently implemented features of the reference compiler are: * `log_syntax` - Allows use of the `log_syntax` macro attribute, which is a nasty hack that will certainly be removed. +* `main` - Allows use of the `#[main]` attribute, which changes the entry point + into a Rust program. This capabiilty is subject to change. + +* `macro_reexport` - Allows macros to be re-exported from one crate after being imported + from another. This feature was originally designed with the sole + use case of the Rust standard library in mind, and is subject to + change. + * `non_ascii_idents` - The compiler supports the use of non-ascii identifiers, but the implementation is a little rough around the edges, so this can be seen as an experimental feature for now until the specification of identifiers is fully fleshed out. +* `no_std` - Allows the `#![no_std]` crate attribute, which disables the implicit + `extern crate std`. This typically requires use of the unstable APIs + behind the libstd "facade", such as libcore and libcollections. It + may also cause problems when using syntax extensions, including + `#[derive]`. + +* `on_unimplemented` - Allows the `#[rustc_on_unimplemented]` attribute, which allows + trait definitions to add specialized notes to error messages + when an implementation was expected but not found. + +* `optin_builtin_traits` - Allows the definition of default and negative trait + implementations. Experimental. + * `plugin` - Usage of [compiler plugins][plugin] for custom lints or syntax extensions. These depend on compiler internals and are subject to change. @@ -2431,8 +2465,15 @@ The currently implemented features of the reference compiler are: * `simd` - Allows use of the `#[simd]` attribute, which is overly simple and not the SIMD interface we want to expose in the long term. +* `simd_ffi` - Allows use of SIMD vectors in signatures for foreign functions. + The SIMD interface is subject to change. + * `staged_api` - Allows usage of stability markers and `#![staged_api]` in a crate +* `start` - Allows use of the `#[start]` attribute, which changes the entry point + into a Rust program. This capabiilty, especially the signature for the + annotated function, is subject to change. + * `struct_inherit` - Allows using struct inheritance, which is barely implemented and will probably be removed. Don't use this. @@ -2460,18 +2501,20 @@ The currently implemented features of the reference compiler are: which is considered wildly unsafe and will be obsoleted by language improvements. +* `unsafe_no_drop_flag` - Allows use of the `#[unsafe_no_drop_flag]` attribute, + which removes hidden flag added to a type that + implements the `Drop` trait. The design for the + `Drop` flag is subject to change, and this feature + may be removed in the future. + * `unmarked_api` - Allows use of items within a `#![staged_api]` crate which have not been marked with a stability marker. Such items should not be allowed by the compiler to exist, so if you need this there probably is a compiler bug. -* `associated_types` - Allows type aliases in traits. Experimental. - -* `no_std` - Allows the `#![no_std]` crate attribute, which disables the implicit - `extern crate std`. This typically requires use of the unstable APIs - behind the libstd "facade", such as libcore and libcollections. It - may also cause problems when using syntax extensions, including - `#[derive]`. +* `visible_private_types` - Allows public APIs to expose otherwise private + types, e.g. as the return type of a public function. + This capability may be removed in the future. If a feature is promoted to a language feature, then all existing programs will start to receive compilation warnings about #[feature] directives which enabled @@ -2591,9 +2634,8 @@ of any reference that points to it. When a [local variable](#memory-slots) is used as an [rvalue](#lvalues,-rvalues-and-temporaries) the variable will either be moved -or copied, depending on its type. For types that contain [owning -pointers](#pointer-types) or values that implement the special trait `Drop`, -the variable is moved. All other types are copied. +or copied, depending on its type. All values whose type implements `Copy` are +copied, all others are moved. ### Literal expressions @@ -2701,9 +2743,19 @@ items can bring new names into scopes and declared items are in scope for only the block itself. A block will execute each statement sequentially, and then execute the -expression (if given). If the final expression is omitted, the type and return -value of the block are `()`, but if it is provided, the type and return value -of the block are that of the expression itself. +expression (if given). If the block ends in a statement, its value is `()`: + +``` +let x: () = { println!("Hello."); }; +``` + +If it ends in an expression, its value and type are that of the expression: + +``` +let x: i32 = { println!("Hello."); 5 }; + +assert_eq!(5, x); +``` ### Method-call expressions @@ -3502,9 +3554,6 @@ elements, respectively, in a parenthesized, comma-separated list. Because tuple elements don't have a name, they can only be accessed by pattern-matching. -The members of a tuple are laid out in memory contiguously, in order specified -by the tuple type. - An example of a tuple type and its use: ``` diff --git a/src/doc/trpl/arrays-vectors-and-slices.md b/src/doc/trpl/arrays-vectors-and-slices.md index 2df769b3c2c67..d4e2ad5cd5f66 100644 --- a/src/doc/trpl/arrays-vectors-and-slices.md +++ b/src/doc/trpl/arrays-vectors-and-slices.md @@ -49,8 +49,8 @@ languages. A *vector* is a dynamic or "growable" array, implemented as the standard library type [`Vec`](../std/vec/) (we'll talk about what the `` means -later). Vectors are to arrays what `String` is to `&str`. You can create them -with the `vec!` macro: +later). Vectors always allocate their data on the heap. Vectors are to slices +what `String` is to `&str`. You can create them with the `vec!` macro: ```{rust} let v = vec![1, 2, 3]; // v: Vec diff --git a/src/doc/trpl/compound-data-types.md b/src/doc/trpl/compound-data-types.md index 51a4edbdac802..dea19fa73fb49 100644 --- a/src/doc/trpl/compound-data-types.md +++ b/src/doc/trpl/compound-data-types.md @@ -263,15 +263,12 @@ let four_is_smaller = four <= ten; let four_equals_ten = four == ten; ``` -This may seem rather limiting, particularly equality being invalid; in -many cases however, it's unnecessary. Rust provides the [`match`][match] -keyword, which will be examined in more detail in the next section, which -often allows better and easier branch control than a series of `if`/`else` -statements would. However, for our [game][game] we need the comparisons -to work so we will utilize the `Ordering` `enum` provided by the standard -library which supports such comparisons. It has this form: +This may seem rather limiting, but it's a limitation which we can overcome. +There are two ways: by implementing equality ourselves, or by using the +[`match`][match] keyword. We don't know enough about Rust to implement equality +yet, but we can use the `Ordering` enum from the standard library, which does: -```{rust} +``` enum Ordering { Less, Equal, diff --git a/src/doc/trpl/concurrency.md b/src/doc/trpl/concurrency.md index 800b5a2ad9768..3c933c1c5af58 100644 --- a/src/doc/trpl/concurrency.md +++ b/src/doc/trpl/concurrency.md @@ -171,7 +171,7 @@ use std::time::Duration; fn main() { let mut data = vec![1u32, 2, 3]; - for i in 0 .. 2 { + for i in 0..2 { Thread::spawn(move || { data[i] += 1; }); @@ -211,7 +211,7 @@ use std::sync::Mutex; fn main() { let mut data = Mutex::new(vec![1u32, 2, 3]); - for i in 0 .. 2 { + for i in 0..2 { let data = data.lock().unwrap(); Thread::spawn(move || { data[i] += 1; @@ -262,7 +262,7 @@ use std::time::Duration; fn main() { let data = Arc::new(Mutex::new(vec![1u32, 2, 3])); - for i in (0us..2) { + for i in 0us..2 { let data = data.clone(); Thread::spawn(move || { let mut data = data.lock().unwrap(); @@ -285,7 +285,7 @@ thread more closely: # use std::time::Duration; # fn main() { # let data = Arc::new(Mutex::new(vec![1u32, 2, 3])); -# for i in (0us..2) { +# for i in 0us..2 { # let data = data.clone(); Thread::spawn(move || { let mut data = data.lock().unwrap(); @@ -323,7 +323,7 @@ fn main() { let (tx, rx) = mpsc::channel(); - for _ in (0..10) { + for _ in 0..10 { let (data, tx) = (data.clone(), tx.clone()); Thread::spawn(move || { @@ -334,7 +334,7 @@ fn main() { }); } - for _ in 0 .. 10 { + for _ in 0..10 { rx.recv(); } } diff --git a/src/doc/trpl/documentation.md b/src/doc/trpl/documentation.md index 0b686eb76dbfb..2651949747952 100644 --- a/src/doc/trpl/documentation.md +++ b/src/doc/trpl/documentation.md @@ -1,4 +1,4 @@ -% Rust Documentation +% Documentation `rustdoc` is the built-in tool for generating documentation. It integrates with the compiler to provide accurate hyperlinking between usage of types and @@ -294,3 +294,26 @@ Documentation` on the first line). Like with a Rust crate, the `--test` argument will run the code examples to check they compile, and obeys any `--test-args` flags. The tests are named after the last `#` heading. + +# Re-exports + +Rustdoc will show the documentation for a publc re-export in both places: + +```{rust,ignore} +extern crate foo; + +pub use foo::bar; +``` + +This will create documentation for `bar` both inside the documentation for +the crate `foo`, as well as the documentation for your crate. It will use +the same documentation in both places. + +This behavior can be supressed with `no_inline`: + +```{rust,ignore} +extern crate foo; + +#[doc(no_inline)] +pub use foo::bar; +``` diff --git a/src/doc/trpl/ffi.md b/src/doc/trpl/ffi.md index 640f9cc388ef0..5375a8aa46b30 100644 --- a/src/doc/trpl/ffi.md +++ b/src/doc/trpl/ffi.md @@ -420,7 +420,7 @@ fn main() { ``` Alternatively, you may need to alter global state provided by a foreign -interface. To do this, statics can be declared with `mut` so rust can mutate +interface. To do this, statics can be declared with `mut` so we can mutate them. ```no_run @@ -436,12 +436,19 @@ extern { fn main() { let prompt = CString::from_slice(b"[my-awesome-shell] $"); - unsafe { rl_prompt = prompt.as_ptr(); } - // get a line, process it - unsafe { rl_prompt = ptr::null(); } + unsafe { + rl_prompt = prompt.as_ptr(); + + println!("{}", rl_prompt); + + rl_prompt = ptr::null(); + } } ``` +Note that all interaction with a `static mut` is unsafe, both reading and +writing. Dealing with global mutable state requires a great deal of care. + # Foreign calling conventions Most foreign code exposes a C ABI, and Rust uses the platform's C calling convention by default when diff --git a/src/doc/trpl/functions.md b/src/doc/trpl/functions.md index d0ecb6067955d..ca1385fde9c74 100644 --- a/src/doc/trpl/functions.md +++ b/src/doc/trpl/functions.md @@ -2,7 +2,7 @@ You've already seen one function so far, the `main` function: -```{rust} +```rust fn main() { } ``` @@ -12,14 +12,14 @@ This is the simplest possible function declaration. As we mentioned before, this function takes no arguments, and then some curly braces to indicate the body. Here's a function named `foo`: -```{rust} +```rust fn foo() { } ``` So, what about taking arguments? Here's a function that prints a number: -```{rust} +```rust fn print_number(x: i32) { println!("x is: {}", x); } @@ -27,7 +27,7 @@ fn print_number(x: i32) { Here's a complete program that uses `print_number`: -```{rust} +```rust fn main() { print_number(5); } @@ -42,7 +42,7 @@ you add a type to the argument name, after a colon. Here's a complete program that adds two numbers together and prints them: -```{rust} +```rust fn main() { print_sum(5, 6); } @@ -58,9 +58,9 @@ as when you declare it. Unlike `let`, you _must_ declare the types of function arguments. This does not work: -```{ignore} +```{rust,ignore} fn print_sum(x, y) { - println!("x is: {}", x + y); + println!("sum is: {}", x + y); } ``` @@ -79,7 +79,7 @@ sweet spot between full inference and no inference. What about returning a value? Here's a function that adds one to an integer: -```{rust} +```rust fn add_one(x: i32) -> i32 { x + 1 } @@ -90,7 +90,7 @@ Rust functions return exactly one value, and you declare the type after an You'll note the lack of a semicolon here. If we added it in: -```{ignore} +```{rust,ignore} fn add_one(x: i32) -> i32 { x + 1; } @@ -123,7 +123,7 @@ semicolon in a return position would cause a bug. But what about early returns? Rust does have a keyword for that, `return`: -```{rust} +```rust fn foo(x: i32) -> i32 { if x < 5 { return x; } @@ -134,7 +134,7 @@ fn foo(x: i32) -> i32 { Using a `return` as the last line of a function works, but is considered poor style: -```{rust} +```rust fn foo(x: i32) -> i32 { if x < 5 { return x; } @@ -160,5 +160,34 @@ fn foo(x: i32) -> i32 { Because `if` is an expression, and it's the only expression in this function, the value will be the result of the `if`. -There are some additional ways to define functions, but they involve features -that we haven't learned about yet, so let's just leave it at that for now. +## Diverging functions + +Rust has some special syntax for 'diverging functions', which are functions that +do not return: + +``` +fn diverges() -> ! { + panic!("This function never returns!"); +} +``` + +`panic!` is a macro, similar to `println!()` that we've already seen. Unlike +`println!()`, `panic!()` causes the current thread of execution to crash with +the given message. + +Because this function will cause a crash, it will never return, and so it has +the type '`!`', which is read "diverges." A diverging function can be used +as any type: + +```should_fail +# fn diverges() -> ! { +# panic!("This function never returns!"); +# } + +let x: i32 = diverges(); +let x: String = diverges(); +``` + +We don't have a good use for diverging functions yet, because they're used in +conjunction with other Rust features. But when you see `-> !` later, you'll +know what it's called. diff --git a/src/doc/trpl/more-strings.md b/src/doc/trpl/more-strings.md index 986ad23c665a7..b27638435089d 100644 --- a/src/doc/trpl/more-strings.md +++ b/src/doc/trpl/more-strings.md @@ -91,7 +91,7 @@ and only moving to this: fn foo(s: String) { ``` -If you have good reason. It's not polite to hold on to ownership you don't +if you have good reason. It's not polite to hold on to ownership you don't need, and it can make your lifetimes more complex. ## Generic functions diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index 6d15a264172a1..2488973565b9d 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -2282,7 +2282,7 @@ mod tests { #[test] fn test_from_bools() { let bools = vec![true, false, true, true]; - let bitv: Bitv = bools.iter().map(|n| *n).collect(); + let bitv: Bitv = bools.iter().cloned().collect(); assert_eq!(format!("{:?}", bitv), "1011"); } @@ -2295,12 +2295,12 @@ mod tests { #[test] fn test_bitv_iterator() { let bools = vec![true, false, true, true]; - let bitv: Bitv = bools.iter().map(|n| *n).collect(); + let bitv: Bitv = bools.iter().cloned().collect(); assert_eq!(bitv.iter().collect::>(), bools); let long: Vec<_> = (0i32..10000).map(|i| i % 2 == 0).collect(); - let bitv: Bitv = long.iter().map(|n| *n).collect(); + let bitv: Bitv = long.iter().cloned().collect(); assert_eq!(bitv.iter().collect::>(), long) } diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index a080146e0ec50..9159e92a21640 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -895,7 +895,7 @@ impl Ord for DList { #[stable(feature = "rust1", since = "1.0.0")] impl Clone for DList { fn clone(&self) -> DList { - self.iter().map(|x| x.clone()).collect() + self.iter().cloned().collect() } } @@ -1013,7 +1013,7 @@ mod tests { #[cfg(test)] fn list_from(v: &[T]) -> DList { - v.iter().map(|x| (*x).clone()).collect() + v.iter().cloned().collect() } #[test] diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 460c897b6ad36..8325e7247d5fc 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -27,7 +27,6 @@ #![feature(box_patterns)] #![feature(core)] #![feature(hash)] -#![feature(slicing_syntax)] #![feature(staged_api)] #![feature(unboxed_closures)] #![feature(unicode)] diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index b3f398b9cdf49..924589eb44ca9 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -52,7 +52,6 @@ //! interval `[a, b)`: //! //! ```rust -//! #![feature(slicing_syntax)] //! fn main() { //! let numbers = [0, 1, 2]; //! let last_numbers = &numbers[1..3]; diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index edb6d2de1c850..f78a4b7fefd0b 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -1285,7 +1285,8 @@ pub trait StrExt: Index { /// let v: Vec<&str> = some_words.words().collect(); /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]); /// ``` - #[stable(feature = "rust1", since = "1.0.0")] + #[unstable(feature = "str_words", + reason = "the precise algorithm to use is unclear")] fn words(&self) -> Words { UnicodeStr::words(&self[]) } diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs index 0f3823eb7a5b0..32e8cffcae4f9 100644 --- a/src/libcore/atomic.rs +++ b/src/libcore/atomic.rs @@ -21,9 +21,9 @@ //! //! Each method takes an `Ordering` which represents the strength of //! the memory barrier for that operation. These orderings are the -//! same as [C++11 atomic orderings][1]. +//! same as [LLVM atomic orderings][1]. //! -//! [1]: http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync +//! [1]: http://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations //! //! Atomic variables are safe to share between threads (they implement `Sync`) //! but they do not themselves provide the mechanism for sharing. The most diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 050b34508ff87..cf293ded13f00 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -649,7 +649,8 @@ impl<'b, T> DerefMut for RefMut<'b, T> { /// /// **NOTE:** `UnsafeCell`'s fields are public to allow static initializers. It is not /// recommended to access its fields directly, `get` should be used instead. -#[lang="unsafe"] +#[cfg_attr(stage0, lang="unsafe")] // NOTE: remove after next snapshot +#[cfg_attr(not(stage0), lang="unsafe_cell")] #[stable(feature = "rust1", since = "1.0.0")] pub struct UnsafeCell { /// Wrapped value diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 7740cd6867cbd..e2516bf5d36d7 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -325,7 +325,7 @@ pub trait IteratorExt: Iterator + Sized { /// /// ``` /// let xs = [100, 200, 300]; - /// let mut it = xs.iter().map(|x| *x).peekable(); + /// let mut it = xs.iter().cloned().peekable(); /// assert_eq!(*it.peek().unwrap(), 100); /// assert_eq!(it.next().unwrap(), 100); /// assert_eq!(it.next().unwrap(), 200); @@ -2676,9 +2676,9 @@ impl Iterator for ::ops::Range { } } +// Ranges of u64 and i64 are excluded because they cannot guarantee having +// a length <= usize::MAX, which is required by ExactSizeIterator. range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32); -#[cfg(target_pointer_width = "64")] -range_exact_iter_impl!(u64 i64); #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for ::ops::Range { diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index a122bcb2c7aed..7243bd4f0cb25 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -64,7 +64,7 @@ #![feature(int_uint)] #![feature(intrinsics, lang_items)] #![feature(on_unimplemented)] -#![feature(simd, unsafe_destructor, slicing_syntax)] +#![feature(simd, unsafe_destructor)] #![feature(staged_api)] #![feature(unboxed_closures)] diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 83d070feb8a69..b542c9d47f7d4 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -35,14 +35,27 @@ pub const EPSILON: f32 = 1.19209290e-07_f32; /// Smallest finite f32 value #[stable(feature = "rust1", since = "1.0.0")] +#[deprecated(since = "1.0.0", reason = "use `std::f32::MIN`")] pub const MIN_VALUE: f32 = -3.40282347e+38_f32; /// Smallest positive, normalized f32 value #[stable(feature = "rust1", since = "1.0.0")] +#[deprecated(since = "1.0.0", reason = "use `std::f32::MIN_POSITIVE`")] pub const MIN_POS_VALUE: f32 = 1.17549435e-38_f32; /// Largest finite f32 value #[stable(feature = "rust1", since = "1.0.0")] +#[deprecated(since = "1.0.0", reason = "use `std::f32::MAX`")] pub const MAX_VALUE: f32 = 3.40282347e+38_f32; +/// Smallest finite f32 value +#[stable(feature = "rust1", since = "1.0.0")] +pub const MIN: f32 = -3.40282347e+38_f32; +/// Smallest positive, normalized f32 value +#[stable(feature = "rust1", since = "1.0.0")] +pub const MIN_POSITIVE: f32 = 1.17549435e-38_f32; +/// Largest finite f32 value +#[stable(feature = "rust1", since = "1.0.0")] +pub const MAX: f32 = 3.40282347e+38_f32; + #[unstable(feature = "core", reason = "pending integer conventions")] pub const MIN_EXP: int = -125; #[unstable(feature = "core", reason = "pending integer conventions")] @@ -215,17 +228,17 @@ impl Float for f32 { #[inline] #[unstable(feature = "core")] #[deprecated(since = "1.0.0")] - fn min_value() -> f32 { MIN_VALUE } + fn min_value() -> f32 { MIN } #[inline] #[unstable(feature = "core")] #[deprecated(since = "1.0.0")] - fn min_pos_value(_: Option) -> f32 { MIN_POS_VALUE } + fn min_pos_value(_: Option) -> f32 { MIN_POSITIVE } #[inline] #[unstable(feature = "core")] #[deprecated(since = "1.0.0")] - fn max_value() -> f32 { MAX_VALUE } + fn max_value() -> f32 { MAX } /// Returns the mantissa, exponent and sign as integers. fn integer_decode(self) -> (u64, i16, i8) { diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index ce011b3c2eeb6..2aae7107548c6 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -38,14 +38,27 @@ pub const EPSILON: f64 = 2.2204460492503131e-16_f64; /// Smallest finite f64 value #[stable(feature = "rust1", since = "1.0.0")] +#[deprecated(since = "1.0.0", reason = "use `std::f64::MIN`")] pub const MIN_VALUE: f64 = -1.7976931348623157e+308_f64; /// Smallest positive, normalized f64 value #[stable(feature = "rust1", since = "1.0.0")] +#[deprecated(since = "1.0.0", reason = "use `std::f64::MIN_POSITIVE`")] pub const MIN_POS_VALUE: f64 = 2.2250738585072014e-308_f64; /// Largest finite f64 value #[stable(feature = "rust1", since = "1.0.0")] +#[deprecated(since = "1.0.0", reason = "use `std::f64::MAX`")] pub const MAX_VALUE: f64 = 1.7976931348623157e+308_f64; +/// Smallest finite f64 value +#[stable(feature = "rust1", since = "1.0.0")] +pub const MIN: f64 = -1.7976931348623157e+308_f64; +/// Smallest positive, normalized f64 value +#[stable(feature = "rust1", since = "1.0.0")] +pub const MIN_POSITIVE: f64 = 2.2250738585072014e-308_f64; +/// Largest finite f64 value +#[stable(feature = "rust1", since = "1.0.0")] +pub const MAX: f64 = 1.7976931348623157e+308_f64; + #[unstable(feature = "core", reason = "pending integer conventions")] pub const MIN_EXP: int = -1021; #[unstable(feature = "core", reason = "pending integer conventions")] @@ -222,17 +235,17 @@ impl Float for f64 { #[inline] #[unstable(feature = "core")] #[deprecated(since = "1.0.0")] - fn min_value() -> f64 { MIN_VALUE } + fn min_value() -> f64 { MIN } #[inline] #[unstable(feature = "core")] #[deprecated(since = "1.0.0")] - fn min_pos_value(_: Option) -> f64 { MIN_POS_VALUE } + fn min_pos_value(_: Option) -> f64 { MIN_POSITIVE } #[inline] #[unstable(feature = "core")] #[deprecated(since = "1.0.0")] - fn max_value() -> f64 { MAX_VALUE } + fn max_value() -> f64 { MAX } /// Returns the mantissa, exponent and sign as integers. fn integer_decode(self) -> (u64, i16, i8) { diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index b7c5c6640ced0..8aef16c2874ee 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -956,7 +956,7 @@ macro_rules! impl_to_primitive_float_to_float { Some($slf as $DstT) } else { let n = $slf as f64; - let max_value: $SrcT = ::$SrcT::MAX_VALUE; + let max_value: $SrcT = ::$SrcT::MAX; if -max_value as f64 <= n && n <= max_value as f64 { Some($slf as $DstT) } else { @@ -1331,18 +1331,18 @@ pub trait Float /// Returns the smallest finite value that this type can represent. #[unstable(feature = "core")] #[deprecated(since = "1.0.0", - reason = "use `std::f32::MIN_VALUE` or `std::f64::MIN_VALUE` as appropriate")] + reason = "use `std::f32::MIN` or `std::f64::MIN` as appropriate")] fn min_value() -> Self; /// Returns the smallest normalized positive number that this type can represent. #[unstable(feature = "core")] #[deprecated(since = "1.0.0", - reason = "use `std::f32::MIN_POS_VALUE` or \ - `std::f64::MIN_POS_VALUE` as appropriate")] + reason = "use `std::f32::MIN_POSITIVE` or \ + `std::f64::MIN_POSITIVE` as appropriate")] fn min_pos_value(unused_self: Option) -> Self; /// Returns the largest finite value that this type can represent. #[unstable(feature = "core")] #[deprecated(since = "1.0.0", - reason = "use `std::f32::MAX_VALUE` or `std::f64::MAX_VALUE` as appropriate")] + reason = "use `std::f32::MAX` or `std::f64::MAX` as appropriate")] fn max_value() -> Self; /// Returns true if this value is NaN and false otherwise. diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 2f261b0628faf..081c895c3175c 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -162,7 +162,7 @@ use slice; // `Iterator` is an enumeration with one type parameter and two variants, // which basically means it must be `Option`. -/// The `Option` type. +/// The `Option` type. See [the module level documentation](../index.html) for more. #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] #[stable(feature = "rust1", since = "1.0.0")] pub enum Option { diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index 3fd244b46e30f..bb0c22d3561d2 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -21,7 +21,40 @@ use marker::Copy; use mem; -/// The representation of a Rust slice +/// The representation of a slice like `&[T]`. +/// +/// This struct is guaranteed to have the layout of types like `&[T]`, +/// `&str`, and `Box<[T]>`, but is not the type of such slices +/// (e.g. the fields are not directly accessible on a `&[T]`) nor does +/// it control that layout (changing the definition will not change +/// the layout of a `&[T]`). It is only designed to be used by unsafe +/// code that needs to manipulate the low-level details. +/// +/// However, it is not recommended to use this type for such code, +/// since there are alternatives which may be safer: +/// +/// - Creating a slice from a data pointer and length can be done with +/// `std::slice::from_raw_parts` or `std::slice::from_raw_parts_mut` +/// instead of `std::mem::transmute`ing a value of type `Slice`. +/// - Extracting the data pointer and length from a slice can be +/// performed with the `as_ptr` (or `as_mut_ptr`) and `len` +/// methods. +/// +/// If one does decide to convert a slice value to a `Slice`, the +/// `Repr` trait in this module provides a method for a safe +/// conversion from `&[T]` (and `&str`) to a `Slice`, more type-safe +/// than a call to `transmute`. +/// +/// # Examples +/// +/// ``` +/// use std::raw::{self, Repr}; +/// +/// let slice: &[u16] = &[1, 2, 3, 4]; +/// +/// let repr: raw::Slice = slice.repr(); +/// println!("data pointer = {:?}, length = {}", repr.data, repr.len); +/// ``` #[repr(C)] pub struct Slice { pub data: *const T, @@ -30,18 +63,88 @@ pub struct Slice { impl Copy for Slice {} -/// The representation of a Rust closure +/// The representation of an old closure. #[repr(C)] #[derive(Copy)] +#[unstable(feature = "core")] +#[deprecated(reason = "unboxed new closures do not have a universal representation; \ + `&Fn` (etc) trait objects should use `TraitObject` instead", + since= "1.0.0")] pub struct Closure { pub code: *mut (), pub env: *mut (), } -/// The representation of a Rust trait object. +/// The representation of a trait object like `&SomeTrait`. +/// +/// This struct has the same layout as types like `&SomeTrait` and +/// `Box`. The [Static and Dynamic Dispatch chapter of the +/// Book][moreinfo] contains more details about the precise nature of +/// these internals. +/// +/// [moreinfo]: ../../book/static-and-dynamic-dispatch.html#representation +/// +/// `TraitObject` is guaranteed to match layouts, but it is not the +/// type of trait objects (e.g. the fields are not directly accessible +/// on a `&SomeTrait`) nor does it control that layout (changing the +/// definition will not change the layout of a `&SometTrait`). It is +/// only designed to be used by unsafe code that needs to manipulate +/// the low-level details. +/// +/// There is no `Repr` implementation for `TraitObject` because there +/// is no way to refer to all trait objects generically, so the only +/// way to create values of this type is with functions like +/// `std::mem::transmute`. Similarly, the only way to create a true +/// trait object from a `TraitObject` value is with `transmute`. +/// +/// Synthesizing a trait object with mismatched types—one where the +/// vtable does not correspond to the type of the value to which the +/// data pointer points—is highly likely to lead to undefined +/// behaviour. +/// +/// # Examples +/// +/// ``` +/// use std::mem; +/// use std::raw; +/// +/// // an example trait +/// trait Foo { +/// fn bar(&self) -> i32; +/// } +/// impl Foo for i32 { +/// fn bar(&self) -> i32 { +/// *self + 1 +/// } +/// } +/// +/// let value: i32 = 123; +/// +/// // let the compiler make a trait object +/// let object: &Foo = &value; +/// +/// // look at the raw representation +/// let raw_object: raw::TraitObject = unsafe { mem::transmute(object) }; +/// +/// // the data pointer is the address of `value` +/// assert_eq!(raw_object.data as *const i32, &value as *const _); +/// +/// +/// let other_value: i32 = 456; +/// +/// // construct a new object, pointing to a different `i32`, being +/// // careful to use the `i32` vtable from `object` +/// let synthesized: &Foo = unsafe { +/// mem::transmute(raw::TraitObject { +/// data: &other_value as *const _ as *mut (), +/// vtable: raw_object.vtable +/// }) +/// }; /// -/// This struct does not have a `Repr` implementation -/// because there is no way to refer to all trait objects generically. +/// // it should work just like we constructed a trait object out of +/// // `other_value` directly +/// assert_eq!(synthesized.bar(), 457); +/// ``` #[repr(C)] #[derive(Copy)] pub struct TraitObject { @@ -51,7 +154,7 @@ pub struct TraitObject { /// This trait is meant to map equivalences between raw structs and their /// corresponding rust values. -pub trait Repr { +pub unsafe trait Repr { /// This function "unwraps" a rust value (without consuming it) into its raw /// struct representation. This can be used to read/write different values /// for the struct. This is a safe method because by default it does not @@ -60,5 +163,5 @@ pub trait Repr { fn repr(&self) -> T { unsafe { mem::transmute_copy(&self) } } } -impl Repr> for [T] {} -impl Repr> for str {} +unsafe impl Repr> for [T] {} +unsafe impl Repr> for str {} diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index 7eb0fb97bed2a..88777da0bcd35 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -713,7 +713,7 @@ fn test_random_access_inspect() { fn test_random_access_map() { let xs = [1, 2, 3, 4, 5]; - let mut it = xs.iter().map(|x| *x); + let mut it = xs.iter().cloned(); assert_eq!(xs.len(), it.indexable()); for (i, elt) in xs.iter().enumerate() { assert_eq!(Some(*elt), it.idx(i)); diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs index 50066ab07f555..2dfd81f32c270 100644 --- a/src/libcoretest/lib.rs +++ b/src/libcoretest/lib.rs @@ -11,7 +11,7 @@ #![feature(box_syntax)] #![feature(int_uint)] #![feature(unboxed_closures)] -#![feature(unsafe_destructor, slicing_syntax)] +#![feature(unsafe_destructor)] #![allow(deprecated)] // rand extern crate core; diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index fc8d18df81523..60392550cfb1c 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -25,7 +25,6 @@ html_playground_url = "http://play.rust-lang.org/")] #![feature(int_uint)] -#![feature(slicing_syntax)] #![feature(staged_api)] #![feature(unicode)] diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index a3cae259fd3e5..ca184fb8736cd 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -91,7 +91,6 @@ #![deny(missing_docs)] #![feature(collections)] #![feature(int_uint)] -#![feature(slicing_syntax)] #![feature(staged_api)] #![cfg_attr(test, feature(rustc_private))] diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 2d94ddaef1835..a1a271bc5abb5 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -273,7 +273,6 @@ #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] -#![feature(slicing_syntax)] #![feature(int_uint)] #![feature(collections)] #![feature(core)] diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index 1fedf49738cdf..5edb4a96a7df6 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -168,7 +168,6 @@ #![deny(missing_docs)] #![feature(staged_api)] -#![feature(slicing_syntax)] #![feature(box_syntax)] #![feature(int_uint)] #![feature(core)] diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index 20af4dadfcae9..154dbbdb75034 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -30,7 +30,6 @@ #![feature(int_uint)] #![feature(io)] #![feature(rustc_private)] -#![feature(slicing_syntax)] #![feature(staged_api)] extern crate serialize; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index a4c4ea5438691..f060d464e410f 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -36,7 +36,7 @@ #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] -#![feature(slicing_syntax, unsafe_destructor)] +#![feature(unsafe_destructor)] #![feature(staged_api)] #![feature(std_misc)] #![feature(unicode)] diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index a415ff3ed7165..fe1d695ab7b3e 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -318,8 +318,8 @@ impl LintPass for TypeLimits { fn float_ty_range(float_ty: ast::FloatTy) -> (f64, f64) { match float_ty { - ast::TyF32 => (f32::MIN_VALUE as f64, f32::MAX_VALUE as f64), - ast::TyF64 => (f64::MIN_VALUE, f64::MAX_VALUE) + ast::TyF32 => (f32::MIN as f64, f32::MAX as f64), + ast::TyF64 => (f64::MIN, f64::MAX) } } @@ -674,6 +674,7 @@ impl LintPass for UnusedAttributes { "stable", "unstable", "rustc_on_unimplemented", + "rustc_error", // FIXME: #19470 this shouldn't be needed forever "old_orphan_check", diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 0a3e173b35ee5..8673aec552dcb 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -218,7 +218,7 @@ impl CStore { pub fn find_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option { - self.extern_mod_crate_map.borrow().get(&emod_id).map(|x| *x) + self.extern_mod_crate_map.borrow().get(&emod_id).cloned() } } diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 7ac690f02e1b5..ba40798af3f0b 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -75,7 +75,7 @@ impl<'a> fmt::Debug for Matrix<'a> { pretty_printed_matrix.iter().map(|row| row[col].len()).max().unwrap_or(0) }).collect(); - let total_width = column_widths.iter().map(|n| *n).sum() + column_count * 3 + 1; + let total_width = column_widths.iter().cloned().sum() + column_count * 3 + 1; let br = repeat('+').take(total_width).collect::(); try!(write!(f, "{}\n", br)); for row in pretty_printed_matrix { diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index a6a647173faa7..c4e1d9a64bd96 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -600,7 +600,7 @@ pub fn lit_to_const(lit: &ast::Lit) -> const_val { match lit.node { ast::LitStr(ref s, _) => const_str((*s).clone()), ast::LitBinary(ref data) => { - const_binary(Rc::new(data.iter().map(|x| *x).collect())) + const_binary(Rc::new(data.iter().cloned().collect())) } ast::LitByte(n) => const_uint(n as u64), ast::LitChar(n) => const_uint(n as u64), diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index 6d35a82d153cd..ad9f4eade5c90 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -158,7 +158,7 @@ fn calculate_type(sess: &session::Session, // Collect what we've got so far in the return vector. let mut ret = (1..sess.cstore.next_crate_num()).map(|i| { - match formats.get(&i).map(|v| *v) { + match formats.get(&i).cloned() { v @ Some(cstore::RequireDynamic) => v, _ => None, } diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 5d7a56ef0e6c6..4bb7f03655fee 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -924,7 +924,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { fn rebuild(&self) -> (ast::FnDecl, Option, ast::Generics) { - let mut expl_self_opt = self.expl_self_opt.map(|x| x.clone()); + let mut expl_self_opt = self.expl_self_opt.cloned(); let mut inputs = self.fn_decl.inputs.clone(); let mut output = self.fn_decl.output.clone(); let mut ty_params = self.generics.ty_params.clone(); diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index ef72c2242c1e7..fc7f7568132b0 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -149,7 +149,7 @@ impl<'a, 'v> Visitor<'v> for LanguageItemCollector<'a> { fn visit_item(&mut self, item: &ast::Item) { match extract(&item.attrs) { Some(value) => { - let item_index = self.item_refs.get(&value[]).map(|x| *x); + let item_index = self.item_refs.get(&value[]).cloned(); match item_index { Some(item_index) => { @@ -271,7 +271,7 @@ lets_do_this! { RangeToStructLangItem, "range_to", range_to_struct; RangeFullStructLangItem, "range_full", range_full_struct; - UnsafeTypeLangItem, "unsafe", unsafe_type; + UnsafeCellTypeLangItem, "unsafe_cell", unsafe_cell_type; DerefTraitLangItem, "deref", deref_trait; DerefMutTraitLangItem, "deref_mut", deref_mut_trait; diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 2f0462ab8c338..e539f6ae6cb93 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -407,7 +407,7 @@ impl RegionMaps { pub fn opt_encl_scope(&self, id: CodeExtent) -> Option { //! Returns the narrowest scope that encloses `id`, if any. - self.scope_map.borrow().get(&id).map(|x| *x) + self.scope_map.borrow().get(&id).cloned() } #[allow(dead_code)] // used in middle::cfg diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index e91d7d8c52cde..3ba08c1032031 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -562,7 +562,7 @@ pub fn early_bound_lifetimes<'a>(generics: &'a ast::Generics) -> Vec SelectionContext<'cx, 'tcx> { { let cache = self.pick_candidate_cache(); let hashmap = cache.hashmap.borrow(); - hashmap.get(&cache_fresh_trait_pred.0.trait_ref).map(|c| (*c).clone()) + hashmap.get(&cache_fresh_trait_pred.0.trait_ref).cloned() } fn insert_candidate_cache(&mut self, @@ -1654,7 +1654,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::BoundSync => { if Some(def_id) == tcx.lang_items.managed_bound() || - Some(def_id) == tcx.lang_items.unsafe_type() + Some(def_id) == tcx.lang_items.unsafe_cell_type() { return Err(Unimplemented) } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 6026359ddace0..0387eba5ea686 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3577,7 +3577,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { -> TypeContents { if Some(did) == cx.lang_items.managed_bound() { tc | TC::Managed - } else if Some(did) == cx.lang_items.unsafe_type() { + } else if Some(did) == cx.lang_items.unsafe_cell_type() { tc | TC::InteriorUnsafe } else { tc @@ -4944,7 +4944,7 @@ pub fn note_and_explain_type_err(cx: &ctxt, err: &type_err) { } pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option { - cx.provided_method_sources.borrow().get(&id).map(|x| *x) + cx.provided_method_sources.borrow().get(&id).cloned() } pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) diff --git a/src/librustc_back/target/apple_ios_base.rs b/src/librustc_back/target/apple_ios_base.rs index 715bcc4f36dd0..904b337c03f46 100644 --- a/src/librustc_back/target/apple_ios_base.rs +++ b/src/librustc_back/target/apple_ios_base.rs @@ -73,8 +73,11 @@ fn pre_link_args(arch: Arch) -> Vec { fn target_cpu(arch: Arch) -> String { match arch { + Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher + Armv7s => "cortex-a9", + Arm64 => "cyclone", + I386 => "generic", X86_64 => "x86-64", - _ => "generic", }.to_string() } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index b087c0c2aa1c9..9b8ca398b12b8 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -35,7 +35,7 @@ #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] -#![feature(slicing_syntax, unsafe_destructor)] +#![feature(unsafe_destructor)] #![feature(staged_api)] #![feature(std_misc)] #![feature(unicode)] @@ -477,6 +477,10 @@ pub fn commit_date_str() -> Option<&'static str> { option_env!("CFG_VER_DATE") } +pub fn build_date_str() -> Option<&'static str> { + option_env!("CFG_BUILD_DATE") +} + /// Prints version information and returns None on success or an error /// message on panic. pub fn version(binary: &str, matches: &getopts::Matches) { @@ -488,6 +492,7 @@ pub fn version(binary: &str, matches: &getopts::Matches) { println!("binary: {}", binary); println!("commit-hash: {}", unw(commit_hash_str())); println!("commit-date: {}", unw(commit_date_str())); + println!("build-date: {}", unw(build_date_str())); println!("host: {}", config::host_triple()); println!("release: {}", unw(release_str())); } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 848c3557b1bdb..874c8f2a9402d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -24,7 +24,6 @@ #![feature(int_uint)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] -#![feature(slicing_syntax)] #![feature(staged_api)] #![feature(std_misc)] diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index c4d1416d975cc..21557379e3ae2 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -37,7 +37,7 @@ #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] -#![feature(slicing_syntax, unsafe_destructor)] +#![feature(unsafe_destructor)] #![feature(staged_api)] #![feature(std_misc)] #![feature(unicode)] diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 52ef2b75f9571..3dbcf238db4ae 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -2425,6 +2425,14 @@ fn finish_register_fn(ccx: &CrateContext, sp: Span, sym: String, node_id: ast::N if is_entry_fn(ccx.sess(), node_id) { + // check for the #[rustc_error] annotation, which forces an + // error in trans. This is used to write compile-fail tests + // that actually test that compilation succeeds without + // reporting an error. + if ty::has_attr(ccx.tcx(), local_def(node_id), "rustc_error") { + ccx.tcx().sess.span_fatal(sp, "compilation successful"); + } + create_entry_wrapper(ccx, sp, llfn); } } @@ -3228,7 +3236,7 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>) reachable.push("rust_eh_personality_catch".to_string()); if codegen_units > 1 { - internalize_symbols(&shared_ccx, &reachable.iter().map(|x| x.clone()).collect()); + internalize_symbols(&shared_ccx, &reachable.iter().cloned().collect()); } let metadata_module = ModuleTranslation { diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 9ea7a276d97c6..9b64e87202b26 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -1153,7 +1153,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let trait_ref = bcx.tcx().object_cast_map.borrow() .get(&expr.id) - .map(|t| (*t).clone()) + .cloned() .unwrap(); let trait_ref = bcx.monomorphize(&trait_ref); let datum = unpack_datum!(bcx, trans(bcx, &**val)); diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index 9d1c0fadefcd2..546c62e5dd247 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -67,7 +67,7 @@ pub fn untuple_arguments_if_necessary<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, abi: abi::Abi) -> Vec> { if abi != abi::RustCall { - return inputs.iter().map(|x| (*x).clone()).collect() + return inputs.iter().cloned().collect() } if inputs.len() == 0 { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index d12b23187b80b..5b75e06c88706 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3223,7 +3223,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, for field in ast_fields { let mut expected_field_type = tcx.types.err; - let pair = class_field_map.get(&field.ident.node.name).map(|x| *x); + let pair = class_field_map.get(&field.ident.node.name).cloned(); match pair { None => { fcx.type_error_message( @@ -3871,7 +3871,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, } ast::ExprStruct(ref path, ref fields, ref base_expr) => { // Resolve the path. - let def = tcx.def_map.borrow().get(&id).map(|i| *i); + let def = tcx.def_map.borrow().get(&id).cloned(); let struct_id = match def { Some(def::DefVariant(enum_id, variant_id, true)) => { check_struct_enum_variant(fcx, id, expr.span, enum_id, diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index ccfadaba2440b..7498dc8179d75 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -83,7 +83,7 @@ This API is completely unstable and subject to change. #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] -#![feature(slicing_syntax, unsafe_destructor)] +#![feature(unsafe_destructor)] #![feature(staged_api)] #[macro_use] extern crate log; diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index 567a388836f25..d5883d8bf864b 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -412,7 +412,7 @@ struct ConstraintContext<'a, 'tcx: 'a> { invariant_lang_items: [Option; 2], covariant_lang_items: [Option; 2], contravariant_lang_items: [Option; 2], - unsafe_lang_item: Option, + unsafe_cell_lang_item: Option, // These are pointers to common `ConstantTerm` instances covariant: VarianceTermPtr<'a>, @@ -453,7 +453,7 @@ fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>, invariant_lang_items[RegionParam as uint] = terms_cx.tcx.lang_items.invariant_lifetime(); - let unsafe_lang_item = terms_cx.tcx.lang_items.unsafe_type(); + let unsafe_cell_lang_item = terms_cx.tcx.lang_items.unsafe_cell_type(); let covariant = terms_cx.arena.alloc(ConstantTerm(ty::Covariant)); let contravariant = terms_cx.arena.alloc(ConstantTerm(ty::Contravariant)); @@ -465,7 +465,7 @@ fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>, invariant_lang_items: invariant_lang_items, covariant_lang_items: covariant_lang_items, contravariant_lang_items: contravariant_lang_items, - unsafe_lang_item: unsafe_lang_item, + unsafe_cell_lang_item: unsafe_cell_lang_item, covariant: covariant, contravariant: contravariant, @@ -654,7 +654,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { self.covariant } else if self.contravariant_lang_items[kind as uint] == Some(item_def_id) { self.contravariant - } else if kind == TypeParam && Some(item_def_id) == self.unsafe_lang_item { + } else if kind == TypeParam && Some(item_def_id) == self.unsafe_cell_lang_item { self.invariant } else if param_def_id.krate == ast::LOCAL_CRATE { // Parameter on an item defined within current crate: diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index b30b251e8ba6f..95994af7dc8de 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1849,6 +1849,7 @@ fn render_method(w: &mut fmt::Formatter, meth: &clean::Item) -> fmt::Result { fn item_struct(w: &mut fmt::Formatter, it: &clean::Item, s: &clean::Struct) -> fmt::Result { try!(write!(w, "
"));
+    try!(render_attributes(w, it));
     try!(render_struct(w,
                        it,
                        Some(&s.generics),
@@ -1885,7 +1886,9 @@ fn item_struct(w: &mut fmt::Formatter, it: &clean::Item,
 
 fn item_enum(w: &mut fmt::Formatter, it: &clean::Item,
              e: &clean::Enum) -> fmt::Result {
-    try!(write!(w, "
{}enum {}{}{}",
+    try!(write!(w, "
"));
+    try!(render_attributes(w, it));
+    try!(write!(w, "{}enum {}{}{}",
                   VisSpace(it.visibility),
                   it.name.as_ref().unwrap(),
                   e.generics,
@@ -1982,6 +1985,21 @@ fn item_enum(w: &mut fmt::Formatter, it: &clean::Item,
     Ok(())
 }
 
+fn render_attributes(w: &mut fmt::Formatter, it: &clean::Item) -> fmt::Result {
+    for attr in &it.attrs {
+        match *attr {
+            clean::Word(ref s) if *s == "must_use" => {
+                try!(write!(w, "#[{}]\n", s));
+            }
+            clean::NameValue(ref k, ref v) if *k == "must_use" => {
+                try!(write!(w, "#[{} = \"{}\"]\n", k, v));
+            }
+            _ => ()
+        }
+    }
+    Ok(())
+}
+
 fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
                  g: Option<&clean::Generics>,
                  ty: doctree::StructType,
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 9d45caf76696a..b09c3f730fc64 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -30,7 +30,6 @@
 #![feature(os)]
 #![feature(path)]
 #![feature(rustc_private)]
-#![feature(slicing_syntax)]
 #![feature(staged_api)]
 #![feature(std_misc)]
 #![feature(test)]
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
index abd73fcfb7028..722f14fa6d4c7 100644
--- a/src/librustdoc/passes.rs
+++ b/src/librustdoc/passes.rs
@@ -293,7 +293,7 @@ pub fn collapse_docs(krate: clean::Crate) -> plugins::PluginResult {
             let mut a: Vec = i.attrs.iter().filter(|&a| match a {
                 &clean::NameValue(ref x, _) if "doc" == *x => false,
                 _ => true
-            }).map(|x| x.clone()).collect();
+            }).cloned().collect();
             if docstr.len() > 0 {
                 a.push(clean::NameValue("doc".to_string(), docstr));
             }
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index ac1a02854124a..c52b0bab1fa8b 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -333,7 +333,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     name: name,
                     items: items.clone(),
                     generics: gen.clone(),
-                    bounds: b.iter().map(|x| (*x).clone()).collect(),
+                    bounds: b.iter().cloned().collect(),
                     id: item.id,
                     attrs: item.attrs.clone(),
                     whence: item.span,
diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs
index 4579d1f19d3f0..6cada2e5614ba 100644
--- a/src/libserialize/lib.rs
+++ b/src/libserialize/lib.rs
@@ -33,7 +33,6 @@ Core encoding and decoding interfaces.
 #![feature(path)]
 #![feature(hash)]
 #![feature(rustc_private)]
-#![feature(slicing_syntax)]
 #![feature(staged_api)]
 #![feature(std_misc)]
 #![feature(unicode)]
diff --git a/src/libstd/env.rs b/src/libstd/env.rs
index ea18838211f26..bfc1afc6eb4f2 100644
--- a/src/libstd/env.rs
+++ b/src/libstd/env.rs
@@ -918,7 +918,7 @@ mod tests {
     #[cfg(unix)]
     fn join_paths_unix() {
         fn test_eq(input: &[&str], output: &str) -> bool {
-            &*join_paths(input.iter().map(|s| *s)).unwrap() ==
+            &*join_paths(input.iter().cloned()).unwrap() ==
                 OsStr::from_str(output)
         }
 
@@ -927,14 +927,14 @@ mod tests {
                          "/bin:/usr/bin:/usr/local/bin"));
         assert!(test_eq(&["", "/bin", "", "", "/usr/bin", ""],
                          ":/bin:::/usr/bin:"));
-        assert!(join_paths(["/te:st"].iter().map(|s| *s)).is_err());
+        assert!(join_paths(["/te:st"].iter().cloned()).is_err());
     }
 
     #[test]
     #[cfg(windows)]
     fn join_paths_windows() {
         fn test_eq(input: &[&str], output: &str) -> bool {
-            &*join_paths(input.iter().map(|s| *s)).unwrap() ==
+            &*join_paths(input.iter().cloned()).unwrap() ==
                 OsStr::from_str(output)
         }
 
@@ -945,6 +945,6 @@ mod tests {
                         r";c:\windows;;;c:\;"));
         assert!(test_eq(&[r"c:\te;st", r"c:\"],
                         r#""c:\te;st";c:\"#));
-        assert!(join_paths([r#"c:\te"st"#].iter().map(|s| *s)).is_err());
+        assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err());
     }
     }
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs
index 58b93665fe153..83a5c68912cf3 100644
--- a/src/libstd/num/f32.rs
+++ b/src/libstd/num/f32.rs
@@ -30,6 +30,7 @@ use core::num;
 pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE};
 pub use core::f32::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP};
 pub use core::f32::{MAX_10_EXP, NAN, INFINITY, NEG_INFINITY};
+pub use core::f32::{MIN, MIN_POSITIVE, MAX};
 pub use core::f32::consts;
 
 #[allow(dead_code)]
diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs
index 8b17feeb70cdc..f243955d199dc 100644
--- a/src/libstd/num/f64.rs
+++ b/src/libstd/num/f64.rs
@@ -29,6 +29,7 @@ use core::num;
 pub use core::f64::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE};
 pub use core::f64::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP};
 pub use core::f64::{MAX_10_EXP, NAN, INFINITY, NEG_INFINITY};
+pub use core::f64::{MIN, MIN_POSITIVE, MAX};
 pub use core::f64::consts;
 
 #[allow(dead_code)]
diff --git a/src/libstd/old_io/net/udp.rs b/src/libstd/old_io/net/udp.rs
index 5f1089bc63b99..8dc19047de08e 100644
--- a/src/libstd/old_io/net/udp.rs
+++ b/src/libstd/old_io/net/udp.rs
@@ -32,7 +32,6 @@ use sys_common;
 ///
 /// ```rust,no_run
 /// # #![allow(unused_must_use)]
-/// #![feature(slicing_syntax)]
 ///
 /// use std::old_io::net::udp::UdpSocket;
 /// use std::old_io::net::ip::{Ipv4Addr, SocketAddr};
diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs
index babae93b2d440..87b2fe8f100c3 100644
--- a/src/libstd/sync/mpsc/select.rs
+++ b/src/libstd/sync/mpsc/select.rs
@@ -111,11 +111,18 @@ pub trait Packet {
 }
 
 impl Select {
-    /// Creates a new selection structure. This set is initially empty and
-    /// `wait` will panic!() if called.
+    /// Creates a new selection structure. This set is initially empty.
     ///
-    /// Usage of this struct directly can sometimes be burdensome, and usage is
-    /// rather much easier through the `select!` macro.
+    /// Usage of this struct directly can sometimes be burdensome, and usage is much easier through
+    /// the `select!` macro.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::sync::mpsc::Select;
+    ///
+    /// let select = Select::new();
+    /// ```
     pub fn new() -> Select {
         Select {
             head: ptr::null_mut(),
diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs
index 5535e5911e0c2..6535705388d01 100644
--- a/src/libsyntax/ast_map/mod.rs
+++ b/src/libsyntax/ast_map/mod.rs
@@ -251,7 +251,7 @@ impl<'ast> Map<'ast> {
     }
 
     fn find_entry(&self, id: NodeId) -> Option> {
-        self.map.borrow().get(id as usize).map(|e| *e)
+        self.map.borrow().get(id as usize).cloned()
     }
 
     pub fn krate(&self) -> &'ast Crate {
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 64ae6162ef4e5..26e291a4c693a 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -639,7 +639,7 @@ impl<'a> ExtCtxt<'a> {
     pub fn mod_path(&self) -> Vec {
         let mut v = Vec::new();
         v.push(token::str_to_ident(&self.ecfg.crate_name[]));
-        v.extend(self.mod_path.iter().map(|a| *a));
+        v.extend(self.mod_path.iter().cloned());
         return v;
     }
     pub fn bt_push(&mut self, ei: ExpnInfo) {
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index d9242417e0475..dba92009a962d 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -367,7 +367,7 @@ impl<'a> TraitDef<'a> {
                 "allow" | "warn" | "deny" | "forbid" => true,
                 _ => false,
             }
-        }).map(|a| a.clone()));
+        }).cloned());
         push(P(ast::Item {
             attrs: attrs,
             ..(*newitem).clone()
@@ -410,7 +410,7 @@ impl<'a> TraitDef<'a> {
         let mut ty_params = ty_params.into_vec();
 
         // Copy the lifetimes
-        lifetimes.extend(generics.lifetimes.iter().map(|l| (*l).clone()));
+        lifetimes.extend(generics.lifetimes.iter().cloned());
 
         // Create the type parameters.
         ty_params.extend(generics.ty_params.iter().map(|ty_param| {
@@ -445,14 +445,14 @@ impl<'a> TraitDef<'a> {
                         span: self.span,
                         bound_lifetimes: wb.bound_lifetimes.clone(),
                         bounded_ty: wb.bounded_ty.clone(),
-                        bounds: OwnedSlice::from_vec(wb.bounds.iter().map(|b| b.clone()).collect())
+                        bounds: OwnedSlice::from_vec(wb.bounds.iter().cloned().collect())
                     })
                 }
                 ast::WherePredicate::RegionPredicate(ref rb) => {
                     ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
                         span: self.span,
                         lifetime: rb.lifetime,
-                        bounds: rb.bounds.iter().map(|b| b.clone()).collect()
+                        bounds: rb.bounds.iter().cloned().collect()
                     })
                 }
                 ast::WherePredicate::EqPredicate(ref we) => {
@@ -500,7 +500,7 @@ impl<'a> TraitDef<'a> {
         let opt_trait_ref = Some(trait_ref);
         let ident = ast_util::impl_pretty_name(&opt_trait_ref, &*self_type);
         let mut a = vec![attr];
-        a.extend(self.attributes.iter().map(|a| a.clone()));
+        a.extend(self.attributes.iter().cloned());
         cx.item(
             self.span,
             ident,
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index 7a3a3562bdfdc..d1dee115b6bcd 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -179,7 +179,7 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
             return DummyResult::expr(sp);
         }
         Ok(bytes) => {
-            let bytes = bytes.iter().map(|x| *x).collect();
+            let bytes = bytes.iter().cloned().collect();
             base::MacExpr::new(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes))))
         }
     }
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index d752e34c11253..7e996f46c4b07 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -282,9 +282,7 @@ pub fn parse(sess: &ParseSess,
              ms: &[TokenTree])
              -> ParseResult {
     let mut cur_eis = Vec::new();
-    cur_eis.push(initial_matcher_pos(Rc::new(ms.iter()
-                                                .map(|x| (*x).clone())
-                                                .collect()),
+    cur_eis.push(initial_matcher_pos(Rc::new(ms.iter().cloned().collect()),
                                      None,
                                      rdr.peek().sp.lo));
 
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index de61bdefa5de3..e899b46c009d1 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -160,7 +160,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                                                       None,
                                                       None,
                                                       arg.iter()
-                                                         .map(|x| (*x).clone())
+                                                         .cloned()
                                                          .collect(),
                                                       true);
             match parse(cx.parse_sess(), cx.cfg(), arg_rdr, lhs_tt) {
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index ca7ae32f09ec9..fd1ca11818c98 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -79,7 +79,7 @@ static KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
     ("tuple_indexing", "1.0.0", Accepted),
     ("associated_types", "1.0.0", Accepted),
     ("visible_private_types", "1.0.0", Active),
-    ("slicing_syntax", "1.0.0", Active),
+    ("slicing_syntax", "1.0.0", Accepted),
     ("box_syntax", "1.0.0", Active),
     ("on_unimplemented", "1.0.0", Active),
     ("simd_ffi", "1.0.0", Active),
@@ -134,6 +134,7 @@ static KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
     // switch to Accepted; see RFC 320)
     ("unsafe_no_drop_flag", "1.0.0", Active),
 ];
+// (changing above list without updating src/doc/reference.md makes @cmr sad)
 
 enum Status {
     /// Represents an active feature that is currently being implemented or
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 951e4dcf79254..f4b0c867f42c6 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -35,7 +35,6 @@
 #![feature(path)]
 #![feature(quote, unsafe_destructor)]
 #![feature(rustc_private)]
-#![feature(slicing_syntax)]
 #![feature(staged_api)]
 #![feature(std_misc)]
 #![feature(unicode)]
diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs
index b17fc7fe82e6c..6f5da94f21059 100644
--- a/src/libsyntax/parse/lexer/comments.rs
+++ b/src/libsyntax/parse/lexer/comments.rs
@@ -82,7 +82,7 @@ pub fn strip_doc_comment_decoration(comment: &str) -> String {
         while j > i && lines[j - 1].trim().is_empty() {
             j -= 1;
         }
-        return lines[i..j].iter().map(|x| (*x).clone()).collect();
+        return lines[i..j].iter().cloned().collect();
     }
 
     /// remove a "[ \t]*\*" block from each line, if possible
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index fd2f0685cab83..adbb22786f922 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -241,7 +241,7 @@ macro_rules! maybe_whole {
 fn maybe_append(mut lhs: Vec, rhs: Option>)
                 -> Vec {
     match rhs {
-        Some(ref attrs) => lhs.extend(attrs.iter().map(|a| a.clone())),
+        Some(ref attrs) => lhs.extend(attrs.iter().cloned()),
         None => {}
     }
     lhs
@@ -467,7 +467,7 @@ impl<'a> Parser<'a> {
         debug!("commit_expr {:?}", e);
         if let ExprPath(..) = e.node {
             // might be unit-struct construction; check for recoverableinput error.
-            let mut expected = edible.iter().map(|x| x.clone()).collect::>();
+            let mut expected = edible.iter().cloned().collect::>();
             expected.push_all(inedible);
             self.check_for_erroneous_unit_struct_expecting(&expected[]);
         }
@@ -485,7 +485,7 @@ impl<'a> Parser<'a> {
         if self.last_token
                .as_ref()
                .map_or(false, |t| t.is_ident() || t.is_path()) {
-            let mut expected = edible.iter().map(|x| x.clone()).collect::>();
+            let mut expected = edible.iter().cloned().collect::>();
             expected.push_all(&inedible[]);
             self.check_for_erroneous_unit_struct_expecting(
                 &expected[]);
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 583095e157427..78bfc0b3de706 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -983,7 +983,7 @@ impl<'a> State<'a> {
                 try!(self.word_nbsp("trait"));
                 try!(self.print_ident(item.ident));
                 try!(self.print_generics(generics));
-                let bounds: Vec<_> = bounds.iter().map(|b| b.clone()).collect();
+                let bounds: Vec<_> = bounds.iter().cloned().collect();
                 let mut real_bounds = Vec::with_capacity(bounds.len());
                 for b in bounds {
                     if let TraitTyParamBound(ref ptr, ast::TraitBoundModifier::Maybe) = b {
diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs
index 1bb038603c39c..c4b3d2813afe4 100644
--- a/src/libterm/lib.rs
+++ b/src/libterm/lib.rs
@@ -57,7 +57,6 @@
 #![feature(io)]
 #![feature(path)]
 #![feature(rustc_private)]
-#![feature(slicing_syntax)]
 #![feature(staged_api)]
 #![feature(std_misc)]
 #![feature(unicode)]
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index cc468df87f383..860ce209d451f 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -32,7 +32,7 @@
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 
-#![feature(asm, slicing_syntax)]
+#![feature(asm)]
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
diff --git a/src/libunicode/lib.rs b/src/libunicode/lib.rs
index 0ac569b9c8ea3..4cab61fd8fade 100644
--- a/src/libunicode/lib.rs
+++ b/src/libunicode/lib.rs
@@ -31,7 +31,6 @@
        html_playground_url = "http://play.rust-lang.org/")]
 #![feature(no_std)]
 #![no_std]
-#![feature(slicing_syntax)]
 #![feature(int_uint)]
 #![feature(core)]
 
diff --git a/src/rustbook/main.rs b/src/rustbook/main.rs
index 3e571bad09ca4..b29538ad62078 100644
--- a/src/rustbook/main.rs
+++ b/src/rustbook/main.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(slicing_syntax, box_syntax)]
+#![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
 #![feature(io)]
diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs
index 141e098745e7b..0d28dd481a63b 100644
--- a/src/test/bench/shootout-fasta.rs
+++ b/src/test/bench/shootout-fasta.rs
@@ -133,7 +133,7 @@ fn run(writer: &mut W) -> std::old_io::IoResult<()> {
                         ('t', 0.3015094502008)];
 
     try!(make_fasta(writer, ">ONE Homo sapiens alu\n",
-                    alu.as_bytes().iter().cycle().map(|c| *c), n * 2));
+                    alu.as_bytes().iter().cycle().cloned(), n * 2));
     try!(make_fasta(writer, ">TWO IUB ambiguity codes\n",
                     AAGen::new(rng, iub), n * 3));
     try!(make_fasta(writer, ">THREE Homo sapiens frequency\n",
diff --git a/src/test/bench/shootout-meteor.rs b/src/test/bench/shootout-meteor.rs
index d061403d5901d..59abd63e12d59 100644
--- a/src/test/bench/shootout-meteor.rs
+++ b/src/test/bench/shootout-meteor.rs
@@ -270,7 +270,7 @@ fn handle_sol(raw_sol: &List, data: &mut Data) {
     // reverse order, i.e. the board rotated by half a turn.
     data.nb += 2;
     let sol1 = to_vec(raw_sol);
-    let sol2: Vec = sol1.iter().rev().map(|x| *x).collect();
+    let sol2: Vec = sol1.iter().rev().cloned().collect();
 
     if data.nb == 2 {
         data.min = sol1.clone();
diff --git a/src/test/compile-fail/rustc-error.rs b/src/test/compile-fail/rustc-error.rs
new file mode 100644
index 0000000000000..6497439c3dc57
--- /dev/null
+++ b/src/test/compile-fail/rustc-error.rs
@@ -0,0 +1,14 @@
+// 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.
+
+#[rustc_error]
+fn main() {
+    //~^ ERROR compilation successful
+}
diff --git a/src/test/run-make/rustdoc-must-use/Makefile b/src/test/run-make/rustdoc-must-use/Makefile
new file mode 100644
index 0000000000000..74fca83f5f915
--- /dev/null
+++ b/src/test/run-make/rustdoc-must-use/Makefile
@@ -0,0 +1,5 @@
+-include ../tools.mk
+
+all: lib.rs
+	$(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc lib.rs
+	$(HTMLDOCCK) $(TMPDIR)/doc lib.rs
diff --git a/src/test/run-make/rustdoc-must-use/lib.rs b/src/test/run-make/rustdoc-must-use/lib.rs
new file mode 100644
index 0000000000000..cef79d4536bef
--- /dev/null
+++ b/src/test/run-make/rustdoc-must-use/lib.rs
@@ -0,0 +1,23 @@
+// 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.
+
+#![crate_type="lib"]
+
+// @has lib/struct.Struct.html //pre '#[must_use]'
+#[must_use]
+pub struct Struct {
+    field: i32,
+}
+
+// @has lib/enum.Enum.html //pre '#[must_use = "message"]'
+#[must_use = "message"]
+pub enum Enum {
+    Variant(i32),
+}
diff --git a/src/test/run-pass/issue-21909.rs b/src/test/run-pass/issue-21909.rs
new file mode 100644
index 0000000000000..5bbc90b260639
--- /dev/null
+++ b/src/test/run-pass/issue-21909.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.
+
+trait A {}
+
+trait B {
+    type X;
+    type Y: A;
+}
+
+fn main () { }
diff --git a/src/test/run-pass/ranges-precedence.rs b/src/test/run-pass/ranges-precedence.rs
index cd49094851695..6d150fa886181 100644
--- a/src/test/run-pass/ranges-precedence.rs
+++ b/src/test/run-pass/ranges-precedence.rs
@@ -10,8 +10,6 @@
 
 // Test that the precedence of ranges is correct
 
-#![feature(slicing_syntax)]
-
 struct Foo {
     foo: uint,
 }