Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rolling up PRs in the queue #23681

Merged
merged 46 commits into from
Mar 25, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
1ec9adc
std: Tweak rt::at_exit behavior
alexcrichton Mar 21, 2015
558c427
Fix a typo in the Rust Book ownership page.
liammonahan Mar 23, 2015
3760113
Make the `Fn` traits inherit from one another and remove the bridging
nikomatsakis Feb 15, 2015
9330bae
Fallout from changing fn traits to use inheritance rather than bridge
nikomatsakis Mar 11, 2015
37dc801
Improve the wording of the example section description on the ownersh…
liammonahan Mar 24, 2015
a9b3196
Add the other S_I(RWX)(GRP/OTH) for posix `creat`
ubsan Mar 24, 2015
a34e87f
Add Examples for File
steveklabnik Mar 23, 2015
f2996c0
Add basic information about associated types
steveklabnik Mar 21, 2015
0031d57
Clean up Any's title line
steveklabnik Mar 24, 2015
f2e0810
correct reference wrt shifts
steveklabnik Mar 24, 2015
4ccf374
std: Zero memory when calling `read_to_end()`
alexcrichton Mar 24, 2015
4065246
An example for clone
steveklabnik Mar 24, 2015
95602a7
Add trivial cast lints.
nrc Mar 20, 2015
9374c21
Minor refactoring in coercion.rs
nrc Mar 23, 2015
088cd56
Remove the UnusedCasts lint
nrc Mar 23, 2015
dc206a9
Add tests
nrc Mar 23, 2015
e7122a5
Change lint names to plurals
nrc Mar 23, 2015
5fa4b4c
Remove unnecessary bounds from Drop impl for `Arc` and `arc::Weak` and
pnkfelix Mar 21, 2015
0adab50
Added `T:Send` bound to `sync::mpsc::Receiver` and `sync::mpsc::Sender`.
pnkfelix Mar 21, 2015
26a79e3
Added `Write` bounds to avoid a specialized Drop impl for `BufWriter`.
pnkfelix Mar 21, 2015
1249e60
Added `T:Send` bound to `Queue<T>` to avoid specialized Drop impl.
pnkfelix Mar 21, 2015
1e71d2e
Added `W: Writer` bound to `BufferedWriter<W>` to avoid specialized `…
pnkfelix Mar 21, 2015
018eeb7
added `T:Send` bound to `Mutex<T>` to avoid specialized Drop impl.
pnkfelix Mar 21, 2015
123b5c1
Added `T:Send` bound to `Packet<T>` to avoid specialized `Drop` impl.
pnkfelix Mar 21, 2015
5f57fd5
Added `T:Send` bound to `Queue<T>` to avoid specialized `Drop` impl.
pnkfelix Mar 21, 2015
290c8de
Added `T:Send` bound to `JoinGuard<T>` to avoid specialized `Drop` impl.
pnkfelix Mar 21, 2015
5b2e869
Reject specialized Drop impls.
pnkfelix Mar 21, 2015
1955e05
Unit tests for Issue 8142, collected into one file.
pnkfelix Mar 24, 2015
7e3ee02
Bug fixes
nrc Mar 24, 2015
8f6c879
rollup merge of #23282: nikomatsakis/fn-trait-inheritance
alexcrichton Mar 24, 2015
f5b65c5
rollup merge of #23573: steveklabnik/doc_associated_types
alexcrichton Mar 24, 2015
6106345
rollup merge of #23592: alexcrichton/tweak-at-exit
alexcrichton Mar 24, 2015
6da0b9d
rollup merge of #23629: liammonahan/master
alexcrichton Mar 24, 2015
a1d2e62
rollup merge of #23630: nrc/coerce-tidy
alexcrichton Mar 24, 2015
37d57e7
rollup merge of #23646: steveklabnik/doc_file
alexcrichton Mar 24, 2015
5c74ed9
rollup merge of #23659: GBGamer/master
alexcrichton Mar 24, 2015
8a0bb42
rollup merge of #23661: steveklabnik/any_docs
alexcrichton Mar 24, 2015
020efc7
rollup merge of #23662: steveklabnik/gh23421
alexcrichton Mar 24, 2015
5ed8733
rollup merge of #23668: alexcrichton/io-zero
alexcrichton Mar 24, 2015
91b633a
rollup merge of #23546: alexcrichton/hyphens
alexcrichton Mar 24, 2015
3b13b9c
rollup merge of #23638: pnkfelix/fsk-reject-specialized-drops
alexcrichton Mar 24, 2015
19cd000
rollup merge of #23671: steveklabnik/doc_std_clone
alexcrichton Mar 24, 2015
492f07b
Fix some fallout in librustdoc
nagisa Mar 24, 2015
efaef24
Test fixes and rebase conflicts, round 1
alexcrichton Mar 24, 2015
db2c3ba
rollup merge of #23674: nagisa/fallout-1
alexcrichton Mar 24, 2015
3021d4c
Test fixes and rebase conflicts, round 2
alexcrichton Mar 24, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1265,7 +1265,7 @@ be undesired.
* Sending signals
* Accessing/modifying the file system
* Unsigned integer overflow (well-defined as wrapping)
* Signed integer overflow (well-defined as two's complement representation
* Signed integer overflow (well-defined as twos complement representation
wrapping)

#### Diverging functions
Expand Down Expand Up @@ -2961,10 +2961,10 @@ meaning of the operators on standard types is given here.
: Exclusive or.
Calls the `bitxor` method of the `std::ops::BitXor` trait.
* `<<`
: Logical left shift.
: Left shift.
Calls the `shl` method of the `std::ops::Shl` trait.
* `>>`
: Logical right shift.
: Right shift.
Calls the `shr` method of the `std::ops::Shr` trait.

#### Lazy boolean operators
Expand Down
1 change: 1 addition & 0 deletions src/doc/trpl/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* [More Strings](more-strings.md)
* [Patterns](patterns.md)
* [Method Syntax](method-syntax.md)
* [Associated Types](associated-types.md)
* [Closures](closures.md)
* [Iterators](iterators.md)
* [Generics](generics.md)
Expand Down
202 changes: 202 additions & 0 deletions src/doc/trpl/associated-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
% Associated Types

Associated types are a powerful part of Rust's type system. They're related to
the idea of a 'type family', in other words, grouping multiple types together. That
description is a bit abstract, so let's dive right into an example. If you want
to write a `Graph` trait, you have two types to be generic over: the node type
and the edge type. So you might write a trait, `Graph<N, E>`, that looks like
this:

```rust
trait Graph<N, E> {
fn has_edge(&self, &N, &N) -> bool;
fn edges(&self, &N) -> Vec<E>;
// etc
}
```

While this sort of works, it ends up being awkward. For example, any function
that wants to take a `Graph` as a parameter now _also_ needs to be generic over
the `N`ode and `E`dge types too:

```rust,ignore
fn distance<N, E, G: Graph<N, E>>(graph: &G, start: &N, end: &N) -> u32 { ... }
```

Our distance calculation works regardless of our `Edge` type, so the `E` stuff in
this signature is just a distraction.

What we really want to say is that a certain `E`dge and `N`ode type come together
to form each kind of `Graph`. We can do that with associated types:

```rust
trait Graph {
type N;
type E;

fn has_edge(&self, &Self::N, &Self::N) -> bool;
fn edges(&self, &Self::N) -> Vec<Self::E>;
// etc
}
```

Now, our clients can be abstract over a given `Graph`:

```rust,ignore
fn distance<G: Graph>(graph: &G, start: &G::N, end: &G::N) -> uint { ... }
```

No need to deal with the `E`dge type here!

Let's go over all this in more detail.

## Defining associated types

Let's build that `Graph` trait. Here's the definition:

```rust
trait Graph {
type N;
type E;

fn has_edge(&self, &Self::N, &Self::N) -> bool;
fn edges(&self, &Self::N) -> Vec<Self::E>;
}
```

Simple enough. Associated types use the `type` keyword, and go inside the body
of the trait, with the functions.

These `type` declarations can have all the same thing as functions do. For example,
if we wanted our `N` type to implement `Display`, so we can print the nodes out,
we could do this:

```rust
use std::fmt;

