From 16334e508e6c7feaea7cdf68649f6cbc29fadb3a Mon Sep 17 00:00:00 2001 From: Max Jacobson Date: Mon, 25 May 2015 22:35:53 -0400 Subject: [PATCH 01/18] Add a missing space to the Glossary page of TRPL r? @steveklabnik --- src/doc/trpl/glossary.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/trpl/glossary.md b/src/doc/trpl/glossary.md index 9845fcbdcd1..c97da0e95b8 100644 --- a/src/doc/trpl/glossary.md +++ b/src/doc/trpl/glossary.md @@ -19,7 +19,7 @@ In the example above `x` and `y` have arity 2. `z` has arity 3. When a compiler is compiling your program, it does a number of different things. One of the things that it does is turn the text of your program into an -‘abstract syntax tree’, or‘AST’. This tree is a representation of the +‘abstract syntax tree’, or ‘AST’. This tree is a representation of the structure of your program. For example, `2 + 3` can be turned into a tree: ```text From 15ab4813223ed5252a9c434f14eb5b66462b018b Mon Sep 17 00:00:00 2001 From: Mathieu David Date: Thu, 28 May 2015 23:47:27 +0200 Subject: [PATCH 02/18] removed lonely closing parenthesis There was no opening parenthesis for this closing parenthesis... --- src/doc/trpl/method-syntax.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/trpl/method-syntax.md b/src/doc/trpl/method-syntax.md index e5f490e15e1..1f694f71a88 100644 --- a/src/doc/trpl/method-syntax.md +++ b/src/doc/trpl/method-syntax.md @@ -4,7 +4,7 @@ Functions are great, but if you want to call a bunch of them on some data, it can be awkward. Consider this code: ```rust,ignore -baz(bar(foo))); +baz(bar(foo)); ``` We would read this left-to right, and so we see ‘baz bar foo’. But this isn’t the From 15aeea5477f1cf0fed4fead4ba1cfda37eba7c8d Mon Sep 17 00:00:00 2001 From: Mathieu David Date: Fri, 29 May 2015 00:43:39 +0200 Subject: [PATCH 03/18] Corrected typo "workd" corrected to "world" --- src/doc/trpl/traits.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/trpl/traits.md b/src/doc/trpl/traits.md index 9ac170ddec2..2ef9e7ca22e 100644 --- a/src/doc/trpl/traits.md +++ b/src/doc/trpl/traits.md @@ -285,7 +285,7 @@ fn bar(x: T, y: K) where T: Clone, K: Clone + Debug { fn main() { foo("Hello", "world"); - bar("Hello", "workd"); + bar("Hello", "world"); } ``` From f6074406dbb139adec89c5826619d5cfbcb41ff7 Mon Sep 17 00:00:00 2001 From: Nick Hamann Date: Wed, 27 May 2015 12:55:33 -0500 Subject: [PATCH 04/18] Update E0015 explanation, fix E0053. --- src/librustc/diagnostics.rs | 10 +++++++--- src/librustc_typeck/diagnostics.rs | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index a1fa1834ef4..49997371526 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -196,9 +196,13 @@ struct X { x: (), } "##, E0015: r##" -The only function calls allowed in static or constant expressions are enum -variant constructors or struct constructors (for unit or tuple structs). This -is because Rust currently does not support compile-time function execution. +The only function calls allowed in static or constant expressions are +constructors for enum variants and structs, or `const fn`s. Rust currently does +not support more general compile-time function execution. + +See [RFC 911] for more details on the design of `const fn`s. + +[RFC 911]: https://github.com/rust-lang/rfcs/pull/911 "##, E0018: r##" diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index edfad77d588..a3d77bb351d 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -241,7 +241,7 @@ impl Foo for Bar { fn foo(x: i16) { } // error, values differ in mutability - fn foo(&mut self) { } + fn bar(&mut self) { } } ``` "##, From eb15030dc18933c189daa0f9e0dfc780691a217b Mon Sep 17 00:00:00 2001 From: Nick Hamann Date: Wed, 27 May 2015 14:07:20 -0500 Subject: [PATCH 05/18] Add error explanations for E0040, E0087, E0378, E0379, E0394. --- src/librustc/diagnostics.rs | 37 ++++++++++++++++++++-- src/librustc_typeck/diagnostics.rs | 50 ++++++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 49997371526..cc0ea621a49 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -846,6 +846,40 @@ struct Foo { foo: &'static T } ``` +"##, + +E0378: r##" +Method calls that aren't calls to inherent `const` methods are disallowed +in statics, constants, and constant functions. + +For example: + +``` +const BAZ: i32 = Foo(25).bar(); // error, `bar` isn't `const` + +struct Foo(i32); + +impl Foo { + const fn foo(&self) -> i32 { + self.bar() // error, `bar` isn't `const` + } + + fn bar(&self) -> i32 { self.0 } +} +``` + +For more information about `const fn`'s, see [RFC 911]. + +[RFC 911]: https://github.com/rust-lang/rfcs/pull/911 +"##, + +E0394: r##" +From [RFC 246]: + + > It is illegal for a static to reference another static by value. It is + > required that all references be borrowed. + +[RFC 246]: https://github.com/rust-lang/rfcs/pull/246 "## } @@ -895,9 +929,6 @@ struct Foo { E0315, // cannot invoke closure outside of its lifetime E0316, // nested quantification of lifetimes E0370, // discriminant overflow - E0378, // method calls limited to constant inherent methods - E0394, // cannot refer to other statics by value, use the address-of - // operator or a constant instead E0395, // pointer comparison in const-expr E0396 // pointer dereference in const-expr } diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index a3d77bb351d..c822a7faa19 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -170,6 +170,31 @@ struct Dog { http://doc.rust-lang.org/reference.html#trait-objects "##, +E0040: r##" +It is not allowed to manually call destructors in Rust. It is also not +necessary to do this since `drop` is called automatically whenever a value goes +out of scope. + +Here's an example of this error: + +``` +struct Foo { + x: i32, +} + +impl Drop for Foo { + fn drop(&mut self) { + println!("kaboom"); + } +} + +fn main() { + let mut x = Foo { x: -7 }; + x.drop(); // error: explicit use of destructor method +} +``` +"##, + E0046: r##" When trying to make some type implement a trait `Foo`, you must, at minimum, provide implementations for all of `Foo`'s required methods (meaning the @@ -542,6 +567,21 @@ enum Empty {} ``` "##, +E0087: r##" +Too many type parameters were supplied for a function. For example: + +``` +fn foo() {} + +fn main() { + foo::(); // error, expected 1 parameter, found 2 parameters +} +``` + +The number of supplied parameters much exactly match the number of defined type +parameters. +"##, + E0089: r##" Not enough type parameters were supplied for a function. For example: @@ -1098,6 +1138,13 @@ impl Baz for Bar { } // Note: This is OK [RFC 255]: https://github.com/rust-lang/rfcs/pull/255 "##, +E0379: r##" +Trait methods cannot be declared `const` by design. For more information, see +[RFC 911]. + +[RFC 911]: https://github.com/rust-lang/rfcs/pull/911 +"##, + E0380: r##" Default impls are only allowed for traits with no methods or associated items. For more information see the [opt-in builtin traits RFC](https://github.com/rust @@ -1113,7 +1160,6 @@ impl Baz for Bar { } // Note: This is OK E0034, // multiple applicable methods in scope E0035, // does not take type parameters E0036, // incorrect number of type parameters given for this method - E0040, // explicit use of destructor method E0044, // foreign items may not have type parameters E0045, // variadic function must have C calling convention E0057, // method has an incompatible type for trait @@ -1128,7 +1174,6 @@ impl Baz for Bar { } // Note: This is OK E0077, E0085, E0086, - E0087, E0088, E0090, E0091, @@ -1235,7 +1280,6 @@ impl Baz for Bar { } // Note: This is OK // between structures E0377, // the trait `CoerceUnsized` may only be implemented for a coercion // between structures with the same definition - E0379, // trait fns cannot be const E0390, // only a single inherent implementation marked with // `#[lang = \"{}\"]` is allowed for the `{}` primitive E0391, // unsupported cyclic reference between types/traits detected From 19cb2a77076657063768e6db342a38933f0ba874 Mon Sep 17 00:00:00 2001 From: David Campbell Date: Sat, 14 Feb 2015 14:17:03 -0500 Subject: [PATCH 06/18] add newline before list in functions-and-methods The current version of hoedown treats lists interrupting paragraphs in the Markdown.pl style rather than CommonMark, so a newline is needed for the list to be rendered properly. --- src/doc/style/features/functions-and-methods/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/style/features/functions-and-methods/README.md b/src/doc/style/features/functions-and-methods/README.md index 2dcfc382d0b..611cd564cca 100644 --- a/src/doc/style/features/functions-and-methods/README.md +++ b/src/doc/style/features/functions-and-methods/README.md @@ -20,6 +20,7 @@ for any operation that is clearly associated with a particular type. Methods have numerous advantages over functions: + * They do not need to be imported or qualified to be used: all you need is a value of the appropriate type. * Their invocation performs autoborrowing (including mutable borrows). From 06706510cbb0035b713a32c17291742c8090d9eb Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 21 Feb 2015 10:53:42 -0500 Subject: [PATCH 07/18] Make adjancent code examples more similar --- src/doc/style/features/let.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/style/features/let.md b/src/doc/style/features/let.md index f13a84f6fee..6f423c6de8e 100644 --- a/src/doc/style/features/let.md +++ b/src/doc/style/features/let.md @@ -61,8 +61,8 @@ conditional expression. Prefer ```rust -s.iter().map(|x| x * 2) - .collect::>() +let v = s.iter().map(|x| x * 2) + .collect::>(); ``` over From 4d90b4d9b8ba4275be9031bf19c49f90c33c9823 Mon Sep 17 00:00:00 2001 From: David Campbell Date: Mon, 30 Mar 2015 18:31:42 -0400 Subject: [PATCH 08/18] Update let.md -- follow whitespace style guideline "Idiomatic code should not use extra whitespace in the middle of a line to provide alignment." --- src/doc/style/features/let.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/style/features/let.md b/src/doc/style/features/let.md index 6f423c6de8e..4a0bf4353b9 100644 --- a/src/doc/style/features/let.md +++ b/src/doc/style/features/let.md @@ -34,7 +34,7 @@ Prefer ```rust let foo = match bar { - Baz => 0, + Baz => 0, Quux => 1 }; ``` From 31a007af1964891ef820b10c6a8d3e667fbca1ae Mon Sep 17 00:00:00 2001 From: David Campbell Date: Mon, 30 Mar 2015 18:35:17 -0400 Subject: [PATCH 09/18] remove extra space from "over" code as well --- src/doc/style/features/let.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/style/features/let.md b/src/doc/style/features/let.md index 4a0bf4353b9..01dff3dccea 100644 --- a/src/doc/style/features/let.md +++ b/src/doc/style/features/let.md @@ -44,7 +44,7 @@ over ```rust let foo; match bar { - Baz => { + Baz => { foo = 0; } Quux => { From d0744ba3e7b60a25837af8350b3af7ef1d2b4548 Mon Sep 17 00:00:00 2001 From: Nils Liberg Date: Sat, 23 May 2015 11:19:11 +0200 Subject: [PATCH 10/18] Fix mistake: "to to" -> "to" --- src/doc/style/ownership/builders.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/style/ownership/builders.md b/src/doc/style/ownership/builders.md index 54992341ce5..348be516e37 100644 --- a/src/doc/style/ownership/builders.md +++ b/src/doc/style/ownership/builders.md @@ -16,7 +16,7 @@ If `T` is such a data structure, consider introducing a `T` _builder_: value. When possible, choose a better name: e.g. `Command` is the builder for `Process`. 2. The builder constructor should take as parameters only the data _required_ to - to make a `T`. + make a `T`. 3. The builder should offer a suite of convenient methods for configuration, including setting up compound inputs (like slices) incrementally. These methods should return `self` to allow chaining. From adac861db28b79f52455b1fd3121cd1964d0aceb Mon Sep 17 00:00:00 2001 From: Nils Liberg Date: Sat, 23 May 2015 17:31:57 +0200 Subject: [PATCH 11/18] Fix link to newtypes page --- src/doc/style/features/functions-and-methods/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/style/features/functions-and-methods/input.md b/src/doc/style/features/functions-and-methods/input.md index a1310de2e60..072021194c1 100644 --- a/src/doc/style/features/functions-and-methods/input.md +++ b/src/doc/style/features/functions-and-methods/input.md @@ -159,7 +159,7 @@ fn foo(a: u8) { ... } Note that [`ascii::Ascii`](http://static.rust-lang.org/doc/master/std/ascii/struct.Ascii.html) is a _wrapper_ around `u8` that guarantees the highest bit is zero; see -[newtype patterns]() for more details on creating typesafe wrappers. +[newtype patterns](../types/newtype.md) for more details on creating typesafe wrappers. Static enforcement usually comes at little run-time cost: it pushes the costs to the boundaries (e.g. when a `u8` is first converted into an From 7e78e708fb3f5115b47cc1c0b32c77a381519ecc Mon Sep 17 00:00:00 2001 From: Nick Hamann Date: Thu, 28 May 2015 13:11:05 -0500 Subject: [PATCH 12/18] Convert mutable statics error to have error code and add explanation. Also changes 'owned pointers' => 'boxes' in the error message. --- src/librustc/diagnostics.rs | 13 +++++++++++++ src/librustc/middle/check_const.rs | 6 +++--- src/test/compile-fail/static-mut-not-constant.rs | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index cc0ea621a49..1b63bd7a437 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -880,6 +880,19 @@ fn bar(&self) -> i32 { self.0 } > required that all references be borrowed. [RFC 246]: https://github.com/rust-lang/rfcs/pull/246 +"##, + +E0397: r##" +It is not allowed for a mutable static to allocate or have destructors. For +example: + +``` +// error: mutable statics are not allowed to have boxes +static mut FOO: Option> = None; + +// error: mutable statics are not allowed to have destructors +static mut BAR: Option> = None; +``` "## } diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 3e084f3eeb3..2fd39c9d412 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -249,13 +249,13 @@ fn check_static_mut_type(&self, e: &ast::Expr) { let suffix = if tcontents.has_dtor() { "destructors" } else if tcontents.owns_owned() { - "owned pointers" + "boxes" } else { return }; - self.tcx.sess.span_err(e.span, &format!("mutable statics are not allowed \ - to have {}", suffix)); + span_err!(self.tcx.sess, e.span, E0397, + "mutable statics are not allowed to have {}", suffix); } fn check_static_type(&self, e: &ast::Expr) { diff --git a/src/test/compile-fail/static-mut-not-constant.rs b/src/test/compile-fail/static-mut-not-constant.rs index 08148328edc..e3bb01e6970 100644 --- a/src/test/compile-fail/static-mut-not-constant.rs +++ b/src/test/compile-fail/static-mut-not-constant.rs @@ -12,6 +12,6 @@ static mut a: Box = box 3; //~^ ERROR allocations are not allowed in statics -//~^^ ERROR mutable statics are not allowed to have owned pointers +//~^^ ERROR mutable statics are not allowed to have boxes fn main() {} From 364035497c2bf882cd46a33e0cd6bf4e64370ea4 Mon Sep 17 00:00:00 2001 From: Nick Hamann Date: Thu, 28 May 2015 21:02:13 -0500 Subject: [PATCH 13/18] Revise E0015 according to feedback. --- src/librustc/diagnostics.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 1b63bd7a437..657a4e6bd6e 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -196,9 +196,9 @@ struct X { x: (), } "##, E0015: r##" -The only function calls allowed in static or constant expressions are -constructors for enum variants and structs, or `const fn`s. Rust currently does -not support more general compile-time function execution. +The only functions that can be called in static or constant expressions are +`const` functions. Rust currently does not support more general compile-time +function execution. See [RFC 911] for more details on the design of `const fn`s. From fdf3ce76cfe6be7b5343d191411019836ff3373f Mon Sep 17 00:00:00 2001 From: Nick Hamann Date: Thu, 28 May 2015 21:12:46 -0500 Subject: [PATCH 14/18] Change E0015 and E0378 explanations to link to text of RFC 911, not rfc PR. --- src/librustc/diagnostics.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 657a4e6bd6e..a3577981c1e 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -202,7 +202,7 @@ struct X { x: (), } See [RFC 911] for more details on the design of `const fn`s. -[RFC 911]: https://github.com/rust-lang/rfcs/pull/911 +[RFC 911]: https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md "##, E0018: r##" @@ -870,7 +870,7 @@ fn bar(&self) -> i32 { self.0 } For more information about `const fn`'s, see [RFC 911]. -[RFC 911]: https://github.com/rust-lang/rfcs/pull/911 +[RFC 911]: https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md "##, E0394: r##" From deb4948395a2cff13e05596c6f86d2987d706f99 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 29 May 2015 10:58:39 +0200 Subject: [PATCH 15/18] remove the last mention of IoResult --- .../run-pass/method-mut-self-modifies-mut-slice-lvalue.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs b/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs index 5eecf27db67..5b104d4bb0c 100644 --- a/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs +++ b/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs @@ -17,14 +17,12 @@ use std::slice; -pub type IoResult = Result; - trait MyWriter { - fn my_write(&mut self, buf: &[u8]) -> IoResult<()>; + fn my_write(&mut self, buf: &[u8]) -> Result<(), ()>; } impl<'a> MyWriter for &'a mut [u8] { - fn my_write(&mut self, buf: &[u8]) -> IoResult<()> { + fn my_write(&mut self, buf: &[u8]) -> Result<(), ()> { slice::bytes::copy_memory(buf, *self); let write_len = buf.len(); From 5e941877fe0619497aced26243123b0c853b517d Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 29 May 2015 12:37:18 -0400 Subject: [PATCH 16/18] Add syntax for multiple lifetimes Fixes #25417 --- src/doc/trpl/lifetimes.md | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/doc/trpl/lifetimes.md b/src/doc/trpl/lifetimes.md index 04ae4c7ccf3..580960b7e80 100644 --- a/src/doc/trpl/lifetimes.md +++ b/src/doc/trpl/lifetimes.md @@ -134,8 +134,29 @@ x: &'a i32, # } ``` -uses it. So why do we need a lifetime here? We need to ensure that any -reference to the contained `i32` does not outlive the containing `Foo`. +uses it. So why do we need a lifetime here? We need to ensure that any reference +to a `Foo` cannot outlive the reference to an `i32` it contains. + +If you have multiple references, you can use the same lifetime multiple times: + +```rust +fn x_or_y<'a>(x: &'a str, y: &'a str) -> &'a str { +# x +# } +``` + +This says that `x` and `y` both are alive for the same scope, and that the +return value is also alive for that scope. If you wanted `x` and `y` to have +different lifetimes, you can use multiple lifetime parameters: + +```rust +fn x_or_y<'a, 'b>(x: &'a str, y: &'b str) -> &'a str { +# x +# } +``` + +In this example, `x` and `y` have different valid scopes, but the return value +has the same lifetime as `x`. ## Thinking in scopes From 81a413bb011ef7051073bc0c1cea735f45e64ce8 Mon Sep 17 00:00:00 2001 From: Nick Howell Date: Fri, 29 May 2015 14:29:35 -0400 Subject: [PATCH 17/18] trpl: eight sections, not seven --- src/doc/trpl/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/trpl/README.md b/src/doc/trpl/README.md index d7f810dd857..12384b00b43 100644 --- a/src/doc/trpl/README.md +++ b/src/doc/trpl/README.md @@ -15,7 +15,7 @@ language would. [rust]: http://rust-lang.org -“The Rust Programming Language” is split into seven sections. This introduction +“The Rust Programming Language” is split into eight sections. This introduction is the first. After this: * [Getting started][gs] - Set up your computer for Rust development. From 8746b1ac6f3c95383a19ad2ab365a62140516206 Mon Sep 17 00:00:00 2001 From: Tim Ringenbach Date: Thu, 28 May 2015 13:04:17 -0500 Subject: [PATCH 18/18] Improve mem::forget documentation This adds an example from mem::swap, and provides some suggested uses of this function. Change wording on comment on forget line to be more specific as to why we need to call forget. This breaks the examples up into three pieces. The last piece isn't compiling for some reason. --- src/libcore/mem.rs | 56 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 7749d053285..26c6e899df1 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -52,20 +52,61 @@ /// * `mpsc::{Sender, Receiver}` cycles (they use `Arc` internally) /// * Panicking destructors are likely to leak local resources /// +/// # When To Use +/// +/// There's only a few reasons to use this function. They mainly come +/// up in unsafe code or FFI code. +/// +/// * You have an uninitialized value, perhaps for performance reasons, and +/// need to prevent the destructor from running on it. +/// * You have two copies of a value (like `std::mem::swap`), but need the +/// destructor to only run once to prevent a double free. +/// * Transferring resources across FFI boundries. +/// /// # Example /// +/// Leak some heap memory by never deallocating it. +/// +/// ```rust +/// use std::mem; +/// +/// let heap_memory = Box::new(3); +/// mem::forget(heap_memory); +/// ``` +/// +/// Leak an I/O object, never closing the file. +/// /// ```rust,no_run /// use std::mem; /// use std::fs::File; /// -/// // Leak some heap memory by never deallocating it -/// let heap_memory = Box::new(3); -/// mem::forget(heap_memory); -/// -/// // Leak an I/O object, never closing the file /// let file = File::open("foo.txt").unwrap(); /// mem::forget(file); /// ``` +/// +/// The swap function uses forget to good effect. +/// +/// ```rust +/// use std::mem; +/// use std::ptr; +/// +/// fn swap(x: &mut T, y: &mut T) { +/// unsafe { +/// // Give ourselves some scratch space to work with +/// let mut t: T = mem::uninitialized(); +/// +/// // Perform the swap, `&mut` pointers never alias +/// ptr::copy_nonoverlapping(&*x, &mut t, 1); +/// ptr::copy_nonoverlapping(&*y, x, 1); +/// ptr::copy_nonoverlapping(&t, y, 1); +/// +/// // y and t now point to the same thing, but we need to completely +/// // forget `t` because we do not want to run the destructor for `T` +/// // on its value, which is still owned somewhere outside this function. +/// mem::forget(t); +/// } +/// } +/// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn forget(t: T) { unsafe { intrinsics::forget(t) } @@ -267,8 +308,9 @@ pub fn swap(x: &mut T, y: &mut T) { ptr::copy_nonoverlapping(&*y, x, 1); ptr::copy_nonoverlapping(&t, y, 1); - // y and t now point to the same thing, but we need to completely forget `t` - // because it's no longer relevant. + // y and t now point to the same thing, but we need to completely + // forget `t` because we do not want to run the destructor for `T` + // on its value, which is still owned somewhere outside this function. forget(t); } }