From 8d0be731f543837251ea10a77499725f91d02560 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 26 Mar 2014 16:07:44 -0700 Subject: [PATCH] doc: Update the tutorial about bounds for traits --- src/doc/tutorial.md | 32 +++++++++++++++++--------------- src/libnative/io/file_win32.rs | 4 ++-- src/libnative/io/pipe_win32.rs | 12 ++++++------ 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/doc/tutorial.md b/src/doc/tutorial.md index 09539e6d59d8d..b0d9e3e9802f3 100644 --- a/src/doc/tutorial.md +++ b/src/doc/tutorial.md @@ -2103,7 +2103,7 @@ a `&T` pointer. `MutexArc` is an example of a *sharable* type with internal muta These are types that do not contain any data whose lifetime is bound to a particular stack frame. These are types that do not contain any references, or types where the only contained references -have the `'static` lifetime. (For more on named lifetimes and their uses, +have the `'static` lifetime. (For more on named lifetimes and their uses, see the [references and lifetimes guide][lifetimes].) > ***Note:*** These two traits were referred to as 'kinds' in earlier @@ -2430,23 +2430,25 @@ select the method to call at runtime. This usage of traits is similar to Java interfaces. -By default, each of the three storage classes for traits enforce a -particular set of built-in kinds that their contents must fulfill in -order to be packaged up in a trait object of that storage class. +There are some built-in bounds, such as `Send` and `Share`, which are properties +of the components of types. By design, trait objects don't know the exact type +of their contents and so the compiler cannot reason about those properties. -* The contents of owned traits (`~Trait`) must fulfill the `Send` bound. -* The contents of reference traits (`&Trait`) are not constrained by any bound. +You can instruct the compiler, however, that the contents of a trait object must +acribe to a particular bound with a trailing colon (`:`). These are examples of +valid types: -Consequently, the trait objects themselves automatically fulfill their -respective kind bounds. However, this default behavior can be overridden by -specifying a list of bounds on the trait type, for example, by writing `~Trait:` -(which indicates that the contents of the owned trait need not fulfill any -bounds), or by writing `~Trait:Send+Share`, which indicates that in addition -to fulfilling `Send`, contents must also fulfill `Share`, and as a consequence, -the trait itself fulfills `Share`. +~~~rust +trait Foo {} +trait Bar {} -* `~Trait:Send` is equivalent to `~Trait`. -* `&Trait:` is equivalent to `&Trait`. +fn sendable_foo(f: ~Foo:Send) { /* ... */ } +fn shareable_bar(b: &Bar: Share) { /* ... */ } +~~~ + +When no colon is specified (such as the type `~Foo`), it is inferred that the +value ascribes to no bounds. They must be added manually if any bounds are +necessary for usage. Builtin kind bounds can also be specified on closure types in the same way (for example, by writing `fn:Send()`), and the default behaviours are the same as diff --git a/src/libnative/io/file_win32.rs b/src/libnative/io/file_win32.rs index 28b963ab34850..d9d7fbbce9cac 100644 --- a/src/libnative/io/file_win32.rs +++ b/src/libnative/io/file_win32.rs @@ -206,8 +206,8 @@ impl rtio::RtioPipe for FileDesc { fn write(&mut self, buf: &[u8]) -> Result<(), IoError> { self.inner_write(buf) } - fn clone(&self) -> ~rtio::RtioPipe { - ~FileDesc { inner: self.inner.clone() } as ~rtio::RtioPipe + fn clone(&self) -> ~rtio::RtioPipe:Send { + ~FileDesc { inner: self.inner.clone() } as ~rtio::RtioPipe:Send } } diff --git a/src/libnative/io/pipe_win32.rs b/src/libnative/io/pipe_win32.rs index e5e9592eb5ab5..d629e5867c983 100644 --- a/src/libnative/io/pipe_win32.rs +++ b/src/libnative/io/pipe_win32.rs @@ -335,12 +335,12 @@ impl rtio::RtioPipe for UnixStream { Ok(()) } - fn clone(&self) -> ~rtio::RtioPipe { + fn clone(&self) -> ~rtio::RtioPipe:Send { ~UnixStream { inner: self.inner.clone(), read: None, write: None, - } as ~rtio::RtioPipe + } as ~rtio::RtioPipe:Send } } @@ -383,8 +383,8 @@ impl Drop for UnixListener { } impl rtio::RtioUnixListener for UnixListener { - fn listen(~self) -> IoResult<~rtio::RtioUnixAcceptor> { - self.native_listen().map(|a| ~a as ~rtio::RtioUnixAcceptor) + fn listen(~self) -> IoResult<~rtio::RtioUnixAcceptor:Send> { + self.native_listen().map(|a| ~a as ~rtio::RtioUnixAcceptor:Send) } } @@ -485,8 +485,8 @@ impl UnixAcceptor { } impl rtio::RtioUnixAcceptor for UnixAcceptor { - fn accept(&mut self) -> IoResult<~rtio::RtioPipe> { - self.native_accept().map(|s| ~s as ~rtio::RtioPipe) + fn accept(&mut self) -> IoResult<~rtio::RtioPipe:Send> { + self.native_accept().map(|s| ~s as ~rtio::RtioPipe:Send) } }