trait Graph {
type N: fmt::Display;
type E;

fn has_edge(&self, &Self::N, &Self::N) -> bool;
fn edges(&self, &Self::N) -> Vec<Self::E>;
}
```

## Implementing associated types

Just like any trait, traits that use associated types use the `impl` keyword to
provide implementations. Here's a simple implementation of Graph:

```rust
# trait Graph {
# type N;
# type E;
# fn has_edge(&self, &Self::N, &Self::N) -> bool;
# fn edges(&self, &Self::N) -> Vec<Self::E>;
# }
struct Node;

struct Edge;

struct MyGraph;

impl Graph for MyGraph {
type N = Node;
type E = Edge;

fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
true
}

fn edges(&self, n: &Node) -> Vec<Edge> {
Vec::new()
}
}
```

This silly implementation always returns `true` and an empty `Vec<Edge>`, but it
gives you an idea of how to implement this kind of thing. We first need three
`struct`s, one for the graph, one for the node, and one for the edge. If it made
more sense to use a different type, that would work as well, we're just going to
use `struct`s for all three here.

Next is the `impl` line, which is just like implementing any other trait.

From here, we use `=` to define our associated types. The name the trait uses
goes on the left of the `=`, and the concrete type we're `impl`ementing this
for goes on the right. Finally, we use the concrete types in our function
declarations.

## Trait objects with associated types

There’s one more bit of syntax we should talk about: trait objects. If you
try to create a trait object from an associated type, like this:

```rust,ignore
# trait Graph {
# type N;
# type E;
# fn has_edge(&self, &Self::N, &Self::N) -> bool;
# fn edges(&self, &Self::N) -> Vec<Self::E>;
# }
# struct Node;
# struct Edge;
# struct MyGraph;
# impl Graph for MyGraph {
# type N = Node;
# type E = Edge;
# fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
# true
# }
# fn edges(&self, n: &Node) -> Vec<Edge> {
# Vec::new()
# }
# }
let graph = MyGraph;
let obj = Box::new(graph) as Box<Graph>;
```

You’ll get two errors:

```text
error: the value of the associated type `E` (from the trait `main::Graph`) must
be specified [E0191]
let obj = Box::new(graph) as Box<Graph>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24:44 error: the value of the associated type `N` (from the trait
`main::Graph`) must be specified [E0191]
let obj = Box::new(graph) as Box<Graph>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```

We can’t create a trait object like this, becuase we don’t know the associated
types. Instead, we can write this:

```rust
# trait Graph {
# type N;
# type E;
# fn has_edge(&self, &Self::N, &Self::N) -> bool;
# fn edges(&self, &Self::N) -> Vec<Self::E>;
# }
# struct Node;
# struct Edge;
# struct MyGraph;
# impl Graph for MyGraph {
# type N = Node;
# type E = Edge;
# fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
# true
# }
# fn edges(&self, n: &Node) -> Vec<Edge> {
# Vec::new()
# }
# }
let graph = MyGraph;
let obj = Box::new(graph) as Box<Graph<N=Node, E=Edge>>;
```

The `N=Node` syntax allows us to provide a concrete type, `Node`, for the `N`
type parameter. Same with `E=Edge`. If we didn’t proide this constraint, we
couldn’t be sure which `impl` to match this trait object to.
4 changes: 2 additions & 2 deletions src/doc/trpl/ownership.md
Original file line number Diff line number Diff line change
Expand Up @@ -513,8 +513,8 @@ Otherwise, it is an error to elide an output lifetime.

### Examples

Here are some examples of functions with elided lifetimes, and the version of
what the elided lifetimes are expand to:
Here are some examples of functions with elided lifetimes. We've paired each
example of an elided lifetime with its expanded form.

```{rust,ignore}
fn print(s: &str); // elided
Expand Down
17 changes: 9 additions & 8 deletions src/doc/trpl/unsafe.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,15 +197,16 @@ use std::ptr;

