Auto merge of #22796 - Manishearth:rollup, r=Manishearth

This commit is contained in:
bors 2015-02-25 20:32:58 +00:00
commit 4db0b32467
139 changed files with 1692 additions and 1087 deletions

View file

@ -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

View file

@ -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
* `stringify!` : turn the identifier argument into a string literal
* `concat!` : concatenates a comma-separated list of literals
## 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
* `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:
## 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*

View file

@ -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.

View file

@ -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.

View file

@ -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,
"<html><head><title>Macros guide</title></head>\
<body><h1>Macros are the best!</h1></body></html>");
}
```
# 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

View file

@ -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

View file

@ -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))]

View file

@ -480,7 +480,7 @@ impl<T: Ord> BinaryHeap<T> {
/// 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<T> {
let mut end = self.len();

View file

@ -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<u8> {
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();

View file

@ -347,7 +347,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
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<K: Ord, V> BTreeMap<K, V> {
}
});
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<K: Ord, V> BTreeMap<K, V> {
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<K: Ord, V: Ord> Ord for BTreeMap<K, V> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<K: Debug, V: Debug> Debug for BTreeMap<K, V> {
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<K, V> BTreeMap<K, V> {
/// a.insert(2, "b");
///
/// let keys: Vec<usize> = 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<K, V> BTreeMap<K, V> {
/// 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<K: Ord, V> BTreeMap<K, V> {
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 {

View file

@ -1136,12 +1136,12 @@ impl<K, V> Node<K, V> {
// 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<K, V> Node<K, V> {
// This can only be called immediately after a call to insert_kv.
#[inline]
unsafe fn insert_edge(&mut self, index: usize, edge: Node<K, V>) {
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<K, V> Node<K, V> {
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<K, V> Node<K, V> {
unsafe fn remove_edge(&mut self, index: usize) -> Node<K, V> {
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<K, V> Node<K, V> {
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<K, V> Node<K, V> {
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

View file

@ -121,7 +121,7 @@ impl<T> BTreeSet<T> {
/// }
///
/// let v: Vec<usize> = 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<T> {
@ -138,7 +138,7 @@ impl<T> BTreeSet<T> {
/// let set: BTreeSet<usize> = [1, 2, 3, 4].iter().cloned().collect();
///
/// let v: Vec<usize> = 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<T> {
@ -197,7 +197,7 @@ impl<T: Ord> BTreeSet<T> {
/// b.insert(3);
///
/// let diff: Vec<usize> = 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<T>) -> Difference<'a, T> {
@ -220,7 +220,7 @@ impl<T: Ord> BTreeSet<T> {
/// b.insert(3);
///
/// let sym_diff: Vec<usize> = 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<T>)
@ -244,7 +244,7 @@ impl<T: Ord> BTreeSet<T> {
/// b.insert(3);
///
/// let intersection: Vec<usize> = 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<T>)
@ -266,7 +266,7 @@ impl<T: Ord> BTreeSet<T> {
/// b.insert(2);
///
/// let union: Vec<usize> = 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<T>) -> Union<'a, T> {
@ -534,7 +534,7 @@ impl<'a, 'b, T: Ord + Clone> Sub<&'b BTreeSet<T>> for &'a BTreeSet<T> {
///
/// 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<T>) -> BTreeSet<T> {
self.difference(rhs).cloned().collect()
@ -557,7 +557,7 @@ impl<'a, 'b, T: Ord + Clone> BitXor<&'b BTreeSet<T>> for &'a BTreeSet<T> {
///
/// 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<T>) -> BTreeSet<T> {
self.symmetric_difference(rhs).cloned().collect()
@ -580,7 +580,7 @@ impl<'a, 'b, T: Ord + Clone> BitAnd<&'b BTreeSet<T>> for &'a BTreeSet<T> {
///
/// 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<T>) -> BTreeSet<T> {
self.intersection(rhs).cloned().collect()
@ -603,7 +603,7 @@ impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet<T>> for &'a BTreeSet<T> {
///
/// 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<T>) -> BTreeSet<T> {
self.union(rhs).cloned().collect()
@ -613,7 +613,7 @@ impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet<T>> for &'a BTreeSet<T> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Debug> Debug for BTreeSet<T> {
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), "{}");
}
}

View file

@ -36,7 +36,7 @@ impl<E> Copy for EnumSet<E> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<E:CLike + fmt::Debug> fmt::Debug for EnumSet<E> {
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]

View file

@ -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

View file

@ -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<A: Clone> Clone for LinkedList<A> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<A: fmt::Debug> fmt::Debug for LinkedList<A> {
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<_>>(), vec![-2,0,1,2,3,4,5,6,7,8,9,0,1]);
assert_eq!(m.into_iter().collect::<Vec<_>>(), [-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)]

View file

@ -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

View file

@ -1331,12 +1331,10 @@ fn insertion_sort<T, F>(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<T, F>(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<T, F>(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::<T>();
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::<T>();
ptr::copy_nonoverlapping_memory(out, &*left, elems);
ptr::copy_nonoverlapping(out, &*left, elems);
break;
}
@ -1478,7 +1476,7 @@ fn merge_sort<T, F>(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<T, F>(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<i32>; 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<i32>; 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]

View file

@ -552,7 +552,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
/// ```
/// let v: Vec<char> = "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<RangeFull, Output = str> {
///
/// ```
/// 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<RangeFull, Output = str> {
///
/// ```
/// 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<RangeFull, Output = str> {
///
/// ```
/// 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<RangeFull, Output = str> {
///
/// ```
/// 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<RangeFull, Output = str> {
///
/// ```
/// 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<RangeFull, Output = str> {
///
/// ```
/// 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<RangeFull, Output = str> {
/// 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<RangeFull, Output = str> {
/// 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<RangeFull, Output = str> {
/// 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<RangeFull, Output = str> {
/// 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<RangeFull, Output = str> {
/// 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]

View file

@ -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");

View file

@ -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<T>` as an efficient stack:
@ -242,7 +242,7 @@ impl<T> Vec<T> {
///
/// // 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<T> Vec<T> {
pub unsafe fn from_raw_buf(ptr: *const T, elts: usize) -> Vec<T> {
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<T> Vec<T> {
/// ```
/// 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<T> Vec<T> {
/// 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<T> Vec<T> {
/// ```
/// 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<T> Vec<T> {
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<T> Vec<T> {
/// ```
/// 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<T> Vec<T> {
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<T> Vec<T> {
/// ```
/// 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<F>(&mut self, mut f: F) where F: FnMut(&T) -> bool {
@ -636,7 +636,7 @@ impl<T> Vec<T> {
/// ```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<T> Vec<T> {
/// ```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<T> Vec<T> {
/// 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<T> Vec<T> {
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<T> Vec<T> {
/// ```
/// 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<T> Vec<T> {
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<T: Clone> Vec<T> {
/// ```
/// 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<T: Clone> Vec<T> {
/// ```
/// 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<T: PartialEq> Vec<T> {
///
/// 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]

View file

@ -134,7 +134,7 @@ impl<T> VecDeque<T> {
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<T> VecDeque<T> {
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<T> VecDeque<T> {
// `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<A> Extend<A> for VecDeque<A> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: fmt::Debug> fmt::Debug for VecDeque<T> {
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<_>>(), vec!(4, 2, 3, 1));
assert_eq!(d.iter().cloned().collect::<Vec<_>>(), [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::<Vec<_>>(), [1, 2, 3, 4, 5, 6]);
assert_eq!(b.iter().cloned().collect::<Vec<_>>(), []);
// 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::<Vec<_>>(), [1, 2, 3, 4, 5, 6]);
assert_eq!(b.iter().cloned().collect::<Vec<_>>(), []);
// 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::<Vec<_>>(), [1, 2, 3, 4, 5, 6]);
assert_eq!(a.iter().cloned().collect::<Vec<_>>(), []);
}
}

View file

@ -308,7 +308,7 @@ impl<V> VecMap<V> {
///
/// 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<V> {
@ -425,7 +425,7 @@ impl<V> VecMap<V> {
///
/// 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<V: Ord> Ord for VecMap<V> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<V: fmt::Debug> fmt::Debug for VecMap<V> {
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]

View file

@ -293,7 +293,7 @@ extern "rust-intrinsic" {
/// }
/// }
/// ```
#[unstable(feature = "core")]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize);
/// Copies `count * size_of<T>` 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<T>(dst: *mut T, src: *const T, count: usize);
/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
/// 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<T>(dst: *mut T, val: u8, count: usize);
/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with

View file

@ -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")]

View file

@ -203,9 +203,9 @@ pub fn swap<T>(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.

View file

@ -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;

View file

@ -556,7 +556,7 @@ impl<T> Option<T> {
/// ```
/// 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();

View file

@ -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<T>(dst: *mut T, src: *const T, count: usize);
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0", reason = "renamed to `copy`")]
pub fn copy_memory<T>(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<T>(dst: *mut T, val: u8, count: usize);
}
/// Creates a null raw pointer.
///
@ -150,8 +162,9 @@ pub fn null_mut<T>() -> *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<T>(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<T>(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<T>(dest: *mut T, mut src: T) -> T {
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn read<T>(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<T>(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<T>(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<T> PtrExt for *const T {
impl<T: ?Sized> PtrExt for *const T {
type Target = T;
#[inline]
@ -311,7 +324,7 @@ impl<T> 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<T> PtrExt for *const T {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> PtrExt for *mut T {
impl<T: ?Sized> PtrExt for *mut T {
type Target = T;
#[inline]
@ -338,7 +351,7 @@ impl<T> 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<T> PtrExt for *mut T {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> MutPtrExt for *mut T {
impl<T: ?Sized> MutPtrExt for *mut T {
type Target = T;
#[inline]
@ -374,33 +387,25 @@ impl<T> MutPtrExt for *mut T {
// Equality for pointers
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> PartialEq for *const T {
impl<T: ?Sized> 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<T> Eq for *const T {}
impl<T: ?Sized> Eq for *const T {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> PartialEq for *mut T {
impl<T: ?Sized> PartialEq for *mut T {
#[inline]
fn eq(&self, other: &*mut T) -> bool {
*self == *other
}
#[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<T> Eq for *mut T {}
impl<T: ?Sized> Eq for *mut T {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Clone for *const T {
impl<T: ?Sized> Clone for *const T {
#[inline]
fn clone(&self) -> *const T {
*self
@ -408,7 +413,7 @@ impl<T> Clone for *const T {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Clone for *mut T {
impl<T: ?Sized> 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<T> Ord for *const T {
impl<T: ?Sized> Ord for *const T {
#[inline]
fn cmp(&self, other: &*const T) -> Ordering {
if self < other {
@ -466,7 +471,7 @@ impl<T> Ord for *const T {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> PartialOrd for *const T {
impl<T: ?Sized> PartialOrd for *const T {
#[inline]
fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
Some(self.cmp(other))
@ -486,7 +491,7 @@ impl<T> PartialOrd for *const T {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Ord for *mut T {
impl<T: ?Sized> Ord for *mut T {
#[inline]
fn cmp(&self, other: &*mut T) -> Ordering {
if self < other {
@ -500,7 +505,7 @@ impl<T> Ord for *mut T {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> PartialOrd for *mut T {
impl<T: ?Sized> PartialOrd for *mut T {
#[inline]
fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {
Some(self.cmp(other))
@ -527,8 +532,8 @@ impl<T> PartialOrd for *mut T {
/// modified without a unique path to the `Unique` reference. Useful
/// for building abstractions like `Vec<T>` or `Box<T>`, which
/// internally use raw pointers to manage the memory that they own.
#[unstable(feature = "core", reason = "recently added to this module")]
pub struct Unique<T:?Sized> {
#[unstable(feature = "unique")]
pub struct Unique<T: ?Sized> {
pointer: NonZero<*const T>,
_marker: PhantomData<T>,
}
@ -537,39 +542,37 @@ pub struct Unique<T:?Sized> {
/// 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<T: Send + ?Sized> Send for Unique<T> { }
/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they
/// reference is unaliased. Note that this aliasing invariant is
/// unenforced by the type system; the abstraction using the
/// `Unique` must enforce it.
#[unstable(feature = "core", reason = "recently added to this module")]
#[unstable(feature = "unique")]
unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
impl<T:?Sized> Unique<T> {
impl<T: ?Sized> Unique<T> {
/// Create a new `Unique`.
#[unstable(feature = "core",
reason = "recently added to this module")]
#[unstable(feature = "unique")]
pub unsafe fn new(ptr: *mut T) -> Unique<T> {
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<T:?Sized> Deref for Unique<T> {
type Target = *mut T;

View file

@ -548,11 +548,11 @@ impl<T, E> Result<T, E> {
/// ```
/// let x: Result<u32, &str> = Ok(5);
/// let v: Vec<u32> = x.into_iter().collect();
/// assert_eq!(v, vec![5]);
/// assert_eq!(v, [5]);
///
/// let x: Result<u32, &str> = Err("nothing!");
/// let v: Vec<u32> = x.into_iter().collect();
/// assert_eq!(v, vec![]);
/// assert_eq!(v, []);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]

View file

@ -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);
}
}
}

View file

@ -74,7 +74,7 @@ fn test_multi_iter() {
fn test_counter_from_iter() {
let it = count(0, 5).take(10);
let xs: Vec<int> = 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<uint>>() == vec![0*0, 2*2, 4*4, 6*6, 8*8]);
assert_eq!(it.collect::<Vec<uint>>(), [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<_>>() == vec![13, 12, 11]);
assert_eq!((11..14).rev().collect::<Vec<_>>(), [13, 12, 11]);
for _ in (10..0).rev() {
panic!("unreachable");
}
assert!((11..14).rev().collect::<Vec<_>>() == vec![13, 12, 11]);
assert_eq!((11..14).rev().collect::<Vec<_>>(), [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<_>>() == vec![0, 1, 2, 3, 4]);
assert!((-10..-1).collect::<Vec<_>>() ==
vec![-10, -9, -8, -7, -6, -5, -4, -3, -2]);
assert!((0..5).rev().collect::<Vec<_>>() == vec![4, 3, 2, 1, 0]);
assert_eq!((0..5).collect::<Vec<_>>(), [0, 1, 2, 3, 4]);
assert_eq!((-10..-1).collect::<Vec<_>>(), [-10, -9, -8, -7, -6, -5, -4, -3, -2]);
assert_eq!((0..5).rev().collect::<Vec<_>>(), [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<int>>() == vec![200]);
assert!(range_inclusive(200, 200).rev().collect::<Vec<int>>() == vec![200]);
assert_eq!(range_inclusive(200, 200).collect::<Vec<int>>(), [200]);
assert_eq!(range_inclusive(200, 200).rev().collect::<Vec<int>>(), [200]);
}
#[test]
fn test_range_step() {
assert!(range_step(0, 20, 5).collect::<Vec<int>>() ==
vec![0, 5, 10, 15]);
assert!(range_step(20, 0, -5).collect::<Vec<int>>() ==
vec![20, 15, 10, 5]);
assert!(range_step(20, 0, -6).collect::<Vec<int>>() ==
vec![20, 14, 8, 2]);
assert!(range_step(200u8, 255, 50).collect::<Vec<u8>>() ==
vec![200u8, 250]);
assert!(range_step(200, -5, 1).collect::<Vec<int>>() == vec![]);
assert!(range_step(200, 200, 1).collect::<Vec<int>>() == vec![]);
assert_eq!(range_step(0, 20, 5).collect::<Vec<int>>(), [0, 5, 10, 15]);
assert_eq!(range_step(20, 0, -5).collect::<Vec<int>>(), [20, 15, 10, 5]);
assert_eq!(range_step(20, 0, -6).collect::<Vec<int>>(), [20, 14, 8, 2]);
assert_eq!(range_step(200u8, 255, 50).collect::<Vec<u8>>(), [200u8, 250]);
assert_eq!(range_step(200i, -5, 1).collect::<Vec<int>>(), []);
assert_eq!(range_step(200i, 200, 1).collect::<Vec<int>>(), []);
}
#[test]
fn test_range_step_inclusive() {
assert!(range_step_inclusive(0, 20, 5).collect::<Vec<int>>() ==
vec![0, 5, 10, 15, 20]);
assert!(range_step_inclusive(20, 0, -5).collect::<Vec<int>>() ==
vec![20, 15, 10, 5, 0]);
assert!(range_step_inclusive(20, 0, -6).collect::<Vec<int>>() ==
vec![20, 14, 8, 2]);
assert!(range_step_inclusive(200u8, 255, 50).collect::<Vec<u8>>() ==
vec![200u8, 250]);
assert!(range_step_inclusive(200, -5, 1).collect::<Vec<int>>() ==
vec![]);
assert!(range_step_inclusive(200, 200, 1).collect::<Vec<int>>() ==
vec![200]);
assert_eq!(range_step_inclusive(0, 20, 5).collect::<Vec<int>>(), [0, 5, 10, 15, 20]);
assert_eq!(range_step_inclusive(20, 0, -5).collect::<Vec<int>>(), [20, 15, 10, 5, 0]);
assert_eq!(range_step_inclusive(20, 0, -6).collect::<Vec<int>>(), [20, 14, 8, 2]);
assert_eq!(range_step_inclusive(200u8, 255, 50).collect::<Vec<u8>>(), [200u8, 250]);
assert_eq!(range_step_inclusive(200, -5, 1).collect::<Vec<int>>(), []);
assert_eq!(range_step_inclusive(200, 200, 1).collect::<Vec<int>>(), [200]);
}
#[test]

View file

@ -103,7 +103,7 @@ fn test_transmute() {
}
unsafe {
assert!(vec![76u8] == transmute::<_, Vec<u8>>("L".to_string()));
assert_eq!([76u8], transmute::<_, Vec<u8>>("L".to_string()));
}
}

View file

@ -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])")
}
}

View file

@ -122,4 +122,9 @@ mod test {
assert_eq!("-9223372036854775808".parse::<i64>().ok(), Some(i64_val));
assert_eq!("-9223372036854775809".parse::<i64>().ok(), None);
}
#[test]
fn test_int_from_minus_sign() {
assert_eq!("-".parse::<i32>().ok(), None);
}
}

View file

@ -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]);
}
}

View file

@ -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<u16>>(),
vec![0xE9, 0xD83D, 0xDCA9])
[0xE9, 0xD83D, 0xDCA9])
}
#[test]

View file

@ -27,6 +27,7 @@
#![feature(int_uint)]
#![feature(libc)]
#![feature(staged_api)]
#![feature(unique)]
#[cfg(test)] #[macro_use] extern crate log;

View file

@ -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;

View file

@ -45,7 +45,7 @@ fn combine(seek: SeekStyle, cur: uint, end: uint, offset: i64) -> IoResult<u64>
/// 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<u8>,

View file

@ -40,6 +40,7 @@
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(unicode)]
#![feature(os)]
#![cfg_attr(test, feature(test))]
extern crate arena;

View file

@ -1295,48 +1295,38 @@ 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<ast::Method>) {
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");
}
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),
_ => (),
}
}
},
ast::ItemImpl(impl_safety, _, _, _, _, ref impls) => {
if impl_safety == Unsafe {
cx.span_lint(UNSAFE_CODE, it.span, "implementation of an `unsafe` trait");
}
for item in impls {
if let ast::ImplItem::MethodImplItem(ref meth) = *item {
check_method(cx, meth);
}
}
},
ast::ItemImpl(ast::Unsafety::Unsafe, _, _, _, _, _) =>
cx.span_lint(UNSAFE_CODE, it.span, "implementation of an `unsafe` trait"),
_ => return,
}
}
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"),
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")
}
},
_ => (),
}
}
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")
}
}
}
declare_lint! {

View file

@ -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<Path> {
}
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<Path> {
}
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);

View file

@ -736,12 +736,10 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
}
};
return match ArchiveMetadata::new(archive).map(|ar| MetadataArchive(ar)) {
None => {
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<MetadataBlo
}
llvm::LLVMMoveToNextSection(si.llsi);
}
return Err(format!("metadata not found: '{}'", filename.display()));
Err(format!("metadata not found: '{}'", filename.display()))
}
}

View file

@ -228,11 +228,11 @@ pub trait Combine<'tcx> : Sized {
variadic: a.variadic});
fn argvecs<'tcx, C: Combine<'tcx>>(combiner: &C,
a_args: &[Ty<'tcx>],
b_args: &[Ty<'tcx>])
-> cres<'tcx, Vec<Ty<'tcx>>>
{
fn argvecs<'tcx, C>(combiner: &C,
a_args: &[Ty<'tcx>],
b_args: &[Ty<'tcx>])
-> cres<'tcx, Vec<Ty<'tcx>>>
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 `<T as Foo>::Bar` and `<U as
// Foo>::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<T>
where T : Combineable<'tcx>
{
fn combine<C:Combine<'tcx>>(combiner: &C,
a: &Rc<T>,
b: &Rc<T>)
-> cres<'tcx, Rc<T>>
{
fn combine<C>(combiner: &C,
a: &Rc<T>,
b: &Rc<T>)
-> cres<'tcx, Rc<T>>
where C: Combine<'tcx> {
Ok(Rc::new(try!(Combineable::combine(combiner, &**a, &**b))))
}
}
impl<'tcx> Combineable<'tcx> for ty::TraitRef<'tcx> {
fn combine<C:Combine<'tcx>>(combiner: &C,
a: &ty::TraitRef<'tcx>,
b: &ty::TraitRef<'tcx>)
-> cres<'tcx, ty::TraitRef<'tcx>>
{
fn combine<C>(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<C:Combine<'tcx>>(combiner: &C,
a: &Ty<'tcx>,
b: &Ty<'tcx>)
-> cres<'tcx, Ty<'tcx>>
{
fn combine<C>(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<C:Combine<'tcx>>(combiner: &C,
a: &ty::ProjectionPredicate<'tcx>,
b: &ty::ProjectionPredicate<'tcx>)
-> cres<'tcx, ty::ProjectionPredicate<'tcx>>
{
fn combine<C>(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<C:Combine<'tcx>>(combiner: &C,
a: &ty::FnSig<'tcx>,
b: &ty::FnSig<'tcx>)
-> cres<'tcx, ty::FnSig<'tcx>>
{
fn combine<C>(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<T> {
pub fn expected_found<'tcx, C, T>(this: &C,
a: T,
b: T)
-> ty::expected_found<T>
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)));
}
// 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)
}
(&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_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_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_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_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_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_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_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_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_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::<Result<_, _>>()
.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::<Result<_, _>>()
.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)

View file

@ -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 {

View file

@ -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

View file

@ -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,
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);
// 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.
// Normalized failed? use what they gave us, it's better than nothing.
unnormalized_env
}
}
}
let tcx = unnormalized_env.tcx;
let span = cause.span;
let body_id = cause.body_id;
pub fn normalize_param_env<'a,'tcx>(param_env: &ty::ParameterEnvironment<'a,'tcx>,
cause: ObligationCause<'tcx>)
-> Result<ty::ParameterEnvironment<'a,'tcx>,
Vec<FulfillmentError<'tcx>>>
{
let tcx = param_env.tcx;
debug!("normalize_param_env(param_env={})",
param_env.repr(tcx));
debug!("normalize_param_env_or_error(unnormalized_env={})",
unnormalized_env.repr(tcx));
let infcx = infer::new_infer_ctxt(tcx);
let predicates = try!(fully_normalize(&infcx, param_env, cause, &param_env.caller_bounds));
let predicates = match fully_normalize(&infcx, &unnormalized_env, cause,
&unnormalized_env.caller_bounds) {
Ok(predicates) => predicates,
Err(errors) => {
report_fulfillment_errors(&infcx, &errors);
return unnormalized_env; // an unnormalized env is better than nothing
}
};
debug!("normalize_param_env: predicates={}",
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_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)
}

View file

@ -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<T>
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<Ty<'tcx>>)
-> Result<BuiltinBoundConditions<'tcx>,SelectionError<'tcx>>
-> Result<BuiltinBoundConditions<'tcx>, 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<T>
@ -1909,7 +1883,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}).collect::<Result<_, _>>();
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<Vec<PredicateObligation<'tcx>>,()>
{
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,
}
}
}

View file

@ -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,

View file

@ -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;
@ -356,7 +356,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)
}
);
@ -379,7 +379,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()),

View file

@ -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]);

View file

@ -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<Path> {
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) {

View file

@ -41,6 +41,7 @@
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(env)]
#![feature(path)]
extern crate syntax;
extern crate serialize;

View file

@ -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<F, G> where
@ -109,7 +109,7 @@ fn get_rpath_relative_to_output<F, G>(config: &mut RPathConfig<F, G>, 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<F, G>(config: RPathConfig<F, G>) -> 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<String> {

View file

@ -310,6 +310,7 @@ impl Target {
/// JSON decoding.
pub fn search(target: &str) -> Result<Target, String> {
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);

View file

@ -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.

View file

@ -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", (), |_|

View file

@ -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);
})
}

View file

@ -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")
};
}
}
}

View file

@ -203,6 +203,56 @@
//! failure, but rather because the target type `Foo<Y>` 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:
//!
//! <T as Trait> <: <U as Trait>
//!
//! 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 `<T as Trait>` is safe
//! to use where a dictionary for `<U as
//! Trait>` is expected.
//!
//! The problem is that when you can
//! project types out from `<T as Trait>`,
//! the relationship to types projected out
//! of `<U as Trait>` 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<T> 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) => {

View file

@ -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),

View file

@ -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<bool> = super::decode("[true]").unwrap();
assert_eq!(v, vec![true]);
assert_eq!(v, [true]);
let v: Vec<int> = super::decode("[3, 1]").unwrap();
assert_eq!(v, vec![3, 1]);
assert_eq!(v, [3, 1]);
let v: Vec<Vec<uint>> = super::decode("[[3], [1, 2]]").unwrap();
assert_eq!(v, vec![vec![3], vec![1, 2]]);
assert_eq!(v, [vec![3], vec![1, 2]]);
}
#[test]

View file

@ -1212,7 +1212,7 @@ impl<K, V, S> Debug for HashMap<K, V, S>
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]

View file

@ -598,7 +598,7 @@ impl<T, S> fmt::Debug for HashSet<T, S>
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]

View file

@ -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<K, V, M: Deref<Target=RawTable<K, V>>> GapThenFull<K, V, M> {
pub fn shift(mut self) -> Option<GapThenFull<K, V, M>> {
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<K, V> RawTable<K, V> {
pub fn new(capacity: usize) -> RawTable<K, V> {
unsafe {
let ret = RawTable::new_uninitialized(capacity);
zero_memory(*ret.hashes, capacity);
ptr::write_bytes(*ret.hashes, 0, capacity);
ret
}
}

View file

@ -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<Path> {
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(),
}
}

View file

@ -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<Path> {
pub fn current_dir() -> io::Result<PathBuf> {
os_imp::getcwd()
}
@ -57,14 +58,14 @@ pub fn current_dir() -> IoResult<Path> {
///
/// ```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: AsPath + ?Sized>(p: &P) -> io::Result<()> {
os_imp::chdir(p.as_path())
}
static ENV_LOCK: StaticMutex = MUTEX_INIT;
@ -280,8 +281,8 @@ pub fn split_paths<T: AsOsStr + ?Sized>(unparsed: &T) -> SplitPaths {
}
impl<'a> Iterator for SplitPaths<'a> {
type Item = Path;
fn next(&mut self) -> Option<Path> { self.inner.next() }
type Item = PathBuf;
fn next(&mut self) -> Option<PathBuf> { self.inner.next() }
fn size_hint(&self) -> (usize, Option<usize>) { 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::<Vec<_>>();
/// 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<Path> {
pub fn home_dir() -> Option<PathBuf> {
os_imp::home_dir()
}
@ -369,7 +371,7 @@ pub fn home_dir() -> Option<Path> {
/// 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<Path> {
pub fn current_exe() -> io::Result<PathBuf> {
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::<Vec<_>>() ==
parsed.iter().map(|s| Path::new(*s)).collect::<Vec<_>>()
parsed.iter().map(|s| PathBuf::new(*s)).collect::<Vec<_>>()
}
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::<Vec<_>>() ==
parsed.iter().map(|s| Path::new(*s)).collect::<Vec<_>>()
parsed.iter().map(|s| PathBuf::new(*s)).collect::<Vec<_>>()
}
assert!(check_parse("", &mut [""]));

View file

@ -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<fs_imp::FilePermissions> for Permissions {
}
}
impl AsInner<fs_imp::FilePermissions> for Permissions {
fn as_inner(&self) -> &fs_imp::FilePermissions { &self.0 }
}
impl Iterator for ReadDir {
type Item = io::Result<DirEntry>;
@ -540,7 +548,14 @@ pub fn create_dir_all<P: AsPath + ?Sized>(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/")));
}
}

125
src/libstd/fs/tempdir.rs Normal file
View file

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![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<PathBuf>,
}
// 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<P: AsPath + ?Sized>(tmpdir: &P, prefix: &str)
-> io::Result<TempDir> {
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> {
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

View file

@ -48,7 +48,7 @@ impl<R: Read> BufReader<R> {
}
/// 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<W: Write> BufWriter<W> {
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);

View file

@ -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.

View file

@ -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
}

View file

@ -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]

View file

@ -60,7 +60,7 @@ impl Writer for Vec<u8> {
/// 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<u8>,
@ -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());
}

View file

@ -87,7 +87,7 @@ mod test {
let mut writer: old_io::IoResult<Vec<u8>> = 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]

View file

@ -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<TempDir> {
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> {
TempDir::new_in(&env::temp_dir(), prefix)
TempDir::new_in(&::os::tmpdir(), prefix)
}
/// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper.

View file

@ -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;

View file

@ -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]

View file

@ -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(<OsStr as OsStrExt>::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<Path> {
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<T: BytesContainer>(unparsed: T) -> Vec<Path> {
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<T: BytesContainer>(unparsed: T) -> Vec<Path> {
/// 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<T: BytesContainer>(paths: &[T]) -> Result<Vec<u8>, &'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<Path> {
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<Path> {
/// 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<Path> {
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<Path> {
/// 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<Path> {
#[inline]
#[cfg(unix)]
@ -424,9 +448,8 @@ pub fn homedir() -> Option<Path> {
/// 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<Path> {
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<Path> {
/// 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

View file

@ -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" {

View file

@ -61,9 +61,6 @@ use sync::{mutex, MutexGuard, PoisonError};
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Condvar { inner: Box<StaticCondvar> }
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")]

View file

@ -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;

View file

@ -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.
///

View file

@ -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 {

View file

@ -16,6 +16,12 @@ use fmt;
use thread;
pub struct Flag { failed: UnsafeCell<bool> }
// 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 {

View file

@ -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")]

View file

@ -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::*;

View file

@ -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<()> {

View file

@ -1202,11 +1202,11 @@ mod tests {
string.code_points().map(|c| c.to_char()).collect::<Vec<_>>()
}
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]

View file

@ -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) {

View file

@ -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<ffi::pthread_cond_t> }
unsafe impl Send for Condvar {}
unsafe impl Sync for Condvar {}
pub const CONDVAR_INIT: Condvar = Condvar {
inner: UnsafeCell { value: ffi::PTHREAD_COND_INITIALIZER },
};

View file

@ -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));
}

View file

@ -90,6 +90,7 @@ impl FilePermissions {
self.mode |= 0o222;
}
}
pub fn mode(&self) -> i32 { self.mode as i32 }
}
impl FromInner<i32> for FilePermissions {

View file

@ -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

View file

@ -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 {

View file

@ -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(<OsStr as OsStrExt>::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<Path> {
pub fn getcwd() -> io::Result<PathBuf> {
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<slice::Split<'a, u8, fn(&u8) -> 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<Path> { self.iter.next() }
type Item = PathBuf;
fn next(&mut self) -> Option<PathBuf> { self.iter.next() }
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
@ -174,7 +183,7 @@ impl StdError for JoinPathsError {
}
#[cfg(target_os = "freebsd")]
pub fn current_exe() -> IoResult<Path> {
pub fn current_exe() -> io::Result<PathBuf> {
unsafe {
use libc::funcs::bsd44::*;
use libc::consts::os::extra::*;
@ -186,26 +195,26 @@ pub fn current_exe() -> IoResult<Path> {
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<u8> = 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::<OsString>(&OsStringExt::from_vec(v)))
}
}
#[cfg(target_os = "dragonfly")]
pub fn current_exe() -> IoResult<Path> {
fs::readlink(&Path::new("/proc/curproc/file"))
pub fn current_exe() -> io::Result<PathBuf> {
::fs::read_link("/proc/curproc/file")
}
#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
pub fn current_exe() -> IoResult<Path> {
pub fn current_exe() -> io::Result<PathBuf> {
use sync::{StaticMutex, MUTEX_INIT};
static LOCK: StaticMutex = MUTEX_INIT;
@ -218,7 +227,7 @@ pub fn current_exe() -> IoResult<Path> {
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<Path> {
}
#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn current_exe() -> IoResult<Path> {
fs::readlink(&Path::new("/proc/self/exe"))
pub fn current_exe() -> io::Result<PathBuf> {
::fs::read_link("/proc/self/exe")
}
#[cfg(any(target_os = "macos", target_os = "ios"))]
pub fn current_exe() -> IoResult<Path> {
pub fn current_exe() -> io::Result<PathBuf> {
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<u8> = 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::<OsString>(&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<Path> {
pub fn home_dir() -> Option<PathBuf> {
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"))]

View file

@ -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,

View file

@ -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<Req>,
(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<ProcessExit>, u64)>::new();

View file

@ -141,7 +141,6 @@ impl Process {
-> io::Result<Process>
{
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| {

View file

@ -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 {

Some files were not shown because too many files have changed in this diff Show more