Skip to content

Syntax highlight all rust code in librustc/traits/README.md #42311

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

Merged
merged 1 commit into from
May 30, 2017
Merged
Changes from all commits
Commits
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
50 changes: 31 additions & 19 deletions src/librustc/traits/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ things.
Trait resolution is the process of pairing up an impl with each
reference to a trait. So, for example, if there is a generic function like:

fn clone_slice<T:Clone>(x: &[T]) -> Vec<T> { ... }
```rust
fn clone_slice<T:Clone>(x: &[T]) -> Vec<T> { /*...*/ }
```

and then a call to that function:

let v: Vec<isize> = clone_slice([1, 2, 3])
```rust
let v: Vec<isize> = clone_slice(&[1, 2, 3])
```

it is the job of trait resolution to figure out (in which case)
whether there exists an impl of `isize : Clone`
Expand All @@ -21,12 +25,14 @@ Note that in some cases, like generic functions, we may not be able to
find a specific impl, but we can figure out that the caller must
provide an impl. To see what I mean, consider the body of `clone_slice`:

fn clone_slice<T:Clone>(x: &[T]) -> Vec<T> {
let mut v = Vec::new();
for e in &x {
v.push((*e).clone()); // (*)
}
```rust
fn clone_slice<T:Clone>(x: &[T]) -> Vec<T> {
let mut v = Vec::new();
for e in &x {
v.push((*e).clone()); // (*)
}
}
```

The line marked `(*)` is only legal if `T` (the type of `*e`)
implements the `Clone` trait. Naturally, since we don't know what `T`
Expand Down Expand Up @@ -107,7 +113,7 @@ otherwise the result is considered ambiguous.
This process is easier if we work through some examples. Consider
the following trait:

```
```rust
trait Convert<Target> {
fn convert(&self) -> Target;
}
Expand All @@ -119,8 +125,8 @@ wanted to permit conversion between `isize` and `usize`, we might
implement `Convert` like so:

```rust
impl Convert<usize> for isize { ... } // isize -> usize
impl Convert<isize> for usize { ... } // usize -> isize
impl Convert<usize> for isize { /*...*/ } // isize -> usize
impl Convert<isize> for usize { /*...*/ } // usize -> isize
```

Now imagine there is some code like the following:
Expand Down Expand Up @@ -205,12 +211,14 @@ using the definition of *matching* given above.

Consider this simple example:

trait A1 { ... }
trait A2 : A1 { ... }
```rust
trait A1 { /*...*/ }
trait A2 : A1 { /*...*/ }

trait B { ... }
trait B { /*...*/ }

fn foo<X:A2+B> { ... }
fn foo<X:A2+B> { /*...*/ }
```

Clearly we can use methods offered by `A1`, `A2`, or `B` within the
body of `foo`. In each case, that will incur an obligation like `X :
Expand Down Expand Up @@ -247,10 +255,12 @@ to us, so we must run trait selection to figure everything out.

Here is an example:

trait Foo { ... }
impl<U,T:Bar<U>> Foo for Vec<T> { ... }
```rust
trait Foo { /*...*/ }
impl<U,T:Bar<U>> Foo for Vec<T> { /*...*/ }

impl Bar<usize> for isize { ... }
impl Bar<usize> for isize { /*...*/ }
```

After one shallow round of selection for an obligation like `Vec<isize>
: Foo`, we would know which impl we want, and we would know that
Expand Down Expand Up @@ -343,7 +353,7 @@ Once the basic matching is done, we get to another interesting topic:
how to deal with impl obligations. I'll work through a simple example
here. Imagine we have the traits `Foo` and `Bar` and an associated impl:

```
```rust
trait Foo<X> {
fn foo(&self, x: X) { }
}
Expand Down Expand Up @@ -401,7 +411,9 @@ Therefore, we search through impls and where clauses and so forth, and
we come to the conclusion that the only possible impl is this one,
with def-id 22:

impl Foo<isize> for usize { ... } // Impl #22
```rust
impl Foo<isize> for usize { ... } // Impl #22
```

We would then record in the cache `usize : Foo<%0> ==>
ImplCandidate(22)`. Next we would confirm `ImplCandidate(22)`, which
Expand Down