// Define a wrapper around the handle returned by the foreign code.
// Unique<T> has the same semantics as Box<T>
pub struct Unique<T> {
//
// NB: For simplicity and correctness, we require that T has kind Send
// (owned boxes relax this restriction).
pub struct Unique<T: Send> {
// It contains a single raw, mutable pointer to the object in question.
ptr: *mut T
}

// Implement methods for creating and using the values in the box.

// NB: For simplicity and correctness, we require that T has kind Send
// (owned boxes relax this restriction).
impl<T: Send> Unique<T> {
pub fn new(value: T) -> Unique<T> {
unsafe {
Expand Down Expand Up @@ -239,11 +240,11 @@ impl<T: Send> Unique<T> {
// Unique<T>, making the struct manage the raw pointer: when the
// struct goes out of scope, it will automatically free the raw pointer.
//
// NB: This is an unsafe destructor, because rustc will not normally
// allow destructors to be associated with parameterized types, due to
// bad interaction with managed boxes. (With the Send restriction,
// we don't have this problem.) Note that the `#[unsafe_destructor]`
// feature gate is required to use unsafe destructors.
// NB: This is an unsafe destructor; rustc will not normally allow
// destructors to be associated with parameterized types (due to
// historically failing to check them soundly). Note that the
// `#[unsafe_destructor]` feature gate is currently required to use
// unsafe destructors.
#[unsafe_destructor]
impl<T: Send> Drop for Unique<T> {
fn drop(&mut self) {
Expand Down
10 changes: 10 additions & 0 deletions src/etc/libc.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,16 @@ void posix88_consts() {
put_const(S_IWUSR, int);
put_const(S_IRUSR, int);

put_const(S_IRWXG, int);
put_const(S_IXGRP, int);
put_const(S_IWGRP, int);
put_const(S_IRGRP, int);

put_const(S_IRWXO, int);
put_const(S_IXOTH, int);
put_const(S_IWOTH, int);
put_const(S_IROTH, int);

#ifdef F_OK
put_const(F_OK, int);
#endif
Expand Down
6 changes: 3 additions & 3 deletions src/liballoc/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ impl<T: Send + Sync + Clone> Arc<T> {

#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Sync + Send> Drop for Arc<T> {
impl<T> Drop for Arc<T> {
/// Drops the `Arc<T>`.
///
/// This will decrement the strong reference count. If the strong reference
Expand Down Expand Up @@ -388,7 +388,7 @@ impl<T: Sync + Send> Drop for Arc<T> {

#[unstable(feature = "alloc",
reason = "Weak pointers may not belong in this module.")]
impl<T: Sync + Send> Weak<T> {
impl<T> Weak<T> {
/// Upgrades a weak reference to a strong reference.
///
/// Upgrades the `Weak<T>` reference to an `Arc<T>`, if possible.
Expand Down Expand Up @@ -454,7 +454,7 @@ impl<T: Sync + Send> Clone for Weak<T> {

#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Sync + Send> Drop for Weak<T> {
impl<T> Drop for Weak<T> {
/// Drops the `Weak<T>`.
///
/// This will decrement the weak reference count.
Expand Down
3 changes: 2 additions & 1 deletion src/libarena/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,8 @@ impl<T> TypedArenaChunk<T> {
// Destroy the next chunk.
let next = self.next;
let size = calculate_size::<T>(self.capacity);
deallocate(self as *mut TypedArenaChunk<T> as *mut u8, size,
let self_ptr: *mut TypedArenaChunk<T> = self;
deallocate(self_ptr as *mut u8, size,
mem::min_align_of::<TypedArenaChunk<T>>());
if !next.is_null() {
let capacity = (*next).capacity;
Expand Down
2 changes: 2 additions & 0 deletions src/libcollections/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
html_playground_url = "http://play.rust-lang.org/")]
#![doc(test(no_crate_inject))]

#![allow(trivial_casts)]
#![allow(trivial_numeric_casts)]
#![feature(alloc)]
#![feature(box_syntax)]
#![feature(box_patterns)]
Expand Down
4 changes: 2 additions & 2 deletions src/libcollections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1199,8 +1199,8 @@ impl<T: PartialEq> Vec<T> {

// Avoid bounds checks by using unsafe pointers.
let p = self.as_mut_ptr();
let mut r = 1;
let mut w = 1;
let mut r: usize = 1;
let mut w: usize = 1;

while r < ln {
let p_r = p.offset(r as isize);
Expand Down
10 changes: 8 additions & 2 deletions src/libcollectionstest/btree/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,21 @@ struct Counter<'a, 'b> {
}

impl<'a, 'b, 'c> FnMut<(&'c i32,)> for Counter<'a, 'b> {
type Output = bool;

extern "rust-call" fn call_mut(&mut self, (&x,): (&'c i32,)) -> bool {
assert_eq!(x, self.expected[*self.i]);
*self.i += 1;
true
}
}

impl<'a, 'b, 'c> FnOnce<(&'c i32,)> for Counter<'a, 'b> {
type Output = bool;

extern "rust-call" fn call_once(mut self, args: (&'c i32,)) -> bool {
self.call_mut(args)
}
}

fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F) where
// FIXME Replace Counter with `Box<FnMut(_) -> _>`
F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, Counter) -> bool,
Expand Down
8 changes: 4 additions & 4 deletions src/libcore/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,11 @@ use marker::Sized;
// Any trait
///////////////////////////////////////////////////////////////////////////////

/// The `Any` trait is implemented by all `'static` types, and can be used for
/// dynamic typing
/// A type to emulate dynamic typing. See the [module-level documentation][mod] for more details.
///
/// Every type with no non-`'static` references implements `Any`, so `Any` can
/// be used as a trait object to emulate the effects dynamic typing.
/// Every type with no non-`'static` references implements `Any`.
///
/// [mod]: ../index.html
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Any: 'static {
/// Get the `TypeId` of `self`
Expand Down
Loading