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

Also replace `...` with `/*...*/`
This commit is contained in:
bjorn3 2017-05-30 14:37:19 +02:00 committed by GitHub
parent e1fe1a8933
commit 681d97f19c

@ -8,11 +8,15 @@ things.
Trait resolution is the process of pairing up an impl with each 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: 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: 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) it is the job of trait resolution to figure out (in which case)
whether there exists an impl of `isize : Clone` whether there exists an impl of `isize : Clone`
@ -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 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`: provide an impl. To see what I mean, consider the body of `clone_slice`:
fn clone_slice<T:Clone>(x: &[T]) -> Vec<T> { ```rust
let mut v = Vec::new(); fn clone_slice<T:Clone>(x: &[T]) -> Vec<T> {
for e in &x { let mut v = Vec::new();
v.push((*e).clone()); // (*) for e in &x {
} v.push((*e).clone()); // (*)
} }
}
```
The line marked `(*)` is only legal if `T` (the type of `*e`) The line marked `(*)` is only legal if `T` (the type of `*e`)
implements the `Clone` trait. Naturally, since we don't know what `T` implements the `Clone` trait. Naturally, since we don't know what `T`
@ -107,7 +113,7 @@ otherwise the result is considered ambiguous.
This process is easier if we work through some examples. Consider This process is easier if we work through some examples. Consider
the following trait: the following trait:
``` ```rust
trait Convert<Target> { trait Convert<Target> {
fn convert(&self) -> Target; fn convert(&self) -> Target;
} }
@ -119,8 +125,8 @@ wanted to permit conversion between `isize` and `usize`, we might
implement `Convert` like so: implement `Convert` like so:
```rust ```rust
impl Convert<usize> for isize { ... } // isize -> usize impl Convert<usize> for isize { /*...*/ } // isize -> usize
impl Convert<isize> for usize { ... } // usize -> isize impl Convert<isize> for usize { /*...*/ } // usize -> isize
``` ```
Now imagine there is some code like the following: Now imagine there is some code like the following:
@ -205,12 +211,14 @@ using the definition of *matching* given above.
Consider this simple example: Consider this simple example:
trait A1 { ... } ```rust
trait A2 : A1 { ... } 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 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 : body of `foo`. In each case, that will incur an obligation like `X :
@ -247,10 +255,12 @@ to us, so we must run trait selection to figure everything out.
Here is an example: Here is an example:
trait Foo { ... } ```rust
impl<U,T:Bar<U>> Foo for Vec<T> { ... } 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> 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 : Foo`, we would know which impl we want, and we would know that
@ -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 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: here. Imagine we have the traits `Foo` and `Bar` and an associated impl:
``` ```rust
trait Foo<X> { trait Foo<X> {
fn foo(&self, x: X) { } fn foo(&self, x: X) { }
} }
@ -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, we come to the conclusion that the only possible impl is this one,
with def-id 22: 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> ==> We would then record in the cache `usize : Foo<%0> ==>
ImplCandidate(22)`. Next we would confirm `ImplCandidate(22)`, which ImplCandidate(22)`. Next we would confirm `ImplCandidate(22)`, which