Auto merge of #28665 - steveklabnik:rollup, r=steveklabnik

- Successful merges: #28319, #28588, #28637, #28652, #28654, #28655
- Failed merges: #28621
This commit is contained in:
bors 2015-09-25 21:52:52 +00:00
commit 69f27c856b
6 changed files with 45 additions and 24 deletions

View file

@ -411,8 +411,9 @@ fn factory() -> &(Fn(i32) -> i32) {
```
Right. Because we have a reference, we need to give it a lifetime. But
our `factory()` function takes no arguments, so elision doesnt kick in
here. What lifetime can we choose? `'static`:
our `factory()` function takes no arguments, so
[elision](lifetimes.html#lifetime-elision) doesnt kick in here. Then what
choices do we have? Try `'static`:
```rust,ignore
fn factory() -> &'static (Fn(i32) -> i32) {
@ -432,7 +433,7 @@ But we get another error:
```text
error: mismatched types:
expected `&'static core::ops::Fn(i32) -> i32`,
found `[closure <anon>:7:9: 7:20]`
found `[closure@<anon>:7:9: 7:20]`
(expected &-ptr,
found closure) [E0308]
|x| x + num
@ -441,21 +442,17 @@ error: mismatched types:
```
This error is letting us know that we dont have a `&'static Fn(i32) -> i32`,
we have a `[closure <anon>:7:9: 7:20]`. Wait, what?
we have a `[closure@<anon>:7:9: 7:20]`. Wait, what?
Because each closure generates its own environment `struct` and implementation
of `Fn` and friends, these types are anonymous. They exist just solely for
this closure. So Rust shows them as `closure <anon>`, rather than some
this closure. So Rust shows them as `closure@<anon>`, rather than some
autogenerated name.
But why doesnt our closure implement `&'static Fn`? Well, as we discussed before,
closures borrow their environment. And in this case, our environment is based
on a stack-allocated `5`, the `num` variable binding. So the borrow has a lifetime
of the stack frame. So if we returned this closure, the function call would be
over, the stack frame would go away, and our closure is capturing an environment
of garbage memory!
So what to do? This _almost_ works:
The error also points out that the return type is expected to be a reference,
but what we are trying to return is not. Further, we cannot directly assign a
`'static` lifetime to an object. So we'll take a different approach and return
a "trait object" by `Box`ing up the `Fn`. This _almost_ works:
```rust,ignore
fn factory() -> Box<Fn(i32) -> i32> {
@ -471,7 +468,7 @@ assert_eq!(6, answer);
# }
```
We use a trait object, by `Box`ing up the `Fn`. Theres just one last problem:
Theres just one last problem:
```text
error: closure may outlive the current function, but it borrows `num`,
@ -480,8 +477,12 @@ Box::new(|x| x + num)
^~~~~~~~~~~
```
We still have a reference to the parent stack frame. With one last fix, we can
make this work:
Well, as we discussed before, closures borrow their environment. And in this
case, our environment is based on a stack-allocated `5`, the `num` variable
binding. So the borrow has a lifetime of the stack frame. So if we returned
this closure, the function call would be over, the stack frame would go away,
and our closure is capturing an environment of garbage memory! With one last
fix, we can make this work:
```rust
fn factory() -> Box<Fn(i32) -> i32> {

View file

@ -349,9 +349,9 @@ fn frob<'a, 'b>(s: &'a str, t: &'b str) -> &str; // Expanded: Output lifetime is
fn get_mut(&mut self) -> &mut T; // elided
fn get_mut<'a>(&'a mut self) -> &'a mut T; // expanded
fn args<T:ToCStr>(&mut self, args: &[T]) -> &mut Command // elided
fn args<'a, 'b, T:ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command // expanded
fn args<T:ToCStr>(&mut self, args: &[T]) -> &mut Command; // elided
fn args<'a, 'b, T:ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command; // expanded
fn new(buf: &mut [u8]) -> BufWriter; // elided
fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> // expanded
fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a>; // expanded
```

View file

@ -434,6 +434,11 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
/// While this does call the argument's implementation of `Drop`, it will not
/// release any borrows, as borrows are based on lexical scope.
///
/// This effectively does nothing for
/// [types which implement `Copy`](../../book/ownership.html#copy-types),
/// e.g. integers. Such values are copied and _then_ moved into the function,
/// so the value persists after this function call.
///
/// # Examples
///
/// Basic usage:
@ -486,6 +491,21 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
/// let borrow = x.borrow();
/// println!("{}", *borrow);
/// ```
///
/// Integers and other types implementing `Copy` are unaffected by `drop()`
///
/// ```
/// #[derive(Copy, Clone)]
/// struct Foo(u8);
///
/// let x = 1;
/// let y = Foo(2);
/// drop(x); // a copy of `x` is moved and dropped
/// drop(y); // a copy of `y` is moved and dropped
///
/// println!("x: {}, y: {}", x, y.0); // still available
/// ```
///
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn drop<T>(_x: T) { }

View file

@ -1410,7 +1410,7 @@ impl<'a, T> ExactSizeIterator for ChunksMut<'a, T> {}
// Free functions
//
/// Converts a pointer to A into a slice of length 1 (without copying).
/// Converts a reference to A into a slice of length 1 (without copying).
#[unstable(feature = "ref_slice", issue = "27774")]
pub fn ref_slice<A>(s: &A) -> &[A] {
unsafe {
@ -1418,7 +1418,7 @@ pub fn ref_slice<A>(s: &A) -> &[A] {
}
}
/// Converts a pointer to A into a slice of length 1 (without copying).
/// Converts a reference to A into a slice of length 1 (without copying).
#[unstable(feature = "ref_slice", issue = "27774")]
pub fn mut_ref_slice<A>(s: &mut A) -> &mut [A] {
unsafe {

View file

@ -115,8 +115,8 @@ impl Utf8Error {
/// Returns the index in the given string up to which valid UTF-8 was
/// verified.
///
/// Starting at the index provided, but not necessarily at it precisely, an
/// invalid UTF-8 encoding sequence was found.
/// It is the maximum index such that `from_utf8(input[..index])`
/// would return `Some(_)`.
#[unstable(feature = "utf8_error", reason = "method just added",
issue = "27734")]
pub fn valid_up_to(&self) -> usize { self.valid_up_to }

View file

@ -98,7 +98,7 @@ macro_rules! print {
($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
}
/// Macro for printing to the standard output.
/// Macro for printing to the standard output, with a newline.
///
/// Use the `format!` syntax to write data to the standard output.
/// See `std::fmt` for more information.