1
Fork 0

auto merge of #12298 : alexcrichton/rust/rustdoc-testing, r=sfackler

It's too easy to forget the `rust` tag to test something.

Closes #11698
This commit is contained in:
bors 2014-02-15 16:36:27 -08:00
commit 0c62d9d83d
21 changed files with 131 additions and 100 deletions

View file

@ -100,34 +100,29 @@ rustdoc --test crate.rs
## Defining tests ## Defining tests
Rust documentation currently uses the markdown format, and code blocks can refer Rust documentation currently uses the markdown format, and rustdoc treats all
to any piece of code-related documentation, which isn't always rust. Because of code blocks as testable-by-default. In order to not run a test over a block of
this, only code blocks with the language of "rust" will be considered for code, the `ignore` string can be added to the three-backtick form of markdown
testing. code block.
~~~ ~~~
```rust ```
// This is a testable code block // This is a testable code block
``` ```
``` ```ignore
// This is not a testable code block // This is not a testable code block
``` ```
// This is not a testable code block (4-space indent) // This is a testable code block (4-space indent)
~~~ ~~~
In addition to only testing "rust"-language code blocks, there are additional In addition to the `ignore` directive, you can specify that the test's execution
specifiers that can be used to dictate how a code block is tested: should fail with the `should_fail` directive.
~~~ ~~~
```rust,ignore ```should_fail
// This code block is ignored by rustdoc, but is passed through to the test // This code block is expected to generate a failure when run
// harness
```
```rust,should_fail
// This code block is expected to generate a failure
``` ```
~~~ ~~~
@ -143,7 +138,7 @@ that one can still write things like `#[deriving(Eq)]`).
# the doc-generating tool. In order to display them anyway in this particular # the doc-generating tool. In order to display them anyway in this particular
# case, the character following the leading '#' is not a usual space like in # case, the character following the leading '#' is not a usual space like in
# these first five lines but a non breakable one. # these first five lines but a non breakable one.
# #
# // showing 'fib' in this documentation would just be tedious and detracts from # // showing 'fib' in this documentation would just be tedious and detracts from
# // what's actualy being documented. # // what's actualy being documented.
# fn fib(n: int) { n + 2 } # fn fib(n: int) { n + 2 }
@ -169,9 +164,6 @@ rustdoc --test lib.rs --test-args 'foo'
// See what's possible when running tests // See what's possible when running tests
rustdoc --test lib.rs --test-args '--help' rustdoc --test lib.rs --test-args '--help'
// Run all ignored tests
rustdoc --test lib.rs --test-args '--ignored'
~~~ ~~~
When testing a library, code examples will often show how functions are used, When testing a library, code examples will often show how functions are used,

View file

