From 081278eb7acc761f583351e846ebad21c88331ff Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 24 Sep 2015 18:54:12 +0200 Subject: [PATCH 1/6] Utf8Error::valid_up_to: make documented semantics more precise/useful --- src/libcore/str/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 69ebcb1ab7e1..456e89d47212 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -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 } From 09d4deef5b3f84548c0b9f6e1f70b0f5818eba2d Mon Sep 17 00:00:00 2001 From: critiqjo Date: Tue, 22 Sep 2015 18:25:01 +0530 Subject: [PATCH 2/6] trpl: Refactor returning closures section --- src/doc/trpl/closures.md | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/doc/trpl/closures.md b/src/doc/trpl/closures.md index 161c4ce90b24..983af4a0efe7 100644 --- a/src/doc/trpl/closures.md +++ b/src/doc/trpl/closures.md @@ -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 doesn’t kick in -here. What lifetime can we choose? `'static`: +our `factory()` function takes no arguments, so +[elision](lifetimes.html#lifetime-elision) doesn’t 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 :7:9: 7:20]` + found `[closure@: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 don’t have a `&'static Fn(i32) -> i32`, -we have a `[closure :7:9: 7:20]`. Wait, what? +we have a `[closure@: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 `, rather than some +this closure. So Rust shows them as `closure@`, rather than some autogenerated name. -But why doesn’t 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 i32> { @@ -471,7 +468,7 @@ assert_eq!(6, answer); # } ``` -We use a trait object, by `Box`ing up the `Fn`. There’s just one last problem: +There’s 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 i32> { From 761d16327ab41b80aa7fd142fe74acdc79f0a4b2 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 25 Sep 2015 13:01:31 +0200 Subject: [PATCH 3/6] Docs: &A and &mut A are references, not pointers Caught by Brian Smith: https://github.com/rust-lang/rust/issues/27774#issuecomment-143154735 --- src/libcore/slice.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 5518bacb019e..a4ccc975d56b 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -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(s: &A) -> &[A] { unsafe { @@ -1418,7 +1418,7 @@ pub fn ref_slice(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(s: &mut A) -> &mut [A] { unsafe { From c6e1b12a58b33ecfe7793d39b28827e05d3106f5 Mon Sep 17 00:00:00 2001 From: Ben S Date: Fri, 25 Sep 2015 12:29:47 +0100 Subject: [PATCH 4/6] Change the first line of the println macro doc This makes the first lines of the print! and println! macros different. Previously, they would show up exactly the same in the documentation for the macros in libstd [1], with nothing about how one of them also prints a newline. [1]: https://doc.rust-lang.org/stable/std/#macros --- src/libstd/macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index a07d21add8db..a88ddb997f61 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -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. From 29048c3a803d085eb814c4410f9258dde81af59d Mon Sep 17 00:00:00 2001 From: Alfie John Date: Fri, 25 Sep 2015 12:02:21 +0000 Subject: [PATCH 5/6] Keep examples consistent --- src/doc/trpl/lifetimes.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/trpl/lifetimes.md b/src/doc/trpl/lifetimes.md index 62270cb45b5e..fb2fc83e0626 100644 --- a/src/doc/trpl/lifetimes.md +++ b/src/doc/trpl/lifetimes.md @@ -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(&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(&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 ``` From 012f36947afb3362a686f3d85f6398c8886b9255 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 21 Sep 2015 08:10:30 +0530 Subject: [PATCH 6/6] Add note about Copy for drop() --- src/libcore/mem.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 48d003c2cffb..193b8d6d620d 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -434,6 +434,11 @@ pub fn replace(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(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(_x: T) { }