diff --git a/src/doc/index.md b/src/doc/index.md index a4f7941222018..f6b0a18824a02 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -68,7 +68,7 @@ There are questions that are asked quite often, and so we've made FAQs for them: * [Language Design FAQ](complement-design-faq.html) * [Language FAQ](complement-lang-faq.html) * [Project FAQ](complement-project-faq.html) -* [How to submit a bug report](complement-bugreport.html) +* [How to submit a bug report](https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports) # The standard library diff --git a/src/doc/reference.md b/src/doc/reference.md index 31524579df7c0..781b40be768c8 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -731,15 +731,20 @@ Rust syntax is restricted in two ways: pairs when they occur at the beginning of, or immediately after, a `$(...)*`; requiring a distinctive token in front can solve the problem. -## Syntax extensions useful for the macro author +## Syntax extensions useful in macros -* `log_syntax!` : print out the arguments at compile time -* `trace_macros!` : supply `true` or `false` to enable or disable macro expansion logging * `stringify!` : turn the identifier argument into a string literal * `concat!` : concatenates a comma-separated list of literals -* `concat_idents!` : create a new identifier by concatenating the arguments -The following attributes are used for quasiquoting in procedural macros: +## Syntax extensions for macro debugging + +* `log_syntax!` : print out the arguments at compile time +* `trace_macros!` : supply `true` or `false` to enable or disable macro expansion logging + +## Quasiquoting + +The following syntax extensions are used for quasiquoting Rust syntax trees, +usually in [procedural macros](book/plugins.html#syntax-extensions): * `quote_expr!` * `quote_item!` @@ -748,6 +753,8 @@ The following attributes are used for quasiquoting in procedural macros: * `quote_tokens!` * `quote_ty!` +Documentation is very limited at the moment. + # Crates and source files Rust is a *compiled* language. Its semantics obey a *phase distinction* diff --git a/src/doc/trpl/advanced-macros.md b/src/doc/trpl/advanced-macros.md index aff365051a4ea..a226e4d0bf911 100644 --- a/src/doc/trpl/advanced-macros.md +++ b/src/doc/trpl/advanced-macros.md @@ -192,19 +192,58 @@ To keep this system simple and correct, `#[macro_use] extern crate ...` may only appear at the root of your crate, not inside `mod`. This ensures that `$crate` is a single identifier. -# A final note +# The deep end -Macros, as currently implemented, are not for the faint of heart. Even -ordinary syntax errors can be more difficult to debug when they occur inside a -macro, and errors caused by parse problems in generated code can be very -tricky. Invoking the `log_syntax!` macro can help elucidate intermediate -states, invoking `trace_macros!(true)` will automatically print those -intermediate states out, and passing the flag `--pretty expanded` as a -command-line argument to the compiler will show the result of expansion. +The introductory chapter mentioned recursive macros, but it did not give the +full story. Recursive macros are useful for another reason: Each recursive +invocation gives you another opportunity to pattern-match the macro's +arguments. + +As an extreme example, it is possible, though hardly advisable, to implement +the [Bitwise Cyclic Tag](http://esolangs.org/wiki/Bitwise_Cyclic_Tag) automaton +within Rust's macro system. + +```rust +#![feature(trace_macros)] + +macro_rules! bct { + // cmd 0: d ... => ... + (0, $($ps:tt),* ; $_d:tt) + => (bct!($($ps),*, 0 ; )); + (0, $($ps:tt),* ; $_d:tt, $($ds:tt),*) + => (bct!($($ps),*, 0 ; $($ds),*)); + + // cmd 1p: 1 ... => 1 ... p + (1, $p:tt, $($ps:tt),* ; 1) + => (bct!($($ps),*, 1, $p ; 1, $p)); + (1, $p:tt, $($ps:tt),* ; 1, $($ds:tt),*) + => (bct!($($ps),*, 1, $p ; 1, $($ds),*, $p)); + + // cmd 1p: 0 ... => 0 ... + (1, $p:tt, $($ps:tt),* ; $($ds:tt),*) + => (bct!($($ps),*, 1, $p ; $($ds),*)); + + // halt on empty data string + ( $($ps:tt),* ; ) + => (()); +} + +fn main() { + trace_macros!(true); +# /* just check the definition + bct!(0, 0, 1, 1, 1 ; 1, 0, 1); +# */ +} +``` + +Exercise: use macros to reduce duplication in the above definition of the +`bct!` macro. + +# Procedural macros If Rust's macro system can't do what you need, you may want to write a [compiler plugin](plugins.html) instead. Compared to `macro_rules!` macros, this is significantly more work, the interfaces are much less stable, -and the warnings about debugging apply ten-fold. In exchange you get the +and bugs can be much harder to track down. In exchange you get the flexibility of running arbitrary Rust code within the compiler. Syntax extension plugins are sometimes called *procedural macros* for this reason. diff --git a/src/doc/trpl/error-handling.md b/src/doc/trpl/error-handling.md index 68b36e7a4b7ca..cf60bd88c542b 100644 --- a/src/doc/trpl/error-handling.md +++ b/src/doc/trpl/error-handling.md @@ -223,6 +223,78 @@ let input = io::stdin().read_line() .ok() .expect("Failed to read line"); ``` + `ok()` converts the `IoResult` into an `Option`, and `expect()` does the same thing as `unwrap()`, but takes a message. This message is passed along to the underlying `panic!`, providing a better error message if the code errors. + +# Using `try!` + +When writing code that calls many functions that return the `Result` type, the +error handling can be tedious. The `try!` macro hides some of the boilerplate +of propagating errors up the call stack. + +It replaces this: + +```rust +use std::fs::File; +use std::io; +use std::io::prelude::*; + +struct Info { + name: String, + age: i32, + rating: i32, +} + +fn write_info(info: &Info) -> io::Result<()> { + let mut file = File::open("my_best_friends.txt").unwrap(); + + if let Err(e) = writeln!(&mut file, "name: {}", info.name) { + return Err(e) + } + if let Err(e) = writeln!(&mut file, "age: {}", info.age) { + return Err(e) + } + if let Err(e) = writeln!(&mut file, "rating: {}", info.rating) { + return Err(e) + } + + return Ok(()); +} +``` + +With this: + +```rust +use std::fs::File; +use std::io; +use std::io::prelude::*; + +struct Info { + name: String, + age: i32, + rating: i32, +} + +fn write_info(info: &Info) -> io::Result<()> { + let mut file = try!(File::open("my_best_friends.txt")); + + try!(writeln!(&mut file, "name: {}", info.name)); + try!(writeln!(&mut file, "age: {}", info.age)); + try!(writeln!(&mut file, "rating: {}", info.rating)); + + return Ok(()); +} +``` + +Wrapping an expression in `try!` will result in the unwrapped success (`Ok`) +value, unless the result is `Err`, in which case `Err` is returned early from +the enclosing function. + +It's worth noting that you can only use `try!` from a function that returns a +`Result`, which means that you cannot use `try!` inside of `main()`, because +`main()` doesn't return anything. + +`try!` makes use of [`FromError`](../std/error/#the-fromerror-trait) to determine +what to return in the error case. diff --git a/src/doc/trpl/macros.md b/src/doc/trpl/macros.md index ce6fa3ce949cd..7da36043f6cf1 100644 --- a/src/doc/trpl/macros.md +++ b/src/doc/trpl/macros.md @@ -73,7 +73,7 @@ macro_rules! vec { }; } # fn main() { -# assert_eq!(&[1,2,3], &vec![1,2,3]); +# assert_eq!([1,2,3], vec![1,2,3]); # } ``` @@ -189,14 +189,12 @@ shorthand for a data type could be valid as either an expression or a pattern. ## Repetition -The repetition behavior can seem somewhat magical, especially when multiple -names are bound at multiple nested levels of repetition. The two rules to keep -in mind are: +The repetition operator follows two principal rules: -1. the behavior of `$(...)*` is to walk through one "layer" of repetitions, for -all of the `$name`s it contains, in lockstep, and +1. `$(...)*` walks through one "layer" of repetitions, for all of the `$name`s + it contains, in lockstep, and 2. each `$name` must be under at least as many `$(...)*`s as it was matched -against. If it is under more, it'll be duplicated, as appropriate. + against. If it is under more, it'll be duplicated, as appropriate. This baroque macro illustrates the duplication of variables from outer repetition levels. @@ -226,6 +224,10 @@ That's most of the matcher syntax. These examples use `$(...)*`, which is a more" match. Both forms optionally include a separator, which can be any token except `+` or `*`. +This system is based on +"[Macro-by-Example](http://www.cs.indiana.edu/ftp/techreports/TR206.pdf)" +(PDF link). + # Hygiene Some languages implement macros using simple text substitution, which leads to @@ -273,19 +275,26 @@ macro, using [a GNU C extension] to emulate Rust's expression blocks. }) ``` -This looks reasonable, but watch what happens in this example: +Here's a simple use case that goes terribly wrong: ```text const char *state = "reticulating splines"; -LOG(state); +LOG(state) ``` -The program will likely segfault, after it tries to execute +This expands to ```text -printf("log(%d): %s\n", state, state); +const char *state = "reticulating splines"; +int state = get_log_state(); +if (state > 0) { + printf("log(%d): %s\n", state, state); +} ``` +The second variable named `state` shadows the first one. This is a problem +because the print statement should refer to both of them. + The equivalent Rust macro has the desired behavior. ```rust @@ -357,6 +366,64 @@ fn main() { [items]: ../reference.html#items +# Recursive macros + +A macro's expansion can include more macro invocations, including invocations +of the very same macro being expanded. These recursive macros are useful for +processing tree-structured input, as illustrated by this (simplistic) HTML +shorthand: + +```rust +# #![allow(unused_must_use)] +macro_rules! write_html { + ($w:expr, ) => (()); + + ($w:expr, $e:tt) => (write!($w, "{}", $e)); + + ($w:expr, $tag:ident [ $($inner:tt)* ] $($rest:tt)*) => {{ + write!($w, "<{}>", stringify!($tag)); + write_html!($w, $($inner)*); + write!($w, "", stringify!($tag)); + write_html!($w, $($rest)*); + }}; +} + +fn main() { +# // FIXME(#21826) + use std::fmt::Write; + let mut out = String::new(); + + write_html!(&mut out, + html[ + head[title["Macros guide"]] + body[h1["Macros are the best!"]] + ]); + + assert_eq!(out, + "Macros guide\ +

Macros are the best!

"); +} +``` + +# Debugging macro code + +To see the results of expanding macros, run `rustc --pretty expanded`. The +output represents a whole crate, so you can also feed it back in to `rustc`, +which will sometimes produce better error messages than the original +compilation. Note that the `--pretty expanded` output may have a different +meaning if multiple variables of the same name (but different syntax contexts) +are in play in the same scope. In this case `--pretty expanded,hygiene` will +tell you about the syntax contexts. + +`rustc` provides two syntax extensions that help with macro debugging. For now, +they are unstable and require feature gates. + +* `log_syntax!(...)` will print its arguments to standard output, at compile + time, and "expand" to nothing. + +* `trace_macros!(true)` will enable a compiler message every time a macro is + expanded. Use `trace_macros!(false)` later in expansion to turn it off. + # Further reading The [advanced macros chapter][] goes into more detail about macro syntax. It diff --git a/src/doc/trpl/plugins.md b/src/doc/trpl/plugins.md index 79502f3cd17f7..f609a0a918aa7 100644 --- a/src/doc/trpl/plugins.md +++ b/src/doc/trpl/plugins.md @@ -146,14 +146,7 @@ a more involved macro example, see ## Tips and tricks -To see the results of expanding syntax extensions, run -`rustc --pretty expanded`. The output represents a whole crate, so you -can also feed it back in to `rustc`, which will sometimes produce better -error messages than the original compilation. Note that the -`--pretty expanded` output may have a different meaning if multiple -variables of the same name (but different syntax contexts) are in play -in the same scope. In this case `--pretty expanded,hygiene` will tell -you about the syntax contexts. +Some of the [macro debugging tips](macros.html#debugging-macro-code) are applicable. You can use [`syntax::parse`](../syntax/parse/index.html) to turn token trees into higher-level syntax elements like expressions: @@ -184,6 +177,11 @@ and return [`DummyResult`](../syntax/ext/base/struct.DummyResult.html), so that the compiler can continue and find further errors. +To print syntax fragments for debugging, you can use +[`span_note`](../syntax/ext/base/struct.ExtCtxt.html#method.span_note) together +with +[`syntax::print::pprust::*_to_string`](http://doc.rust-lang.org/syntax/print/pprust/index.html#functions). + The example above produced an integer literal using [`AstBuilder::expr_uint`](../syntax/ext/build/trait.AstBuilder.html#tymethod.expr_uint). As an alternative to the `AstBuilder` trait, `libsyntax` provides a set of diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 0cdc71b6f604f..82bd13475c74e 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -73,6 +73,7 @@ #![feature(unboxed_closures)] #![feature(unsafe_no_drop_flag)] #![feature(core)] +#![feature(unique)] #![cfg_attr(test, feature(test, alloc, rustc_private))] #![cfg_attr(all(not(feature = "external_funcs"), not(feature = "external_crate")), feature(libc))] diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index 9f549fd723771..36c76dbad14ae 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -480,7 +480,7 @@ impl BinaryHeap { /// heap.push(3); /// /// let vec = heap.into_sorted_vec(); - /// assert_eq!(vec, vec![1, 2, 3, 4, 5, 6, 7]); + /// assert_eq!(vec, [1, 2, 3, 4, 5, 6, 7]); /// ``` pub fn into_sorted_vec(mut self) -> Vec { let mut end = self.len(); diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index f28f9976f0c5d..5b19de42ac919 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -640,13 +640,13 @@ impl BitVec { /// let mut bv = BitVec::from_elem(3, true); /// bv.set(1, false); /// - /// assert_eq!(bv.to_bytes(), vec!(0b10100000)); + /// assert_eq!(bv.to_bytes(), [0b10100000]); /// /// let mut bv = BitVec::from_elem(9, false); /// bv.set(2, true); /// bv.set(8, true); /// - /// assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000)); + /// assert_eq!(bv.to_bytes(), [0b00100000, 0b10000000]); /// ``` pub fn to_bytes(&self) -> Vec { fn bit(bit_vec: &BitVec, byte: usize, bit: usize) -> u8 { @@ -806,7 +806,7 @@ impl BitVec { /// let mut bv = BitVec::from_bytes(&[0b01001011]); /// bv.grow(2, true); /// assert_eq!(bv.len(), 10); - /// assert_eq!(bv.to_bytes(), vec!(0b01001011, 0b11000000)); + /// assert_eq!(bv.to_bytes(), [0b01001011, 0b11000000]); /// ``` pub fn grow(&mut self, n: usize, value: bool) { // Note: we just bulk set all the bits in the last word in this fn in multiple places @@ -978,7 +978,7 @@ impl Ord for BitVec { impl fmt::Debug for BitVec { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { for bit in self { - try!(write!(fmt, "{}", if bit { 1u32 } else { 0u32 })); + try!(write!(fmt, "{}", if bit { 1 } else { 0 })); } Ok(()) } @@ -1752,7 +1752,7 @@ impl BitSet { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for BitSet { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - try!(write!(fmt, "BitSet {{")); + try!(write!(fmt, "{{")); let mut first = true; for n in self { if !first { @@ -2285,12 +2285,12 @@ mod tests { fn test_to_bytes() { let mut bv = BitVec::from_elem(3, true); bv.set(1, false); - assert_eq!(bv.to_bytes(), vec!(0b10100000)); + assert_eq!(bv.to_bytes(), [0b10100000]); let mut bv = BitVec::from_elem(9, false); bv.set(2, true); bv.set(8, true); - assert_eq!(bv.to_bytes(), vec!(0b00100000, 0b10000000)); + assert_eq!(bv.to_bytes(), [0b00100000, 0b10000000]); } #[test] @@ -2655,7 +2655,7 @@ mod bit_set_test { s.insert(10); s.insert(50); s.insert(2); - assert_eq!("BitSet {1, 2, 10, 50}", format!("{:?}", s)); + assert_eq!("{1, 2, 10, 50}", format!("{:?}", s)); } #[test] @@ -2675,7 +2675,7 @@ mod bit_set_test { let bit_vec: BitSet = usizes.into_iter().collect(); let idxs: Vec<_> = bit_vec.iter().collect(); - assert_eq!(idxs, vec![0, 2, 3]); + assert_eq!(idxs, [0, 2, 3]); let long: BitSet = (0..10000).filter(|&n| n % 2 == 0).collect(); let real: Vec<_> = range_step(0, 10000, 2).collect(); diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 1b456eec830b1..8a3a1fcb9f387 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -347,7 +347,7 @@ impl BTreeMap { let result = stack.with(move |pusher, node| { // Same basic logic as found in `find`, but with PartialSearchStack mediating the // actual nodes for us - return match Node::search(node, &key) { + match Node::search(node, &key) { Found(mut handle) => { // Perfect match, swap the values and return the old one mem::swap(handle.val_mut(), &mut value); @@ -372,7 +372,7 @@ impl BTreeMap { } }); match result { - Finished(ret) => { return ret; }, + Finished(ret) => return ret, Continue((new_stack, renewed_key, renewed_val)) => { stack = new_stack; key = renewed_key; @@ -439,7 +439,7 @@ impl BTreeMap { let mut stack = stack::PartialSearchStack::new(self); loop { let result = stack.with(move |pusher, node| { - return match Node::search(node, key) { + match Node::search(node, key) { Found(handle) => { // Perfect match. Terminate the stack here, and remove the entry Finished(Some(pusher.seal(handle).remove())) @@ -899,7 +899,7 @@ impl Ord for BTreeMap { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for BTreeMap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "BTreeMap {{")); + try!(write!(f, "{{")); for (i, (k, v)) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -1281,7 +1281,7 @@ impl BTreeMap { /// a.insert(2, "b"); /// /// let keys: Vec = a.keys().cloned().collect(); - /// assert_eq!(keys, vec![1,2,]); + /// assert_eq!(keys, [1, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { @@ -1303,7 +1303,7 @@ impl BTreeMap { /// a.insert(2, "b"); /// /// let values: Vec<&str> = a.values().cloned().collect(); - /// assert_eq!(values, vec!["a","b"]); + /// assert_eq!(values, ["a", "b"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn values<'a>(&'a self) -> Values<'a, K, V> { @@ -1560,7 +1560,7 @@ impl BTreeMap { let mut stack = stack::PartialSearchStack::new(self); loop { let result = stack.with(move |pusher, node| { - return match Node::search(node, &key) { + match Node::search(node, &key) { Found(handle) => { // Perfect match Finished(Occupied(OccupiedEntry { diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index f0fc12da7275e..b8703f6e7d935 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -1136,12 +1136,12 @@ impl Node { // This must be followed by insert_edge on an internal node. #[inline] unsafe fn insert_kv(&mut self, index: usize, key: K, val: V) -> &mut V { - ptr::copy_memory( + ptr::copy( self.keys_mut().as_mut_ptr().offset(index as isize + 1), self.keys().as_ptr().offset(index as isize), self.len() - index ); - ptr::copy_memory( + ptr::copy( self.vals_mut().as_mut_ptr().offset(index as isize + 1), self.vals().as_ptr().offset(index as isize), self.len() - index @@ -1158,7 +1158,7 @@ impl Node { // This can only be called immediately after a call to insert_kv. #[inline] unsafe fn insert_edge(&mut self, index: usize, edge: Node) { - ptr::copy_memory( + ptr::copy( self.edges_mut().as_mut_ptr().offset(index as isize + 1), self.edges().as_ptr().offset(index as isize), self.len() - index @@ -1191,12 +1191,12 @@ impl Node { let key = ptr::read(self.keys().get_unchecked(index)); let val = ptr::read(self.vals().get_unchecked(index)); - ptr::copy_memory( + ptr::copy( self.keys_mut().as_mut_ptr().offset(index as isize), self.keys().as_ptr().offset(index as isize + 1), self.len() - index - 1 ); - ptr::copy_memory( + ptr::copy( self.vals_mut().as_mut_ptr().offset(index as isize), self.vals().as_ptr().offset(index as isize + 1), self.len() - index - 1 @@ -1212,7 +1212,7 @@ impl Node { unsafe fn remove_edge(&mut self, index: usize) -> Node { let edge = ptr::read(self.edges().get_unchecked(index)); - ptr::copy_memory( + ptr::copy( self.edges_mut().as_mut_ptr().offset(index as isize), self.edges().as_ptr().offset(index as isize + 1), self.len() - index + 1 @@ -1239,18 +1239,18 @@ impl Node { unsafe { right._len = self.len() / 2; let right_offset = self.len() - right.len(); - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( right.keys_mut().as_mut_ptr(), self.keys().as_ptr().offset(right_offset as isize), right.len() ); - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( right.vals_mut().as_mut_ptr(), self.vals().as_ptr().offset(right_offset as isize), right.len() ); if !self.is_leaf() { - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( right.edges_mut().as_mut_ptr(), self.edges().as_ptr().offset(right_offset as isize), right.len() + 1 @@ -1280,18 +1280,18 @@ impl Node { ptr::write(self.keys_mut().get_unchecked_mut(old_len), key); ptr::write(self.vals_mut().get_unchecked_mut(old_len), val); - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( self.keys_mut().as_mut_ptr().offset(old_len as isize + 1), right.keys().as_ptr(), right.len() ); - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( self.vals_mut().as_mut_ptr().offset(old_len as isize + 1), right.vals().as_ptr(), right.len() ); if !self.is_leaf() { - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( self.edges_mut().as_mut_ptr().offset(old_len as isize + 1), right.edges().as_ptr(), right.len() + 1 diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 929b2f5804303..bc2e68b999a55 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -121,7 +121,7 @@ impl BTreeSet { /// } /// /// let v: Vec = set.iter().cloned().collect(); - /// assert_eq!(v, vec![1,2,3,4]); + /// assert_eq!(v, [1, 2, 3, 4]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn iter(&self) -> Iter { @@ -138,7 +138,7 @@ impl BTreeSet { /// let set: BTreeSet = [1, 2, 3, 4].iter().cloned().collect(); /// /// let v: Vec = set.into_iter().collect(); - /// assert_eq!(v, vec![1,2,3,4]); + /// assert_eq!(v, [1, 2, 3, 4]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn into_iter(self) -> IntoIter { @@ -197,7 +197,7 @@ impl BTreeSet { /// b.insert(3); /// /// let diff: Vec = a.difference(&b).cloned().collect(); - /// assert_eq!(diff, vec![1]); + /// assert_eq!(diff, [1]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn difference<'a>(&'a self, other: &'a BTreeSet) -> Difference<'a, T> { @@ -220,7 +220,7 @@ impl BTreeSet { /// b.insert(3); /// /// let sym_diff: Vec = a.symmetric_difference(&b).cloned().collect(); - /// assert_eq!(sym_diff, vec![1,3]); + /// assert_eq!(sym_diff, [1, 3]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn symmetric_difference<'a>(&'a self, other: &'a BTreeSet) @@ -244,7 +244,7 @@ impl BTreeSet { /// b.insert(3); /// /// let intersection: Vec = a.intersection(&b).cloned().collect(); - /// assert_eq!(intersection, vec![2]); + /// assert_eq!(intersection, [2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn intersection<'a>(&'a self, other: &'a BTreeSet) @@ -266,7 +266,7 @@ impl BTreeSet { /// b.insert(2); /// /// let union: Vec = a.union(&b).cloned().collect(); - /// assert_eq!(union, vec![1,2]); + /// assert_eq!(union, [1, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn union<'a>(&'a self, other: &'a BTreeSet) -> Union<'a, T> { @@ -534,7 +534,7 @@ impl<'a, 'b, T: Ord + Clone> Sub<&'b BTreeSet> for &'a BTreeSet { /// /// let result = &a - &b; /// let result_vec: Vec<_> = result.into_iter().collect(); - /// assert_eq!(result_vec, vec![1, 2]); + /// assert_eq!(result_vec, [1, 2]); /// ``` fn sub(self, rhs: &BTreeSet) -> BTreeSet { self.difference(rhs).cloned().collect() @@ -557,7 +557,7 @@ impl<'a, 'b, T: Ord + Clone> BitXor<&'b BTreeSet> for &'a BTreeSet { /// /// let result = &a ^ &b; /// let result_vec: Vec<_> = result.into_iter().collect(); - /// assert_eq!(result_vec, vec![1, 4]); + /// assert_eq!(result_vec, [1, 4]); /// ``` fn bitxor(self, rhs: &BTreeSet) -> BTreeSet { self.symmetric_difference(rhs).cloned().collect() @@ -580,7 +580,7 @@ impl<'a, 'b, T: Ord + Clone> BitAnd<&'b BTreeSet> for &'a BTreeSet { /// /// let result = &a & &b; /// let result_vec: Vec<_> = result.into_iter().collect(); - /// assert_eq!(result_vec, vec![2, 3]); + /// assert_eq!(result_vec, [2, 3]); /// ``` fn bitand(self, rhs: &BTreeSet) -> BTreeSet { self.intersection(rhs).cloned().collect() @@ -603,7 +603,7 @@ impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet> for &'a BTreeSet { /// /// let result = &a | &b; /// let result_vec: Vec<_> = result.into_iter().collect(); - /// assert_eq!(result_vec, vec![1, 2, 3, 4, 5]); + /// assert_eq!(result_vec, [1, 2, 3, 4, 5]); /// ``` fn bitor(self, rhs: &BTreeSet) -> BTreeSet { self.union(rhs).cloned().collect() @@ -613,7 +613,7 @@ impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet> for &'a BTreeSet { #[stable(feature = "rust1", since = "1.0.0")] impl Debug for BTreeSet { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "BTreeSet {{")); + try!(write!(f, "{{")); for (i, x) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -911,7 +911,7 @@ mod test { let set_str = format!("{:?}", set); - assert_eq!(set_str, "BTreeSet {1, 2}"); - assert_eq!(format!("{:?}", empty), "BTreeSet {}"); + assert_eq!(set_str, "{1, 2}"); + assert_eq!(format!("{:?}", empty), "{}"); } } diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index 0c95742606083..62dd91915211b 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -36,7 +36,7 @@ impl Copy for EnumSet {} #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for EnumSet { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - try!(write!(fmt, "EnumSet {{")); + try!(write!(fmt, "{{")); let mut first = true; for e in self { if !first { @@ -314,11 +314,11 @@ mod test { #[test] fn test_show() { let mut e = EnumSet::new(); - assert!(format!("{:?}", e) == "EnumSet {}"); + assert!(format!("{:?}", e) == "{}"); e.insert(A); - assert!(format!("{:?}", e) == "EnumSet {A}"); + assert!(format!("{:?}", e) == "{A}"); e.insert(C); - assert!(format!("{:?}", e) == "EnumSet {A, C}"); + assert!(format!("{:?}", e) == "{A, C}"); } #[test] @@ -428,19 +428,19 @@ mod test { e1.insert(A); let elems: ::vec::Vec<_> = e1.iter().collect(); - assert_eq!(vec![A], elems); + assert_eq!([A], elems); e1.insert(C); let elems: ::vec::Vec<_> = e1.iter().collect(); - assert_eq!(vec![A,C], elems); + assert_eq!([A,C], elems); e1.insert(C); let elems: ::vec::Vec<_> = e1.iter().collect(); - assert_eq!(vec![A,C], elems); + assert_eq!([A,C], elems); e1.insert(B); let elems: ::vec::Vec<_> = e1.iter().collect(); - assert_eq!(vec![A,B,C], elems); + assert_eq!([A,B,C], elems); } /////////////////////////////////////////////////////////////////////////// @@ -458,35 +458,35 @@ mod test { let e_union = e1 | e2; let elems: ::vec::Vec<_> = e_union.iter().collect(); - assert_eq!(vec![A,B,C], elems); + assert_eq!([A,B,C], elems); let e_intersection = e1 & e2; let elems: ::vec::Vec<_> = e_intersection.iter().collect(); - assert_eq!(vec![C], elems); + assert_eq!([C], elems); // Another way to express intersection let e_intersection = e1 - (e1 - e2); let elems: ::vec::Vec<_> = e_intersection.iter().collect(); - assert_eq!(vec![C], elems); + assert_eq!([C], elems); let e_subtract = e1 - e2; let elems: ::vec::Vec<_> = e_subtract.iter().collect(); - assert_eq!(vec![A], elems); + assert_eq!([A], elems); // Bitwise XOR of two sets, aka symmetric difference let e_symmetric_diff = e1 ^ e2; let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect(); - assert_eq!(vec![A,B], elems); + assert_eq!([A,B], elems); // Another way to express symmetric difference let e_symmetric_diff = (e1 - e2) | (e2 - e1); let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect(); - assert_eq!(vec![A,B], elems); + assert_eq!([A,B], elems); // Yet another way to express symmetric difference let e_symmetric_diff = (e1 | e2) - (e1 & e2); let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect(); - assert_eq!(vec![A,B], elems); + assert_eq!([A,B], elems); } #[test] diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 1f3c54a4cb53f..7b66bfee34f21 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -30,6 +30,7 @@ #![feature(unboxed_closures)] #![feature(unicode)] #![feature(unsafe_destructor)] +#![feature(unique)] #![feature(unsafe_no_drop_flag)] #![cfg_attr(test, feature(rand, rustc_private, test))] #![cfg_attr(test, allow(deprecated))] // rand diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index 3c61fc3da90e3..3d68bb13db8e9 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -777,7 +777,7 @@ impl<'a, A> IterMut<'a, A> { /// } /// { /// let vec: Vec<_> = list.into_iter().collect(); - /// assert_eq!(vec, vec![1, 2, 3, 4]); + /// assert_eq!(vec, [1, 2, 3, 4]); /// } /// ``` #[inline] @@ -918,7 +918,7 @@ impl Clone for LinkedList { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for LinkedList { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "LinkedList [")); + try!(write!(f, "[")); for (i, e) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -1273,7 +1273,7 @@ mod tests { } check_links(&m); assert_eq!(m.len(), 3 + len * 2); - assert_eq!(m.into_iter().collect::>(), vec![-2,0,1,2,3,4,5,6,7,8,9,0,1]); + assert_eq!(m.into_iter().collect::>(), [-2,0,1,2,3,4,5,6,7,8,9,0,1]); } #[test] @@ -1387,10 +1387,10 @@ mod tests { #[test] fn test_show() { let list: LinkedList<_> = (0..10).collect(); - assert_eq!(format!("{:?}", list), "LinkedList [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); + assert_eq!(format!("{:?}", list), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); let list: LinkedList<_> = vec!["just", "one", "test", "more"].iter().cloned().collect(); - assert_eq!(format!("{:?}", list), "LinkedList [\"just\", \"one\", \"test\", \"more\"]"); + assert_eq!(format!("{:?}", list), "[\"just\", \"one\", \"test\", \"more\"]"); } #[cfg(test)] diff --git a/src/libcollections/macros.rs b/src/libcollections/macros.rs index ebcfb8d1cf84e..e9764547628c0 100644 --- a/src/libcollections/macros.rs +++ b/src/libcollections/macros.rs @@ -26,7 +26,7 @@ /// /// ``` /// let v = vec![1; 3]; -/// assert_eq!(v, vec![1, 1, 1]); +/// assert_eq!(v, [1, 1, 1]); /// ``` /// /// Note that unlike array expressions this syntax supports all elements diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 4b2b125fc99f2..d4c5373968614 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1331,12 +1331,10 @@ fn insertion_sort(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> O if i != j { let tmp = ptr::read(read_ptr); - ptr::copy_memory(buf_v.offset(j + 1), - &*buf_v.offset(j), - (i - j) as usize); - ptr::copy_nonoverlapping_memory(buf_v.offset(j), - &tmp, - 1); + ptr::copy(buf_v.offset(j + 1), + &*buf_v.offset(j), + (i - j) as usize); + ptr::copy_nonoverlapping(buf_v.offset(j), &tmp, 1); mem::forget(tmp); } } @@ -1409,10 +1407,10 @@ fn merge_sort(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order // j + 1 could be `len` (for the last `i`), but in // that case, `i == j` so we don't copy. The // `.offset(j)` is always in bounds. - ptr::copy_memory(buf_dat.offset(j + 1), - &*buf_dat.offset(j), - i - j as usize); - ptr::copy_nonoverlapping_memory(buf_dat.offset(j), read_ptr, 1); + ptr::copy(buf_dat.offset(j + 1), + &*buf_dat.offset(j), + i - j as usize); + ptr::copy_nonoverlapping(buf_dat.offset(j), read_ptr, 1); } } } @@ -1460,11 +1458,11 @@ fn merge_sort(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order if left == right_start { // the number remaining in this run. let elems = (right_end as usize - right as usize) / mem::size_of::(); - ptr::copy_nonoverlapping_memory(out, &*right, elems); + ptr::copy_nonoverlapping(out, &*right, elems); break; } else if right == right_end { let elems = (right_start as usize - left as usize) / mem::size_of::(); - ptr::copy_nonoverlapping_memory(out, &*left, elems); + ptr::copy_nonoverlapping(out, &*left, elems); break; } @@ -1478,7 +1476,7 @@ fn merge_sort(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order } else { step(&mut left) }; - ptr::copy_nonoverlapping_memory(out, &*to_copy, 1); + ptr::copy_nonoverlapping(out, &*to_copy, 1); step(&mut out); } } @@ -1492,7 +1490,7 @@ fn merge_sort(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order // write the result to `v` in one go, so that there are never two copies // of the same object in `v`. unsafe { - ptr::copy_nonoverlapping_memory(v.as_mut_ptr(), &*buf_dat, len); + ptr::copy_nonoverlapping(v.as_mut_ptr(), &*buf_dat, len); } // increment the pointer, returning the old pointer. @@ -1779,10 +1777,10 @@ mod tests { let mut v = vec![1, 2, 3, 4, 5]; let mut e = v.swap_remove(0); assert_eq!(e, 1); - assert_eq!(v, vec![5, 2, 3, 4]); + assert_eq!(v, [5, 2, 3, 4]); e = v.swap_remove(3); assert_eq!(e, 4); - assert_eq!(v, vec![5, 2, 3]); + assert_eq!(v, [5, 2, 3]); } #[test] @@ -1890,7 +1888,7 @@ mod tests { fn test_retain() { let mut v = vec![1, 2, 3, 4, 5]; v.retain(is_odd); - assert_eq!(v, vec![1, 3, 5]); + assert_eq!(v, [1, 3, 5]); } #[test] @@ -2159,45 +2157,45 @@ mod tests { let v: [Vec; 0] = []; let c = v.concat(); assert_eq!(c, []); - let d = [vec![1], vec![2,3]].concat(); - assert_eq!(d, vec![1, 2, 3]); + let d = [vec![1], vec![2, 3]].concat(); + assert_eq!(d, [1, 2, 3]); let v: &[&[_]] = &[&[1], &[2, 3]]; - assert_eq!(v.connect(&0), vec![1, 0, 2, 3]); + assert_eq!(v.connect(&0), [1, 0, 2, 3]); let v: &[&[_]] = &[&[1], &[2], &[3]]; - assert_eq!(v.connect(&0), vec![1, 0, 2, 0, 3]); + assert_eq!(v.connect(&0), [1, 0, 2, 0, 3]); } #[test] fn test_connect() { let v: [Vec; 0] = []; - assert_eq!(v.connect(&0), vec![]); - assert_eq!([vec![1], vec![2, 3]].connect(&0), vec![1, 0, 2, 3]); - assert_eq!([vec![1], vec![2], vec![3]].connect(&0), vec![1, 0, 2, 0, 3]); + assert_eq!(v.connect(&0), []); + assert_eq!([vec![1i], vec![2, 3]].connect(&0), [1, 0, 2, 3]); + assert_eq!([vec![1i], vec![2], vec![3]].connect(&0), [1, 0, 2, 0, 3]); let v: [&[_]; 2] = [&[1], &[2, 3]]; - assert_eq!(v.connect(&0), vec![1, 0, 2, 3]); + assert_eq!(v.connect(&0), [1, 0, 2, 3]); let v: [&[_]; 3] = [&[1], &[2], &[3]]; - assert_eq!(v.connect(&0), vec![1, 0, 2, 0, 3]); + assert_eq!(v.connect(&0), [1, 0, 2, 0, 3]); } #[test] fn test_insert() { let mut a = vec![1, 2, 4]; a.insert(2, 3); - assert_eq!(a, vec![1, 2, 3, 4]); + assert_eq!(a, [1, 2, 3, 4]); let mut a = vec![1, 2, 3]; a.insert(0, 0); - assert_eq!(a, vec![0, 1, 2, 3]); + assert_eq!(a, [0, 1, 2, 3]); let mut a = vec![1, 2, 3]; a.insert(3, 4); - assert_eq!(a, vec![1, 2, 3, 4]); + assert_eq!(a, [1, 2, 3, 4]); let mut a = vec![]; a.insert(0, 1); - assert_eq!(a, vec![1]); + assert_eq!(a, [1]); } #[test] @@ -2212,16 +2210,16 @@ mod tests { let mut a = vec![1, 2, 3, 4]; assert_eq!(a.remove(2), 3); - assert_eq!(a, vec![1, 2, 4]); + assert_eq!(a, [1, 2, 4]); assert_eq!(a.remove(2), 4); - assert_eq!(a, vec![1, 2]); + assert_eq!(a, [1, 2]); assert_eq!(a.remove(0), 1); - assert_eq!(a, vec![2]); + assert_eq!(a, [2]); assert_eq!(a.remove(0), 2); - assert_eq!(a, vec![]); + assert_eq!(a, []); } #[test] diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index f3b2e9738979c..c58cca828d8c3 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -552,7 +552,7 @@ pub trait StrExt: Index { /// ``` /// let v: Vec = "abc åäö".chars().collect(); /// - /// assert_eq!(v, vec!['a', 'b', 'c', ' ', 'å', 'ä', 'ö']); + /// assert_eq!(v, ['a', 'b', 'c', ' ', 'å', 'ä', 'ö']); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn chars(&self) -> Chars { @@ -600,20 +600,20 @@ pub trait StrExt: Index { /// /// ``` /// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect(); - /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]); + /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]); /// /// let v: Vec<&str> = "".split('X').collect(); - /// assert_eq!(v, vec![""]); + /// assert_eq!(v, [""]); /// ``` /// /// More complex patterns with a lambda: /// /// ``` /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect(); - /// assert_eq!(v, vec!["abc", "def", "ghi"]); + /// assert_eq!(v, ["abc", "def", "ghi"]); /// /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect(); - /// assert_eq!(v, vec!["lion", "", "tiger", "leopard"]); + /// assert_eq!(v, ["lion", "", "tiger", "leopard"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> { @@ -632,23 +632,23 @@ pub trait StrExt: Index { /// /// ``` /// let v: Vec<&str> = "Mary had a little lambda".splitn(2, ' ').collect(); - /// assert_eq!(v, vec!["Mary", "had", "a little lambda"]); + /// assert_eq!(v, ["Mary", "had", "a little lambda"]); /// /// let v: Vec<&str> = "lionXXtigerXleopard".splitn(2, 'X').collect(); - /// assert_eq!(v, vec!["lion", "", "tigerXleopard"]); + /// assert_eq!(v, ["lion", "", "tigerXleopard"]); /// /// let v: Vec<&str> = "abcXdef".splitn(0, 'X').collect(); - /// assert_eq!(v, vec!["abcXdef"]); + /// assert_eq!(v, ["abcXdef"]); /// /// let v: Vec<&str> = "".splitn(1, 'X').collect(); - /// assert_eq!(v, vec![""]); + /// assert_eq!(v, [""]); /// ``` /// /// More complex patterns with a lambda: /// /// ``` /// let v: Vec<&str> = "abc1def2ghi".splitn(1, |c: char| c.is_numeric()).collect(); - /// assert_eq!(v, vec!["abc", "def2ghi"]); + /// assert_eq!(v, ["abc", "def2ghi"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P> { @@ -669,17 +669,17 @@ pub trait StrExt: Index { /// /// ``` /// let v: Vec<&str> = "A.B.".split_terminator('.').collect(); - /// assert_eq!(v, vec!["A", "B"]); + /// assert_eq!(v, ["A", "B"]); /// /// let v: Vec<&str> = "A..B..".split_terminator('.').collect(); - /// assert_eq!(v, vec!["A", "", "B", ""]); + /// assert_eq!(v, ["A", "", "B", ""]); /// ``` /// /// More complex patterns with a lambda: /// /// ``` /// let v: Vec<&str> = "abc1def2ghi3".split_terminator(|c: char| c.is_numeric()).collect(); - /// assert_eq!(v, vec!["abc", "def", "ghi"]); + /// assert_eq!(v, ["abc", "def", "ghi"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> { @@ -699,17 +699,17 @@ pub trait StrExt: Index { /// /// ``` /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(2, ' ').collect(); - /// assert_eq!(v, vec!["lamb", "little", "Mary had a"]); + /// assert_eq!(v, ["lamb", "little", "Mary had a"]); /// /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(2, 'X').collect(); - /// assert_eq!(v, vec!["leopard", "tiger", "lionX"]); + /// assert_eq!(v, ["leopard", "tiger", "lionX"]); /// ``` /// /// More complex patterns with a lambda: /// /// ``` /// let v: Vec<&str> = "abc1def2ghi".rsplitn(1, |c: char| c.is_numeric()).collect(); - /// assert_eq!(v, vec!["ghi", "abc1def"]); + /// assert_eq!(v, ["ghi", "abc1def"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P> { @@ -727,13 +727,13 @@ pub trait StrExt: Index { /// /// ``` /// let v: Vec<(usize, usize)> = "abcXXXabcYYYabc".match_indices("abc").collect(); - /// assert_eq!(v, vec![(0,3), (6,9), (12,15)]); + /// assert_eq!(v, [(0,3), (6,9), (12,15)]); /// /// let v: Vec<(usize, usize)> = "1abcabc2".match_indices("abc").collect(); - /// assert_eq!(v, vec![(1,4), (4,7)]); + /// assert_eq!(v, [(1,4), (4,7)]); /// /// let v: Vec<(usize, usize)> = "ababa".match_indices("aba").collect(); - /// assert_eq!(v, vec![(0, 3)]); // only the first `aba` + /// assert_eq!(v, [(0, 3)]); // only the first `aba` /// ``` #[unstable(feature = "collections", reason = "might have its iterator type changed")] @@ -749,10 +749,10 @@ pub trait StrExt: Index { /// /// ``` /// let v: Vec<&str> = "abcXXXabcYYYabc".split_str("abc").collect(); - /// assert_eq!(v, vec!["", "XXX", "YYY", ""]); + /// assert_eq!(v, ["", "XXX", "YYY", ""]); /// /// let v: Vec<&str> = "1abcabc2".split_str("abc").collect(); - /// assert_eq!(v, vec!["1", "", "2"]); + /// assert_eq!(v, ["1", "", "2"]); /// ``` #[unstable(feature = "collections")] #[deprecated(since = "1.0.0", reason = "use `split()` with a `&str`")] @@ -770,7 +770,7 @@ pub trait StrExt: Index { /// let four_lines = "foo\nbar\n\nbaz"; /// let v: Vec<&str> = four_lines.lines().collect(); /// - /// assert_eq!(v, vec!["foo", "bar", "", "baz"]); + /// assert_eq!(v, ["foo", "bar", "", "baz"]); /// ``` /// /// Leaving off the trailing character: @@ -779,7 +779,7 @@ pub trait StrExt: Index { /// let four_lines = "foo\nbar\n\nbaz\n"; /// let v: Vec<&str> = four_lines.lines().collect(); /// - /// assert_eq!(v, vec!["foo", "bar", "", "baz"]); + /// assert_eq!(v, ["foo", "bar", "", "baz"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn lines(&self) -> Lines { @@ -796,7 +796,7 @@ pub trait StrExt: Index { /// let four_lines = "foo\r\nbar\n\r\nbaz"; /// let v: Vec<&str> = four_lines.lines_any().collect(); /// - /// assert_eq!(v, vec!["foo", "bar", "", "baz"]); + /// assert_eq!(v, ["foo", "bar", "", "baz"]); /// ``` /// /// Leaving off the trailing character: @@ -805,7 +805,7 @@ pub trait StrExt: Index { /// let four_lines = "foo\r\nbar\n\r\nbaz\n"; /// let v: Vec<&str> = four_lines.lines_any().collect(); /// - /// assert_eq!(v, vec!["foo", "bar", "", "baz"]); + /// assert_eq!(v, ["foo", "bar", "", "baz"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn lines_any(&self) -> LinesAny { @@ -1441,7 +1441,7 @@ pub trait StrExt: Index { /// let some_words = " Mary had\ta little \n\t lamb"; /// let v: Vec<&str> = some_words.words().collect(); /// - /// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]); + /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]); /// ``` #[unstable(feature = "str_words", reason = "the precise algorithm to use is unclear")] @@ -2400,17 +2400,17 @@ mod tests { let data = "\nMäry häd ä little lämb\nLittle lämb\n"; let split: Vec<&str> = data.splitn(3, ' ').collect(); - assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]); + assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]); let split: Vec<&str> = data.splitn(3, |c: char| c == ' ').collect(); - assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]); + assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]); // Unicode let split: Vec<&str> = data.splitn(3, 'ä').collect(); - assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); + assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); let split: Vec<&str> = data.splitn(3, |c: char| c == 'ä').collect(); - assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); + assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]); } #[test] @@ -2418,17 +2418,17 @@ mod tests { let data = "\nMäry häd ä little lämb\nLittle lämb\n"; let split: Vec<&str> = data.split('\n').collect(); - assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb", ""]); + assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]); let split: Vec<&str> = data.split_terminator('\n').collect(); - assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]); + assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]); } #[test] fn test_words() { let data = "\n \tMäry häd\tä little lämb\nLittle lämb\n"; let words: Vec<&str> = data.words().collect(); - assert_eq!(words, vec!["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"]) + assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"]) } #[test] @@ -2513,11 +2513,11 @@ mod tests { fn test_lines() { let data = "\nMäry häd ä little lämb\n\nLittle lämb\n"; let lines: Vec<&str> = data.lines().collect(); - assert_eq!(lines, vec!["", "Märy häd ä little lämb", "", "Little lämb"]); + assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]); let data = "\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n let lines: Vec<&str> = data.lines().collect(); - assert_eq!(lines, vec!["", "Märy häd ä little lämb", "", "Little lämb"]); + assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]); } #[test] diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 6c2624cd204de..94abffa3db61c 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -120,7 +120,7 @@ impl String { /// let invalid_vec = vec![240, 144, 128]; /// let s = String::from_utf8(invalid_vec).err().unwrap(); /// assert_eq!(s.utf8_error(), Utf8Error::TooShort); - /// assert_eq!(s.into_bytes(), vec![240, 144, 128]); + /// assert_eq!(s.into_bytes(), [240, 144, 128]); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -340,7 +340,7 @@ impl String { /// ``` /// let s = String::from_str("hello"); /// let bytes = s.into_bytes(); - /// assert_eq!(bytes, vec![104, 101, 108, 108, 111]); + /// assert_eq!(bytes, [104, 101, 108, 108, 111]); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -568,9 +568,9 @@ impl String { let CharRange { ch, next } = self.char_range_at(idx); unsafe { - ptr::copy_memory(self.vec.as_mut_ptr().offset(idx as isize), - self.vec.as_ptr().offset(next as isize), - len - next); + ptr::copy(self.vec.as_mut_ptr().offset(idx as isize), + self.vec.as_ptr().offset(next as isize), + len - next); self.vec.set_len(len - (next - idx)); } ch @@ -598,12 +598,12 @@ impl String { let amt = ch.encode_utf8(&mut bits).unwrap(); unsafe { - ptr::copy_memory(self.vec.as_mut_ptr().offset((idx + amt) as isize), - self.vec.as_ptr().offset(idx as isize), - len - idx); - ptr::copy_memory(self.vec.as_mut_ptr().offset(idx as isize), - bits.as_ptr(), - amt); + ptr::copy(self.vec.as_mut_ptr().offset((idx + amt) as isize), + self.vec.as_ptr().offset(idx as isize), + len - idx); + ptr::copy(self.vec.as_mut_ptr().offset(idx as isize), + bits.as_ptr(), + amt); self.vec.set_len(len + amt); } } @@ -619,7 +619,7 @@ impl String { /// let mut s = String::from_str("hello"); /// unsafe { /// let vec = s.as_mut_vec(); - /// assert!(vec == &mut vec![104, 101, 108, 108, 111]); + /// assert!(vec == &[104, 101, 108, 108, 111]); /// vec.reverse(); /// } /// assert_eq!(s.as_slice(), "olleh"); diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 3f5f92889166f..6d4541b5bde16 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -93,7 +93,7 @@ use borrow::{Cow, IntoCow}; /// for x in vec.iter() { /// println!("{}", x); /// } -/// assert_eq!(vec, vec![7, 1, 2, 3]); +/// assert_eq!(vec, [7, 1, 2, 3]); /// ``` /// /// The `vec!` macro is provided to make initialization more convenient: @@ -101,7 +101,7 @@ use borrow::{Cow, IntoCow}; /// ``` /// let mut vec = vec![1, 2, 3]; /// vec.push(4); -/// assert_eq!(vec, vec![1, 2, 3, 4]); +/// assert_eq!(vec, [1, 2, 3, 4]); /// ``` /// /// Use a `Vec` as an efficient stack: @@ -242,7 +242,7 @@ impl Vec { /// /// // Put everything back together into a Vec /// let rebuilt = Vec::from_raw_parts(p, len, cap); - /// assert_eq!(rebuilt, vec![4, 5, 6]); + /// assert_eq!(rebuilt, [4, 5, 6]); /// } /// } /// ``` @@ -267,7 +267,7 @@ impl Vec { pub unsafe fn from_raw_buf(ptr: *const T, elts: usize) -> Vec { let mut dst = Vec::with_capacity(elts); dst.set_len(elts); - ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(), ptr, elts); + ptr::copy_nonoverlapping(dst.as_mut_ptr(), ptr, elts); dst } @@ -404,7 +404,7 @@ impl Vec { /// ``` /// let mut vec = vec![1, 2, 3, 4]; /// vec.truncate(2); - /// assert_eq!(vec, vec![1, 2]); + /// assert_eq!(vec, [1, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn truncate(&mut self, len: usize) { @@ -505,10 +505,10 @@ impl Vec { /// let mut v = vec!["foo", "bar", "baz", "qux"]; /// /// assert_eq!(v.swap_remove(1), "bar"); - /// assert_eq!(v, vec!["foo", "qux", "baz"]); + /// assert_eq!(v, ["foo", "qux", "baz"]); /// /// assert_eq!(v.swap_remove(0), "foo"); - /// assert_eq!(v, vec!["baz", "qux"]); + /// assert_eq!(v, ["baz", "qux"]); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -531,9 +531,9 @@ impl Vec { /// ``` /// let mut vec = vec![1, 2, 3]; /// vec.insert(1, 4); - /// assert_eq!(vec, vec![1, 4, 2, 3]); + /// assert_eq!(vec, [1, 4, 2, 3]); /// vec.insert(4, 5); - /// assert_eq!(vec, vec![1, 4, 2, 3, 5]); + /// assert_eq!(vec, [1, 4, 2, 3, 5]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn insert(&mut self, index: usize, element: T) { @@ -548,7 +548,7 @@ impl Vec { let p = self.as_mut_ptr().offset(index as isize); // Shift everything over to make space. (Duplicating the // `index`th element into two consecutive places.) - ptr::copy_memory(p.offset(1), &*p, len - index); + ptr::copy(p.offset(1), &*p, len - index); // Write it in, overwriting the first copy of the `index`th // element. ptr::write(&mut *p, element); @@ -569,7 +569,7 @@ impl Vec { /// ``` /// let mut v = vec![1, 2, 3]; /// assert_eq!(v.remove(1), 2); - /// assert_eq!(v, vec![1, 3]); + /// assert_eq!(v, [1, 3]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove(&mut self, index: usize) -> T { @@ -585,7 +585,7 @@ impl Vec { ret = ptr::read(ptr); // Shift everything down to fill in that spot. - ptr::copy_memory(ptr, &*ptr.offset(1), len - index - 1); + ptr::copy(ptr, &*ptr.offset(1), len - index - 1); } self.set_len(len - 1); ret @@ -603,7 +603,7 @@ impl Vec { /// ``` /// let mut vec = vec![1, 2, 3, 4]; /// vec.retain(|&x| x%2 == 0); - /// assert_eq!(vec, vec![2, 4]); + /// assert_eq!(vec, [2, 4]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn retain(&mut self, mut f: F) where F: FnMut(&T) -> bool { @@ -636,7 +636,7 @@ impl Vec { /// ```rust /// let mut vec = vec!(1, 2); /// vec.push(3); - /// assert_eq!(vec, vec!(1, 2, 3)); + /// assert_eq!(vec, [1, 2, 3]); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -674,7 +674,7 @@ impl Vec { /// ```rust /// let mut vec = vec![1, 2, 3]; /// assert_eq!(vec.pop(), Some(3)); - /// assert_eq!(vec, vec![1, 2]); + /// assert_eq!(vec, [1, 2]); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -701,8 +701,8 @@ impl Vec { /// let mut vec = vec![1, 2, 3]; /// let mut vec2 = vec![4, 5, 6]; /// vec.append(&mut vec2); - /// assert_eq!(vec, vec![1, 2, 3, 4, 5, 6]); - /// assert_eq!(vec2, vec![]); + /// assert_eq!(vec, [1, 2, 3, 4, 5, 6]); + /// assert_eq!(vec2, []); /// ``` #[inline] #[unstable(feature = "collections", @@ -718,7 +718,7 @@ impl Vec { self.reserve(other.len()); let len = self.len(); unsafe { - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( self.get_unchecked_mut(len), other.as_ptr(), other.len()); @@ -1019,8 +1019,8 @@ impl Vec { /// ``` /// let mut vec = vec![1,2,3]; /// let vec2 = vec.split_off(1); - /// assert_eq!(vec, vec![1]); - /// assert_eq!(vec2, vec![2, 3]); + /// assert_eq!(vec, [1]); + /// assert_eq!(vec2, [2, 3]); /// ``` #[inline] #[unstable(feature = "collections", @@ -1036,7 +1036,7 @@ impl Vec { self.set_len(at); other.set_len(other_len); - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( other.as_mut_ptr(), self.as_ptr().offset(at as isize), other.len()); @@ -1057,11 +1057,11 @@ impl Vec { /// ``` /// let mut vec = vec!["hello"]; /// vec.resize(3, "world"); - /// assert_eq!(vec, vec!["hello", "world", "world"]); + /// assert_eq!(vec, ["hello", "world", "world"]); /// /// let mut vec = vec![1, 2, 3, 4]; /// vec.resize(2, 0); - /// assert_eq!(vec, vec![1, 2]); + /// assert_eq!(vec, [1, 2]); /// ``` #[unstable(feature = "collections", reason = "matches collection reform specification; waiting for dust to settle")] @@ -1085,7 +1085,7 @@ impl Vec { /// ``` /// let mut vec = vec![1]; /// vec.push_all(&[2, 3, 4]); - /// assert_eq!(vec, vec![1, 2, 3, 4]); + /// assert_eq!(vec, [1, 2, 3, 4]); /// ``` #[inline] #[unstable(feature = "collections", @@ -1121,7 +1121,7 @@ impl Vec { /// /// vec.dedup(); /// - /// assert_eq!(vec, vec![1, 2, 3, 2]); + /// assert_eq!(vec, [1, 2, 3, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn dedup(&mut self) { @@ -2105,7 +2105,7 @@ mod tests { } } - assert!(values == vec![2, 3, 5, 6, 7]); + assert_eq!(values, [2, 3, 5, 6, 7]); } #[test] @@ -2147,7 +2147,7 @@ mod tests { fn test_retain() { let mut vec = vec![1, 2, 3, 4]; vec.retain(|&x| x % 2 == 0); - assert!(vec == vec![2, 4]); + assert_eq!(vec, [2, 4]); } #[test] @@ -2207,13 +2207,13 @@ mod tests { let a = [1, 2, 3]; let ptr = a.as_ptr(); let b = Vec::from_raw_buf(ptr, 3); - assert_eq!(b, vec![1, 2, 3]); + assert_eq!(b, [1, 2, 3]); // Test on-heap copy-from-buf. let c = vec![1, 2, 3, 4, 5]; let ptr = c.as_ptr(); let d = Vec::from_raw_buf(ptr, 5); - assert_eq!(d, vec![1, 2, 3, 4, 5]); + assert_eq!(d, [1, 2, 3, 4, 5]); } } @@ -2375,7 +2375,7 @@ mod tests { for i in vec { vec2.push(i); } - assert!(vec2 == vec![1, 2, 3]); + assert_eq!(vec2, [1, 2, 3]); } #[test] @@ -2385,7 +2385,7 @@ mod tests { for i in vec.into_iter().rev() { vec2.push(i); } - assert!(vec2 == vec![3, 2, 1]); + assert_eq!(vec2, [3, 2, 1]); } #[test] @@ -2395,7 +2395,7 @@ mod tests { for i in vec { vec2.push(i); } - assert!(vec2 == vec![(), (), ()]); + assert_eq!(vec2, [(), (), ()]); } #[test] @@ -2443,16 +2443,16 @@ mod tests { let mut vec = vec![1, 2, 3]; let mut vec2 = vec![4, 5, 6]; vec.append(&mut vec2); - assert_eq!(vec, vec![1, 2, 3, 4, 5, 6]); - assert_eq!(vec2, vec![]); + assert_eq!(vec, [1, 2, 3, 4, 5, 6]); + assert_eq!(vec2, []); } #[test] fn test_split_off() { let mut vec = vec![1, 2, 3, 4, 5, 6]; let vec2 = vec.split_off(4); - assert_eq!(vec, vec![1, 2, 3, 4]); - assert_eq!(vec2, vec![5, 6]); + assert_eq!(vec, [1, 2, 3, 4]); + assert_eq!(vec2, [5, 6]); } #[bench] diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index f65e644fa5284..e99d44551d536 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -134,7 +134,7 @@ impl VecDeque { self.cap); debug_assert!(src + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len, self.cap); - ptr::copy_memory( + ptr::copy( self.ptr.offset(dst as isize), self.ptr.offset(src as isize), len); @@ -147,7 +147,7 @@ impl VecDeque { self.cap); debug_assert!(src + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len, self.cap); - ptr::copy_nonoverlapping_memory( + ptr::copy_nonoverlapping( self.ptr.offset(dst as isize), self.ptr.offset(src as isize), len); @@ -1343,22 +1343,22 @@ impl VecDeque { // `at` lies in the first half. let amount_in_first = first_len - at; - ptr::copy_nonoverlapping_memory(*other.ptr, - first_half.as_ptr().offset(at as isize), - amount_in_first); + ptr::copy_nonoverlapping(*other.ptr, + first_half.as_ptr().offset(at as isize), + amount_in_first); // just take all of the second half. - ptr::copy_nonoverlapping_memory(other.ptr.offset(amount_in_first as isize), - second_half.as_ptr(), - second_len); + ptr::copy_nonoverlapping(other.ptr.offset(amount_in_first as isize), + second_half.as_ptr(), + second_len); } else { // `at` lies in the second half, need to factor in the elements we skipped // in the first half. let offset = at - first_len; let amount_in_second = second_len - offset; - ptr::copy_nonoverlapping_memory(*other.ptr, - second_half.as_ptr().offset(offset as isize), - amount_in_second); + ptr::copy_nonoverlapping(*other.ptr, + second_half.as_ptr().offset(offset as isize), + amount_in_second); } } @@ -1754,7 +1754,7 @@ impl Extend for VecDeque { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for VecDeque { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "VecDeque [")); + try!(write!(f, "[")); for (i, e) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -2105,7 +2105,7 @@ mod tests { let mut d: VecDeque<_> = (0..5).collect(); d.pop_front(); d.swap(0, 3); - assert_eq!(d.iter().cloned().collect::>(), vec!(4, 2, 3, 1)); + assert_eq!(d.iter().cloned().collect::>(), [4, 2, 3, 1]); } #[test] @@ -2435,12 +2435,12 @@ mod tests { #[test] fn test_show() { let ringbuf: VecDeque<_> = (0..10).collect(); - assert_eq!(format!("{:?}", ringbuf), "VecDeque [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); + assert_eq!(format!("{:?}", ringbuf), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"); let ringbuf: VecDeque<_> = vec!["just", "one", "test", "more"].iter() .cloned() .collect(); - assert_eq!(format!("{:?}", ringbuf), "VecDeque [\"just\", \"one\", \"test\", \"more\"]"); + assert_eq!(format!("{:?}", ringbuf), "[\"just\", \"one\", \"test\", \"more\"]"); } #[test] @@ -2868,17 +2868,17 @@ mod tests { // normal append a.append(&mut b); - assert_eq!(a.iter().cloned().collect(), vec![1, 2, 3, 4, 5, 6]); - assert_eq!(b.iter().cloned().collect(), vec![]); + assert_eq!(a.iter().cloned().collect::>(), [1, 2, 3, 4, 5, 6]); + assert_eq!(b.iter().cloned().collect::>(), []); // append nothing to something a.append(&mut b); - assert_eq!(a.iter().cloned().collect(), vec![1, 2, 3, 4, 5, 6]); - assert_eq!(b.iter().cloned().collect(), vec![]); + assert_eq!(a.iter().cloned().collect::>(), [1, 2, 3, 4, 5, 6]); + assert_eq!(b.iter().cloned().collect::>(), []); // append something to nothing b.append(&mut a); - assert_eq!(b.iter().cloned().collect(), vec![1, 2, 3, 4, 5, 6]); - assert_eq!(a.iter().cloned().collect(), vec![]); + assert_eq!(b.iter().cloned().collect::>(), [1, 2, 3, 4, 5, 6]); + assert_eq!(a.iter().cloned().collect::>(), []); } } diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index d92249379fa8f..5a0aa750bf567 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -308,7 +308,7 @@ impl VecMap { /// /// let vec: Vec<(usize, &str)> = map.into_iter().collect(); /// - /// assert_eq!(vec, vec![(1, "a"), (2, "b"), (3, "c")]); + /// assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn into_iter(self) -> IntoIter { @@ -425,7 +425,7 @@ impl VecMap { /// /// let vec: Vec<(usize, &str)> = map.drain().collect(); /// - /// assert_eq!(vec, vec![(1, "a"), (2, "b"), (3, "c")]); + /// assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]); /// ``` #[unstable(feature = "collections", reason = "matches collection reform specification, waiting for dust to settle")] @@ -739,7 +739,7 @@ impl Ord for VecMap { #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for VecMap { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "VecMap {{")); + try!(write!(f, "{{")); for (i, (k, v)) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -1226,7 +1226,7 @@ mod test_map { let vec: Vec<_> = map.drain().collect(); - assert_eq!(vec, vec![(1, "a"), (2, "b"), (3, "c")]); + assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]); assert_eq!(map.len(), 0); } @@ -1318,8 +1318,8 @@ mod test_map { map.insert(3, 4); let map_str = format!("{:?}", map); - assert!(map_str == "VecMap {1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}"); - assert_eq!(format!("{:?}", empty), "VecMap {}"); + assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}"); + assert_eq!(format!("{:?}", empty), "{}"); } #[test] diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index b2ee95963878e..e7af0be88a085 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -293,7 +293,7 @@ extern "rust-intrinsic" { /// } /// } /// ``` - #[unstable(feature = "core")] + #[stable(feature = "rust1", since = "1.0.0")] pub fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: usize); /// Copies `count * size_of` bytes from `src` to `dst`. The source @@ -323,13 +323,12 @@ extern "rust-intrinsic" { /// } /// ``` /// - #[unstable(feature = "core")] + #[stable(feature = "rust1", since = "1.0.0")] pub fn copy_memory(dst: *mut T, src: *const T, count: usize); /// Invokes memset on the specified pointer, setting `count * size_of::()` /// bytes of memory starting at `dst` to `c`. - #[unstable(feature = "core", - reason = "uncertain about naming and semantics")] + #[stable(feature = "rust1", since = "1.0.0")] pub fn set_memory(dst: *mut T, val: u8, count: usize); /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 48ec13429717c..b4ccf93043729 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -582,8 +582,8 @@ pub trait IteratorExt: Iterator + Sized { /// ``` /// let vec = vec![1, 2, 3, 4]; /// let (even, odd): (Vec<_>, Vec<_>) = vec.into_iter().partition(|&n| n % 2 == 0); - /// assert_eq!(even, vec![2, 4]); - /// assert_eq!(odd, vec![1, 3]); + /// assert_eq!(even, [2, 4]); + /// assert_eq!(odd, [1, 3]); /// ``` #[unstable(feature = "core", reason = "recently added as part of collections reform")] diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 740997b7a249d..2aa8ec0c548d9 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -203,9 +203,9 @@ pub fn swap(x: &mut T, y: &mut T) { let mut t: T = uninitialized(); // Perform the swap, `&mut` pointers never alias - ptr::copy_nonoverlapping_memory(&mut t, &*x, 1); - ptr::copy_nonoverlapping_memory(x, &*y, 1); - ptr::copy_nonoverlapping_memory(y, &t, 1); + ptr::copy_nonoverlapping(&mut t, &*x, 1); + ptr::copy_nonoverlapping(x, &*y, 1); + ptr::copy_nonoverlapping(y, &t, 1); // y and t now point to the same thing, but we need to completely forget `t` // because it's no longer relevant. diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 7612469c8088b..b1039f79f23de 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1672,6 +1672,7 @@ macro_rules! from_str_radix_int_impl { let is_signed_ty = (0 as $T) > Int::min_value(); match src.slice_shift_char() { + Some(('-', "")) => Err(PIE { kind: Empty }), Some(('-', src)) if is_signed_ty => { // The number is negative let mut result = 0; diff --git a/src/libcore/option.rs b/src/libcore/option.rs index abfef72a5dbc3..1ecbd8fae8cdb 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -556,7 +556,7 @@ impl Option { /// ``` /// let x = Some("string"); /// let v: Vec<&str> = x.into_iter().collect(); - /// assert_eq!(v, vec!["string"]); + /// assert_eq!(v, ["string"]); /// /// let x = None; /// let v: Vec<&str> = x.into_iter().collect(); diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index b44cc899787f5..0625c3c7d6018 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -101,16 +101,28 @@ use cmp::Ordering::{self, Less, Equal, Greater}; // FIXME #19649: intrinsic docs don't render, so these have no docs :( -#[unstable(feature = "core")] -pub use intrinsics::copy_nonoverlapping_memory; +#[stable(feature = "rust1", since = "1.0.0")] +pub use intrinsics::copy_nonoverlapping_memory as copy_nonoverlapping; -#[unstable(feature = "core")] -pub use intrinsics::copy_memory; +#[stable(feature = "rust1", since = "1.0.0")] +pub use intrinsics::copy_memory as copy; -#[unstable(feature = "core", - reason = "uncertain about naming and semantics")] -pub use intrinsics::set_memory; +#[stable(feature = "rust1", since = "1.0.0")] +pub use intrinsics::set_memory as write_bytes; +extern "rust-intrinsic" { + #[unstable(feature = "core")] + #[deprecated(since = "1.0.0", reason = "renamed to `copy_nonoverlapping`")] + pub fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: usize); + #[unstable(feature = "core")] + #[deprecated(since = "1.0.0", reason = "renamed to `copy`")] + pub fn copy_memory(dst: *mut T, src: *const T, count: usize); + + #[unstable(feature = "core", + reason = "uncertain about naming and semantics")] + #[deprecated(since = "1.0.0", reason = "renamed to `write_bytes`")] + pub fn set_memory(dst: *mut T, val: u8, count: usize); +} /// Creates a null raw pointer. /// @@ -150,8 +162,9 @@ pub fn null_mut() -> *mut T { 0 as *mut T } #[inline] #[unstable(feature = "core", reason = "may play a larger role in std::ptr future extensions")] +#[deprecated(since = "1.0.0", reason = "use `write_bytes` instead")] pub unsafe fn zero_memory(dst: *mut T, count: usize) { - set_memory(dst, 0, count); + write_bytes(dst, 0, count); } /// Swaps the values at two mutable locations of the same type, without @@ -169,9 +182,9 @@ pub unsafe fn swap(x: *mut T, y: *mut T) { let t: *mut T = &mut tmp; // Perform the swap - copy_nonoverlapping_memory(t, &*x, 1); - copy_memory(x, &*y, 1); // `x` and `y` may overlap - copy_nonoverlapping_memory(y, &*t, 1); + copy_nonoverlapping(t, &*x, 1); + copy(x, &*y, 1); // `x` and `y` may overlap + copy_nonoverlapping(y, &*t, 1); // y and t now point to the same thing, but we need to completely forget `tmp` // because it's no longer relevant. @@ -207,7 +220,7 @@ pub unsafe fn replace(dest: *mut T, mut src: T) -> T { #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn read(src: *const T) -> T { let mut tmp: T = mem::uninitialized(); - copy_nonoverlapping_memory(&mut tmp, src, 1); + copy_nonoverlapping(&mut tmp, src, 1); tmp } @@ -224,7 +237,7 @@ pub unsafe fn read_and_zero(dest: *mut T) -> T { let tmp = read(&*dest); // Now zero out `dest`: - zero_memory(dest, 1); + write_bytes(dest, 0, 1); tmp } @@ -248,9 +261,9 @@ pub unsafe fn write(dst: *mut T, src: T) { /// Methods on raw pointers #[stable(feature = "rust1", since = "1.0.0")] -pub trait PtrExt: Sized { +pub trait PtrExt { /// The type which is being pointed at - type Target; + type Target: ?Sized; /// Returns true if the pointer is null. #[stable(feature = "rust1", since = "1.0.0")] @@ -279,14 +292,14 @@ pub trait PtrExt: Sized { /// Otherwise `offset` invokes Undefined Behaviour, regardless of whether /// the pointer is used. #[stable(feature = "rust1", since = "1.0.0")] - unsafe fn offset(self, count: isize) -> Self; + unsafe fn offset(self, count: isize) -> Self where Self::Target: Sized; } /// Methods on mutable raw pointers #[stable(feature = "rust1", since = "1.0.0")] pub trait MutPtrExt { /// The type which is being pointed at - type Target; + type Target: ?Sized; /// Returns `None` if the pointer is null, or else returns a mutable /// reference to the value wrapped in `Some`. @@ -302,7 +315,7 @@ pub trait MutPtrExt { } #[stable(feature = "rust1", since = "1.0.0")] -impl PtrExt for *const T { +impl PtrExt for *const T { type Target = T; #[inline] @@ -311,7 +324,7 @@ impl PtrExt for *const T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] - unsafe fn offset(self, count: isize) -> *const T { + unsafe fn offset(self, count: isize) -> *const T where T: Sized { intrinsics::offset(self, count) } @@ -329,7 +342,7 @@ impl PtrExt for *const T { } #[stable(feature = "rust1", since = "1.0.0")] -impl PtrExt for *mut T { +impl PtrExt for *mut T { type Target = T; #[inline] @@ -338,7 +351,7 @@ impl PtrExt for *mut T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] - unsafe fn offset(self, count: isize) -> *mut T { + unsafe fn offset(self, count: isize) -> *mut T where T: Sized { intrinsics::offset(self, count) as *mut T } @@ -356,7 +369,7 @@ impl PtrExt for *mut T { } #[stable(feature = "rust1", since = "1.0.0")] -impl MutPtrExt for *mut T { +impl MutPtrExt for *mut T { type Target = T; #[inline] @@ -374,33 +387,25 @@ impl MutPtrExt for *mut T { // Equality for pointers #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for *const T { +impl PartialEq for *const T { #[inline] - fn eq(&self, other: &*const T) -> bool { - *self == *other - } - #[inline] - fn ne(&self, other: &*const T) -> bool { !self.eq(other) } + fn eq(&self, other: &*const T) -> bool { *self == *other } } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for *const T {} +impl Eq for *const T {} #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for *mut T { - #[inline] - fn eq(&self, other: &*mut T) -> bool { - *self == *other - } +impl PartialEq for *mut T { #[inline] - fn ne(&self, other: &*mut T) -> bool { !self.eq(other) } + fn eq(&self, other: &*mut T) -> bool { *self == *other } } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for *mut T {} +impl Eq for *mut T {} #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for *const T { +impl Clone for *const T { #[inline] fn clone(&self) -> *const T { *self @@ -408,7 +413,7 @@ impl Clone for *const T { } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for *mut T { +impl Clone for *mut T { #[inline] fn clone(&self) -> *mut T { *self @@ -452,7 +457,7 @@ mod externfnpointers { // Comparison for pointers #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for *const T { +impl Ord for *const T { #[inline] fn cmp(&self, other: &*const T) -> Ordering { if self < other { @@ -466,7 +471,7 @@ impl Ord for *const T { } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for *const T { +impl PartialOrd for *const T { #[inline] fn partial_cmp(&self, other: &*const T) -> Option { Some(self.cmp(other)) @@ -486,7 +491,7 @@ impl PartialOrd for *const T { } #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for *mut T { +impl Ord for *mut T { #[inline] fn cmp(&self, other: &*mut T) -> Ordering { if self < other { @@ -500,7 +505,7 @@ impl Ord for *mut T { } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for *mut T { +impl PartialOrd for *mut T { #[inline] fn partial_cmp(&self, other: &*mut T) -> Option { Some(self.cmp(other)) @@ -527,8 +532,8 @@ impl PartialOrd for *mut T { /// modified without a unique path to the `Unique` reference. 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 { +#[unstable(feature = "unique")] +pub struct Unique { pointer: NonZero<*const T>, _marker: PhantomData, } @@ -537,39 +542,37 @@ pub struct Unique { /// 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")] +#[unstable(feature = "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")] +#[unstable(feature = "unique")] unsafe impl Sync for Unique { } -impl Unique { +impl Unique { /// Create a new `Unique`. - #[unstable(feature = "core", - reason = "recently added to this module")] + #[unstable(feature = "unique")] pub unsafe fn new(ptr: *mut T) -> Unique { Unique { pointer: NonZero::new(ptr as *const T), _marker: PhantomData } } /// Dereference the content. - #[unstable(feature = "core", - reason = "recently added to this module")] + #[unstable(feature = "unique")] pub unsafe fn get(&self) -> &T { &**self.pointer } /// Mutably dereference the content. - #[unstable(feature = "core", - reason = "recently added to this module")] + #[unstable(feature = "unique")] pub unsafe fn get_mut(&mut self) -> &mut T { &mut ***self } } +#[unstable(feature = "unique")] impl Deref for Unique { type Target = *mut T; diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 23e936a75d709..bca73782491bf 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -548,11 +548,11 @@ impl Result { /// ``` /// let x: Result = Ok(5); /// let v: Vec = x.into_iter().collect(); - /// assert_eq!(v, vec![5]); + /// assert_eq!(v, [5]); /// /// let x: Result = Err("nothing!"); /// let v: Vec = x.into_iter().collect(); - /// assert_eq!(v, vec![]); + /// assert_eq!(v, []); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 2debcaa581342..ae64a57a390f8 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -1500,7 +1500,7 @@ pub mod bytes { impl MutableByteVector for [u8] { #[inline] fn set_memory(&mut self, value: u8) { - unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) }; + unsafe { ptr::write_bytes(self.as_mut_ptr(), value, self.len()) }; } } @@ -1514,9 +1514,9 @@ pub mod bytes { // `dst` is unaliasable, so we know statically it doesn't overlap // with `src`. unsafe { - ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(), - src.as_ptr(), - len_src); + ptr::copy_nonoverlapping(dst.as_mut_ptr(), + src.as_ptr(), + len_src); } } } diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index 6cbc7bf1bbc51..8a27400389f4a 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -74,7 +74,7 @@ fn test_multi_iter() { fn test_counter_from_iter() { let it = count(0, 5).take(10); let xs: Vec = FromIterator::from_iter(it); - assert!(xs == vec![0, 5, 10, 15, 20, 25, 30, 35, 40, 45]); + assert_eq!(xs, [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]); } #[test] @@ -104,7 +104,7 @@ fn test_iterator_chain() { fn test_filter_map() { let it = count(0, 1).take(10) .filter_map(|x| if x % 2 == 0 { Some(x*x) } else { None }); - assert!(it.collect::>() == vec![0*0, 2*2, 4*4, 6*6, 8*8]); + assert_eq!(it.collect::>(), [0*0, 2*2, 4*4, 6*6, 8*8]); } #[test] @@ -730,12 +730,12 @@ fn test_random_access_cycle() { #[test] fn test_double_ended_range() { - assert!((11..14).rev().collect::>() == vec![13, 12, 11]); + assert_eq!((11..14).rev().collect::>(), [13, 12, 11]); for _ in (10..0).rev() { panic!("unreachable"); } - assert!((11..14).rev().collect::>() == vec![13, 12, 11]); + assert_eq!((11..14).rev().collect::>(), [13, 12, 11]); for _ in (10..0).rev() { panic!("unreachable"); } @@ -743,10 +743,9 @@ fn test_double_ended_range() { #[test] fn test_range() { - assert!((0..5).collect::>() == vec![0, 1, 2, 3, 4]); - assert!((-10..-1).collect::>() == - vec![-10, -9, -8, -7, -6, -5, -4, -3, -2]); - assert!((0..5).rev().collect::>() == vec![4, 3, 2, 1, 0]); + assert_eq!((0..5).collect::>(), [0, 1, 2, 3, 4]); + assert_eq!((-10..-1).collect::>(), [-10, -9, -8, -7, -6, -5, -4, -3, -2]); + assert_eq!((0..5).rev().collect::>(), [4, 3, 2, 1, 0]); assert_eq!((200..-5).count(), 0); assert_eq!((200..-5).rev().count(), 0); assert_eq!((200..200).count(), 0); @@ -767,38 +766,28 @@ fn test_range_inclusive() { vec![5, 4, 3, 2, 1, 0]); assert_eq!(range_inclusive(200, -5).count(), 0); assert_eq!(range_inclusive(200, -5).rev().count(), 0); - assert!(range_inclusive(200, 200).collect::>() == vec![200]); - assert!(range_inclusive(200, 200).rev().collect::>() == vec![200]); + assert_eq!(range_inclusive(200, 200).collect::>(), [200]); + assert_eq!(range_inclusive(200, 200).rev().collect::>(), [200]); } #[test] fn test_range_step() { - assert!(range_step(0, 20, 5).collect::>() == - vec![0, 5, 10, 15]); - assert!(range_step(20, 0, -5).collect::>() == - vec![20, 15, 10, 5]); - assert!(range_step(20, 0, -6).collect::>() == - vec![20, 14, 8, 2]); - assert!(range_step(200u8, 255, 50).collect::>() == - vec![200u8, 250]); - assert!(range_step(200, -5, 1).collect::>() == vec![]); - assert!(range_step(200, 200, 1).collect::>() == vec![]); + assert_eq!(range_step(0, 20, 5).collect::>(), [0, 5, 10, 15]); + assert_eq!(range_step(20, 0, -5).collect::>(), [20, 15, 10, 5]); + assert_eq!(range_step(20, 0, -6).collect::>(), [20, 14, 8, 2]); + assert_eq!(range_step(200u8, 255, 50).collect::>(), [200u8, 250]); + assert_eq!(range_step(200i, -5, 1).collect::>(), []); + assert_eq!(range_step(200i, 200, 1).collect::>(), []); } #[test] fn test_range_step_inclusive() { - assert!(range_step_inclusive(0, 20, 5).collect::>() == - vec![0, 5, 10, 15, 20]); - assert!(range_step_inclusive(20, 0, -5).collect::>() == - vec![20, 15, 10, 5, 0]); - assert!(range_step_inclusive(20, 0, -6).collect::>() == - vec![20, 14, 8, 2]); - assert!(range_step_inclusive(200u8, 255, 50).collect::>() == - vec![200u8, 250]); - assert!(range_step_inclusive(200, -5, 1).collect::>() == - vec![]); - assert!(range_step_inclusive(200, 200, 1).collect::>() == - vec![200]); + assert_eq!(range_step_inclusive(0, 20, 5).collect::>(), [0, 5, 10, 15, 20]); + assert_eq!(range_step_inclusive(20, 0, -5).collect::>(), [20, 15, 10, 5, 0]); + assert_eq!(range_step_inclusive(20, 0, -6).collect::>(), [20, 14, 8, 2]); + assert_eq!(range_step_inclusive(200u8, 255, 50).collect::>(), [200u8, 250]); + assert_eq!(range_step_inclusive(200, -5, 1).collect::>(), []); + assert_eq!(range_step_inclusive(200, 200, 1).collect::>(), [200]); } #[test] diff --git a/src/libcoretest/mem.rs b/src/libcoretest/mem.rs index 5aeb330b78b54..73000670c61aa 100644 --- a/src/libcoretest/mem.rs +++ b/src/libcoretest/mem.rs @@ -103,7 +103,7 @@ fn test_transmute() { } unsafe { - assert!(vec![76u8] == transmute::<_, Vec>("L".to_string())); + assert_eq!([76u8], transmute::<_, Vec>("L".to_string())); } } diff --git a/src/libcoretest/nonzero.rs b/src/libcoretest/nonzero.rs index be4c83d23e8b3..f60570eaaf417 100644 --- a/src/libcoretest/nonzero.rs +++ b/src/libcoretest/nonzero.rs @@ -54,7 +54,7 @@ fn test_match_option_empty_vec() { fn test_match_option_vec() { let a = Some(vec![1, 2, 3, 4]); match a { - Some(v) => assert_eq!(v, vec![1, 2, 3, 4]), + Some(v) => assert_eq!(v, [1, 2, 3, 4]), None => panic!("unexpected None while matching on Some(vec![1, 2, 3, 4])") } } diff --git a/src/libcoretest/num/mod.rs b/src/libcoretest/num/mod.rs index 2c6efc0040fae..03f6e51a3498a 100644 --- a/src/libcoretest/num/mod.rs +++ b/src/libcoretest/num/mod.rs @@ -122,4 +122,9 @@ mod test { assert_eq!("-9223372036854775808".parse::().ok(), Some(i64_val)); assert_eq!("-9223372036854775809".parse::().ok(), None); } + + #[test] + fn test_int_from_minus_sign() { + assert_eq!("-".parse::().ok(), None); + } } diff --git a/src/libcoretest/ptr.rs b/src/libcoretest/ptr.rs index 57456bfb1a79b..c8a54ef59abda 100644 --- a/src/libcoretest/ptr.rs +++ b/src/libcoretest/ptr.rs @@ -156,7 +156,7 @@ fn test_ptr_subtraction() { m_ptr = m_ptr.offset(-1); } - assert!(xs_mut == vec![0,2,4,6,8,10,12,14,16,18]); + assert_eq!(xs_mut, [0,2,4,6,8,10,12,14,16,18]); } } diff --git a/src/libcoretest/str.rs b/src/libcoretest/str.rs index beb746d25b61c..019f935911f7a 100644 --- a/src/libcoretest/str.rs +++ b/src/libcoretest/str.rs @@ -22,7 +22,7 @@ fn test_pattern_deref_forward() { fn test_empty_match_indices() { let data = "aä中!"; let vec: Vec<_> = data.match_indices("").collect(); - assert_eq!(vec, vec![(0, 0), (1, 1), (3, 3), (6, 6), (7, 7)]); + assert_eq!(vec, [(0, 0), (1, 1), (3, 3), (6, 6), (7, 7)]); } #[test] @@ -69,20 +69,20 @@ fn test_rsplitn_char_iterator() { let mut split: Vec<&str> = data.rsplitn(3, ' ').collect(); split.reverse(); - assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); + assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == ' ').collect(); split.reverse(); - assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); + assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]); // Unicode let mut split: Vec<&str> = data.rsplitn(3, 'ä').collect(); split.reverse(); - assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); + assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); let mut split: Vec<&str> = data.rsplitn(3, |c: char| c == 'ä').collect(); split.reverse(); - assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); + assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]); } #[test] @@ -90,33 +90,33 @@ fn test_split_char_iterator() { let data = "\nMäry häd ä little lämb\nLittle lämb\n"; let split: Vec<&str> = data.split(' ').collect(); - assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); + assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); let mut rsplit: Vec<&str> = data.split(' ').rev().collect(); rsplit.reverse(); - assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); + assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); let split: Vec<&str> = data.split(|c: char| c == ' ').collect(); - assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); + assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect(); rsplit.reverse(); - assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); + assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]); // Unicode let split: Vec<&str> = data.split('ä').collect(); - assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); + assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); let mut rsplit: Vec<&str> = data.split('ä').rev().collect(); rsplit.reverse(); - assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); + assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); let split: Vec<&str> = data.split(|c: char| c == 'ä').collect(); - assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); + assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect(); rsplit.reverse(); - assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); + assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]); } #[test] @@ -125,18 +125,18 @@ fn test_rev_split_char_iterator_no_trailing() { let mut split: Vec<&str> = data.split('\n').rev().collect(); split.reverse(); - assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb", ""]); + assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]); let mut split: Vec<&str> = data.split_terminator('\n').rev().collect(); split.reverse(); - assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]); + assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]); } #[test] fn test_utf16_code_units() { use unicode::str::Utf16Encoder; assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::>(), - vec![0xE9, 0xD83D, 0xDCA9]) + [0xE9, 0xD83D, 0xDCA9]) } #[test] diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index 24660b3f396c1..2ce52cdec2560 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -27,6 +27,7 @@ #![feature(int_uint)] #![feature(libc)] #![feature(staged_api)] +#![feature(unique)] #[cfg(test)] #[macro_use] extern crate log; diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 8d8f6a406f5d4..74a95b3aba056 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -1362,7 +1362,6 @@ pub mod types { use types::os::arch::c95::{c_long}; pub type off_t = i64; pub type dev_t = i32; - pub type ino_t = u64; pub type pid_t = i32; pub type uid_t = u32; pub type gid_t = u32; diff --git a/src/librbml/io.rs b/src/librbml/io.rs index 230fda11ab5ac..c52465a889907 100644 --- a/src/librbml/io.rs +++ b/src/librbml/io.rs @@ -45,7 +45,7 @@ fn combine(seek: SeekStyle, cur: uint, end: uint, offset: i64) -> IoResult /// let mut w = SeekableMemWriter::new(); /// w.write(&[0, 1, 2]); /// -/// assert_eq!(w.unwrap(), vec!(0, 1, 2)); +/// assert_eq!(w.unwrap(), [0, 1, 2]); /// ``` pub struct SeekableMemWriter { buf: Vec, diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index fe9a81bb7c984..26cb4f917c566 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -40,6 +40,7 @@ #![feature(staged_api)] #![feature(std_misc)] #![feature(unicode)] +#![feature(os)] #![cfg_attr(test, feature(test))] extern crate arena; diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 3c0d9e93ccb93..a4f69e651df60 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -1295,46 +1295,36 @@ impl LintPass for UnsafeCode { } fn check_item(&mut self, cx: &Context, it: &ast::Item) { - use syntax::ast::Unsafety::Unsafe; - - fn check_method(cx: &Context, meth: &P) { - if let ast::Method_::MethDecl(_, _, _, _, Unsafe, _, _, _) = meth.node { - cx.span_lint(UNSAFE_CODE, meth.span, "implementation of an `unsafe` method"); - } - } - match it.node { - ast::ItemFn(_, Unsafe, _, _, _) => - cx.span_lint(UNSAFE_CODE, it.span, "declaration of an `unsafe` function"), + ast::ItemTrait(ast::Unsafety::Unsafe, _, _, _) => + cx.span_lint(UNSAFE_CODE, it.span, "declaration of an `unsafe` trait"), - ast::ItemTrait(trait_safety, _, _, ref items) => { - if trait_safety == Unsafe { - cx.span_lint(UNSAFE_CODE, it.span, "declaration of an `unsafe` trait"); - } + ast::ItemImpl(ast::Unsafety::Unsafe, _, _, _, _, _) => + cx.span_lint(UNSAFE_CODE, it.span, "implementation of an `unsafe` trait"), - for it in items { - match *it { - ast::RequiredMethod(ast::TypeMethod { unsafety: Unsafe, span, ..}) => - cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` method"), - ast::ProvidedMethod(ref meth) => check_method(cx, meth), - _ => (), - } - } - }, + _ => return, + } + } - ast::ItemImpl(impl_safety, _, _, _, _, ref impls) => { - if impl_safety == Unsafe { - cx.span_lint(UNSAFE_CODE, it.span, "implementation of an `unsafe` trait"); - } + fn check_fn(&mut self, cx: &Context, fk: visit::FnKind, _: &ast::FnDecl, + _: &ast::Block, span: Span, _: ast::NodeId) { + match fk { + visit::FkItemFn(_, _, ast::Unsafety::Unsafe, _) => + cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"), - for item in impls { - if let ast::ImplItem::MethodImplItem(ref meth) = *item { - check_method(cx, meth); - } + visit::FkMethod(_, _, m) => { + if let ast::Method_::MethDecl(_, _, _, _, ast::Unsafety::Unsafe, _, _, _) = m.node { + cx.span_lint(UNSAFE_CODE, m.span, "implementation of an `unsafe` method") } }, - _ => return, + _ => (), + } + } + + fn check_ty_method(&mut self, cx: &Context, ty_method: &ast::TypeMethod) { + if let ast::TypeMethod { unsafety: ast::Unsafety::Unsafe, span, ..} = *ty_method { + cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` method") } } } diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index d63b3dd60d01d..a8d39f9573932 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -14,6 +14,7 @@ pub use self::FileMatch::*; use std::collections::HashSet; use std::env; +use std::os; use std::old_io::fs::PathExtensions; use std::old_io::fs; @@ -194,7 +195,7 @@ pub fn get_or_default_sysroot() -> Path { }) } - match canonicalize(env::current_exe().ok()) { + match canonicalize(os::self_exe_name()) { Some(mut p) => { p.pop(); p.pop(); p } None => panic!("can't determine value for sysroot") } @@ -224,7 +225,7 @@ pub fn rust_path() -> Vec { } None => Vec::new() }; - let mut cwd = env::current_dir().unwrap(); + let mut cwd = os::getcwd().unwrap(); // now add in default entries let cwd_dot_rust = cwd.join(".rust"); if !env_rust_path.contains(&cwd_dot_rust) { @@ -243,7 +244,7 @@ pub fn rust_path() -> Vec { } cwd.pop(); } - if let Some(h) = env::home_dir() { + if let Some(h) = os::homedir() { let p = h.join(".rust"); if !env_rust_path.contains(&p) && p.exists() { env_rust_path.push(p); diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index fbc3e76cf934b..07082d818769c 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -736,12 +736,10 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result { - return Err((format!("failed to read rlib metadata: '{}'", - filename.display()))) - } - Some(blob) => return Ok(blob) - } + None => Err(format!("failed to read rlib metadata: '{}'", + filename.display())), + Some(blob) => Ok(blob) + }; } unsafe { let buf = CString::new(filename.as_vec()).unwrap(); @@ -791,7 +789,7 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result : Sized { variadic: a.variadic}); - fn argvecs<'tcx, C: Combine<'tcx>>(combiner: &C, - a_args: &[Ty<'tcx>], - b_args: &[Ty<'tcx>]) - -> cres<'tcx, Vec>> - { + fn argvecs<'tcx, C>(combiner: &C, + a_args: &[Ty<'tcx>], + b_args: &[Ty<'tcx>]) + -> cres<'tcx, Vec>> + where C: Combine<'tcx> { if a_args.len() == b_args.len() { a_args.iter().zip(b_args.iter()) .map(|(a, b)| combiner.args(*a, *b)).collect() @@ -265,13 +265,7 @@ pub trait Combine<'tcx> : Sized { Err(ty::terr_projection_name_mismatched( expected_found(self, a.item_name, b.item_name))) } else { - // Note that the trait refs for the projection must be - // *equal*. This is because there is no inherent - // relationship between `::Bar` and `::Bar` that we can derive based on how `T` relates - // to `U`. Issue #21726 contains further discussion and - // in-depth examples. - let trait_ref = try!(self.equate().trait_refs(&*a.trait_ref, &*b.trait_ref)); + let trait_ref = try!(self.trait_refs(&*a.trait_ref, &*b.trait_ref)); Ok(ty::ProjectionTy { trait_ref: Rc::new(trait_ref), item_name: a.item_name }) } } @@ -351,51 +345,51 @@ pub trait Combineable<'tcx> : Repr<'tcx> + TypeFoldable<'tcx> { impl<'tcx,T> Combineable<'tcx> for Rc where T : Combineable<'tcx> { - fn combine>(combiner: &C, - a: &Rc, - b: &Rc) - -> cres<'tcx, Rc> - { + fn combine(combiner: &C, + a: &Rc, + b: &Rc) + -> cres<'tcx, Rc> + where C: Combine<'tcx> { Ok(Rc::new(try!(Combineable::combine(combiner, &**a, &**b)))) } } impl<'tcx> Combineable<'tcx> for ty::TraitRef<'tcx> { - fn combine>(combiner: &C, - a: &ty::TraitRef<'tcx>, - b: &ty::TraitRef<'tcx>) - -> cres<'tcx, ty::TraitRef<'tcx>> - { + fn combine(combiner: &C, + a: &ty::TraitRef<'tcx>, + b: &ty::TraitRef<'tcx>) + -> cres<'tcx, ty::TraitRef<'tcx>> + where C: Combine<'tcx> { combiner.trait_refs(a, b) } } impl<'tcx> Combineable<'tcx> for Ty<'tcx> { - fn combine>(combiner: &C, - a: &Ty<'tcx>, - b: &Ty<'tcx>) - -> cres<'tcx, Ty<'tcx>> - { + fn combine(combiner: &C, + a: &Ty<'tcx>, + b: &Ty<'tcx>) + -> cres<'tcx, Ty<'tcx>> + where C: Combine<'tcx> { combiner.tys(*a, *b) } } impl<'tcx> Combineable<'tcx> for ty::ProjectionPredicate<'tcx> { - fn combine>(combiner: &C, - a: &ty::ProjectionPredicate<'tcx>, - b: &ty::ProjectionPredicate<'tcx>) - -> cres<'tcx, ty::ProjectionPredicate<'tcx>> - { + fn combine(combiner: &C, + a: &ty::ProjectionPredicate<'tcx>, + b: &ty::ProjectionPredicate<'tcx>) + -> cres<'tcx, ty::ProjectionPredicate<'tcx>> + where C: Combine<'tcx> { combiner.projection_predicates(a, b) } } impl<'tcx> Combineable<'tcx> for ty::FnSig<'tcx> { - fn combine>(combiner: &C, - a: &ty::FnSig<'tcx>, - b: &ty::FnSig<'tcx>) - -> cres<'tcx, ty::FnSig<'tcx>> - { + fn combine(combiner: &C, + a: &ty::FnSig<'tcx>, + b: &ty::FnSig<'tcx>) + -> cres<'tcx, ty::FnSig<'tcx>> + where C: Combine<'tcx> { combiner.fn_sigs(a, b) } } @@ -407,8 +401,11 @@ pub struct CombineFields<'a, 'tcx: 'a> { pub trace: TypeTrace<'tcx>, } -pub fn expected_found<'tcx, C: Combine<'tcx>, T>( - this: &C, a: T, b: T) -> ty::expected_found { +pub fn expected_found<'tcx, C, T>(this: &C, + a: T, + b: T) + -> ty::expected_found + where C: Combine<'tcx> { if this.a_is_expected() { ty::expected_found {expected: a, found: b} } else { @@ -416,29 +413,26 @@ pub fn expected_found<'tcx, C: Combine<'tcx>, T>( } } -pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, - a: Ty<'tcx>, - b: Ty<'tcx>) - -> cres<'tcx, Ty<'tcx>> -{ +pub fn super_tys<'tcx, C>(this: &C, + a: Ty<'tcx>, + b: Ty<'tcx>) + -> cres<'tcx, Ty<'tcx>> + where C: Combine<'tcx> { let tcx = this.infcx().tcx; let a_sty = &a.sty; let b_sty = &b.sty; debug!("super_tys: a_sty={:?} b_sty={:?}", a_sty, b_sty); return match (a_sty, b_sty) { - // The "subtype" ought to be handling cases involving var: - (&ty::ty_infer(TyVar(_)), _) | - (_, &ty::ty_infer(TyVar(_))) => { - tcx.sess.bug( - &format!("{}: bot and var types should have been handled ({},{})", - this.tag(), - a.repr(this.infcx().tcx), - b.repr(this.infcx().tcx))); - } - - (&ty::ty_err, _) | (_, &ty::ty_err) => { - Ok(tcx.types.err) - } + // The "subtype" ought to be handling cases involving var: + (&ty::ty_infer(TyVar(_)), _) + | (_, &ty::ty_infer(TyVar(_))) => + tcx.sess.bug( + &format!("{}: bot and var types should have been handled ({},{})", + this.tag(), + a.repr(this.infcx().tcx), + b.repr(this.infcx().tcx))), + + (&ty::ty_err, _) | (_, &ty::ty_err) => Ok(tcx.types.err), // Relate integral variables to other types (&ty::ty_infer(IntVar(a_id)), &ty::ty_infer(IntVar(b_id))) => { @@ -475,68 +469,62 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, unify_float_variable(this, !this.a_is_expected(), v_id, v) } - (&ty::ty_char, _) | - (&ty::ty_bool, _) | - (&ty::ty_int(_), _) | - (&ty::ty_uint(_), _) | - (&ty::ty_float(_), _) => { - if a == b { - Ok(a) - } else { - Err(ty::terr_sorts(expected_found(this, a, b))) - } - } - - (&ty::ty_param(ref a_p), &ty::ty_param(ref b_p)) if - a_p.idx == b_p.idx && a_p.space == b_p.space => { - Ok(a) - } - - (&ty::ty_enum(a_id, a_substs), - &ty::ty_enum(b_id, b_substs)) - if a_id == b_id => { - let substs = try!(this.substs(a_id, - a_substs, - b_substs)); - Ok(ty::mk_enum(tcx, a_id, tcx.mk_substs(substs))) - } - - (&ty::ty_trait(ref a_), - &ty::ty_trait(ref b_)) => { - debug!("Trying to match traits {:?} and {:?}", a, b); - let principal = try!(this.binders(&a_.principal, &b_.principal)); - let bounds = try!(this.existential_bounds(&a_.bounds, &b_.bounds)); - Ok(ty::mk_trait(tcx, principal, bounds)) - } - - (&ty::ty_struct(a_id, a_substs), &ty::ty_struct(b_id, b_substs)) - if a_id == b_id => { + (&ty::ty_char, _) + | (&ty::ty_bool, _) + | (&ty::ty_int(_), _) + | (&ty::ty_uint(_), _) + | (&ty::ty_float(_), _) => { + if a == b { + Ok(a) + } else { + Err(ty::terr_sorts(expected_found(this, a, b))) + } + } + + (&ty::ty_param(ref a_p), &ty::ty_param(ref b_p)) if + a_p.idx == b_p.idx && a_p.space == b_p.space => Ok(a), + + (&ty::ty_enum(a_id, a_substs), &ty::ty_enum(b_id, b_substs)) + if a_id == b_id => { + let substs = try!(this.substs(a_id, a_substs, b_substs)); + Ok(ty::mk_enum(tcx, a_id, tcx.mk_substs(substs))) + } + + (&ty::ty_trait(ref a_), &ty::ty_trait(ref b_)) => { + debug!("Trying to match traits {:?} and {:?}", a, b); + let principal = try!(this.binders(&a_.principal, &b_.principal)); + let bounds = try!(this.existential_bounds(&a_.bounds, &b_.bounds)); + Ok(ty::mk_trait(tcx, principal, bounds)) + } + + (&ty::ty_struct(a_id, a_substs), &ty::ty_struct(b_id, b_substs)) + if a_id == b_id => { let substs = try!(this.substs(a_id, a_substs, b_substs)); Ok(ty::mk_struct(tcx, a_id, tcx.mk_substs(substs))) - } - - (&ty::ty_closure(a_id, a_region, a_substs), - &ty::ty_closure(b_id, b_region, b_substs)) - if a_id == b_id => { - // All ty_closure types with the same id represent - // the (anonymous) type of the same closure expression. So - // all of their regions should be equated. - let region = try!(this.equate().regions(*a_region, *b_region)); - let substs = try!(this.substs_variances(None, a_substs, b_substs)); - Ok(ty::mk_closure(tcx, a_id, tcx.mk_region(region), tcx.mk_substs(substs))) - } - - (&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) => { - let typ = try!(this.tys(a_inner, b_inner)); - Ok(ty::mk_uniq(tcx, typ)) - } - - (&ty::ty_ptr(ref a_mt), &ty::ty_ptr(ref b_mt)) => { - let mt = try!(this.mts(a_mt, b_mt)); - Ok(ty::mk_ptr(tcx, mt)) - } - - (&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) => { + } + + (&ty::ty_closure(a_id, a_region, a_substs), + &ty::ty_closure(b_id, b_region, b_substs)) + if a_id == b_id => { + // All ty_closure types with the same id represent + // the (anonymous) type of the same closure expression. So + // all of their regions should be equated. + let region = try!(this.equate().regions(*a_region, *b_region)); + let substs = try!(this.substs_variances(None, a_substs, b_substs)); + Ok(ty::mk_closure(tcx, a_id, tcx.mk_region(region), tcx.mk_substs(substs))) + } + + (&ty::ty_uniq(a_inner), &ty::ty_uniq(b_inner)) => { + let typ = try!(this.tys(a_inner, b_inner)); + Ok(ty::mk_uniq(tcx, typ)) + } + + (&ty::ty_ptr(ref a_mt), &ty::ty_ptr(ref b_mt)) => { + let mt = try!(this.mts(a_mt, b_mt)); + Ok(ty::mk_ptr(tcx, mt)) + } + + (&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) => { let r = try!(this.regions_with_variance(ty::Contravariant, *a_r, *b_r)); // FIXME(14985) If we have mutable references to trait objects, we @@ -551,45 +539,43 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, _ => try!(this.mts(a_mt, b_mt)) }; Ok(ty::mk_rptr(tcx, tcx.mk_region(r), mt)) - } + } - (&ty::ty_vec(a_t, Some(sz_a)), &ty::ty_vec(b_t, Some(sz_b))) => { - this.tys(a_t, b_t).and_then(|t| { - if sz_a == sz_b { - Ok(ty::mk_vec(tcx, t, Some(sz_a))) - } else { - Err(ty::terr_fixed_array_size(expected_found(this, sz_a, sz_b))) - } - }) - } + (&ty::ty_vec(a_t, Some(sz_a)), &ty::ty_vec(b_t, Some(sz_b))) => { + this.tys(a_t, b_t).and_then(|t| { + if sz_a == sz_b { + Ok(ty::mk_vec(tcx, t, Some(sz_a))) + } else { + Err(ty::terr_fixed_array_size(expected_found(this, sz_a, sz_b))) + } + }) + } - (&ty::ty_vec(a_t, sz_a), &ty::ty_vec(b_t, sz_b)) => { - this.tys(a_t, b_t).and_then(|t| { - if sz_a == sz_b { - Ok(ty::mk_vec(tcx, t, sz_a)) + (&ty::ty_vec(a_t, sz_a), &ty::ty_vec(b_t, sz_b)) => { + this.tys(a_t, b_t).and_then(|t| { + if sz_a == sz_b { + Ok(ty::mk_vec(tcx, t, sz_a)) + } else { + Err(ty::terr_sorts(expected_found(this, a, b))) + } + }) + } + + (&ty::ty_str, &ty::ty_str) => Ok(ty::mk_str(tcx)), + + (&ty::ty_tup(ref as_), &ty::ty_tup(ref bs)) => { + if as_.len() == bs.len() { + as_.iter().zip(bs.iter()) + .map(|(a, b)| this.tys(*a, *b)) + .collect::>() + .map(|ts| ty::mk_tup(tcx, ts)) + } else if as_.len() != 0 && bs.len() != 0 { + Err(ty::terr_tuple_size( + expected_found(this, as_.len(), bs.len()))) } else { Err(ty::terr_sorts(expected_found(this, a, b))) } - }) - } - - (&ty::ty_str, &ty::ty_str) => { - Ok(ty::mk_str(tcx)) - } - - (&ty::ty_tup(ref as_), &ty::ty_tup(ref bs)) => { - if as_.len() == bs.len() { - as_.iter().zip(bs.iter()) - .map(|(a, b)| this.tys(*a, *b)) - .collect::>() - .map(|ts| ty::mk_tup(tcx, ts)) - } else if as_.len() != 0 && bs.len() != 0 { - Err(ty::terr_tuple_size( - expected_found(this, as_.len(), bs.len()))) - } else { - Err(ty::terr_sorts(expected_found(this, a, b))) } - } (&ty::ty_bare_fn(a_opt_def_id, a_fty), &ty::ty_bare_fn(b_opt_def_id, b_fty)) if a_opt_def_id == b_opt_def_id => @@ -598,33 +584,33 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C, Ok(ty::mk_bare_fn(tcx, a_opt_def_id, tcx.mk_bare_fn(fty))) } - (&ty::ty_projection(ref a_data), &ty::ty_projection(ref b_data)) => { - let projection_ty = try!(this.projection_tys(a_data, b_data)); - Ok(ty::mk_projection(tcx, projection_ty.trait_ref, projection_ty.item_name)) - } + (&ty::ty_projection(ref a_data), &ty::ty_projection(ref b_data)) => { + let projection_ty = try!(this.projection_tys(a_data, b_data)); + Ok(ty::mk_projection(tcx, projection_ty.trait_ref, projection_ty.item_name)) + } - _ => Err(ty::terr_sorts(expected_found(this, a, b))) + _ => Err(ty::terr_sorts(expected_found(this, a, b))), }; - fn unify_integral_variable<'tcx, C: Combine<'tcx>>( - this: &C, - vid_is_expected: bool, - vid: ty::IntVid, - val: ty::IntVarValue) -> cres<'tcx, Ty<'tcx>> - { + fn unify_integral_variable<'tcx, C>(this: &C, + vid_is_expected: bool, + vid: ty::IntVid, + val: ty::IntVarValue) + -> cres<'tcx, Ty<'tcx>> + where C: Combine<'tcx> { try!(this.infcx().simple_var_t(vid_is_expected, vid, val)); match val { IntType(v) => Ok(ty::mk_mach_int(this.tcx(), v)), - UintType(v) => Ok(ty::mk_mach_uint(this.tcx(), v)) + UintType(v) => Ok(ty::mk_mach_uint(this.tcx(), v)), } } - fn unify_float_variable<'tcx, C: Combine<'tcx>>( - this: &C, - vid_is_expected: bool, - vid: ty::FloatVid, - val: ast::FloatTy) -> cres<'tcx, Ty<'tcx>> - { + fn unify_float_variable<'tcx, C>(this: &C, + vid_is_expected: bool, + vid: ty::FloatVid, + val: ast::FloatTy) + -> cres<'tcx, Ty<'tcx>> + where C: Combine<'tcx> { try!(this.infcx().simple_var_t(vid_is_expected, vid, val)); Ok(ty::mk_mach_float(this.tcx(), val)) } @@ -696,12 +682,8 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> { None => { // ...not yet instantiated: // Generalize type if necessary. let generalized_ty = try!(match dir { - EqTo => { - self.generalize(a_ty, b_vid, false) - } - BiTo | SupertypeOf | SubtypeOf => { - self.generalize(a_ty, b_vid, true) - } + EqTo => self.generalize(a_ty, b_vid, false), + BiTo | SupertypeOf | SubtypeOf => self.generalize(a_ty, b_vid, true), }); debug!("instantiate(a_ty={}, dir={:?}, \ b_vid={}, generalized_ty={})", @@ -723,22 +705,14 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> { // to associate causes/spans with each of the relations in // the stack to get this right. match dir { - BiTo => { - try!(self.bivariate().tys(a_ty, b_ty)); - } + BiTo => try!(self.bivariate().tys(a_ty, b_ty)), - EqTo => { - try!(self.equate().tys(a_ty, b_ty)); - } + EqTo => try!(self.equate().tys(a_ty, b_ty)), - SubtypeOf => { - try!(self.sub().tys(a_ty, b_ty)); - } + SubtypeOf => try!(self.sub().tys(a_ty, b_ty)), - SupertypeOf => { - try!(self.sub().tys_with_variance(ty::Contravariant, a_ty, b_ty)); - } - } + SupertypeOf => try!(self.sub().tys_with_variance(ty::Contravariant, a_ty, b_ty)), + }; } Ok(()) @@ -754,11 +728,13 @@ impl<'f, 'tcx> CombineFields<'f, 'tcx> { make_region_vars: bool) -> cres<'tcx, Ty<'tcx>> { - let mut generalize = Generalizer { infcx: self.infcx, - span: self.trace.origin.span(), - for_vid: for_vid, - make_region_vars: make_region_vars, - cycle_detected: false }; + let mut generalize = Generalizer { + infcx: self.infcx, + span: self.trace.origin.span(), + for_vid: for_vid, + make_region_vars: make_region_vars, + cycle_detected: false + }; let u = ty.fold_with(&mut generalize); if generalize.cycle_detected { Err(ty::terr_cyclic_ty) diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs index 7800d99f8ed4c..759d7357df193 100644 --- a/src/librustc/middle/infer/region_inference/mod.rs +++ b/src/librustc/middle/infer/region_inference/mod.rs @@ -1133,18 +1133,12 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { true // changed } - ErrorValue => { - false // no change - } + ErrorValue => false, // no change Value(a_region) => { match a_data.classification { - Expanding => { - check_node(self, a_vid, a_data, a_region, b_region) - } - Contracting => { - adjust_node(self, a_vid, a_data, a_region, b_region) - } + Expanding => check_node(self, a_vid, a_data, a_region, b_region), + Contracting => adjust_node(self, a_vid, a_data, a_region, b_region), } } }; @@ -1154,7 +1148,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { a_data: &mut VarData, a_region: Region, b_region: Region) - -> bool { + -> bool { if !this.is_subregion_of(a_region, b_region) { debug!("Setting {:?} to ErrorValue: {} not subregion of {}", a_vid, @@ -1170,7 +1164,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { a_data: &mut VarData, a_region: Region, b_region: Region) - -> bool { + -> bool { match this.glb_concrete_regions(a_region, b_region) { Ok(glb) => { if glb == a_region { diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index 4d45bb841f49f..62b81f0ebe7db 100644 --- a/src/librustc/middle/traits/coherence.rs +++ b/src/librustc/middle/traits/coherence.rs @@ -52,9 +52,16 @@ fn overlap(selcx: &mut SelectionContext, b_def_id: ast::DefId) -> bool { + debug!("overlap(a_def_id={}, b_def_id={})", + a_def_id.repr(selcx.tcx()), + b_def_id.repr(selcx.tcx())); + let (a_trait_ref, a_obligations) = impl_trait_ref_and_oblig(selcx, a_def_id); let (b_trait_ref, b_obligations) = impl_trait_ref_and_oblig(selcx, b_def_id); + debug!("overlap: a_trait_ref={}", a_trait_ref.repr(selcx.tcx())); + debug!("overlap: b_trait_ref={}", b_trait_ref.repr(selcx.tcx())); + // Does `a <: b` hold? If not, no overlap. if let Err(_) = infer::mk_sub_poly_trait_refs(selcx.infcx(), true, @@ -64,10 +71,20 @@ fn overlap(selcx: &mut SelectionContext, return false; } + debug!("overlap: subtraitref check succeeded"); + // Are any of the obligations unsatisfiable? If so, no overlap. - a_obligations.iter() - .chain(b_obligations.iter()) - .all(|o| selcx.evaluate_obligation(o)) + let opt_failing_obligation = + a_obligations.iter() + .chain(b_obligations.iter()) + .find(|o| !selcx.evaluate_obligation(o)); + + if let Some(failing_obligation) = opt_failing_obligation { + debug!("overlap: obligation unsatisfiable {}", failing_obligation.repr(selcx.tcx())); + return false; + } + + true } /// Instantiate fresh variables for all bound parameters of the impl diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 8b836fd322e3c..5a5639c701291 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -18,7 +18,7 @@ pub use self::ObligationCauseCode::*; use middle::subst; use middle::ty::{self, HasProjectionTypes, Ty}; use middle::ty_fold::TypeFoldable; -use middle::infer::{self, InferCtxt}; +use middle::infer::{self, fixup_err_to_string, InferCtxt}; use std::slice::Iter; use std::rc::Rc; use syntax::ast; @@ -395,53 +395,64 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, } } +/// Normalizes the parameter environment, reporting errors if they occur. pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvironment<'a,'tcx>, cause: ObligationCause<'tcx>) -> ty::ParameterEnvironment<'a,'tcx> { - match normalize_param_env(&unnormalized_env, cause) { - Ok(p) => p, + // I'm not wild about reporting errors here; I'd prefer to + // have the errors get reported at a defined place (e.g., + // during typeck). Instead I have all parameter + // environments, in effect, going through this function + // and hence potentially reporting errors. This ensurse of + // course that we never forget to normalize (the + // alternative seemed like it would involve a lot of + // manual invocations of this fn -- and then we'd have to + // deal with the errors at each of those sites). + // + // In any case, in practice, typeck constructs all the + // parameter environments once for every fn as it goes, + // and errors will get reported then; so after typeck we + // can be sure that no errors should occur. + + let tcx = unnormalized_env.tcx; + let span = cause.span; + let body_id = cause.body_id; + + debug!("normalize_param_env_or_error(unnormalized_env={})", + unnormalized_env.repr(tcx)); + + let infcx = infer::new_infer_ctxt(tcx); + let predicates = match fully_normalize(&infcx, &unnormalized_env, cause, + &unnormalized_env.caller_bounds) { + Ok(predicates) => predicates, Err(errors) => { - // I'm not wild about reporting errors here; I'd prefer to - // have the errors get reported at a defined place (e.g., - // during typeck). Instead I have all parameter - // environments, in effect, going through this function - // and hence potentially reporting errors. This ensurse of - // course that we never forget to normalize (the - // alternative seemed like it would involve a lot of - // manual invocations of this fn -- and then we'd have to - // deal with the errors at each of those sites). - // - // In any case, in practice, typeck constructs all the - // parameter environments once for every fn as it goes, - // and errors will get reported then; so after typeck we - // can be sure that no errors should occur. - let infcx = infer::new_infer_ctxt(unnormalized_env.tcx); report_fulfillment_errors(&infcx, &errors); - - // Normalized failed? use what they gave us, it's better than nothing. - unnormalized_env + return unnormalized_env; // an unnormalized env is better than nothing } - } -} - -pub fn normalize_param_env<'a,'tcx>(param_env: &ty::ParameterEnvironment<'a,'tcx>, - cause: ObligationCause<'tcx>) - -> Result, - Vec>> -{ - let tcx = param_env.tcx; - - debug!("normalize_param_env(param_env={})", - param_env.repr(tcx)); + }; - let infcx = infer::new_infer_ctxt(tcx); - let predicates = try!(fully_normalize(&infcx, param_env, cause, ¶m_env.caller_bounds)); + infcx.resolve_regions_and_report_errors(body_id); + let predicates = match infcx.fully_resolve(&predicates) { + Ok(predicates) => predicates, + Err(fixup_err) => { + // If we encounter a fixup error, it means that some type + // variable wound up unconstrained. I actually don't know + // if this can happen, and I certainly don't expect it to + // happen often, but if it did happen it probably + // represents a legitimate failure due to some kind of + // unconstrained variable, and it seems better not to ICE, + // all things considered. + let err_msg = fixup_err_to_string(fixup_err); + tcx.sess.span_err(span, &err_msg); + return unnormalized_env; // an unnormalized env is better than nothing + } + }; - debug!("normalize_param_env: predicates={}", + debug!("normalize_param_env_or_error: predicates={}", predicates.repr(tcx)); - Ok(param_env.with_caller_bounds(predicates)) + unnormalized_env.with_caller_bounds(predicates) } pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, @@ -453,8 +464,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, { let tcx = closure_typer.tcx(); - debug!("normalize_param_env(value={})", - value.repr(tcx)); + debug!("normalize_param_env(value={})", value.repr(tcx)); let mut selcx = &mut SelectionContext::new(infcx, closure_typer); let mut fulfill_cx = FulfillmentContext::new(); @@ -468,8 +478,7 @@ pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, } try!(fulfill_cx.select_all_or_error(infcx, closure_typer)); let resolved_value = infcx.resolve_type_vars_if_possible(&normalized_value); - debug!("normalize_param_env: resolved_value={}", - resolved_value.repr(tcx)); + debug!("normalize_param_env: resolved_value={}", resolved_value.repr(tcx)); Ok(resolved_value) } diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 8086ca71e019e..9ec89f55b8f32 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -1409,27 +1409,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let self_ty = self.infcx.shallow_resolve(obligation.predicate.0.self_ty()); return match self_ty.sty { - ty::ty_infer(ty::IntVar(_)) | - ty::ty_infer(ty::FloatVar(_)) | - ty::ty_uint(_) | - ty::ty_int(_) | - ty::ty_bool | - ty::ty_float(_) | - ty::ty_bare_fn(..) | - ty::ty_char => { + ty::ty_infer(ty::IntVar(_)) + | ty::ty_infer(ty::FloatVar(_)) + | ty::ty_uint(_) + | ty::ty_int(_) + | ty::ty_bool + | ty::ty_float(_) + | ty::ty_bare_fn(..) + | ty::ty_char => { // safe for everything Ok(If(Vec::new())) } ty::ty_uniq(_) => { // Box match bound { - ty::BoundCopy => { - Err(Unimplemented) - } + ty::BoundCopy => Err(Unimplemented), - ty::BoundSized => { - Ok(If(Vec::new())) - } + ty::BoundSized => Ok(If(Vec::new())), ty::BoundSync | ty::BoundSend => { self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()"); @@ -1439,9 +1435,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::ty_ptr(..) => { // *const T, *mut T match bound { - ty::BoundCopy | ty::BoundSized => { - Ok(If(Vec::new())) - } + ty::BoundCopy | ty::BoundSized => Ok(If(Vec::new())), ty::BoundSync | ty::BoundSend => { self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()"); @@ -1451,9 +1445,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::ty_trait(ref data) => { match bound { - ty::BoundSized => { - Err(Unimplemented) - } + ty::BoundSized => Err(Unimplemented), ty::BoundCopy => { if data.bounds.builtin_bounds.contains(&bound) { Ok(If(Vec::new())) @@ -1485,20 +1477,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::BoundCopy => { match mutbl { // &mut T is affine and hence never `Copy` - ast::MutMutable => { - Err(Unimplemented) - } + ast::MutMutable => Err(Unimplemented), // &T is always copyable - ast::MutImmutable => { - Ok(If(Vec::new())) - } + ast::MutImmutable => Ok(If(Vec::new())), } } - ty::BoundSized => { - Ok(If(Vec::new())) - } + ty::BoundSized => Ok(If(Vec::new())), ty::BoundSync | ty::BoundSend => { self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()"); @@ -1511,14 +1497,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match bound { ty::BoundCopy => { match *len { - Some(_) => { - // [T, ..n] is copy iff T is copy - Ok(If(vec![element_ty])) - } - None => { - // [T] is unsized and hence affine - Err(Unimplemented) - } + // [T, ..n] is copy iff T is copy + Some(_) => Ok(If(vec![element_ty])), + + // [T] is unsized and hence affine + None => Err(Unimplemented), } } @@ -1543,16 +1526,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.tcx().sess.bug("Send/Sync shouldn't occur in builtin_bounds()"); } - ty::BoundCopy | ty::BoundSized => { - Err(Unimplemented) - } + ty::BoundCopy | ty::BoundSized => Err(Unimplemented), } } - ty::ty_tup(ref tys) => { - // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet - Ok(If(tys.clone())) - } + // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet + ty::ty_tup(ref tys) => Ok(If(tys.clone())), ty::ty_closure(def_id, _, substs) => { // FIXME -- This case is tricky. In the case of by-ref @@ -1581,9 +1560,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } match self.closure_typer.closure_upvars(def_id, substs) { - Some(upvars) => { - Ok(If(upvars.iter().map(|c| c.ty).collect())) - } + Some(upvars) => Ok(If(upvars.iter().map(|c| c.ty).collect())), None => { debug!("assemble_builtin_bound_candidates: no upvar types available yet"); Ok(AmbiguousBuiltin) @@ -1609,8 +1586,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { nominal(bound, types) } - ty::ty_projection(_) | - ty::ty_param(_) => { + ty::ty_projection(_) | ty::ty_param(_) => { // Note: A type parameter is only considered to meet a // particular bound if there is a where clause telling // us that it does, and that case is handled by @@ -1626,12 +1602,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Ok(AmbiguousBuiltin) } - ty::ty_err => { - Ok(If(Vec::new())) - } + ty::ty_err => Ok(If(Vec::new())), - ty::ty_infer(ty::FreshTy(_)) | - ty::ty_infer(ty::FreshIntTy(_)) => { + ty::ty_infer(ty::FreshTy(_)) + | ty::ty_infer(ty::FreshIntTy(_)) => { self.tcx().sess.bug( &format!( "asked to assemble builtin bounds of unexpected type: {}", @@ -1641,7 +1615,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { fn nominal<'cx, 'tcx>(bound: ty::BuiltinBound, types: Vec>) - -> Result,SelectionError<'tcx>> + -> Result, SelectionError<'tcx>> { // First check for markers and other nonsense. match bound { @@ -1692,7 +1666,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.tcx().sess.bug( &format!( "asked to assemble constituent types of unexpected type: {}", - t.repr(self.tcx()))[]); + t.repr(self.tcx()))); } ty::ty_uniq(referent_ty) => { // Box @@ -1909,7 +1883,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }).collect::>(); let obligations = match obligations { Ok(o) => o, - Err(ErrorReported) => Vec::new() + Err(ErrorReported) => Vec::new(), }; let obligations = VecPerParamSpace::new(obligations, Vec::new(), Vec::new()); @@ -1937,14 +1911,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let self_ty = self.infcx.shallow_resolve(obligation.predicate.0.self_ty()); match self.constituent_types_for_ty(self_ty) { - Some(types) => { - Ok(self.vtable_default_impl(obligation, impl_def_id, types)) - } + Some(types) => Ok(self.vtable_default_impl(obligation, impl_def_id, types)), None => { self.tcx().sess.bug( &format!( "asked to confirm default implementation for ambiguous type: {}", - self_ty.repr(self.tcx()))[]); + self_ty.repr(self.tcx()))); } } } @@ -2223,9 +2195,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { { match self.match_impl(impl_def_id, obligation, snapshot, skol_map, skol_obligation_trait_ref) { - Ok(substs) => { - substs - } + Ok(substs) => substs, Err(()) => { self.tcx().sess.bug( &format!("Impl {} was matchable against {} but now is not", @@ -2273,30 +2243,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { skol_obligation_trait_ref.repr(self.tcx())); let origin = infer::RelateOutputImplTypes(obligation.cause.span); - match self.infcx.sub_trait_refs(false, - origin, - impl_trait_ref.value.clone(), - skol_obligation_trait_ref) { - Ok(()) => { } - Err(e) => { - debug!("match_impl: failed sub_trait_refs due to `{}`", - ty::type_err_to_str(self.tcx(), &e)); - return Err(()); - } + if let Err(e) = self.infcx.sub_trait_refs(false, + origin, + impl_trait_ref.value.clone(), + skol_obligation_trait_ref) { + debug!("match_impl: failed sub_trait_refs due to `{}`", + ty::type_err_to_str(self.tcx(), &e)); + return Err(()); } - match self.infcx.leak_check(skol_map, snapshot) { - Ok(()) => { } - Err(e) => { - debug!("match_impl: failed leak check due to `{}`", - ty::type_err_to_str(self.tcx(), &e)); - return Err(()); - } + if let Err(e) = self.infcx.leak_check(skol_map, snapshot) { + debug!("match_impl: failed leak check due to `{}`", + ty::type_err_to_str(self.tcx(), &e)); + return Err(()); } debug!("match_impl: success impl_substs={}", impl_substs.repr(self.tcx())); - Ok(Normalized { value: impl_substs, - obligations: impl_trait_ref.obligations }) + Ok(Normalized { + value: impl_substs, + obligations: impl_trait_ref.obligations + }) } fn fast_reject_trait_refs(&mut self, @@ -2332,9 +2298,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { where_clause_trait_ref: ty::PolyTraitRef<'tcx>) -> Result>,()> { - let () = - try!(self.match_poly_trait_ref(obligation, where_clause_trait_ref)); - + try!(self.match_poly_trait_ref(obligation, where_clause_trait_ref)); Ok(Vec::new()) } @@ -2451,7 +2415,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match self.tcx().trait_impls.borrow().get(&trait_def_id) { None => Vec::new(), - Some(impls) => impls.borrow().clone() + Some(impls) => impls.borrow().clone(), } } @@ -2549,9 +2513,7 @@ impl<'tcx> Repr<'tcx> for SelectionCandidate<'tcx> { DefaultImplCandidate(t) => format!("DefaultImplCandidate({:?})", t), ProjectionCandidate => format!("ProjectionCandidate"), FnPointerCandidate => format!("FnPointerCandidate"), - ObjectCandidate => { - format!("ObjectCandidate") - } + ObjectCandidate => format!("ObjectCandidate"), ClosureCandidate(c, ref s) => { format!("ClosureCandidate({:?},{})", c, s.repr(tcx)) } @@ -2582,9 +2544,7 @@ impl<'o, 'tcx> Iterator for Option<&'o TraitObligationStack<'o, 'tcx>> { *self = o.previous; Some(o) } - None => { - None - } + None => None } } } @@ -2599,15 +2559,11 @@ impl<'o, 'tcx> Repr<'tcx> for TraitObligationStack<'o, 'tcx> { impl<'tcx> EvaluationResult<'tcx> { fn may_apply(&self) -> bool { match *self { - EvaluatedToOk | - EvaluatedToAmbig | - EvaluatedToErr(Overflow) | - EvaluatedToErr(OutputTypeParameterMismatch(..)) => { - true - } - EvaluatedToErr(Unimplemented) => { - false - } + EvaluatedToOk + | EvaluatedToAmbig + | EvaluatedToErr(Overflow) + | EvaluatedToErr(OutputTypeParameterMismatch(..)) => true, + EvaluatedToErr(Unimplemented) => false, } } } diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs index b3bc898748fdc..a419d4134b40e 100644 --- a/src/librustc/plugin/load.rs +++ b/src/librustc/plugin/load.rs @@ -15,7 +15,7 @@ use metadata::creader::CrateReader; use plugin::registry::Registry; use std::mem; -use std::env; +use std::os; use std::dynamic_lib::DynamicLibrary; use std::borrow::ToOwned; use syntax::ast; @@ -103,7 +103,7 @@ impl<'a> PluginLoader<'a> { path: Path, symbol: String) -> PluginRegistrarFun { // Make sure the path contains a / or the linker will search for it. - let path = env::current_dir().unwrap().join(&path); + let path = os::getcwd().unwrap().join(&path); let lib = match DynamicLibrary::open(Some(&path)) { Ok(lib) => lib, diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index b690cc7f7d06b..615ee77c1e095 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -27,8 +27,8 @@ use syntax::{ast, codemap}; use rustc_back::target::Target; -use std::env; use std::cell::{Cell, RefCell}; +use std::os; pub mod config; pub mod search_paths; @@ -347,7 +347,7 @@ pub fn build_session_(sopts: config::Options, if path.is_absolute() { path.clone() } else { - env::current_dir().unwrap().join(&path) + os::getcwd().unwrap().join(&path) } ); @@ -370,7 +370,7 @@ pub fn build_session_(sopts: config::Options, plugin_registrar_fn: Cell::new(None), default_sysroot: default_sysroot, local_crate_source_file: local_crate_source_file, - working_dir: env::current_dir().unwrap(), + working_dir: os::getcwd().unwrap(), lint_store: RefCell::new(lint::LintStore::new()), lints: RefCell::new(NodeMap()), crate_types: RefCell::new(Vec::new()), diff --git a/src/librustc_back/archive.rs b/src/librustc_back/archive.rs index 6bf745315eace..3fcae6a8034c2 100644 --- a/src/librustc_back/archive.rs +++ b/src/librustc_back/archive.rs @@ -14,7 +14,7 @@ use std::old_io::fs::PathExtensions; use std::old_io::process::{Command, ProcessOutput}; use std::old_io::{fs, TempDir}; use std::old_io; -use std::env; +use std::os; use std::str; use syntax::diagnostic::Handler as ErrorHandler; @@ -224,7 +224,7 @@ impl<'a> ArchiveBuilder<'a> { pub fn build(self) -> Archive<'a> { // Get an absolute path to the destination, so `ar` will work even // though we run it from `self.work_dir`. - let abs_dst = env::current_dir().unwrap().join(&self.archive.dst); + let abs_dst = os::getcwd().unwrap().join(&self.archive.dst); assert!(!abs_dst.is_relative()); let mut args = vec![&abs_dst]; let mut total_len = abs_dst.as_vec().len(); @@ -283,7 +283,7 @@ impl<'a> ArchiveBuilder<'a> { // First, extract the contents of the archive to a temporary directory. // We don't unpack directly into `self.work_dir` due to the possibility // of filename collisions. - let archive = env::current_dir().unwrap().join(archive); + let archive = os::getcwd().unwrap().join(archive); run_ar(self.archive.handler, &self.archive.maybe_ar_prog, "x", Some(loc.path()), &[&archive]); diff --git a/src/librustc_back/fs.rs b/src/librustc_back/fs.rs index acf49d1ca46e3..99a1df95a80cd 100644 --- a/src/librustc_back/fs.rs +++ b/src/librustc_back/fs.rs @@ -10,13 +10,13 @@ use std::old_io; use std::old_io::fs; -use std::env; +use std::os; /// Returns an absolute path in the filesystem that `path` points to. The /// returned path does not contain any symlinks in its hierarchy. pub fn realpath(original: &Path) -> old_io::IoResult { static MAX_LINKS_FOLLOWED: uint = 256; - let original = try!(env::current_dir()).join(original); + let original = try!(os::getcwd()).join(original); // Right now lstat on windows doesn't work quite well if cfg!(windows) { diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index d589b063204c7..711f937d2f355 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -41,6 +41,7 @@ #![feature(rustc_private)] #![feature(staged_api)] #![feature(env)] +#![feature(path)] extern crate syntax; extern crate serialize; diff --git a/src/librustc_back/rpath.rs b/src/librustc_back/rpath.rs index 3f2dcee511095..943ff52925a24 100644 --- a/src/librustc_back/rpath.rs +++ b/src/librustc_back/rpath.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - use std::collections::HashSet; use std::env; use std::old_io::IoError; +use std::os; use syntax::ast; pub struct RPathConfig where @@ -109,7 +109,7 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path "$ORIGIN" }; - let cwd = env::current_dir().unwrap(); + let cwd = os::getcwd().unwrap(); let mut lib = (config.realpath)(&cwd.join(lib)).unwrap(); lib.pop(); let mut output = (config.realpath)(&cwd.join(&config.out_filename)).unwrap(); @@ -129,7 +129,7 @@ fn get_install_prefix_rpath(config: RPathConfig) -> String where let path = (config.get_install_prefix_lib_path)(); let path = env::current_dir().unwrap().join(&path); // FIXME (#9639): This needs to handle non-utf8 paths - path.as_str().expect("non-utf8 component in rpath").to_string() + path.to_str().expect("non-utf8 component in rpath").to_string() } fn minimize_rpaths(rpaths: &[String]) -> Vec { diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index b04c07977c369..d09a7c355d3e3 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -310,6 +310,7 @@ impl Target { /// JSON decoding. pub fn search(target: &str) -> Result { use std::env; + use std::os; use std::ffi::OsString; use std::old_io::File; use std::old_path::Path; @@ -396,7 +397,7 @@ impl Target { // FIXME 16351: add a sane default search path? - for dir in env::split_paths(&target_path) { + for dir in os::split_paths(target_path.to_str().unwrap()).iter() { let p = dir.join(path.clone()); if p.is_file() { return load_file(&p); diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index b0a03408b51e1..67462ab01003e 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -105,10 +105,10 @@ fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) { ast::ItemConst(_, ref ex) => { gather_loans::gather_loans_in_static_initializer(this, &**ex); } - _ => { - visit::walk_item(this, item); - } + _ => { } } + + visit::walk_item(this, item); } /// Collection of conclusions determined via borrow checker analyses. diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index bd911c20afc47..425ec7ec452ee 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -32,6 +32,7 @@ use super::Compilation; use serialize::json; use std::env; +use std::os; use std::ffi::OsString; use std::old_io::fs; use std::old_io; @@ -471,7 +472,7 @@ pub fn phase_2_configure_and_expand(sess: &Session, if cfg!(windows) { _old_path = env::var_os("PATH").unwrap_or(_old_path); let mut new_path = sess.host_filesearch(PathKind::All).get_dylib_search_paths(); - new_path.extend(env::split_paths(&_old_path)); + new_path.extend(os::split_paths(_old_path.to_str().unwrap()).into_iter()); env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap()); } let features = sess.features.borrow(); @@ -736,7 +737,7 @@ pub fn phase_6_link_output(sess: &Session, outputs: &OutputFilenames) { let old_path = env::var_os("PATH").unwrap_or(OsString::from_str("")); let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(); - new_path.extend(env::split_paths(&old_path)); + new_path.extend(os::split_paths(old_path.to_str().unwrap()).into_iter()); env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap()); time(sess.time_passes(), "linking", (), |_| diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index cdcc9850e423e..d9cedc4829851 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -806,11 +806,11 @@ fn walk_ty() { let tup2_ty = ty::mk_tup(tcx, vec!(tup1_ty, tup1_ty, uint_ty)); let uniq_ty = ty::mk_uniq(tcx, tup2_ty); let walked: Vec<_> = uniq_ty.walk().collect(); - assert_eq!(vec!(uniq_ty, - tup2_ty, - tup1_ty, int_ty, uint_ty, int_ty, uint_ty, - tup1_ty, int_ty, uint_ty, int_ty, uint_ty, - uint_ty), + assert_eq!([uniq_ty, + tup2_ty, + tup1_ty, int_ty, uint_ty, int_ty, uint_ty, + tup1_ty, int_ty, uint_ty, int_ty, uint_ty, + uint_ty], walked); }) } diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 93ab4a96e6f56..c1d22cc973c24 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -359,7 +359,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, }; unsafe { let _icx = push_ctxt("const_expr"); - return match e.node { + match e.node { ast::ExprLit(ref lit) => { const_lit(cx, e, &**lit) } @@ -379,7 +379,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let (te2, _) = const_expr(cx, &**e2, param_substs); let te2 = base::cast_shift_const_rhs(b, te1, te2); - return match b.node { + match b.node { ast::BiAdd => { if is_float { llvm::LLVMConstFAdd(te1, te2) } else { llvm::LLVMConstAdd(te1, te2) } @@ -433,7 +433,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ast::ExprUnary(u, ref e) => { let (te, ty) = const_expr(cx, &**e, param_substs); let is_float = ty::type_is_fp(ty); - return match u { + match u { ast::UnUniq | ast::UnDeref => { const_deref(cx, te, ty).0 } @@ -514,8 +514,8 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, if expr::cast_is_noop(basety, ety) { return v; } - return match (expr::cast_type_kind(cx.tcx(), basety), - expr::cast_type_kind(cx.tcx(), ety)) { + match (expr::cast_type_kind(cx.tcx(), basety), + expr::cast_type_kind(cx.tcx(), ety)) { (expr::cast_integral, expr::cast_integral) => { let s = ty::type_is_signed(basety) as Bool; @@ -584,13 +584,13 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } let opt_def = cx.tcx().def_map.borrow().get(&cur.id).map(|d| d.full_def()); if let Some(def::DefStatic(def_id, _)) = opt_def { - return get_static_val(cx, def_id, ety); + get_static_val(cx, def_id, ety) + } else { + // If this isn't the address of a static, then keep going through + // normal constant evaluation. + let (v, _) = const_expr(cx, &**sub, param_substs); + addr_of(cx, v, "ref", e.id) } - - // If this isn't the address of a static, then keep going through - // normal constant evaluation. - let (v, _) = const_expr(cx, &**sub, param_substs); - addr_of(cx, v, "ref", e.id) } ast::ExprAddrOf(ast::MutMutable, ref sub) => { let (v, _) = const_expr(cx, &**sub, param_substs); @@ -740,7 +740,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } _ => cx.sess().span_bug(e.span, "bad constant expression type in consts::const_expr") - }; + } } } diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index 90ca6a798056b..1fba4a21ccd37 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -203,6 +203,56 @@ //! failure, but rather because the target type `Foo` is itself just //! not well-formed. Basically we get to assume well-formedness of all //! types involved before considering variance. +//! +//! ### Associated types +//! +//! Any trait with an associated type is invariant with respect to all +//! of its inputs. To see why this makes sense, consider what +//! subtyping for a trait reference means: +//! +//! <: +//! +//! means that if I know that `T as Trait`, +//! I also know that `U as +//! Trait`. Moreover, if you think of it as +//! dictionary passing style, it means that +//! a dictionary for `` is safe +//! to use where a dictionary for `` is expected. +//! +//! The problem is that when you can +//! project types out from ``, +//! the relationship to types projected out +//! of `` is completely unknown +//! unless `T==U` (see #21726 for more +//! details). Making `Trait` invariant +//! ensures that this is true. +//! +//! *Historical note: we used to preserve this invariant another way, +//! by tweaking the subtyping rules and requiring that when a type `T` +//! appeared as part of a projection, that was considered an invariant +//! location, but this version does away with the need for those +//! somewhat "special-case-feeling" rules.* +//! +//! Another related reason is that if we didn't make traits with +//! associated types invariant, then projection is no longer a +//! function with a single result. Consider: +//! +//! ``` +//! trait Identity { type Out; fn foo(&self); } +//! impl Identity for T { type Out = T; ... } +//! ``` +//! +//! Now if I have `<&'static () as Identity>::Out`, this can be +//! validly derived as `&'a ()` for any `'a`: +//! +//! <&'a () as Identity> <: <&'static () as Identity> +//! if &'static () < : &'a () -- Identity is contravariant in Self +//! if 'static : 'a -- Subtyping rules for relations +//! +//! This change otoh means that `<'static () as Identity>::Out` is +//! always `&'static ()` (which might then be upcast to `'a ()`, +//! separately). This was helpful in solving #21750. use self::VarianceTerm::*; use self::ParamKind::*; @@ -613,7 +663,18 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> { &method.fty.sig, self.covariant); } - ty::TypeTraitItem(_) => {} + ty::TypeTraitItem(ref data) => { + // Any trait with an associated type is + // invariant with respect to all of its + // inputs. See length discussion in the comment + // on this module. + let projection_ty = ty::mk_projection(tcx, + trait_def.trait_ref.clone(), + data.name); + self.add_constraints_from_ty(&trait_def.generics, + projection_ty, + self.invariant); + } } } } @@ -893,7 +954,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { trait_def.generics.types.as_slice(), trait_def.generics.regions.as_slice(), trait_ref.substs, - self.invariant); + variance); } ty::ty_trait(ref data) => { diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index bf14b86ebd1e3..78f126dcf6a82 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -13,7 +13,7 @@ use std::sync::mpsc::channel; use std::dynamic_lib::DynamicLibrary; use std::old_io::{Command, TempDir}; use std::old_io; -use std::env; +use std::os; use std::str; use std::thread; use std::thunk::Thunk; @@ -46,7 +46,7 @@ pub fn run(input: &str, let input = config::Input::File(input_path.clone()); let sessopts = config::Options { - maybe_sysroot: Some(env::current_exe().unwrap().dir_path().dir_path()), + maybe_sysroot: Some(os::self_exe_name().unwrap().dir_path().dir_path()), search_paths: libs.clone(), crate_types: vec!(config::CrateTypeDylib), externs: externs.clone(), @@ -113,7 +113,7 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths, let input = config::Input::Str(test.to_string()); let sessopts = config::Options { - maybe_sysroot: Some(env::current_exe().unwrap().dir_path().dir_path()), + maybe_sysroot: Some(os::self_exe_name().unwrap().dir_path().dir_path()), search_paths: libs, crate_types: vec!(config::CrateTypeExecutable), output_types: vec!(config::OutputTypeExe), diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index a0f42815b4396..05d4e0f59fefc 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -3074,19 +3074,19 @@ mod tests { #[test] fn test_decode_array() { let v: Vec<()> = super::decode("[]").unwrap(); - assert_eq!(v, vec![]); + assert_eq!(v, []); let v: Vec<()> = super::decode("[null]").unwrap(); - assert_eq!(v, vec![()]); + assert_eq!(v, [()]); let v: Vec = super::decode("[true]").unwrap(); - assert_eq!(v, vec![true]); + assert_eq!(v, [true]); let v: Vec = super::decode("[3, 1]").unwrap(); - assert_eq!(v, vec![3, 1]); + assert_eq!(v, [3, 1]); let v: Vec> = super::decode("[[3], [1, 2]]").unwrap(); - assert_eq!(v, vec![vec![3], vec![1, 2]]); + assert_eq!(v, [vec![3], vec![1, 2]]); } #[test] diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index df2fb538c0a50..faddbba50590f 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1212,7 +1212,7 @@ impl Debug for HashMap where K: Eq + Hash + Debug, V: Debug, S: HashState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "HashMap {{")); + try!(write!(f, "{{")); for (i, (k, v)) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -1999,9 +1999,9 @@ mod test_map { let map_str = format!("{:?}", map); - assert!(map_str == "HashMap {1: 2, 3: 4}" || - map_str == "HashMap {3: 4, 1: 2}"); - assert_eq!(format!("{:?}", empty), "HashMap {}"); + assert!(map_str == "{1: 2, 3: 4}" || + map_str == "{3: 4, 1: 2}"); + assert_eq!(format!("{:?}", empty), "{}"); } #[test] diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index e0631a64d44b1..cdc0ebd76aada 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -598,7 +598,7 @@ impl fmt::Debug for HashSet S: HashState { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, "HashSet {{")); + try!(write!(f, "{{")); for (i, x) in self.iter().enumerate() { if i != 0 { try!(write!(f, ", ")); } @@ -1186,8 +1186,8 @@ mod test_set { let set_str = format!("{:?}", set); - assert!(set_str == "HashSet {1, 2}" || set_str == "HashSet {2, 1}"); - assert_eq!(format!("{:?}", empty), "HashSet {}"); + assert!(set_str == "{1, 2}" || set_str == "{2, 1}"); + assert_eq!(format!("{:?}", empty), "{}"); } #[test] diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 7513cb8a61c7c..4c03d8915eb8a 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -23,7 +23,7 @@ use num::{Int, UnsignedInt}; use ops::{Deref, DerefMut, Drop}; use option::Option; use option::Option::{Some, None}; -use ptr::{self, PtrExt, copy_nonoverlapping_memory, Unique, zero_memory}; +use ptr::{self, PtrExt, Unique}; use rt::heap::{allocate, deallocate, EMPTY}; use collections::hash_state::HashState; @@ -477,8 +477,8 @@ impl>> GapThenFull { pub fn shift(mut self) -> Option> { unsafe { *self.gap.raw.hash = mem::replace(&mut *self.full.raw.hash, EMPTY_BUCKET); - copy_nonoverlapping_memory(self.gap.raw.key, self.full.raw.key, 1); - copy_nonoverlapping_memory(self.gap.raw.val, self.full.raw.val, 1); + ptr::copy_nonoverlapping(self.gap.raw.key, self.full.raw.key, 1); + ptr::copy_nonoverlapping(self.gap.raw.val, self.full.raw.val, 1); } let FullBucket { raw: prev_raw, idx: prev_idx, .. } = self.full; @@ -637,7 +637,7 @@ impl RawTable { pub fn new(capacity: usize) -> RawTable { unsafe { let ret = RawTable::new_uninitialized(capacity); - zero_memory(*ret.hashes, capacity); + ptr::write_bytes(*ret.hashes, 0, capacity); ret } } diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs index fcae8e791604d..babae3b3019ec 100644 --- a/src/libstd/dynamic_lib.rs +++ b/src/libstd/dynamic_lib.rs @@ -21,6 +21,7 @@ use ffi::CString; use mem; use env; use str; +use os; pub struct DynamicLibrary { handle: *mut u8 @@ -102,7 +103,7 @@ impl DynamicLibrary { /// process pub fn search_path() -> Vec { match env::var_os(DynamicLibrary::envvar()) { - Some(var) => env::split_paths(&var).collect(), + Some(var) => os::split_paths(var.to_str().unwrap()), None => Vec::new(), } } diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 0e1f5f2ba0294..e2849ec92e088 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -21,7 +21,8 @@ use prelude::v1::*; use error::Error; use ffi::{OsString, AsOsStr}; use fmt; -use old_io::IoResult; +use io; +use path::{AsPath, PathBuf}; use sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT, Ordering}; use sync::{StaticMutex, MUTEX_INIT}; use sys::os as os_imp; @@ -46,7 +47,7 @@ use sys::os as os_imp; /// let p = env::current_dir().unwrap(); /// println!("The current directory is {}", p.display()); /// ``` -pub fn current_dir() -> IoResult { +pub fn current_dir() -> io::Result { os_imp::getcwd() } @@ -57,14 +58,14 @@ pub fn current_dir() -> IoResult { /// /// ```rust /// use std::env; -/// use std::old_path::Path; +/// use std::path::Path; /// /// let root = Path::new("/"); /// assert!(env::set_current_dir(&root).is_ok()); /// println!("Successfully changed working directory to {}!", root.display()); /// ``` -pub fn set_current_dir(p: &Path) -> IoResult<()> { - os_imp::chdir(p) +pub fn set_current_dir(p: &P) -> io::Result<()> { + os_imp::chdir(p.as_path()) } static ENV_LOCK: StaticMutex = MUTEX_INIT; @@ -280,8 +281,8 @@ pub fn split_paths(unparsed: &T) -> SplitPaths { } impl<'a> Iterator for SplitPaths<'a> { - type Item = Path; - fn next(&mut self) -> Option { self.inner.next() } + type Item = PathBuf; + fn next(&mut self) -> Option { self.inner.next() } fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } } @@ -305,10 +306,11 @@ pub struct JoinPathsError { /// /// ```rust /// use std::env; +/// use std::path::PathBuf; /// /// if let Some(path) = env::var_os("PATH") { /// let mut paths = env::split_paths(&path).collect::>(); -/// paths.push(Path::new("/home/xyz/bin")); +/// paths.push(PathBuf::new("/home/xyz/bin")); /// let new_path = env::join_paths(paths.iter()).unwrap(); /// env::set_var("PATH", &new_path); /// } @@ -355,7 +357,7 @@ impl Error for JoinPathsError { /// None => println!("Impossible to get your home dir!") /// } /// ``` -pub fn home_dir() -> Option { +pub fn home_dir() -> Option { os_imp::home_dir() } @@ -369,7 +371,7 @@ pub fn home_dir() -> Option { /// On Windows, returns the value of, in order, the 'TMP', 'TEMP', /// 'USERPROFILE' environment variable if any are set and not the empty /// string. Otherwise, tmpdir returns the path to the Windows directory. -pub fn temp_dir() -> Path { +pub fn temp_dir() -> PathBuf { os_imp::temp_dir() } @@ -396,7 +398,7 @@ pub fn temp_dir() -> Path { /// Err(e) => println!("failed to get current exe path: {}", e), /// }; /// ``` -pub fn current_exe() -> IoResult { +pub fn current_exe() -> io::Result { os_imp::current_exe() } @@ -825,6 +827,7 @@ mod tests { use iter::repeat; use rand::{self, Rng}; use ffi::{OsString, OsStr}; + use path::PathBuf; fn make_rand_name() -> OsString { let mut rng = rand::thread_rng(); @@ -924,7 +927,7 @@ mod tests { fn split_paths_windows() { fn check_parse(unparsed: &str, parsed: &[&str]) -> bool { split_paths(unparsed).collect::>() == - parsed.iter().map(|s| Path::new(*s)).collect::>() + parsed.iter().map(|s| PathBuf::new(*s)).collect::>() } assert!(check_parse("", &mut [""])); @@ -944,7 +947,7 @@ mod tests { fn split_paths_unix() { fn check_parse(unparsed: &str, parsed: &[&str]) -> bool { split_paths(unparsed).collect::>() == - parsed.iter().map(|s| Path::new(*s)).collect::>() + parsed.iter().map(|s| PathBuf::new(*s)).collect::>() } assert!(check_parse("", &mut [""])); diff --git a/src/libstd/fs.rs b/src/libstd/fs/mod.rs similarity index 98% rename from src/libstd/fs.rs rename to src/libstd/fs/mod.rs index 98c1b50a9bf14..64ec025a5c423 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs/mod.rs @@ -25,6 +25,10 @@ use sys::fs2 as fs_imp; use sys_common::{AsInnerMut, FromInner, AsInner}; use vec::Vec; +pub use self::tempdir::TempDir; + +mod tempdir; + /// A reference to an open file on the filesystem. /// /// An instance of a `File` can be read and/or written depending on what options @@ -325,6 +329,10 @@ impl FromInner for Permissions { } } +impl AsInner for Permissions { + fn as_inner(&self) -> &fs_imp::FilePermissions { &self.0 } +} + impl Iterator for ReadDir { type Item = io::Result; @@ -540,7 +548,14 @@ pub fn create_dir_all(path: &P) -> io::Result<()> { Some(p) if p != path => try!(create_dir_all(p)), _ => {} } - create_dir(path) + // If the file name of the given `path` is blank then the creation of the + // parent directory will have taken care of the whole path for us, so we're + // good to go. + if path.file_name().is_none() { + Ok(()) + } else { + create_dir(path) + } } /// Remove an existing, empty directory @@ -1500,4 +1515,11 @@ mod tests { check!(fs::set_permissions(&path, perm)); check!(fs::remove_file(&path)); } + + #[test] + fn mkdir_trailing_slash() { + let tmpdir = tmpdir(); + let path = tmpdir.join("file"); + check!(fs::create_dir_all(&path.join("a/"))); + } } diff --git a/src/libstd/fs/tempdir.rs b/src/libstd/fs/tempdir.rs new file mode 100644 index 0000000000000..79bdb35dd48cd --- /dev/null +++ b/src/libstd/fs/tempdir.rs @@ -0,0 +1,125 @@ +// 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. + +#![unstable(feature = "tempdir", reason = "needs an RFC before stabilization")] + +use prelude::v1::*; + +use env; +use io::{self, Error, ErrorKind}; +use fs; +use path::{self, PathBuf, AsPath}; +use rand::{thread_rng, Rng}; + +/// A wrapper for a path to temporary directory implementing automatic +/// scope-based deletion. +pub struct TempDir { + path: Option, +} + +// How many times should we (re)try finding an unused random name? It should be +// enough that an attacker will run out of luck before we run out of patience. +const NUM_RETRIES: u32 = 1 << 31; +// How many characters should we include in a random file name? It needs to +// be enough to dissuade an attacker from trying to preemptively create names +// of that length, but not so huge that we unnecessarily drain the random number +// generator of entropy. +const NUM_RAND_CHARS: uint = 12; + +impl TempDir { + /// Attempts to make a temporary directory inside of `tmpdir` whose name + /// will have the prefix `prefix`. The directory will be automatically + /// deleted once the returned wrapper is destroyed. + /// + /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] // rand usage + pub fn new_in(tmpdir: &P, prefix: &str) + -> io::Result { + let storage; + let mut tmpdir = tmpdir.as_path(); + if !tmpdir.is_absolute() { + let cur_dir = try!(env::current_dir()); + storage = cur_dir.join(tmpdir); + tmpdir = &storage; + // return TempDir::new_in(&cur_dir.join(tmpdir), prefix); + } + + let mut rng = thread_rng(); + for _ in 0..NUM_RETRIES { + let suffix: String = rng.gen_ascii_chars().take(NUM_RAND_CHARS).collect(); + let leaf = if prefix.len() > 0 { + format!("{}.{}", prefix, suffix) + } else { + // If we're given an empty string for a prefix, then creating a + // directory starting with "." would lead to it being + // semi-invisible on some systems. + suffix + }; + let path = tmpdir.join(&leaf); + match fs::create_dir(&path) { + Ok(_) => return Ok(TempDir { path: Some(path) }), + Err(ref e) if e.kind() == ErrorKind::PathAlreadyExists => {} + Err(e) => return Err(e) + } + } + + Err(Error::new(ErrorKind::PathAlreadyExists, + "too many temporary directories already exist", + None)) + } + + /// Attempts to make a temporary directory inside of `env::temp_dir()` whose + /// name will have the prefix `prefix`. The directory will be automatically + /// deleted once the returned wrapper is destroyed. + /// + /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] + pub fn new(prefix: &str) -> io::Result { + TempDir::new_in(&env::temp_dir(), prefix) + } + + /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper. + /// This discards the wrapper so that the automatic deletion of the + /// temporary directory is prevented. + pub fn into_path(mut self) -> PathBuf { + self.path.take().unwrap() + } + + /// Access the wrapped `std::path::Path` to the temporary directory. + pub fn path(&self) -> &path::Path { + self.path.as_ref().unwrap() + } + + /// Close and remove the temporary directory + /// + /// Although `TempDir` removes the directory on drop, in the destructor + /// any errors are ignored. To detect errors cleaning up the temporary + /// directory, call `close` instead. + pub fn close(mut self) -> io::Result<()> { + self.cleanup_dir() + } + + fn cleanup_dir(&mut self) -> io::Result<()> { + match self.path { + Some(ref p) => fs::remove_dir_all(p), + None => Ok(()) + } + } +} + +impl Drop for TempDir { + fn drop(&mut self) { + let _ = self.cleanup_dir(); + } +} + +// the tests for this module need to change the path using change_dir, +// and this doesn't play nicely with other tests so these unit tests are located +// in src/test/run-pass/tempfile.rs diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 9ef319782369d..1135609959015 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -48,7 +48,7 @@ impl BufReader { } /// Gets a reference to the underlying reader. - pub fn get_ref<'a>(&self) -> &R { &self.inner } + pub fn get_ref(&self) -> &R { &self.inner } /// Gets a mutable reference to the underlying reader. /// @@ -155,9 +155,9 @@ impl BufWriter { if written > 0 { // NB: would be better expressed as .remove(0..n) if it existed unsafe { - ptr::copy_memory(self.buf.as_mut_ptr(), - self.buf.as_ptr().offset(written as isize), - len - written); + ptr::copy(self.buf.as_mut_ptr(), + self.buf.as_ptr().offset(written as isize), + len - written); } } self.buf.truncate(len - written); diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index caaedeeb2fc54..b5bdeb7f181b0 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -123,6 +123,7 @@ #![feature(unsafe_no_drop_flag)] #![feature(macro_reexport)] #![feature(hash)] +#![feature(unique)] #![cfg_attr(test, feature(test, rustc_private, env))] // Don't link to std. We are std. diff --git a/src/libstd/net/test.rs b/src/libstd/net/test.rs index c70e92884ac65..aec50d638c69f 100644 --- a/src/libstd/net/test.rs +++ b/src/libstd/net/test.rs @@ -34,6 +34,6 @@ fn base_port() -> u16 { let dirs = ["32-opt", "32-nopt", "64-opt", "64-nopt", "64-opt-vg", "all-opt", "snap3", "dist"]; dirs.iter().enumerate().find(|&(_, dir)| { - cwd.as_str().unwrap().contains(dir) + cwd.to_str().unwrap().contains(dir) }).map(|p| p.0).unwrap_or(0) as u16 * 1000 + 19600 } diff --git a/src/libstd/old_io/extensions.rs b/src/libstd/old_io/extensions.rs index c2a6c515acc70..8bd19f063f030 100644 --- a/src/libstd/old_io/extensions.rs +++ b/src/libstd/old_io/extensions.rs @@ -328,7 +328,7 @@ mod test { fn read_bytes() { let mut reader = MemReader::new(vec!(10, 11, 12, 13)); let bytes = reader.read_exact(4).unwrap(); - assert!(bytes == vec!(10, 11, 12, 13)); + assert_eq!(bytes, [10, 11, 12, 13]); } #[test] @@ -337,7 +337,7 @@ mod test { count: 0, }; let bytes = reader.read_exact(4).unwrap(); - assert!(bytes == vec!(10, 11, 12, 13)); + assert_eq!(bytes, [10, 11, 12, 13]); } #[test] @@ -351,7 +351,7 @@ mod test { let mut reader = MemReader::new(vec![10, 11, 12, 13]); let mut buf = vec![8, 9]; assert!(reader.push_at_least(4, 4, &mut buf).is_ok()); - assert!(buf == vec![8, 9, 10, 11, 12, 13]); + assert_eq!(buf, [8, 9, 10, 11, 12, 13]); } #[test] @@ -361,7 +361,7 @@ mod test { }; let mut buf = vec![8, 9]; assert!(reader.push_at_least(4, 4, &mut buf).is_ok()); - assert!(buf == vec![8, 9, 10, 11, 12, 13]); + assert_eq!(buf, [8, 9, 10, 11, 12, 13]); } #[test] @@ -369,7 +369,7 @@ mod test { let mut reader = MemReader::new(vec![10, 11]); let mut buf = vec![8, 9]; assert!(reader.push_at_least(4, 4, &mut buf).is_err()); - assert!(buf == vec![8, 9, 10, 11]); + assert_eq!(buf, [8, 9, 10, 11]); } #[test] @@ -379,7 +379,7 @@ mod test { }; let mut buf = vec![8, 9]; assert!(reader.push_at_least(4, 4, &mut buf).is_err()); - assert!(buf == vec![8, 9, 10]); + assert_eq!(buf, [8, 9, 10]); } #[test] @@ -388,7 +388,7 @@ mod test { count: 0, }; let buf = reader.read_to_end().unwrap(); - assert!(buf == vec!(10, 11, 12, 13)); + assert_eq!(buf, [10, 11, 12, 13]); } #[test] @@ -398,7 +398,7 @@ mod test { count: 0, }; let buf = reader.read_to_end().unwrap(); - assert!(buf == vec!(10, 11)); + assert_eq!(buf, [10, 11]); } #[test] diff --git a/src/libstd/old_io/mem.rs b/src/libstd/old_io/mem.rs index 1fd527014a3d6..c08a2c1f477b3 100644 --- a/src/libstd/old_io/mem.rs +++ b/src/libstd/old_io/mem.rs @@ -60,7 +60,7 @@ impl Writer for Vec { /// let mut w = MemWriter::new(); /// w.write(&[0, 1, 2]); /// -/// assert_eq!(w.into_inner(), vec!(0, 1, 2)); +/// assert_eq!(w.into_inner(), [0, 1, 2]); /// ``` #[unstable(feature = "io")] #[deprecated(since = "1.0.0", @@ -118,7 +118,7 @@ impl Writer for MemWriter { /// /// let mut r = MemReader::new(vec!(0, 1, 2)); /// -/// assert_eq!(r.read_to_end().unwrap(), vec!(0, 1, 2)); +/// assert_eq!(r.read_to_end().unwrap(), [0, 1, 2]); /// ``` pub struct MemReader { buf: Vec, @@ -321,7 +321,7 @@ impl<'a> Seek for BufWriter<'a> { /// let buf = [0, 1, 2, 3]; /// let mut r = BufReader::new(&buf); /// -/// assert_eq!(r.read_to_end().unwrap(), vec![0, 1, 2, 3]); +/// assert_eq!(r.read_to_end().unwrap(), [0, 1, 2, 3]); /// ``` pub struct BufReader<'a> { buf: &'a [u8], @@ -504,8 +504,8 @@ mod test { assert_eq!(&buf[..3], b); assert!(reader.read(&mut buf).is_err()); let mut reader = MemReader::new(vec!(0, 1, 2, 3, 4, 5, 6, 7)); - assert_eq!(reader.read_until(3).unwrap(), vec!(0, 1, 2, 3)); - assert_eq!(reader.read_until(3).unwrap(), vec!(4, 5, 6, 7)); + assert_eq!(reader.read_until(3).unwrap(), [0, 1, 2, 3]); + assert_eq!(reader.read_until(3).unwrap(), [4, 5, 6, 7]); assert!(reader.read(&mut buf).is_err()); } @@ -530,8 +530,8 @@ mod test { assert_eq!(&buf[..3], b); assert!(reader.read(&mut buf).is_err()); let mut reader = &mut &*in_buf; - assert_eq!(reader.read_until(3).unwrap(), vec!(0, 1, 2, 3)); - assert_eq!(reader.read_until(3).unwrap(), vec!(4, 5, 6, 7)); + assert_eq!(reader.read_until(3).unwrap(), [0, 1, 2, 3]); + assert_eq!(reader.read_until(3).unwrap(), [4, 5, 6, 7]); assert!(reader.read(&mut buf).is_err()); } @@ -557,8 +557,8 @@ mod test { assert_eq!(&buf[..3], b); assert!(reader.read(&mut buf).is_err()); let mut reader = BufReader::new(&in_buf); - assert_eq!(reader.read_until(3).unwrap(), vec!(0, 1, 2, 3)); - assert_eq!(reader.read_until(3).unwrap(), vec!(4, 5, 6, 7)); + assert_eq!(reader.read_until(3).unwrap(), [0, 1, 2, 3]); + assert_eq!(reader.read_until(3).unwrap(), [4, 5, 6, 7]); assert!(reader.read(&mut buf).is_err()); } diff --git a/src/libstd/old_io/result.rs b/src/libstd/old_io/result.rs index f42cb6ce8c97b..cdf2bae1cbad3 100644 --- a/src/libstd/old_io/result.rs +++ b/src/libstd/old_io/result.rs @@ -87,7 +87,7 @@ mod test { let mut writer: old_io::IoResult> = Ok(Vec::new()); writer.write_all(&[0, 1, 2]).unwrap(); writer.flush().unwrap(); - assert_eq!(writer.unwrap(), vec!(0, 1, 2)); + assert_eq!(writer.unwrap(), [0, 1, 2]); } #[test] diff --git a/src/libstd/old_io/tempfile.rs b/src/libstd/old_io/tempfile.rs index 42317c7a2d431..76753dca52e1e 100644 --- a/src/libstd/old_io/tempfile.rs +++ b/src/libstd/old_io/tempfile.rs @@ -96,9 +96,10 @@ impl TempDir { /// deleted once the returned wrapper is destroyed. /// /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] pub fn new_in(tmpdir: &Path, prefix: &str) -> IoResult { if !tmpdir.is_absolute() { - let cur_dir = try!(env::current_dir()); + let cur_dir = try!(::os::getcwd()); return TempDir::new_in(&cur_dir.join(tmpdir), prefix); } @@ -132,8 +133,9 @@ impl TempDir { /// deleted once the returned wrapper is destroyed. /// /// If no directory can be created, `Err` is returned. + #[allow(deprecated)] pub fn new(prefix: &str) -> IoResult { - TempDir::new_in(&env::temp_dir(), prefix) + TempDir::new_in(&::os::tmpdir(), prefix) } /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper. diff --git a/src/libstd/old_io/test.rs b/src/libstd/old_io/test.rs index ee72beccfa848..43c0b9268a242 100644 --- a/src/libstd/old_io/test.rs +++ b/src/libstd/old_io/test.rs @@ -38,10 +38,11 @@ fn next_test_unix_socket() -> String { /// Get a temporary path which could be the location of a unix socket #[cfg(not(target_os = "ios"))] +#[allow(deprecated)] pub fn next_test_unix() -> Path { let string = next_test_unix_socket(); if cfg!(unix) { - env::temp_dir().join(string) + ::os::tmpdir().join(string) } else { Path::new(format!("{}{}", r"\\.\pipe\", string)) } @@ -88,7 +89,7 @@ fn base_port() -> u16 { // FIXME (#9639): This needs to handle non-utf8 paths let path = env::current_dir().unwrap(); - let path_s = path.as_str().unwrap(); + let path_s = path.to_str().unwrap(); let mut final_base = base; diff --git a/src/libstd/old_io/util.rs b/src/libstd/old_io/util.rs index 5ae239014d188..8e49335ed5469 100644 --- a/src/libstd/old_io/util.rs +++ b/src/libstd/old_io/util.rs @@ -284,7 +284,7 @@ mod test { let mut r = MemReader::new(vec!(0, 1, 2)); { let mut r = LimitReader::new(r.by_ref(), 4); - assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap()); + assert_eq!([0, 1, 2], r.read_to_end().unwrap()); } } @@ -293,9 +293,9 @@ mod test { let mut r = MemReader::new(vec!(0, 1, 2)); { let mut r = LimitReader::new(r.by_ref(), 2); - assert_eq!(vec!(0, 1), r.read_to_end().unwrap()); + assert_eq!([0, 1], r.read_to_end().unwrap()); } - assert_eq!(vec!(2), r.read_to_end().unwrap()); + assert_eq!([2], r.read_to_end().unwrap()); } #[test] @@ -305,7 +305,7 @@ mod test { assert_eq!(3, r.limit()); assert_eq!(0, r.read_byte().unwrap()); assert_eq!(2, r.limit()); - assert_eq!(vec!(1, 2), r.read_to_end().unwrap()); + assert_eq!([1, 2], r.read_to_end().unwrap()); assert_eq!(0, r.limit()); } @@ -314,7 +314,7 @@ mod test { let mut r = MemReader::new(vec![0, 1, 2, 3, 4, 5]); let mut r = LimitReader::new(r.by_ref(), 1); r.consume(2); - assert_eq!(vec![], r.read_to_end().unwrap()); + assert_eq!([], r.read_to_end().unwrap()); } #[test] @@ -330,7 +330,7 @@ mod test { let mut s = ZeroReader; let mut buf = vec![1, 2, 3]; assert_eq!(s.read(&mut buf), Ok(3)); - assert_eq!(vec![0, 0, 0], buf); + assert_eq!([0, 0, 0], buf); } #[test] @@ -373,16 +373,16 @@ mod test { let rs = vec!(MemReader::new(vec!(0, 1)), MemReader::new(vec!()), MemReader::new(vec!(2, 3))); let mut r = ChainedReader::new(rs.into_iter()); - assert_eq!(vec!(0, 1, 2, 3), r.read_to_end().unwrap()); + assert_eq!([0, 1, 2, 3], r.read_to_end().unwrap()); } #[test] fn test_tee_reader() { let mut r = TeeReader::new(MemReader::new(vec!(0, 1, 2)), Vec::new()); - assert_eq!(vec!(0, 1, 2), r.read_to_end().unwrap()); + assert_eq!([0, 1, 2], r.read_to_end().unwrap()); let (_, w) = r.into_inner(); - assert_eq!(vec!(0, 1, 2), w); + assert_eq!([0, 1, 2], w); } #[test] @@ -390,7 +390,7 @@ mod test { let mut r = MemReader::new(vec!(0, 1, 2, 3, 4)); let mut w = Vec::new(); copy(&mut r, &mut w).unwrap(); - assert_eq!(vec!(0, 1, 2, 3, 4), w); + assert_eq!([0, 1, 2, 3, 4], w); } #[test] diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 86f5c2c356e5e..9c42d1be77ee1 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -49,6 +49,7 @@ use ops::{Drop, FnOnce}; use option::Option::{Some, None}; use option::Option; use old_path::{Path, GenericPath, BytesContainer}; +use path::{self, PathBuf}; use ptr::PtrExt; use ptr; use result::Result::{Err, Ok}; @@ -67,6 +68,35 @@ use vec::Vec; #[cfg(unix)] pub use sys::ext as unix; #[cfg(windows)] pub use sys::ext as windows; +fn err2old(new: ::io::Error) -> IoError { + IoError { + kind: ::old_io::OtherIoError, + desc: "os error", + detail: Some(new.to_string()), + } +} + +#[cfg(windows)] +fn path2new(path: &Path) -> PathBuf { + PathBuf::new(path.as_str().unwrap()) +} +#[cfg(unix)] +fn path2new(path: &Path) -> PathBuf { + use os::unix::prelude::*; + PathBuf::new(::from_bytes(path.as_vec())) +} + +#[cfg(unix)] +fn path2old(path: &path::Path) -> Path { + use os::unix::prelude::*; + use ffi::AsOsStr; + Path::new(path.as_os_str().as_bytes()) +} +#[cfg(windows)] +fn path2old(path: &path::Path) -> Path { + Path::new(path.to_str().unwrap()) +} + /// Get the number of cores available pub fn num_cpus() -> uint { unsafe { @@ -100,10 +130,9 @@ pub const TMPBUF_SZ : uint = 1000; /// let current_working_directory = os::getcwd().unwrap(); /// println!("The current directory is {:?}", current_working_directory.display()); /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to std::env::current_dir")] #[unstable(feature = "os")] pub fn getcwd() -> IoResult { - env::current_dir() + env::current_dir().map_err(err2old).map(|s| path2old(&s)) } /// Returns a vector of (variable, value) pairs, for all the environment @@ -245,12 +274,11 @@ pub fn unsetenv(n: &str) { /// None => println!("{} is not defined in the environment.", key) /// } /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to env::split_paths")] #[unstable(feature = "os")] pub fn split_paths(unparsed: T) -> Vec { let b = unparsed.container_as_bytes(); let s = str::from_utf8(b).unwrap(); - env::split_paths(s).collect() + env::split_paths(s).map(|s| path2old(&s)).collect() } /// Joins a collection of `Path`s appropriately for the `PATH` @@ -274,7 +302,6 @@ pub fn split_paths(unparsed: T) -> Vec { /// paths.push(Path::new("/home/xyz/bin")); /// os::setenv(key, os::join_paths(paths.as_slice()).unwrap()); /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to env::join_paths")] #[unstable(feature = "os")] pub fn join_paths(paths: &[T]) -> Result, &'static str> { env::join_paths(paths.iter().map(|s| { @@ -335,10 +362,9 @@ pub fn dll_filename(base: &str) -> String { /// None => println!("Unable to get the path of this executable!") /// }; /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to env::current_exe")] #[unstable(feature = "os")] pub fn self_exe_name() -> Option { - env::current_exe().ok() + env::current_exe().ok().map(|p| path2old(&p)) } /// Optionally returns the filesystem path to the current executable which is @@ -356,10 +382,9 @@ pub fn self_exe_name() -> Option { /// None => println!("Impossible to fetch the path of this executable.") /// }; /// ``` -#[deprecated(since = "1.0.0", reason = "use env::current_exe + dir_path/pop")] #[unstable(feature = "os")] pub fn self_exe_path() -> Option { - env::current_exe().ok().map(|mut p| { p.pop(); p }) + env::current_exe().ok().map(|p| { let mut p = path2old(&p); p.pop(); p }) } /// Optionally returns the path to the current user's home directory if known. @@ -386,9 +411,8 @@ pub fn self_exe_path() -> Option { /// None => println!("Impossible to get your home dir!") /// } /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to env::home_dir")] -#[allow(deprecated)] #[unstable(feature = "os")] +#[allow(deprecated)] pub fn homedir() -> Option { #[inline] #[cfg(unix)] @@ -424,9 +448,8 @@ pub fn homedir() -> Option { /// On Windows, returns the value of, in order, the 'TMP', 'TEMP', /// 'USERPROFILE' environment variable if any are set and not the empty /// string. Otherwise, tmpdir returns the path to the Windows directory. -#[deprecated(since = "1.0.0", reason = "renamed to env::temp_dir")] -#[allow(deprecated)] #[unstable(feature = "os")] +#[allow(deprecated)] pub fn tmpdir() -> Path { return lookup(); @@ -488,7 +511,8 @@ pub fn make_absolute(p: &Path) -> IoResult { if p.is_absolute() { Ok(p.clone()) } else { - env::current_dir().map(|mut cwd| { + env::current_dir().map_err(err2old).map(|cwd| { + let mut cwd = path2old(&cwd); cwd.push(p); cwd }) @@ -507,10 +531,9 @@ pub fn make_absolute(p: &Path) -> IoResult { /// assert!(os::change_dir(&root).is_ok()); /// println!("Successfully changed working directory to {}!", root.display()); /// ``` -#[deprecated(since = "1.0.0", reason = "renamed to env::set_current_dir")] #[unstable(feature = "os")] pub fn change_dir(p: &Path) -> IoResult<()> { - return sys::os::chdir(p); + sys::os::chdir(&path2new(p)).map_err(err2old) } /// Returns the platform-specific value of errno diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs index 0e2766f388944..1a13405633d2e 100644 --- a/src/libstd/rand/os.rs +++ b/src/libstd/rand/os.rs @@ -188,7 +188,6 @@ mod imp { extern crate libc; use old_io::{IoResult}; - use marker::Sync; use mem; use os; use rand::Rng; @@ -214,10 +213,8 @@ mod imp { #[repr(C)] struct SecRandom; - unsafe impl Sync for *const SecRandom {} - #[allow(non_upper_case_globals)] - static kSecRandomDefault: *const SecRandom = 0 as *const SecRandom; + const kSecRandomDefault: *const SecRandom = 0 as *const SecRandom; #[link(name = "Security", kind = "framework")] extern "C" { diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index aa87abc6e9aac..e7ee9bd206651 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -61,9 +61,6 @@ use sync::{mutex, MutexGuard, PoisonError}; #[stable(feature = "rust1", since = "1.0.0")] pub struct Condvar { inner: Box } -unsafe impl Send for Condvar {} -unsafe impl Sync for Condvar {} - /// Statically allocated condition variables. /// /// This structure is identical to `Condvar` except that it is suitable for use @@ -83,9 +80,6 @@ pub struct StaticCondvar { mutex: AtomicUsize, } -unsafe impl Send for StaticCondvar {} -unsafe impl Sync for StaticCondvar {} - /// Constant initializer for a statically allocated condition variable. #[unstable(feature = "std_misc", reason = "may be merged with Condvar in the future")] diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs index f3b721438d807..68137601c405c 100644 --- a/src/libstd/sync/mod.rs +++ b/src/libstd/sync/mod.rs @@ -31,6 +31,7 @@ pub use self::barrier::{Barrier, BarrierWaitResult}; pub use self::poison::{PoisonError, TryLockError, TryLockResult, LockResult}; pub use self::future::Future; +#[allow(deprecated)] pub use self::task_pool::TaskPool; pub mod mpsc; diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 02b2db572ec4f..b9785f204406a 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -152,8 +152,6 @@ pub struct StaticMutex { poison: poison::Flag, } -unsafe impl Sync for StaticMutex {} - /// An RAII implementation of a "scoped lock" of a mutex. When this structure is /// dropped (falls out of scope), the lock will be unlocked. /// diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 97f985e21e8ab..d2054a1e819ab 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -13,10 +13,9 @@ //! This primitive is meant to be used to run one-time initialization. An //! example use case would be for initializing an FFI library. +use prelude::v1::*; + use isize; -use marker::Sync; -use mem::drop; -use ops::FnOnce; use sync::atomic::{AtomicIsize, Ordering, ATOMIC_ISIZE_INIT}; use sync::{StaticMutex, MUTEX_INIT}; @@ -43,8 +42,6 @@ pub struct Once { lock_cnt: AtomicIsize, } -unsafe impl Sync for Once {} - /// Initialization value for static `Once` values. #[stable(feature = "rust1", since = "1.0.0")] pub const ONCE_INIT: Once = Once { diff --git a/src/libstd/sync/poison.rs b/src/libstd/sync/poison.rs index 32c8150ba4070..2587ff5238ea7 100644 --- a/src/libstd/sync/poison.rs +++ b/src/libstd/sync/poison.rs @@ -16,6 +16,12 @@ use fmt; use thread; pub struct Flag { failed: UnsafeCell } + +// This flag is only ever accessed with a lock previously held. Note that this +// a totally private structure. +unsafe impl Send for Flag {} +unsafe impl Sync for Flag {} + pub const FLAG_INIT: Flag = Flag { failed: UnsafeCell { value: false } }; impl Flag { diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index 6fd2a6ed77d26..6fee6094d4ffc 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -97,9 +97,6 @@ pub struct StaticRwLock { poison: poison::Flag, } -unsafe impl Send for StaticRwLock {} -unsafe impl Sync for StaticRwLock {} - /// Constant initialization for a statically-initialized rwlock. #[unstable(feature = "std_misc", reason = "may be merged with RwLock in the future")] diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs index 31f3dfd877cfb..efb6689e7855a 100644 --- a/src/libstd/sync/task_pool.rs +++ b/src/libstd/sync/task_pool.rs @@ -10,11 +10,13 @@ //! Abstraction of a thread pool for basic parallelism. -#![unstable(feature = "std_misc", - reason = "the semantics of a failing task and whether a thread is \ - re-attached to a thread pool are somewhat unclear, and the \ - utility of this type in `std::sync` is questionable with \ - respect to the jobs of other primitives")] +#![deprecated(since = "1.0.0", + reason = "This kind of API needs some time to bake in \ + crates.io. This functionality is available through \ + https://crates.io/crates/threadpool")] +#![unstable(feature = "std_misc")] + +#![allow(deprecated)] use core::prelude::*; diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index b5cd42219e128..228362e3d62ae 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -503,7 +503,7 @@ pub fn connect_timeout(fd: sock_t, #[cfg(windows)] use libc::WSAEWOULDBLOCK as WOULDBLOCK; // Make sure the call to connect() doesn't block - try!(set_nonblocking(fd, true)); + set_nonblocking(fd, true); let ret = match unsafe { libc::connect(fd, addrp, len) } { // If the connection is in progress, then we need to wait for it to @@ -533,7 +533,7 @@ pub fn connect_timeout(fd: sock_t, }; // be sure to turn blocking I/O back on - try!(set_nonblocking(fd, false)); + set_nonblocking(fd, false); return ret; #[cfg(unix)] @@ -626,7 +626,7 @@ pub struct Guard<'a> { #[unsafe_destructor] impl<'a> Drop for Guard<'a> { fn drop(&mut self) { - assert!(set_nonblocking(self.fd, false).is_ok()); + set_nonblocking(self.fd, false); } } @@ -723,7 +723,7 @@ impl TcpStream { fd: self.fd(), guard: self.inner.lock.lock().unwrap(), }; - assert!(set_nonblocking(self.fd(), true).is_ok()); + set_nonblocking(self.fd(), true); ret } @@ -862,7 +862,7 @@ impl UdpSocket { fd: self.fd(), guard: self.inner.lock.lock().unwrap(), }; - assert!(set_nonblocking(self.fd(), true).is_ok()); + set_nonblocking(self.fd(), true); ret } @@ -887,9 +887,7 @@ impl UdpSocket { storagep, &mut addrlen) as libc::c_int })); - sockaddr_to_addr(&storage, addrlen as uint).and_then(|addr| { - Ok((n as uint, addr)) - }) + Ok((n as uint, sockaddr_to_addr(&storage, addrlen as uint).unwrap())) } pub fn send_to(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()> { @@ -910,11 +908,8 @@ impl UdpSocket { }; let n = try!(write(fd, self.write_deadline, buf, false, dolock, dowrite)); - if n != buf.len() { - Err(short_write(n, "couldn't send entire packet at once")) - } else { - Ok(()) - } + assert!(n == buf.len(), "UDP packet not completely written."); + Ok(()) } pub fn join_multicast(&mut self, multi: IpAddr) -> IoResult<()> { diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs index 9119a3c60d855..fb9d6fef1faa7 100644 --- a/src/libstd/sys/common/wtf8.rs +++ b/src/libstd/sys/common/wtf8.rs @@ -1202,11 +1202,11 @@ mod tests { string.code_points().map(|c| c.to_char()).collect::>() } let mut string = Wtf8Buf::from_str("é "); - assert_eq!(cp(&string), vec![Some('é'), Some(' ')]); + assert_eq!(cp(&string), [Some('é'), Some(' ')]); string.push(c(0xD83D)); - assert_eq!(cp(&string), vec![Some('é'), Some(' '), None]); + assert_eq!(cp(&string), [Some('é'), Some(' '), None]); string.push(c(0xDCA9)); - assert_eq!(cp(&string), vec![Some('é'), Some(' '), Some('💩')]); + assert_eq!(cp(&string), [Some('é'), Some(' '), Some('💩')]); } #[test] diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs index 6f07dea5279fd..6267792ba745e 100644 --- a/src/libstd/sys/unix/backtrace.rs +++ b/src/libstd/sys/unix/backtrace.rs @@ -84,8 +84,9 @@ /// all unix platforms we support right now, so it at least gets the job done. use prelude::v1::*; +use os::unix::prelude::*; -use ffi::CStr; +use ffi::{CStr, AsOsStr}; use old_io::IoResult; use libc; use mem; @@ -327,7 +328,7 @@ fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> { }; let filename = match selfname { Some(path) => { - let bytes = path.as_vec(); + let bytes = path.as_os_str().as_bytes(); if bytes.len() < LAST_FILENAME.len() { let i = bytes.iter(); for (slot, val) in LAST_FILENAME.iter_mut().zip(i) { diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs index 3bc4147315263..90dfebc4c454c 100644 --- a/src/libstd/sys/unix/condvar.rs +++ b/src/libstd/sys/unix/condvar.rs @@ -8,10 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use prelude::v1::*; + use cell::UnsafeCell; use libc; use ptr; -use std::option::Option::{Some, None}; use sys::mutex::{self, Mutex}; use sys::time; use sys::sync as ffi; @@ -20,6 +21,9 @@ use num::{Int, NumCast}; pub struct Condvar { inner: UnsafeCell } +unsafe impl Send for Condvar {} +unsafe impl Sync for Condvar {} + pub const CONDVAR_INIT: Condvar = Condvar { inner: UnsafeCell { value: ffi::PTHREAD_COND_INITIALIZER }, }; diff --git a/src/libstd/sys/unix/ext.rs b/src/libstd/sys/unix/ext.rs index b8b9dcfb3c689..3f9da6e3c51bb 100644 --- a/src/libstd/sys/unix/ext.rs +++ b/src/libstd/sys/unix/ext.rs @@ -173,10 +173,13 @@ impl OsStrExt for OsStr { // Unix-specific extensions to `Permissions` pub trait PermissionsExt { + fn mode(&self) -> i32; fn set_mode(&mut self, mode: i32); } impl PermissionsExt for Permissions { + fn mode(&self) -> i32 { self.as_inner().mode() } + fn set_mode(&mut self, mode: i32) { *self = FromInner::from_inner(FromInner::from_inner(mode)); } diff --git a/src/libstd/sys/unix/fs2.rs b/src/libstd/sys/unix/fs2.rs index c6b9c2cba5227..72e0b8dd36c66 100644 --- a/src/libstd/sys/unix/fs2.rs +++ b/src/libstd/sys/unix/fs2.rs @@ -90,6 +90,7 @@ impl FilePermissions { self.mode |= 0o222; } } + pub fn mode(&self) -> i32 { self.mode as i32 } } impl FromInner for FilePermissions { diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index b79ad7031fa48..632270bc5ccbf 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -214,9 +214,9 @@ pub fn wouldblock() -> bool { err == libc::EWOULDBLOCK as i32 || err == libc::EAGAIN as i32 } -pub fn set_nonblocking(fd: sock_t, nb: bool) -> IoResult<()> { +pub fn set_nonblocking(fd: sock_t, nb: bool) { let set = nb as libc::c_int; - mkerr_libc(retry(|| unsafe { c::ioctl(fd, c::FIONBIO, &set) })) + mkerr_libc(retry(|| unsafe { c::ioctl(fd, c::FIONBIO, &set) })).unwrap(); } // nothing needed on unix platforms diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs index 9e1527aef201a..f87c0339533df 100644 --- a/src/libstd/sys/unix/mutex.rs +++ b/src/libstd/sys/unix/mutex.rs @@ -8,8 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use prelude::v1::*; + use cell::UnsafeCell; -use marker::Sync; use sys::sync as ffi; use sys_common::mutex; @@ -24,6 +25,7 @@ pub const MUTEX_INIT: Mutex = Mutex { inner: UnsafeCell { value: ffi::PTHREAD_MUTEX_INITIALIZER }, }; +unsafe impl Send for Mutex {} unsafe impl Sync for Mutex {} impl Mutex { diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index d51f907307e46..899280aa7094b 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -16,12 +16,13 @@ use os::unix::*; use error::Error as StdError; use ffi::{CString, CStr, OsString, OsStr, AsOsStr}; use fmt; +use io; use iter; use libc::{self, c_int, c_char, c_void}; use mem; -use io; -use old_io::{IoResult, IoError, fs}; +use old_io::{IoError, IoResult}; use ptr; +use path::{self, PathBuf}; use slice; use str; use sys::c; @@ -32,6 +33,14 @@ use vec; const BUF_BYTES: usize = 2048; const TMPBUF_SZ: usize = 128; +fn bytes2path(b: &[u8]) -> PathBuf { + PathBuf::new(::from_bytes(b)) +} + +fn os2path(os: OsString) -> PathBuf { + bytes2path(os.as_bytes()) +} + /// Returns the platform-specific value of errno pub fn errno() -> i32 { #[cfg(any(target_os = "macos", @@ -102,30 +111,30 @@ pub fn error_string(errno: i32) -> String { } } -pub fn getcwd() -> IoResult { +pub fn getcwd() -> io::Result { let mut buf = [0 as c_char; BUF_BYTES]; unsafe { if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() { - Err(IoError::last_error()) + Err(io::Error::last_os_error()) } else { - Ok(Path::new(CStr::from_ptr(buf.as_ptr()).to_bytes())) + Ok(bytes2path(CStr::from_ptr(buf.as_ptr()).to_bytes())) } } } -pub fn chdir(p: &Path) -> IoResult<()> { - let p = CString::new(p.as_vec()).unwrap(); +pub fn chdir(p: &path::Path) -> io::Result<()> { + let p = try!(CString::new(p.as_os_str().as_bytes())); unsafe { match libc::chdir(p.as_ptr()) == (0 as c_int) { true => Ok(()), - false => Err(IoError::last_error()), + false => Err(io::Error::last_os_error()), } } } pub struct SplitPaths<'a> { iter: iter::Map bool>, - fn(&'a [u8]) -> Path>, + fn(&'a [u8]) -> PathBuf>, } pub fn split_paths<'a>(unparsed: &'a OsStr) -> SplitPaths<'a> { @@ -133,13 +142,13 @@ pub fn split_paths<'a>(unparsed: &'a OsStr) -> SplitPaths<'a> { let unparsed = unparsed.as_bytes(); SplitPaths { iter: unparsed.split(is_colon as fn(&u8) -> bool) - .map(Path::new as fn(&'a [u8]) -> Path) + .map(bytes2path as fn(&'a [u8]) -> PathBuf) } } impl<'a> Iterator for SplitPaths<'a> { - type Item = Path; - fn next(&mut self) -> Option { self.iter.next() } + type Item = PathBuf; + fn next(&mut self) -> Option { self.iter.next() } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } @@ -174,7 +183,7 @@ impl StdError for JoinPathsError { } #[cfg(target_os = "freebsd")] -pub fn current_exe() -> IoResult { +pub fn current_exe() -> io::Result { unsafe { use libc::funcs::bsd44::*; use libc::consts::os::extra::*; @@ -186,26 +195,26 @@ pub fn current_exe() -> IoResult { let err = sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint, ptr::null_mut(), &mut sz, ptr::null_mut(), 0 as libc::size_t); - if err != 0 { return Err(IoError::last_error()); } - if sz == 0 { return Err(IoError::last_error()); } + if err != 0 { return Err(io::Error::last_os_error()); } + if sz == 0 { return Err(io::Error::last_os_error()); } let mut v: Vec = Vec::with_capacity(sz as uint); let err = sysctl(mib.as_mut_ptr(), mib.len() as ::libc::c_uint, v.as_mut_ptr() as *mut libc::c_void, &mut sz, ptr::null_mut(), 0 as libc::size_t); - if err != 0 { return Err(IoError::last_error()); } - if sz == 0 { return Err(IoError::last_error()); } + if err != 0 { return Err(io::Error::last_os_error()); } + if sz == 0 { return Err(io::Error::last_os_error()); } v.set_len(sz as uint - 1); // chop off trailing NUL - Ok(Path::new(v)) + Ok(PathBuf::new::(&OsStringExt::from_vec(v))) } } #[cfg(target_os = "dragonfly")] -pub fn current_exe() -> IoResult { - fs::readlink(&Path::new("/proc/curproc/file")) +pub fn current_exe() -> io::Result { + ::fs::read_link("/proc/curproc/file") } #[cfg(any(target_os = "bitrig", target_os = "openbsd"))] -pub fn current_exe() -> IoResult { +pub fn current_exe() -> io::Result { use sync::{StaticMutex, MUTEX_INIT}; static LOCK: StaticMutex = MUTEX_INIT; @@ -218,7 +227,7 @@ pub fn current_exe() -> IoResult { unsafe { let v = rust_current_exe(); if v.is_null() { - Err(IoError::last_error()) + Err(io::Error::last_os_error()) } else { Ok(Path::new(CStr::from_ptr(v).to_bytes().to_vec())) } @@ -226,22 +235,22 @@ pub fn current_exe() -> IoResult { } #[cfg(any(target_os = "linux", target_os = "android"))] -pub fn current_exe() -> IoResult { - fs::readlink(&Path::new("/proc/self/exe")) +pub fn current_exe() -> io::Result { + ::fs::read_link("/proc/self/exe") } #[cfg(any(target_os = "macos", target_os = "ios"))] -pub fn current_exe() -> IoResult { +pub fn current_exe() -> io::Result { unsafe { use libc::funcs::extra::_NSGetExecutablePath; let mut sz: u32 = 0; _NSGetExecutablePath(ptr::null_mut(), &mut sz); - if sz == 0 { return Err(IoError::last_error()); } + if sz == 0 { return Err(io::Error::last_os_error()); } let mut v: Vec = Vec::with_capacity(sz as uint); let err = _NSGetExecutablePath(v.as_mut_ptr() as *mut i8, &mut sz); - if err != 0 { return Err(IoError::last_error()); } + if err != 0 { return Err(io::Error::last_os_error()); } v.set_len(sz as uint - 1); // chop off trailing NUL - Ok(Path::new(v)) + Ok(PathBuf::new::(&OsStringExt::from_vec(v))) } } @@ -451,22 +460,20 @@ pub fn page_size() -> usize { } } -pub fn temp_dir() -> Path { - getenv("TMPDIR".as_os_str()).map(|p| Path::new(p.into_vec())).unwrap_or_else(|| { +pub fn temp_dir() -> PathBuf { + getenv("TMPDIR".as_os_str()).map(os2path).unwrap_or_else(|| { if cfg!(target_os = "android") { - Path::new("/data/local/tmp") + PathBuf::new("/data/local/tmp") } else { - Path::new("/tmp") + PathBuf::new("/tmp") } }) } -pub fn home_dir() -> Option { +pub fn home_dir() -> Option { return getenv("HOME".as_os_str()).or_else(|| unsafe { fallback() - }).map(|os| { - Path::new(os.into_vec()) - }); + }).map(os2path); #[cfg(any(target_os = "android", target_os = "ios"))] diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index 3c9cdc65975f6..33863d31437f3 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -145,7 +145,7 @@ impl UnixStream { fd: self.fd(), guard: unsafe { self.inner.lock.lock().unwrap() }, }; - assert!(set_nonblocking(self.fd(), true).is_ok()); + set_nonblocking(self.fd(), true); ret } @@ -235,9 +235,9 @@ impl UnixListener { _ => { let (reader, writer) = try!(unsafe { sys::os::pipe() }); - try!(set_nonblocking(reader.fd(), true)); - try!(set_nonblocking(writer.fd(), true)); - try!(set_nonblocking(self.fd(), true)); + set_nonblocking(reader.fd(), true); + set_nonblocking(writer.fd(), true); + set_nonblocking(self.fd(), true); Ok(UnixAcceptor { inner: Arc::new(AcceptorInner { listener: self, diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs index 2be841989e6b3..68c5c65e7cdb1 100644 --- a/src/libstd/sys/unix/process.rs +++ b/src/libstd/sys/unix/process.rs @@ -69,7 +69,6 @@ impl Process { K: BytesContainer + Eq + Hash, V: BytesContainer { use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp}; - use libc::funcs::bsd44::getdtablesize; mod rustrt { extern { @@ -82,6 +81,15 @@ impl Process { assert_eq!(ret, 0); } + #[cfg(all(target_os = "android", target_arch = "aarch64"))] + unsafe fn getdtablesize() -> c_int { + libc::sysconf(libc::consts::os::sysconf::_SC_OPEN_MAX) as c_int + } + #[cfg(not(all(target_os = "android", target_arch = "aarch64")))] + unsafe fn getdtablesize() -> c_int { + libc::funcs::bsd44::getdtablesize() + } + let dirp = cfg.cwd().map(|c| c.as_ptr()).unwrap_or(ptr::null()); // temporary until unboxed closures land @@ -345,8 +353,8 @@ impl Process { unsafe { let mut pipes = [0; 2]; assert_eq!(libc::pipe(pipes.as_mut_ptr()), 0); - set_nonblocking(pipes[0], true).ok().unwrap(); - set_nonblocking(pipes[1], true).ok().unwrap(); + set_nonblocking(pipes[0], true); + set_nonblocking(pipes[1], true); WRITE_FD = pipes[1]; let mut old: c::sigaction = mem::zeroed(); @@ -362,7 +370,7 @@ impl Process { fn waitpid_helper(input: libc::c_int, messages: Receiver, (read_fd, old): (libc::c_int, c::sigaction)) { - set_nonblocking(input, true).ok().unwrap(); + set_nonblocking(input, true); let mut set: c::fd_set = unsafe { mem::zeroed() }; let mut tv: libc::timeval; let mut active = Vec::<(libc::pid_t, Sender, u64)>::new(); diff --git a/src/libstd/sys/unix/process2.rs b/src/libstd/sys/unix/process2.rs index 06fa5c4bba725..b7a1b002f5598 100644 --- a/src/libstd/sys/unix/process2.rs +++ b/src/libstd/sys/unix/process2.rs @@ -141,7 +141,6 @@ impl Process { -> io::Result { use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp}; - use libc::funcs::bsd44::getdtablesize; mod rustrt { extern { @@ -154,6 +153,16 @@ impl Process { assert_eq!(ret, 0); } + #[cfg(all(target_os = "android", target_arch = "aarch64"))] + unsafe fn getdtablesize() -> c_int { + libc::sysconf(libc::consts::os::sysconf::_SC_OPEN_MAX) as c_int + } + + #[cfg(not(all(target_os = "android", target_arch = "aarch64")))] + unsafe fn getdtablesize() -> c_int { + libc::funcs::bsd44::getdtablesize() + } + let dirp = cfg.cwd.as_ref().map(|c| c.as_ptr()).unwrap_or(ptr::null()); with_envp(cfg.env.as_ref(), |envp: *const c_void| { diff --git a/src/libstd/sys/unix/rwlock.rs b/src/libstd/sys/unix/rwlock.rs index 54523e0076dc3..b857f4ab75fed 100644 --- a/src/libstd/sys/unix/rwlock.rs +++ b/src/libstd/sys/unix/rwlock.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use prelude::v1::*; + use cell::UnsafeCell; use sys::sync as ffi; @@ -17,6 +19,9 @@ pub const RWLOCK_INIT: RWLock = RWLock { inner: UnsafeCell { value: ffi::PTHREAD_RWLOCK_INITIALIZER }, }; +unsafe impl Send for RWLock {} +unsafe impl Sync for RWLock {} + impl RWLock { #[inline] pub unsafe fn new() -> RWLock { diff --git a/src/libstd/sys/unix/tcp.rs b/src/libstd/sys/unix/tcp.rs index c8f9d318482b0..b08f6ef9b9032 100644 --- a/src/libstd/sys/unix/tcp.rs +++ b/src/libstd/sys/unix/tcp.rs @@ -67,9 +67,9 @@ impl TcpListener { -1 => Err(last_net_error()), _ => { let (reader, writer) = try!(unsafe { sys::os::pipe() }); - try!(set_nonblocking(reader.fd(), true)); - try!(set_nonblocking(writer.fd(), true)); - try!(set_nonblocking(self.fd(), true)); + set_nonblocking(reader.fd(), true); + set_nonblocking(writer.fd(), true); + set_nonblocking(self.fd(), true); Ok(TcpAcceptor { inner: Arc::new(AcceptorInner { listener: self, diff --git a/src/libstd/sys/windows/condvar.rs b/src/libstd/sys/windows/condvar.rs index db8038006fd6a..071637e3a939f 100644 --- a/src/libstd/sys/windows/condvar.rs +++ b/src/libstd/sys/windows/condvar.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use prelude::v1::*; + use cell::UnsafeCell; use libc::{self, DWORD}; use os; @@ -17,6 +19,9 @@ use time::Duration; pub struct Condvar { inner: UnsafeCell } +unsafe impl Send for Condvar {} +unsafe impl Sync for Condvar {} + pub const CONDVAR_INIT: Condvar = Condvar { inner: UnsafeCell { value: ffi::CONDITION_VARIABLE_INIT } }; diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index 304d7e0153279..309d6c9dc48c2 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -368,7 +368,9 @@ pub fn readlink(p: &Path) -> IoResult { buf as *const u16, sz - 1, libc::VOLUME_NAME_DOS) - }, super::os2path); + }, |data| { + Path::new(String::from_utf16(data).unwrap()) + }); assert!(unsafe { libc::CloseHandle(handle) } != 0); return ret; } diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index a756fb29f81ae..5bb2a134533ed 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -14,13 +14,14 @@ use prelude::v1::*; -use ffi::OsStr; +use ffi::{OsStr, OsString}; use io::{self, ErrorKind}; use libc; use mem; -use old_io::{self, IoResult, IoError}; use num::Int; -use os::windows::OsStrExt; +use old_io::{self, IoResult, IoError}; +use os::windows::{OsStrExt, OsStringExt}; +use path::PathBuf; use sync::{Once, ONCE_INIT}; macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => ( @@ -192,12 +193,12 @@ pub fn wouldblock() -> bool { err == libc::WSAEWOULDBLOCK as i32 } -pub fn set_nonblocking(fd: sock_t, nb: bool) -> IoResult<()> { +pub fn set_nonblocking(fd: sock_t, nb: bool) { let mut set = nb as libc::c_ulong; - if unsafe { c::ioctlsocket(fd, c::FIONBIO, &mut set) != 0 } { - Err(last_error()) - } else { - Ok(()) + if unsafe { c::ioctlsocket(fd, c::FIONBIO, &mut set) } != 0 { + // The above function should not return an error unless we passed it + // invalid parameters. Panic on errors. + panic!("set_nonblocking called with invalid parameters: {}", last_error()); } } @@ -314,9 +315,10 @@ fn fill_utf16_buf_new(f1: F1, f2: F2) -> io::Result fill_utf16_buf_base(f1, f2).map_err(|()| io::Error::last_os_error()) } -fn os2path(s: &[u16]) -> Path { - // FIXME: this should not be a panicking conversion (aka path reform) - Path::new(String::from_utf16(s).unwrap()) +fn os2path(s: &[u16]) -> PathBuf { + let os = ::from_wide(s); + // FIXME(#22751) should consume `os` + PathBuf::new(&os) } pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] { diff --git a/src/libstd/sys/windows/mutex.rs b/src/libstd/sys/windows/mutex.rs index 75495efc7cbb6..0847f3b52bfab 100644 --- a/src/libstd/sys/windows/mutex.rs +++ b/src/libstd/sys/windows/mutex.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use marker::Sync; +use prelude::v1::*; + use cell::UnsafeCell; use sys::sync as ffi; @@ -18,6 +19,7 @@ pub const MUTEX_INIT: Mutex = Mutex { inner: UnsafeCell { value: ffi::SRWLOCK_INIT } }; +unsafe impl Send for Mutex {} unsafe impl Sync for Mutex {} #[inline] @@ -27,14 +29,15 @@ pub unsafe fn raw(m: &Mutex) -> ffi::PSRWLOCK { // So you might be asking why we're using SRWLock instead of CriticalSection? // -// 1. SRWLock is several times faster than CriticalSection according to benchmarks performed on both -// Windows 8 and Windows 7. +// 1. SRWLock is several times faster than CriticalSection according to +// benchmarks performed on both Windows 8 and Windows 7. // -// 2. CriticalSection allows recursive locking while SRWLock deadlocks. The Unix implementation -// deadlocks so consistency is preferred. See #19962 for more details. +// 2. CriticalSection allows recursive locking while SRWLock deadlocks. The Unix +// implementation deadlocks so consistency is preferred. See #19962 for more +// details. // -// 3. While CriticalSection is fair and SRWLock is not, the current Rust policy is there there are -// no guarantees of fairness. +// 3. While CriticalSection is fair and SRWLock is not, the current Rust policy +// is there there are no guarantees of fairness. impl Mutex { #[inline] diff --git a/src/libstd/sys/windows/net.rs b/src/libstd/sys/windows/net.rs index 3451232f40ab8..6caa4df5dfe62 100644 --- a/src/libstd/sys/windows/net.rs +++ b/src/libstd/sys/windows/net.rs @@ -25,6 +25,8 @@ pub type wrlen_t = i32; pub struct Socket(libc::SOCKET); +/// Checks whether the Windows socket interface has been started already, and +/// if not, starts it. pub fn init() { static START: Once = ONCE_INIT; @@ -38,10 +40,16 @@ pub fn init() { }); } +/// Returns the last error from the Windows socket interface. fn last_error() -> io::Error { io::Error::from_os_error(unsafe { c::WSAGetLastError() }) } +/// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1) +/// and if so, returns the last error from the Windows socket interface. . This +/// function must be called before another call to the socket API is made. +/// +/// FIXME: generics needed? pub fn cvt(t: T) -> io::Result { let one: T = Int::one(); if t == -one { @@ -51,11 +59,14 @@ pub fn cvt(t: T) -> io::Result { } } +/// Provides the functionality of `cvt` for the return values of `getaddrinfo` +/// and similar, meaning that they return an error if the return value is 0. pub fn cvt_gai(err: c_int) -> io::Result<()> { if err == 0 { return Ok(()) } cvt(err).map(|_| ()) } +/// Provides the functionality of `cvt` for a closure. pub fn cvt_r(mut f: F) -> io::Result where F: FnMut() -> T { cvt(f()) } @@ -112,7 +123,7 @@ impl Socket { impl Drop for Socket { fn drop(&mut self) { - unsafe { let _ = libc::closesocket(self.0); } + unsafe { cvt(libc::closesocket(self.0)).unwrap(); } } } diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index 6520d30487c76..587ab7924fd1d 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -18,11 +18,13 @@ use os::windows::*; use error::Error as StdError; use ffi::{OsString, OsStr, AsOsStr}; use fmt; -use ops::Range; +use io; use libc::types::os::arch::extra::LPWCH; use libc::{self, c_int, c_void}; use mem; use old_io::{IoError, IoResult}; +use ops::Range; +use path::{self, PathBuf}; use ptr; use slice; use sys::c; @@ -151,8 +153,8 @@ pub fn split_paths(unparsed: &OsStr) -> SplitPaths { } impl<'a> Iterator for SplitPaths<'a> { - type Item = Path; - fn next(&mut self) -> Option { + type Item = PathBuf; + fn next(&mut self) -> Option { // On Windows, the PATH environment variable is semicolon separated. // Double quotes are used as a way of introducing literal semicolons // (since c:\some;dir is a valid Windows path). Double quotes are not @@ -186,7 +188,7 @@ impl<'a> Iterator for SplitPaths<'a> { if !must_yield && in_progress.is_empty() { None } else { - Some(super::os2path(&in_progress[..])) + Some(super::os2path(&in_progress)) } } } @@ -228,33 +230,33 @@ impl StdError for JoinPathsError { fn description(&self) -> &str { "failed to join paths" } } -pub fn current_exe() -> IoResult { - super::fill_utf16_buf(|buf, sz| unsafe { +pub fn current_exe() -> io::Result { + super::fill_utf16_buf_new(|buf, sz| unsafe { libc::GetModuleFileNameW(ptr::null_mut(), buf, sz) }, super::os2path) } -pub fn getcwd() -> IoResult { - super::fill_utf16_buf(|buf, sz| unsafe { +pub fn getcwd() -> io::Result { + super::fill_utf16_buf_new(|buf, sz| unsafe { libc::GetCurrentDirectoryW(sz, buf) }, super::os2path) } -pub fn chdir(p: &Path) -> IoResult<()> { +pub fn chdir(p: &path::Path) -> io::Result<()> { let mut p = p.as_os_str().encode_wide().collect::>(); p.push(0); unsafe { match libc::SetCurrentDirectoryW(p.as_ptr()) != (0 as libc::BOOL) { true => Ok(()), - false => Err(IoError::last_error()), + false => Err(io::Error::last_os_error()), } } } pub fn getenv(k: &OsStr) -> Option { let k = super::to_utf16_os(k); - super::fill_utf16_buf(|buf, sz| unsafe { + super::fill_utf16_buf_new(|buf, sz| unsafe { libc::GetEnvironmentVariableW(k.as_ptr(), buf, sz) }, |buf| { OsStringExt::from_wide(buf) @@ -349,18 +351,18 @@ pub unsafe fn pipe() -> IoResult<(FileDesc, FileDesc)> { } } -pub fn temp_dir() -> Path { - super::fill_utf16_buf(|buf, sz| unsafe { +pub fn temp_dir() -> PathBuf { + super::fill_utf16_buf_new(|buf, sz| unsafe { c::GetTempPathW(sz, buf) }, super::os2path).unwrap() } -pub fn home_dir() -> Option { +pub fn home_dir() -> Option { getenv("HOME".as_os_str()).or_else(|| { getenv("USERPROFILE".as_os_str()) }).map(|os| { - // FIXME: OsString => Path - Path::new(os.to_str().unwrap()) + // FIXME(#22751) should consume `os` + PathBuf::new(&os) }).or_else(|| unsafe { let me = c::GetCurrentProcess(); let mut token = ptr::null_mut(); @@ -368,7 +370,7 @@ pub fn home_dir() -> Option { return None } let _handle = RawHandle::new(token); - super::fill_utf16_buf(|buf, mut sz| { + super::fill_utf16_buf_new(|buf, mut sz| { match c::GetUserProfileDirectoryW(token, buf, &mut sz) { 0 if libc::GetLastError() != 0 => 0, 0 => sz, diff --git a/src/libstd/sys/windows/process2.rs b/src/libstd/sys/windows/process2.rs index 19e38196d199f..d4c6e85489f5d 100644 --- a/src/libstd/sys/windows/process2.rs +++ b/src/libstd/sys/windows/process2.rs @@ -16,16 +16,15 @@ use collections; use env; use ffi::{OsString, OsStr}; use fmt; +use fs; use io::{self, Error}; use libc::{self, c_void}; -use old_io::fs; -use old_path; use os::windows::OsStrExt; use ptr; use sync::{StaticMutex, MUTEX_INIT}; +use sys::handle::Handle; use sys::pipe2::AnonPipe; use sys::{self, cvt}; -use sys::handle::Handle; use sys_common::{AsInner, FromInner}; //////////////////////////////////////////////////////////////////////////////// @@ -142,9 +141,8 @@ impl Process { for path in split_paths(&v) { let path = path.join(cfg.program.to_str().unwrap()) .with_extension(env::consts::EXE_EXTENSION); - // FIXME: update with new fs module once it lands - if fs::stat(&old_path::Path::new(&path)).is_ok() { - return Some(OsString::from_str(path.as_str().unwrap())) + if fs::metadata(&path).is_ok() { + return Some(path.into_os_string()) } } break diff --git a/src/libstd/sys/windows/rwlock.rs b/src/libstd/sys/windows/rwlock.rs index 76fe352ed7717..009605535a023 100644 --- a/src/libstd/sys/windows/rwlock.rs +++ b/src/libstd/sys/windows/rwlock.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use prelude::v1::*; + use cell::UnsafeCell; use sys::sync as ffi; @@ -17,6 +19,9 @@ pub const RWLOCK_INIT: RWLock = RWLock { inner: UnsafeCell { value: ffi::SRWLOCK_INIT } }; +unsafe impl Send for RWLock {} +unsafe impl Sync for RWLock {} + impl RWLock { #[inline] pub unsafe fn read(&self) { diff --git a/src/libstd/sys/windows/tcp.rs b/src/libstd/sys/windows/tcp.rs index 4804ca510cb0b..25b70918591d0 100644 --- a/src/libstd/sys/windows/tcp.rs +++ b/src/libstd/sys/windows/tcp.rs @@ -192,7 +192,7 @@ impl TcpAcceptor { c::WSAEventSelect(socket, events[1], 0) }; if ret != 0 { return Err(last_net_error()) } - try!(set_nonblocking(socket, false)); + set_nonblocking(socket, false); return Ok(stream) } } diff --git a/src/libstd/sys/windows/tty.rs b/src/libstd/sys/windows/tty.rs index 8a8b53090570c..c9bac69c434c3 100644 --- a/src/libstd/sys/windows/tty.rs +++ b/src/libstd/sys/windows/tty.rs @@ -52,7 +52,7 @@ fn invalid_encoding() -> IoError { pub fn is_tty(fd: c_int) -> bool { let mut out: DWORD = 0; - // If this function doesn't panic then fd is a TTY + // If this function doesn't return an error, then fd is a TTY match unsafe { GetConsoleMode(get_osfhandle(fd) as HANDLE, &mut out as LPDWORD) } { 0 => false, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index b6e7b309f356c..bea57ae14e4af 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -2025,7 +2025,7 @@ foo_module!(); let renamed_crate = renamer.fold_crate(the_crate); let idents = crate_idents(&renamed_crate); let resolved : Vec = idents.iter().map(|id| mtwt::resolve(*id)).collect(); - assert_eq!(resolved,vec!(f_ident.name,Name(16),int_ident.name,Name(16),Name(16),Name(16))); + assert_eq!(resolved, [f_ident.name,Name(16),int_ident.name,Name(16),Name(16),Name(16)]); } // test the PatIdentRenamer; only PatIdents get renamed @@ -2041,8 +2041,6 @@ foo_module!(); let idents = crate_idents(&renamed_crate); let resolved : Vec = idents.iter().map(|id| mtwt::resolve(*id)).collect(); let x_name = x_ident.name; - assert_eq!(resolved,vec!(f_ident.name,Name(16),int_ident.name,Name(16),x_name,x_name)); + assert_eq!(resolved, [f_ident.name,Name(16),int_ident.name,Name(16),x_name,x_name]); } - - } diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs index b6563d77b8864..72431d8e6aa2c 100644 --- a/src/libsyntax/ext/mtwt.rs +++ b/src/libsyntax/ext/mtwt.rs @@ -288,19 +288,19 @@ mod tests { fn xorpush_test () { let mut s = Vec::new(); xor_push(&mut s, 14); - assert_eq!(s.clone(), vec!(14)); + assert_eq!(s.clone(), [14]); xor_push(&mut s, 14); - assert_eq!(s.clone(), Vec::new()); + assert_eq!(s.clone(), []); xor_push(&mut s, 14); - assert_eq!(s.clone(), vec!(14)); + assert_eq!(s.clone(), [14]); xor_push(&mut s, 15); - assert_eq!(s.clone(), vec!(14, 15)); + assert_eq!(s.clone(), [14, 15]); xor_push(&mut s, 16); - assert_eq!(s.clone(), vec!(14, 15, 16)); + assert_eq!(s.clone(), [14, 15, 16]); xor_push(&mut s, 16); - assert_eq!(s.clone(), vec!(14, 15)); + assert_eq!(s.clone(), [14, 15]); xor_push(&mut s, 15); - assert_eq!(s.clone(), vec!(14)); + assert_eq!(s.clone(), [14]); } fn id(n: u32, s: SyntaxContext) -> Ident { @@ -389,13 +389,13 @@ mod tests { assert_eq!(marksof_internal (EMPTY_CTXT,stopname,&t),Vec::new()); // FIXME #5074: ANF'd to dodge nested calls { let ans = unfold_marks(vec!(4,98),EMPTY_CTXT,&mut t); - assert_eq! (marksof_internal (ans,stopname,&t),vec!(4,98));} + assert_eq! (marksof_internal (ans,stopname,&t), [4, 98]);} // does xoring work? { let ans = unfold_marks(vec!(5,5,16),EMPTY_CTXT,&mut t); - assert_eq! (marksof_internal (ans,stopname,&t), vec!(16));} + assert_eq! (marksof_internal (ans,stopname,&t), [16]);} // does nested xoring work? { let ans = unfold_marks(vec!(5,10,10,5,16),EMPTY_CTXT,&mut t); - assert_eq! (marksof_internal (ans, stopname,&t), vec!(16));} + assert_eq! (marksof_internal (ans, stopname,&t), [16]);} // rename where stop doesn't match: { let chain = vec!(M(9), R(id(name1.usize() as u32, @@ -403,7 +403,7 @@ mod tests { Name(100101102)), M(14)); let ans = unfold_test_sc(chain,EMPTY_CTXT,&mut t); - assert_eq! (marksof_internal (ans, stopname, &t), vec!(9,14));} + assert_eq! (marksof_internal (ans, stopname, &t), [9, 14]);} // rename where stop does match { let name1sc = apply_mark_internal(4, EMPTY_CTXT, &mut t); let chain = vec!(M(9), @@ -411,7 +411,7 @@ mod tests { stopname), M(14)); let ans = unfold_test_sc(chain,EMPTY_CTXT,&mut t); - assert_eq! (marksof_internal (ans, stopname, &t), vec!(9)); } + assert_eq! (marksof_internal (ans, stopname, &t), [9]); } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 32fd5b49f9a44..c1865ffa9d9a1 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -243,7 +243,9 @@ pub static KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[ ("static_assert", Whitelisted), ("no_debug", Whitelisted), ("omit_gdb_pretty_printer_section", Whitelisted), - ("unsafe_no_drop_flag", Whitelisted), + ("unsafe_no_drop_flag", Gated("unsafe_no_drop_flag", + "unsafe_no_drop_flag has unstable semantics \ + and may be removed in the future")), // used in resolve ("prelude_import", Whitelisted), diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs index 0a39d3809045a..90df23882a1d4 100644 --- a/src/libsyntax/util/small_vector.rs +++ b/src/libsyntax/util/small_vector.rs @@ -229,10 +229,10 @@ mod test { assert_eq!(Vec::new(), v); let v = SmallVector::one(1); - assert_eq!(vec![1], v.into_iter().collect::>()); + assert_eq!([1], v.into_iter().collect::>()); let v = SmallVector::many(vec![1, 2, 3]); - assert_eq!(vec!(1, 2, 3), v.into_iter().collect::>()); + assert_eq!([1, 2, 3], v.into_iter().collect::>()); } #[test] diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 5418533aff1d9..823d2879236d1 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -60,6 +60,7 @@ #![feature(unicode)] #![feature(std_misc)] #![feature(env)] +#![feature(os)] #![cfg_attr(windows, feature(libc))] #[macro_use] extern crate log; diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs index 0b577f8de74c2..112525fcce96e 100644 --- a/src/libterm/terminfo/parm.rs +++ b/src/libterm/terminfo/parm.rs @@ -652,15 +652,15 @@ mod test { let s = format!("%{{1}}%{{2}}%{}%d", op); let res = expand(s.as_bytes(), &[], &mut Variables::new()); assert!(res.is_ok(), res.err().unwrap()); - assert_eq!(res.unwrap(), vec!(b'0' + bs[0])); + assert_eq!(res.unwrap(), [b'0' + bs[0]]); let s = format!("%{{1}}%{{1}}%{}%d", op); let res = expand(s.as_bytes(), &[], &mut Variables::new()); assert!(res.is_ok(), res.err().unwrap()); - assert_eq!(res.unwrap(), vec!(b'0' + bs[1])); + assert_eq!(res.unwrap(), [b'0' + bs[1]]); let s = format!("%{{2}}%{{1}}%{}%d", op); let res = expand(s.as_bytes(), &[], &mut Variables::new()); assert!(res.is_ok(), res.err().unwrap()); - assert_eq!(res.unwrap(), vec!(b'0' + bs[2])); + assert_eq!(res.unwrap(), [b'0' + bs[2]]); } } diff --git a/src/libterm/terminfo/searcher.rs b/src/libterm/terminfo/searcher.rs index c40a5534efbbb..a0cd784207001 100644 --- a/src/libterm/terminfo/searcher.rs +++ b/src/libterm/terminfo/searcher.rs @@ -17,12 +17,13 @@ use std::old_io::fs::PathExtensions; use std::env; /// Return path to database entry for `term` +#[allow(deprecated)] pub fn get_dbpath_for_term(term: &str) -> Option> { if term.len() == 0 { return None; } - let homedir = env::home_dir(); + let homedir = ::std::os::homedir(); let mut dirs_to_search = Vec::new(); let first_char = term.char_at(0); diff --git a/src/rustbook/build.rs b/src/rustbook/build.rs index 9f35bdaa367e5..f36d97d6d120d 100644 --- a/src/rustbook/build.rs +++ b/src/rustbook/build.rs @@ -11,6 +11,7 @@ //! Implementation of the `build` subcommand, used to compile a book. use std::env; +use std::os; use std::old_io; use std::old_io::{fs, File, BufferedWriter, TempDir, IoResult}; @@ -81,7 +82,7 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> { let src; if env::args().len() < 3 { - src = env::current_dir().unwrap().clone(); + src = os::getcwd().unwrap().clone(); } else { src = Path::new(env::args().nth(2).unwrap().clone()); } @@ -149,7 +150,7 @@ impl Subcommand for Build { } fn usage(&self) {} fn execute(&mut self, term: &mut Term) -> CommandResult<()> { - let cwd = env::current_dir().unwrap(); + let cwd = os::getcwd().unwrap(); let src; let tgt; diff --git a/src/rustbook/main.rs b/src/rustbook/main.rs index 68e4ba54d94c1..b9fc011e8b9a5 100644 --- a/src/rustbook/main.rs +++ b/src/rustbook/main.rs @@ -13,6 +13,7 @@ #![feature(core)] #![feature(old_io)] #![feature(env)] +#![feature(os)] #![feature(old_path)] #![feature(rustdoc)] diff --git a/src/rustbook/test.rs b/src/rustbook/test.rs index bff366163dc2f..727a385a8f028 100644 --- a/src/rustbook/test.rs +++ b/src/rustbook/test.rs @@ -17,7 +17,7 @@ use error::Error; use term::Term; use book; use std::old_io::{Command, File}; -use std::env; +use std::os; struct Test; @@ -35,7 +35,7 @@ impl Subcommand for Test { } fn usage(&self) {} fn execute(&mut self, term: &mut Term) -> CommandResult<()> { - let cwd = env::current_dir().unwrap(); + let cwd = os::getcwd().unwrap(); let src = cwd.clone(); let summary = File::open(&src.join("SUMMARY.md")); diff --git a/src/test/compile-fail/borrowck-fn-in-const-a.rs b/src/test/compile-fail/borrowck-fn-in-const-a.rs new file mode 100644 index 0000000000000..3098807f272f3 --- /dev/null +++ b/src/test/compile-fail/borrowck-fn-in-const-a.rs @@ -0,0 +1,22 @@ +// 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. + +// Check that we check fns appearing in constant declarations. +// Issue #22382. + +const MOVE: fn(&String) -> String = { + fn broken(x: &String) -> String { + return *x //~ ERROR cannot move + } + broken +}; + +fn main() { +} diff --git a/src/test/compile-fail/borrowck-fn-in-const-b.rs b/src/test/compile-fail/borrowck-fn-in-const-b.rs new file mode 100644 index 0000000000000..7e29b2ee0fd4e --- /dev/null +++ b/src/test/compile-fail/borrowck-fn-in-const-b.rs @@ -0,0 +1,24 @@ +// 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. + +// Check that we check fns appearing in constant declarations. +// Issue #22382. + +// How about mutating an immutable vector? +const MUTATE: fn(&Vec) = { + fn broken(x: &Vec) { + x.push(format!("this is broken")); + //~^ ERROR cannot borrow + } + broken +}; + +fn main() { +} diff --git a/src/test/compile-fail/borrowck-fn-in-const-c.rs b/src/test/compile-fail/borrowck-fn-in-const-c.rs new file mode 100644 index 0000000000000..e607397e920e2 --- /dev/null +++ b/src/test/compile-fail/borrowck-fn-in-const-c.rs @@ -0,0 +1,33 @@ +// 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. + +// Check that we check fns appearing in constant declarations. +// Issue #22382. + +// Returning local references? +struct DropString { + inner: String +} +impl Drop for DropString { + fn drop(&mut self) { + self.inner.clear(); + self.inner.push_str("dropped"); + } +} +const LOCAL_REF: fn() -> &'static str = { + fn broken() -> &'static str { + let local = DropString { inner: format!("Some local string") }; + return &local.inner; //~ ERROR does not live long enough + } + broken +}; + +fn main() { +} diff --git a/src/test/compile-fail/lint-unsafe-code.rs b/src/test/compile-fail/lint-unsafe-code.rs index 7b17d8877572f..8440cf3a88e10 100644 --- a/src/test/compile-fail/lint-unsafe-code.rs +++ b/src/test/compile-fail/lint-unsafe-code.rs @@ -15,6 +15,8 @@ use std::marker::PhantomFn; struct Bar; +struct Bar2; +struct Bar3; #[allow(unsafe_code)] mod allowed_unsafe { @@ -46,6 +48,53 @@ impl Baz for Bar { unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method } + +#[allow(unsafe_code)] +trait A { + unsafe fn allowed_unsafe(&self); + unsafe fn allowed_unsafe_provided(&self) {} +} + +#[allow(unsafe_code)] +impl Baz for Bar2 { + unsafe fn baz(&self) {} + unsafe fn provided_override(&self) {} +} + +impl Baz for Bar3 { + #[allow(unsafe_code)] + unsafe fn baz(&self) {} + unsafe fn provided_override(&self) {} //~ ERROR: implementation of an `unsafe` method +} + +#[allow(unsafe_code)] +unsafe trait B { + fn dummy(&self) {} +} + +trait C { + #[allow(unsafe_code)] + unsafe fn baz(&self); + unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method +} + +impl C for Bar { + #[allow(unsafe_code)] + unsafe fn baz(&self) {} + unsafe fn provided(&self) {} //~ ERROR: implementation of an `unsafe` method +} + +impl C for Bar2 { + unsafe fn baz(&self) {} //~ ERROR: implementation of an `unsafe` method +} + +trait D { + #[allow(unsafe_code)] + unsafe fn unsafe_provided(&self) {} +} + +impl D for Bar {} + fn main() { unsafe {} //~ ERROR: usage of an `unsafe` block diff --git a/src/test/compile-fail/unsafe_no_drop_flag-gate.rs b/src/test/compile-fail/unsafe_no_drop_flag-gate.rs new file mode 100644 index 0000000000000..542698fd15295 --- /dev/null +++ b/src/test/compile-fail/unsafe_no_drop_flag-gate.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. + +pub struct T; + +#[unsafe_no_drop_flag] +//~^ ERROR unsafe_no_drop_flag has unstable semantics and may be removed +pub struct S { + pub x: T, +} + +impl Drop for S { + fn drop(&mut self) {} +} + +pub fn main() {} diff --git a/src/test/run-pass/auto-ref-sliceable.rs b/src/test/run-pass/auto-ref-sliceable.rs index 652f21c2ae3f8..d2e9bc2efe727 100644 --- a/src/test/run-pass/auto-ref-sliceable.rs +++ b/src/test/run-pass/auto-ref-sliceable.rs @@ -23,5 +23,5 @@ pub fn main() { let mut v = vec!(1); v.push_val(2); v.push_val(3); - assert_eq!(v, vec!(1, 2, 3)); + assert_eq!(v, [1, 2, 3]); } diff --git a/src/test/run-pass/coerce-reborrow-mut-vec-arg.rs b/src/test/run-pass/coerce-reborrow-mut-vec-arg.rs index f87f2e07c9de0..2473b4b674e57 100644 --- a/src/test/run-pass/coerce-reborrow-mut-vec-arg.rs +++ b/src/test/run-pass/coerce-reborrow-mut-vec-arg.rs @@ -22,5 +22,5 @@ fn bar(v: &mut [uint]) { pub fn main() { let mut the_vec = vec!(1, 2, 3, 100); bar(&mut the_vec); - assert_eq!(the_vec, vec!(100, 3, 2, 1)); + assert_eq!(the_vec, [100, 3, 2, 1]); } diff --git a/src/test/run-pass/coerce-reborrow-mut-vec-rcvr.rs b/src/test/run-pass/coerce-reborrow-mut-vec-rcvr.rs index 4f97e6a20815d..ea09bb3904de6 100644 --- a/src/test/run-pass/coerce-reborrow-mut-vec-rcvr.rs +++ b/src/test/run-pass/coerce-reborrow-mut-vec-rcvr.rs @@ -18,5 +18,5 @@ fn bar(v: &mut [uint]) { pub fn main() { let mut the_vec = vec!(1, 2, 3, 100); bar(&mut the_vec); - assert_eq!(the_vec, vec!(100, 3, 2, 1)); + assert_eq!(the_vec, [100, 3, 2, 1]); } diff --git a/src/test/run-pass/env-home-dir.rs b/src/test/run-pass/env-home-dir.rs index 0e1ab73c02d08..5d68a25a14ada 100644 --- a/src/test/run-pass/env-home-dir.rs +++ b/src/test/run-pass/env-home-dir.rs @@ -9,13 +9,14 @@ // except according to those terms. use std::env::*; +use std::path::PathBuf; #[cfg(unix)] fn main() { let oldhome = var("HOME"); set_var("HOME", "/home/MountainView"); - assert!(home_dir() == Some(Path::new("/home/MountainView"))); + assert!(home_dir() == Some(PathBuf::new("/home/MountainView"))); remove_var("HOME"); if cfg!(target_os = "android") { @@ -36,14 +37,14 @@ fn main() { assert!(home_dir().is_some()); set_var("HOME", "/home/MountainView"); - assert!(home_dir() == Some(Path::new("/home/MountainView"))); + assert!(home_dir() == Some(PathBuf::new("/home/MountainView"))); remove_var("HOME"); set_var("USERPROFILE", "/home/MountainView"); - assert!(home_dir() == Some(Path::new("/home/MountainView"))); + assert!(home_dir() == Some(PathBuf::new("/home/MountainView"))); set_var("HOME", "/home/MountainView"); set_var("USERPROFILE", "/home/PaloAlto"); - assert!(home_dir() == Some(Path::new("/home/MountainView"))); + assert!(home_dir() == Some(PathBuf::new("/home/MountainView"))); } diff --git a/src/test/run-pass/generic-static-methods.rs b/src/test/run-pass/generic-static-methods.rs index 7f84efcdd5de8..010f54dd55934 100644 --- a/src/test/run-pass/generic-static-methods.rs +++ b/src/test/run-pass/generic-static-methods.rs @@ -24,5 +24,5 @@ impl vec_utils for Vec { } pub fn main() { - assert_eq!(vec_utils::map_(&vec!(1,2,3), |&x| x+1), vec!(2,3,4)); + assert_eq!(vec_utils::map_(&vec!(1,2,3), |&x| x+1), [2,3,4]); } diff --git a/src/test/run-pass/issue-15149.rs b/src/test/run-pass/issue-15149.rs index aa176d5b0f041..d995ecc492e34 100644 --- a/src/test/run-pass/issue-15149.rs +++ b/src/test/run-pass/issue-15149.rs @@ -1,5 +1,3 @@ -// no-prefer-dynamic - // 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. @@ -10,12 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::slice::SliceExt; -use std::old_io::{fs, USER_RWX}; -use std::process; +// no-prefer-dynamic + +#![feature(fs, process, env, path, rand)] + use std::env; -use std::old_path::BytesContainer; +use std::fs; +use std::process; use std::rand::random; +use std::str; fn main() { // If we're the child, make sure we were invoked correctly @@ -34,21 +35,20 @@ fn main() { fn test() { // If we're the parent, copy our own binary to a new directory. let my_path = env::current_exe().unwrap(); - let my_dir = my_path.dir_path(); + let my_dir = my_path.parent().unwrap(); let random_u32: u32 = random(); - let child_dir = Path::new(my_dir.join(format!("issue-15149-child-{}", - random_u32))); - fs::mkdir(&child_dir, USER_RWX).unwrap(); + let child_dir = my_dir.join(&format!("issue-15149-child-{}", random_u32)); + fs::create_dir(&child_dir).unwrap(); - let child_path = child_dir.join(format!("mytest{}", - env::consts::EXE_SUFFIX)); + let child_path = child_dir.join(&format!("mytest{}", + env::consts::EXE_SUFFIX)); fs::copy(&my_path, &child_path).unwrap(); // Append the new directory to our own PATH. let path = { let mut paths: Vec<_> = env::split_paths(&env::var_os("PATH").unwrap()).collect(); - paths.push(child_dir.clone()); + paths.push(child_dir.to_path_buf()); env::join_paths(paths.iter()).unwrap() }; @@ -58,9 +58,9 @@ fn test() { assert!(child_output.status.success(), format!("child assertion failed\n child stdout:\n {}\n child stderr:\n {}", - child_output.stdout.container_as_str().unwrap(), - child_output.stderr.container_as_str().unwrap())); + str::from_utf8(&child_output.stdout).unwrap(), + str::from_utf8(&child_output.stderr).unwrap())); - fs::rmdir_recursive(&child_dir).unwrap(); + fs::remove_dir_all(&child_dir).unwrap(); } diff --git a/src/test/run-pass/issue-16272.rs b/src/test/run-pass/issue-16272.rs index 3bab78ab0df9f..92d8dfa2cf9a9 100644 --- a/src/test/run-pass/issue-16272.rs +++ b/src/test/run-pass/issue-16272.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::old_io::{process, Command}; +use std::process::Command; use std::env; fn main() { @@ -22,10 +22,8 @@ fn main() { } fn test() { - let status = Command::new(env::current_exe().unwrap()) + let status = Command::new(&env::current_exe().unwrap()) .arg("foo").arg("") - .stdout(process::InheritFd(1)) - .stderr(process::InheritFd(2)) .status().unwrap(); assert!(status.success()); } diff --git a/src/test/run-pass/issue-20091.rs b/src/test/run-pass/issue-20091.rs index 4d20e6360ad4f..ba107dd2cf9a2 100644 --- a/src/test/run-pass/issue-20091.rs +++ b/src/test/run-pass/issue-20091.rs @@ -8,14 +8,19 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-windows currently windows requires UTF-8 for spawning processes - -use std::old_io::Command; -use std::env; - +#[cfg(unix)] fn main() { + use std::process::Command; + use std::env; + use std::os::unix::prelude::*; + use std::ffi::OsStr; + if env::args().len() == 1 { - assert!(Command::new(env::current_exe().unwrap()).arg(b"\xff") + assert!(Command::new(&env::current_exe().unwrap()) + .arg(::from_bytes(b"\xff")) .status().unwrap().success()) } } + +#[cfg(windows)] +fn main() {} diff --git a/src/test/run-pass/issue-3559.rs b/src/test/run-pass/issue-3559.rs index 754412ea94938..3f1a1c75d8a78 100644 --- a/src/test/run-pass/issue-3559.rs +++ b/src/test/run-pass/issue-3559.rs @@ -24,6 +24,6 @@ pub fn main() { let mut table = HashMap::new(); table.insert("one".to_string(), 1); table.insert("two".to_string(), 2); - assert!(check_strs(&format!("{:?}", table), "HashMap {\"one\": 1, \"two\": 2}") || - check_strs(&format!("{:?}", table), "HashMap {\"two\": 2, \"one\": 1}")); + assert!(check_strs(&format!("{:?}", table), "{\"one\": 1, \"two\": 2}") || + check_strs(&format!("{:?}", table), "{\"two\": 2, \"one\": 1}")); } diff --git a/src/test/run-pass/monad.rs b/src/test/run-pass/monad.rs index 457c0a35fd70f..0d563f1a714c3 100644 --- a/src/test/run-pass/monad.rs +++ b/src/test/run-pass/monad.rs @@ -44,11 +44,11 @@ fn transform(x: Option) -> Option { pub fn main() { assert_eq!(transform(Some(10)), Some("11".to_string())); assert_eq!(transform(None), None); - assert!((vec!("hi".to_string())) + assert_eq!((vec!("hi".to_string())) .bind(|x| vec!(x.clone(), format!("{}!", x)) ) - .bind(|x| vec!(x.clone(), format!("{}?", x)) ) == - vec!("hi".to_string(), - "hi?".to_string(), - "hi!".to_string(), - "hi!?".to_string())); + .bind(|x| vec!(x.clone(), format!("{}?", x)) ), + ["hi".to_string(), + "hi?".to_string(), + "hi!".to_string(), + "hi!?".to_string()]); } diff --git a/src/test/run-pass/std-sync-right-kind-impls.rs b/src/test/run-pass/std-sync-right-kind-impls.rs new file mode 100644 index 0000000000000..d2d72ed16618d --- /dev/null +++ b/src/test/run-pass/std-sync-right-kind-impls.rs @@ -0,0 +1,27 @@ +// 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. + +use std::sync; + +fn assert_both() {} + +fn main() { + assert_both::(); + assert_both::(); + assert_both::(); + assert_both::>(); + assert_both::(); + assert_both::>(); + assert_both::(); + assert_both::(); + assert_both::>(); + assert_both::>(); + assert_both::(); +} diff --git a/src/test/run-pass/trait-generic.rs b/src/test/run-pass/trait-generic.rs index 5f4b18df6e16b..0dedf621a4f28 100644 --- a/src/test/run-pass/trait-generic.rs +++ b/src/test/run-pass/trait-generic.rs @@ -44,9 +44,9 @@ fn bar>(x: T) -> Vec { } pub fn main() { - assert_eq!(foo(vec!(1)), vec!("hi".to_string())); - assert_eq!(bar:: >(vec!(4, 5)), vec!("4".to_string(), "5".to_string())); + assert_eq!(foo(vec!(1)), ["hi".to_string()]); + assert_eq!(bar:: >(vec!(4, 5)), ["4".to_string(), "5".to_string()]); assert_eq!(bar:: >(vec!("x".to_string(), "y".to_string())), - vec!("x".to_string(), "y".to_string())); - assert_eq!(bar::<(), Vec<()>>(vec!(())), vec!("()".to_string())); + ["x".to_string(), "y".to_string()]); + assert_eq!(bar::<(), Vec<()>>(vec!(())), ["()".to_string()]); } diff --git a/src/test/run-pass/unboxed-closures-infer-upvar.rs b/src/test/run-pass/unboxed-closures-infer-upvar.rs index 087ef5dcf05e4..1401fe7470b0a 100644 --- a/src/test/run-pass/unboxed-closures-infer-upvar.rs +++ b/src/test/run-pass/unboxed-closures-infer-upvar.rs @@ -18,5 +18,5 @@ fn f(mut f: F) { fn main() { let mut v: Vec<_> = vec![]; f(|| v.push(0)); - assert_eq!(v, vec![0]); + assert_eq!(v, [0]); }