@ -30,7 +30,7 @@ An object is a series of string keys mapping to values, in `"key": value` format
Arrays are enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }). Arrays are enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }).
A simple JSON document encoding a person, his/her age, address and phone numbers could look like: A simple JSON document encoding a person, his/her age, address and phone numbers could look like:
``` ```ignore
{ {
"FirstName": "John", "FirstName": "John",
"LastName": "Doe", "LastName": "Doe",

View file

@ -341,7 +341,7 @@ pub fn write_5_number_summary(w: &mut io::Writer,
/// As an example, the summary with 5-number-summary `(min=15, q1=17, med=20, q3=24, max=31)` might /// As an example, the summary with 5-number-summary `(min=15, q1=17, med=20, q3=24, max=31)` might
/// display as: /// display as:
/// ///
/// ~~~~ /// ~~~~ignore
/// 10 | [--****#******----------] | 40 /// 10 | [--****#******----------] | 40
/// ~~~~ /// ~~~~

View file

@ -67,7 +67,7 @@ pub struct Paths {
/// ///
/// The above code will print: /// The above code will print:
/// ///
/// ``` /// ```ignore
/// /media/pictures/kittens.jpg /// /media/pictures/kittens.jpg
/// /media/pictures/puppies.jpg /// /media/pictures/puppies.jpg
/// ``` /// ```

View file

@ -172,21 +172,23 @@ pub fn render(w: &mut io::Writer, s: &str) -> fmt::Result {
pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) { pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
extern fn block(_ob: *buf, text: *buf, lang: *buf, opaque: *libc::c_void) { extern fn block(_ob: *buf, text: *buf, lang: *buf, opaque: *libc::c_void) {
unsafe { unsafe {
if text.is_null() || lang.is_null() { return } if text.is_null() { return }
let (test, shouldfail, ignore) = let (shouldfail, ignore) = if lang.is_null() {
(false, false)
} else {
vec::raw::buf_as_slice((*lang).data, vec::raw::buf_as_slice((*lang).data,
(*lang).size as uint, |lang| { (*lang).size as uint, |lang| {
let s = str::from_utf8(lang).unwrap(); let s = str::from_utf8(lang).unwrap();
(s.contains("rust"), s.contains("should_fail"), (s.contains("should_fail"), s.contains("ignore"))
s.contains("ignore")) })
}); };
if !test { return } if ignore { return }
vec::raw::buf_as_slice((*text).data, (*text).size as uint, |text| { vec::raw::buf_as_slice((*text).data, (*text).size as uint, |text| {
let tests: &mut ::test::Collector = intrinsics::transmute(opaque); let tests: &mut ::test::Collector = intrinsics::transmute(opaque);
let text = str::from_utf8(text).unwrap(); let text = str::from_utf8(text).unwrap();
let mut lines = text.lines().map(|l| stripped_filtered_line(l).unwrap_or(l)); let mut lines = text.lines().map(|l| stripped_filtered_line(l).unwrap_or(l));
let text = lines.to_owned_vec().connect("\n"); let text = lines.to_owned_vec().connect("\n");
tests.add_test(text, ignore, shouldfail); tests.add_test(text, shouldfail);
}) })
} }
} }

View file

@ -94,7 +94,7 @@ pub fn run(input: &str, matches: &getopts::Matches) -> int {
0 0
} }
fn runtest(test: &str, cratename: &str, libs: HashSet<Path>) { fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool) {
let test = maketest(test, cratename); let test = maketest(test, cratename);
let parsesess = parse::new_parse_sess(); let parsesess = parse::new_parse_sess();
let input = driver::StrInput(test); let input = driver::StrInput(test);
@ -130,9 +130,10 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>) {
match out { match out {
Err(e) => fail!("couldn't run the test: {}", e), Err(e) => fail!("couldn't run the test: {}", e),
Ok(out) => { Ok(out) => {
if !out.status.success() { if should_fail && out.status.success() {
fail!("test executable failed:\n{}", fail!("test executable succeeded when it should have failed");
str::from_utf8(out.error)); } else if !should_fail && !out.status.success() {
fail!("test executable failed:\n{}", str::from_utf8(out.error));
} }
} }
} }
@ -169,7 +170,7 @@ pub struct Collector {
} }
impl Collector { impl Collector {
pub fn add_test(&mut self, test: &str, ignore: bool, should_fail: bool) { pub fn add_test(&mut self, test: &str, should_fail: bool) {
let test = test.to_owned(); let test = test.to_owned();
let name = format!("{}_{}", self.names.connect("::"), self.cnt); let name = format!("{}_{}", self.names.connect("::"), self.cnt);
self.cnt += 1; self.cnt += 1;
@ -180,11 +181,11 @@ impl Collector {
self.tests.push(test::TestDescAndFn { self.tests.push(test::TestDescAndFn {
desc: test::TestDesc { desc: test::TestDesc {
name: test::DynTestName(name), name: test::DynTestName(name),
ignore: ignore, ignore: false,
should_fail: should_fail, should_fail: false, // compiler failures are test failures
}, },
testfn: test::DynTestFn(proc() { testfn: test::DynTestFn(proc() {
runtest(test, cratename, libs); runtest(test, cratename, libs, should_fail);
}), }),
}); });
} }

View file

@ -61,7 +61,7 @@
//! let (port, chan) = Chan::new(); //! let (port, chan) = Chan::new();
//! spawn(proc() { //! spawn(proc() {
//! chan.send(10); //! chan.send(10);
//! }) //! });
//! assert_eq!(port.recv(), 10); //! assert_eq!(port.recv(), 10);
//! //!
//! // Create a shared channel which can be sent along from many tasks //! // Create a shared channel which can be sent along from many tasks

View file

@ -82,7 +82,7 @@ function, but the `format!` macro is a syntax extension which allows it to
leverage named parameters. Named parameters are listed at the end of the leverage named parameters. Named parameters are listed at the end of the
argument list and have the syntax: argument list and have the syntax:
``` ```ignore
identifier '=' expression identifier '=' expression
``` ```
@ -107,7 +107,7 @@ and if all references to one argument do not provide a type, then the format `?`
is used (the type's rust-representation is printed). For example, this is an is used (the type's rust-representation is printed). For example, this is an
invalid format string: invalid format string:
``` ```ignore
{0:d} {0:s} {0:d} {0:s}
``` ```
@ -123,7 +123,7 @@ must have the type `uint`. Although a `uint` can be printed with `{:u}`, it is
illegal to reference an argument as such. For example, this is another invalid illegal to reference an argument as such. For example, this is another invalid
format string: format string:
``` ```ignore
{:.*s} {0:u} {:.*s} {0:u}
``` ```
@ -334,7 +334,7 @@ This example is the equivalent of `{0:s}` essentially.
The select method is a switch over a `&str` parameter, and the parameter *must* The select method is a switch over a `&str` parameter, and the parameter *must*
be of the type `&str`. An example of the syntax is: be of the type `&str`. An example of the syntax is:
``` ```ignore
{0, select, male{...} female{...} other{...}} {0, select, male{...} female{...} other{...}}
``` ```
@ -353,7 +353,7 @@ The plural method is a switch statement over a `uint` parameter, and the
parameter *must* be a `uint`. A plural method in its full glory can be specified parameter *must* be a `uint`. A plural method in its full glory can be specified
as: as:
``` ```ignore
{0, plural, offset=1 =1{...} two{...} many{...} other{...}} {0, plural, offset=1 =1{...} two{...} many{...} other{...}}
``` ```
@ -381,7 +381,7 @@ should not be too alien. Arguments are formatted with python-like syntax,
meaning that arguments are surrounded by `{}` instead of the C-like `%`. The meaning that arguments are surrounded by `{}` instead of the C-like `%`. The
actual grammar for the formatting syntax is: actual grammar for the formatting syntax is:
``` ```ignore
format_string := <text> [ format <text> ] * format_string := <text> [ format <text> ] *
format := '{' [ argument ] [ ':' format_spec ] [ ',' function_spec ] '}' format := '{' [ argument ] [ ':' format_spec ] [ ',' function_spec ] '}'
argument := integer | identifier argument := integer | identifier

View file

@ -22,12 +22,16 @@ use vec::{bytes, CloneableVector, MutableVector, ImmutableVector};
/// # Example /// # Example
/// ///
/// ``` /// ```
/// let reader = PortReader::new(port); /// use std::io::PortReader;
///
/// let (port, chan) = Chan::new();
/// # drop(chan);
/// let mut reader = PortReader::new(port);
/// ///
/// let mut buf = ~[0u8, ..100]; /// let mut buf = ~[0u8, ..100];
/// match reader.read(buf) { /// match reader.read(buf) {
/// Some(nread) => println!("Read {} bytes", nread), /// Ok(nread) => println!("Read {} bytes", nread),
/// None => println!("At the end of the stream!") /// Err(e) => println!("read error: {}", e),
/// } /// }
/// ``` /// ```
pub struct PortReader { pub struct PortReader {
@ -83,7 +87,12 @@ impl Reader for PortReader {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// let writer = ChanWriter::new(chan); /// # #[allow(unused_must_use)];
/// use std::io::ChanWriter;
///
/// let (port, chan) = Chan::new();
/// # drop(port);
/// let mut writer = ChanWriter::new(chan);
/// writer.write("hello, world".as_bytes()); /// writer.write("hello, world".as_bytes());
/// ``` /// ```
pub struct ChanWriter { pub struct ChanWriter {

View file

@ -91,15 +91,18 @@ impl UnixListener {
/// # Example /// # Example
/// ///
/// ``` /// ```
/// # fn main() {}
/// # fn foo() {
/// # #[allow(unused_must_use)];
/// use std::io::net::unix::UnixListener; /// use std::io::net::unix::UnixListener;
/// use std::io::Listener; /// use std::io::{Listener, Acceptor};
/// ///
/// let server = Path::new("path/to/my/socket"); /// let server = Path::new("/path/to/my/socket");
/// let mut stream = UnixListener::bind(&server); /// let stream = UnixListener::bind(&server);
/// for client in stream.incoming() { /// for mut client in stream.listen().incoming() {
/// let mut client = client;
/// client.write([1, 2, 3, 4]); /// client.write([1, 2, 3, 4]);
/// } /// }
/// # }
/// ``` /// ```
pub fn bind<P: ToCStr>(path: &P) -> IoResult<UnixListener> { pub fn bind<P: ToCStr>(path: &P) -> IoResult<UnixListener> {
LocalIo::maybe_raise(|io| { LocalIo::maybe_raise(|io| {

View file

@ -69,7 +69,9 @@ pub mod marker {
/// Given a struct `S` that includes a type parameter `T` /// Given a struct `S` that includes a type parameter `T`
/// but does not actually *reference* that type parameter: /// but does not actually *reference* that type parameter:
/// ///
/// ``` /// ```ignore
/// use std::cast;
///
/// struct S<T> { x: *() } /// struct S<T> { x: *() }
/// fn get<T>(s: &S<T>) -> T { /// fn get<T>(s: &S<T>) -> T {
/// unsafe { /// unsafe {
@ -109,6 +111,8 @@ pub mod marker {
/// but does not actually *reference* that type parameter: /// but does not actually *reference* that type parameter:
/// ///
/// ``` /// ```
/// use std::cast;
///
/// struct S<T> { x: *() } /// struct S<T> { x: *() }
/// fn get<T>(s: &S<T>, v: T) { /// fn get<T>(s: &S<T>, v: T) {
/// unsafe { /// unsafe {
@ -147,7 +151,8 @@ pub mod marker {
/// "interior" mutability: /// "interior" mutability:
/// ///
/// ``` /// ```
/// struct Cell<T> { priv value: T } /// pub struct Cell<T> { priv value: T }
/// # fn main() {}
/// ``` /// ```
/// ///
/// The type system would infer that `value` is only read here and /// The type system would infer that `value` is only read here and

View file

@ -42,7 +42,7 @@ disabled except for `error!` (a log level of 1). Logging is controlled via the
`RUST_LOG` environment variable. The value of this environment variable is a `RUST_LOG` environment variable. The value of this environment variable is a
comma-separated list of logging directives. A logging directive is of the form: comma-separated list of logging directives. A logging directive is of the form:
``` ```ignore
path::to::module=log_level path::to::module=log_level
``` ```
@ -65,7 +65,7 @@ all modules is set to this value.
Some examples of valid values of `RUST_LOG` are: Some examples of valid values of `RUST_LOG` are:
``` ```ignore
hello // turns on all logging for the 'hello' module hello // turns on all logging for the 'hello' module
info // turns on all info logging info // turns on all info logging
hello=debug // turns on debug logging for 'hello' hello=debug // turns on debug logging for 'hello'

View file

@ -119,6 +119,8 @@ impl Rem<$T,$T> for $T {
/// Returns the integer remainder after division, satisfying: /// Returns the integer remainder after division, satisfying:
/// ///
/// ``` /// ```
/// # let n = 1;
/// # let d = 2;
/// assert!((n / d) * d + (n % d) == n) /// assert!((n / d) * d + (n % d) == n)
/// ``` /// ```
/// ///
@ -194,15 +196,15 @@ impl Integer for $T {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// assert!(( 8).div_floor( 3) == 2); /// assert!(( 8i).div_floor(& 3) == 2);
/// assert!(( 8).div_floor(-3) == -3); /// assert!(( 8i).div_floor(&-3) == -3);
/// assert!((-8).div_floor( 3) == -3); /// assert!((-8i).div_floor(& 3) == -3);
/// assert!((-8).div_floor(-3) == 2); /// assert!((-8i).div_floor(&-3) == 2);
/// ///
/// assert!(( 1).div_floor( 2) == 0); /// assert!(( 1i).div_floor(& 2) == 0);
/// assert!(( 1).div_floor(-2) == -1); /// assert!(( 1i).div_floor(&-2) == -1);
/// assert!((-1).div_floor( 2) == -1); /// assert!((-1i).div_floor(& 2) == -1);
/// assert!((-1).div_floor(-2) == 0); /// assert!((-1i).div_floor(&-2) == 0);
/// ``` /// ```
/// ///
#[inline] #[inline]
@ -220,21 +222,22 @@ impl Integer for $T {
/// Integer modulo, satisfying: /// Integer modulo, satisfying:
/// ///
/// ``` /// ```
/// assert!(n.div_floor(d) * d + n.mod_floor(d) == n) /// # let n = 1i; let d = 1i;
/// assert!(n.div_floor(&d) * d + n.mod_floor(&d) == n)
/// ``` /// ```
/// ///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// assert!(( 8).mod_floor( 3) == 2); /// assert!(( 8i).mod_floor(& 3) == 2);
/// assert!(( 8).mod_floor(-3) == -1); /// assert!(( 8i).mod_floor(&-3) == -1);
/// assert!((-8).mod_floor( 3) == 1); /// assert!((-8i).mod_floor(& 3) == 1);
/// assert!((-8).mod_floor(-3) == -2); /// assert!((-8i).mod_floor(&-3) == -2);
/// ///
/// assert!(( 1).mod_floor( 2) == 1); /// assert!(( 1i).mod_floor(& 2) == 1);
/// assert!(( 1).mod_floor(-2) == -1); /// assert!(( 1i).mod_floor(&-2) == -1);
/// assert!((-1).mod_floor( 2) == 1); /// assert!((-1i).mod_floor(& 2) == 1);
/// assert!((-1).mod_floor(-2) == -1); /// assert!((-1i).mod_floor(&-2) == -1);
/// ``` /// ```
/// ///
#[inline] #[inline]

View file

@ -45,7 +45,7 @@ pub trait Zero: Add<Self, Self> {
/// ///
/// # Laws /// # Laws
/// ///
/// ~~~ /// ~~~ignore
/// a + 0 = a ∀ a ∈ Self /// a + 0 = a ∀ a ∈ Self
/// 0 + a = a ∀ a ∈ Self /// 0 + a = a ∀ a ∈ Self
/// ~~~ /// ~~~
@ -71,7 +71,7 @@ pub trait One: Mul<Self, Self> {
/// ///
/// # Laws /// # Laws
/// ///
/// ~~~ /// ~~~ignore
/// a * 1 = a ∀ a ∈ Self /// a * 1 = a ∀ a ∈ Self
/// 1 * a = a ∀ a ∈ Self /// 1 * a = a ∀ a ∈ Self
/// ~~~ /// ~~~
@ -964,6 +964,8 @@ impl_from_primitive!(f64, n.to_f64())
/// # Example /// # Example
/// ///
/// ``` /// ```
/// use std::num;
///
/// let twenty: f32 = num::cast(0x14).unwrap(); /// let twenty: f32 = num::cast(0x14).unwrap();
/// assert_eq!(twenty, 20f32); /// assert_eq!(twenty, 20f32);
/// ``` /// ```

View file

@ -20,7 +20,7 @@ use super::{IndependentSample, Sample, Exp};
/// ///
/// The density function of this distribution is /// The density function of this distribution is
/// ///
/// ``` /// ```ignore
/// f(x) = x^(k - 1) * exp(-x / θ) / (Γ(k) * θ^k) /// f(x) = x^(k - 1) * exp(-x / θ) / (Γ(k) * θ^k)
/// ``` /// ```
/// ///

View file

@ -2011,7 +2011,7 @@ pub trait StrSlice<'a> {
/// ///
/// ## Output /// ## Output
/// ///
/// ``` /// ```ignore
/// 0: 中 /// 0: 中
/// 3: 华 /// 3: 华
/// 6: V /// 6: V

View file

@ -46,7 +46,7 @@
* *
* ``` * ```
* spawn(proc() { * spawn(proc() {
* log(error, "Hello, World!"); * println!("Hello, World!");
* }) * })
* ``` * ```
*/ */

View file

@ -19,13 +19,16 @@ also be used. See that function for more details.
# Example # Example
``` ```
use std::unstable::finally::Finally;
# fn always_run_this() {}
(|| { (|| {
... // ...
}).finally(|| { }).finally(|| {
always_run_this(); always_run_this();
}) })
``` ```
*/ */
use ops::Drop; use ops::Drop;
@ -69,13 +72,16 @@ impl<T> Finally<T> for fn() -> T {
* # Example * # Example
* *
* ``` * ```
* use std::unstable::finally::try_finally;
*
* struct State<'a> { buffer: &'a mut [u8], len: uint } * struct State<'a> { buffer: &'a mut [u8], len: uint }
* # let mut buf = [];
* let mut state = State { buffer: buf, len: 0 }; * let mut state = State { buffer: buf, len: 0 };
* try_finally( * try_finally(
* &mut state, (), * &mut state, (),
* |state, ()| { * |state, ()| {
* // use state.buffer, state.len * // use state.buffer, state.len
* } * },
* |state| { * |state| {
* // use state.buffer, state.len to cleanup * // use state.buffer, state.len to cleanup
* }) * })

View file

@ -955,7 +955,7 @@ pub trait ImmutableVector<'a, T> {
* *
* Equivalent to: * Equivalent to:
* *
* ``` * ```ignore
* if self.len() == 0 { return None } * if self.len() == 0 { return None }
* let head = &self[0]; * let head = &self[0];
* *self = self.slice_from(1); * *self = self.slice_from(1);
@ -973,7 +973,7 @@ pub trait ImmutableVector<'a, T> {
* *
* Equivalent to: * Equivalent to:
* *
* ``` * ```ignore
* if self.len() == 0 { return None; } * if self.len() == 0 { return None; }
* let tail = &self[self.len() - 1]; * let tail = &self[self.len() - 1];
* *self = self.slice_to(self.len() - 1); * *self = self.slice_to(self.len() - 1);
@ -2075,7 +2075,7 @@ pub trait MutableVector<'a, T> {
* *
* Equivalent to: * Equivalent to:
* *
* ``` * ```ignore
* if self.len() == 0 { return None; } * if self.len() == 0 { return None; }
* let head = &mut self[0]; * let head = &mut self[0];
* *self = self.mut_slice_from(1); * *self = self.mut_slice_from(1);
@ -2093,7 +2093,7 @@ pub trait MutableVector<'a, T> {
* *
* Equivalent to: * Equivalent to:
* *
* ``` * ```ignore
* if self.len() == 0 { return None; } * if self.len() == 0 { return None; }
* let tail = &mut self[self.len() - 1]; * let tail = &mut self[self.len() - 1];
* *self = self.mut_slice_to(self.len() - 1); * *self = self.mut_slice_to(self.len() - 1);

View file

@ -17,8 +17,10 @@ Decodable)].
For example, a type like: For example, a type like:
```ignore
#[deriving(Encodable, Decodable)] #[deriving(Encodable, Decodable)]
struct Node {id: uint} struct Node {id: uint}
```
would generate two implementations like: would generate two implementations like:
@ -43,11 +45,14 @@ impl<D:Decoder> Decodable for node_id {
Other interesting scenarios are whe the item has type parameters or Other interesting scenarios are whe the item has type parameters or
references other non-built-in types. A type definition like: references other non-built-in types. A type definition like:
```ignore
#[deriving(Encodable, Decodable)] #[deriving(Encodable, Decodable)]
struct spanned<T> {node: T, span: Span} struct spanned<T> {node: T, span: Span}
```
would yield functions like: would yield functions like:
```ignore
impl< impl<
S: Encoder, S: Encoder,
T: Encodable<S> T: Encodable<S>
@ -73,6 +78,7 @@ would yield functions like:
}) })
} }
} }
```
*/ */
use ast::{MetaItem, Item, Expr, MutMutable}; use ast::{MetaItem, Item, Expr, MutMutable};

View file

@ -59,7 +59,7 @@ associated with. It is only not `None` when the associated field has
an identifier in the source code. For example, the `x`s in the an identifier in the source code. For example, the `x`s in the
following snippet following snippet
~~~ ~~~ignore
struct A { x : int } struct A { x : int }
struct B(int); struct B(int);
@ -83,7 +83,7 @@ variants, it is represented as a count of 0.
The following simplified `Eq` is used for in-code examples: The following simplified `Eq` is used for in-code examples:
~~~ ~~~ignore
trait Eq { trait Eq {
fn eq(&self, other: &Self); fn eq(&self, other: &Self);
} }
@ -101,7 +101,7 @@ above `Eq`, `A`, `B` and `C`.
When generating the `expr` for the `A` impl, the `SubstructureFields` is When generating the `expr` for the `A` impl, the `SubstructureFields` is
~~~ ~~~ignore
Struct(~[FieldInfo { Struct(~[FieldInfo {
span: <span of x> span: <span of x>
name: Some(<ident of x>), name: Some(<ident of x>),
@ -112,7 +112,7 @@ Struct(~[FieldInfo {
For the `B` impl, called with `B(a)` and `B(b)`, For the `B` impl, called with `B(a)` and `B(b)`,
~~~ ~~~ignore
Struct(~[FieldInfo { Struct(~[FieldInfo {
span: <span of `int`>, span: <span of `int`>,
name: None, name: None,
@ -126,7 +126,7 @@ Struct(~[FieldInfo {
When generating the `expr` for a call with `self == C0(a)` and `other When generating the `expr` for a call with `self == C0(a)` and `other
== C0(b)`, the SubstructureFields is == C0(b)`, the SubstructureFields is
~~~ ~~~ignore
EnumMatching(0, <ast::Variant for C0>, EnumMatching(0, <ast::Variant for C0>,
~[FieldInfo { ~[FieldInfo {
span: <span of int> span: <span of int>
@ -138,7 +138,7 @@ EnumMatching(0, <ast::Variant for C0>,
For `C1 {x}` and `C1 {x}`, For `C1 {x}` and `C1 {x}`,
~~~ ~~~ignore
EnumMatching(1, <ast::Variant for C1>, EnumMatching(1, <ast::Variant for C1>,
~[FieldInfo { ~[FieldInfo {
span: <span of x> span: <span of x>
@ -150,7 +150,7 @@ EnumMatching(1, <ast::Variant for C1>,
For `C0(a)` and `C1 {x}` , For `C0(a)` and `C1 {x}` ,
~~~ ~~~ignore
EnumNonMatching(~[(0, <ast::Variant for B0>, EnumNonMatching(~[(0, <ast::Variant for B0>,
~[(<span of int>, None, <expr for &a>)]), ~[(<span of int>, None, <expr for &a>)]),
(1, <ast::Variant for B1>, (1, <ast::Variant for B1>,
@ -164,7 +164,7 @@ EnumNonMatching(~[(0, <ast::Variant for B0>,
A static method on the above would result in, A static method on the above would result in,
~~~~ ~~~~ignore
StaticStruct(<ast::StructDef of A>, Named(~[(<ident of x>, <span of x>)])) StaticStruct(<ast::StructDef of A>, Named(~[(<ident of x>, <span of x>)]))
StaticStruct(<ast::StructDef of B>, Unnamed(~[<span of x>])) StaticStruct(<ast::StructDef of B>, Unnamed(~[<span of x>]))
@ -346,7 +346,9 @@ impl<'a> TraitDef<'a> {
* Given that we are deriving a trait `Tr` for a type `T<'a, ..., * Given that we are deriving a trait `Tr` for a type `T<'a, ...,
* 'z, A, ..., Z>`, creates an impl like: * 'z, A, ..., Z>`, creates an impl like:
* *
* ```ignore
* impl<'a, ..., 'z, A:Tr B1 B2, ..., Z: Tr B1 B2> Tr for T<A, ..., Z> { ... } * impl<'a, ..., 'z, A:Tr B1 B2, ..., Z: Tr B1 B2> Tr for T<A, ..., Z> { ... }
* ```
* *
* where B1, B2, ... are the bounds given by `bounds_paths`.' * where B1, B2, ... are the bounds given by `bounds_paths`.'
* *
@ -620,7 +622,7 @@ impl<'a> MethodDef<'a> {
} }
/** /**
~~~ ~~~ignore
#[deriving(Eq)] #[deriving(Eq)]
struct A { x: int, y: int } struct A { x: int, y: int }
@ -719,7 +721,7 @@ impl<'a> MethodDef<'a> {
} }
/** /**
~~~ ~~~ignore
#[deriving(Eq)] #[deriving(Eq)]
enum A { enum A {
A1 A1
@ -762,7 +764,7 @@ impl<'a> MethodDef<'a> {
/** /**
Creates the nested matches for an enum definition recursively, i.e. Creates the nested matches for an enum definition recursively, i.e.
~~~ ~~~ignore
match self { match self {
Variant1 => match other { Variant1 => matching, Variant2 => nonmatching, ... }, Variant1 => match other { Variant1 => matching, Variant2 => nonmatching, ... },
Variant2 => match other { Variant1 => nonmatching, Variant2 => matching, ... }, Variant2 => match other { Variant1 => nonmatching, Variant2 => matching, ... },
@ -1166,7 +1168,7 @@ pub fn cs_fold(use_foldl: bool,
Call the method that is being derived on all the fields, and then Call the method that is being derived on all the fields, and then
process the collected results. i.e. process the collected results. i.e.
~~~ ~~~ignore
f(cx, span, ~[self_1.method(__arg_1_1, __arg_2_1), f(cx, span, ~[self_1.method(__arg_1_1, __arg_2_1),
self_2.method(__arg_1_2, __arg_2_2)]) self_2.method(__arg_1_2, __arg_2_2)])
~~~ ~~~