diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 2f867912f5824..4a43018e973b1 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -42,8 +42,10 @@ //! Recursive structures must be boxed, because if the definition of `Cons` //! looked like this: //! -//! ```rust,ignore +//! ```compile_fail,E0072 +//! # enum List { //! Cons(T, List), +//! # } //! ``` //! //! It wouldn't work. This is because the size of a `List` depends on how many diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index 62a8816462191..1bd95fb82aa4d 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -230,7 +230,7 @@ //! There are a number of related macros in the `format!` family. The ones that //! are currently implemented are: //! -//! ```ignore +//! ```ignore (only-for-syntax-highlight) //! format! // described above //! write! // first argument is a &mut io::Write, the destination //! writeln! // same as write but appends a newline diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 7117c4468211e..c56a93c046041 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -244,7 +244,11 @@ impl RawVec { /// /// # Examples /// - /// ```ignore + /// ``` + /// # #![feature(alloc)] + /// # extern crate alloc; + /// # use std::ptr; + /// # use alloc::raw_vec::RawVec; /// struct MyVec { /// buf: RawVec, /// len: usize, @@ -261,6 +265,10 @@ impl RawVec { /// self.len += 1; /// } /// } + /// # fn main() { + /// # let mut vec = MyVec { buf: RawVec::new(), len: 0 }; + /// # vec.push(1); + /// # } /// ``` #[inline(never)] #[cold] @@ -440,13 +448,17 @@ impl RawVec { /// /// # Examples /// - /// ```ignore + /// ``` + /// # #![feature(alloc)] + /// # extern crate alloc; + /// # use std::ptr; + /// # use alloc::raw_vec::RawVec; /// struct MyVec { /// buf: RawVec, /// len: usize, /// } /// - /// impl MyVec { + /// impl MyVec { /// pub fn push_all(&mut self, elems: &[T]) { /// self.buf.reserve(self.len, elems.len()); /// // reserve would have aborted or panicked if the len exceeded @@ -459,6 +471,10 @@ impl RawVec { /// } /// } /// } + /// # fn main() { + /// # let mut vector = MyVec { buf: RawVec::new(), len: 0 }; + /// # vector.push_all(&[1, 3, 5, 7, 9]); + /// # } /// ``` pub fn reserve(&mut self, used_cap: usize, needed_extra_cap: usize) { unsafe { diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 2cb81029f95e2..79d1ccf637d37 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -124,7 +124,7 @@ use boxed::Box; /// similar, but without the UTF-8 constraint. The second implication is that /// you cannot index into a `String`: /// -/// ```ignore +/// ```compile_fail,E0277 /// let s = "hello"; /// /// println!("The first letter of s is {}", s[0]); // ERROR!!! diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index c9c7a27c614fa..5d1999a42629a 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -156,7 +156,7 @@ use Bound::{Excluded, Included, Unbounded}; /// However be careful: if you try to access an index which isn't in the `Vec`, /// your software will panic! You cannot do this: /// -/// ```ignore +/// ```should_panic /// let v = vec![0, 2, 4, 6]; /// println!("{}", v[6]); // it will panic! /// ``` diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index c91fd16391aaf..d6a9be4437d43 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -211,7 +211,7 @@ //! There's one more subtle bit here: the standard library contains an //! interesting implementation of [`IntoIterator`]: //! -//! ```ignore +//! ```ignore (only-for-syntax-highlight) //! impl IntoIterator for I //! ``` //! diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 3bed425943f78..e8fd729b638be 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -434,7 +434,7 @@ macro_rules! impls{ /// example, here is a struct `Slice` that has two pointers of type `*const T`, /// presumably pointing into an array somewhere: /// -/// ```ignore +/// ```compile_fail,E0392 /// struct Slice<'a, T> { /// start: *const T, /// end: *const T, diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 509b396f211bb..bba42752f50c6 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -328,11 +328,18 @@ pub fn align_of_val(val: &T) -> usize { /// /// Here's an example of how a collection might make use of needs_drop: /// -/// ```ignore +/// ``` /// #![feature(needs_drop)] /// use std::{mem, ptr}; /// -/// pub struct MyCollection { /* ... */ } +/// pub struct MyCollection { +/// # data: [T; 1], +/// /* ... */ +/// } +/// # impl MyCollection { +/// # fn iter_mut(&mut self) -> &mut [T] { &mut self.data } +/// # fn free_buffer(&mut self) {} +/// # } /// /// impl Drop for MyCollection { /// fn drop(&mut self) { @@ -575,7 +582,7 @@ pub fn swap(x: &mut T, y: &mut T) { /// `replace` allows consumption of a struct field by replacing it with another value. /// Without `replace` you can run into issues like these: /// -/// ```ignore +/// ```compile_fail,E0507 /// struct Buffer { buf: Vec } /// /// impl Buffer { @@ -645,7 +652,7 @@ pub fn replace(dest: &mut T, mut src: T) -> T { /// /// Borrows are based on lexical scope, so this produces an error: /// -/// ```ignore +/// ```compile_fail,E0502 /// let mut v = vec![1, 2, 3]; /// let x = &v[0]; /// diff --git a/src/libcore/ops/place.rs b/src/libcore/ops/place.rs index 996a741c96f93..19da887cbbfbe 100644 --- a/src/libcore/ops/place.rs +++ b/src/libcore/ops/place.rs @@ -38,7 +38,13 @@ pub trait Place { /// /// `PLACE <- EXPR` effectively desugars into: /// -/// ```rust,ignore +/// ``` +/// # #![feature(placement_new_protocol, box_heap)] +/// # use std::ops::{Placer, Place, InPlace}; +/// # #[allow(non_snake_case)] +/// # fn main() { +/// # let PLACE = std::boxed::HEAP; +/// # let EXPR = 1; /// let p = PLACE; /// let mut place = Placer::make_place(p); /// let raw_place = Place::pointer(&mut place); @@ -47,6 +53,7 @@ pub trait Place { /// std::ptr::write(raw_place, value); /// InPlace::finalize(place) /// } +/// # ; } /// ``` /// /// The type of `PLACE <- EXPR` is derived from the type of `PLACE`; @@ -89,14 +96,21 @@ pub trait InPlace: Place { /// /// `box EXPR` effectively desugars into: /// -/// ```rust,ignore +/// ``` +/// # #![feature(placement_new_protocol)] +/// # use std::ops::{BoxPlace, Place, Boxed}; +/// # #[allow(non_snake_case)] +/// # fn main() { +/// # let EXPR = 1; /// let mut place = BoxPlace::make_place(); /// let raw_place = Place::pointer(&mut place); /// let value = EXPR; +/// # let _: Box<_> = /// unsafe { /// ::std::ptr::write(raw_place, value); /// Boxed::finalize(place) /// } +/// # ; } /// ``` /// /// The type of `box EXPR` is supplied from its surrounding diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 70c35df87ddaf..33258b7a875c5 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -26,7 +26,7 @@ use fmt; /// It does not have an `IntoIterator` implementation, so you can't use it in a /// `for` loop directly. This won't compile: /// -/// ```ignore +/// ```compile_fail,E0277 /// for i in .. { /// // ... /// } @@ -184,7 +184,7 @@ impl> RangeFrom { /// It does not have an `IntoIterator` implementation, so you can't use it in a /// `for` loop directly. This won't compile: /// -/// ```ignore +/// ```compile_fail,E0277 /// for i in ..5 { /// // ... /// } @@ -313,7 +313,8 @@ impl> RangeInclusive { /// It does not have an `IntoIterator` implementation, so you can't use it in a /// `for` loop directly. This won't compile: /// -/// ```ignore +/// ```compile_fail,E0277 +/// #![feature(inclusive_range_syntax)] /// for i in ...5 { /// // ... /// } diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs index 93ddfa72f63ca..60b7669f3b2d9 100644 --- a/src/libcore/panicking.rs +++ b/src/libcore/panicking.rs @@ -15,8 +15,10 @@ //! useful an upstream crate must define panicking for libcore to use. The current //! interface for panicking is: //! -//! ```ignore -//! fn panic_impl(fmt: fmt::Arguments, &(&'static str, u32)) -> !; +//! ``` +//! # use std::fmt; +//! fn panic_impl(fmt: fmt::Arguments, file_line: &(&'static str, u32)) -> ! +//! # { loop {} } //! ``` //! //! This definition allows for panicking with any general message, but it does not diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index f89f86e18a149..54ae9e0d628d5 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -408,11 +408,11 @@ impl *const T { /// /// Basic usage: /// - /// ```ignore - /// let val: *const u8 = &10u8 as *const u8; + /// ``` + /// let ptr: *const u8 = &10u8 as *const u8; /// /// unsafe { - /// if let Some(val_back) = val.as_ref() { + /// if let Some(val_back) = ptr.as_ref() { /// println!("We got back the value: {}!", val_back); /// } /// } @@ -570,11 +570,11 @@ impl *mut T { /// /// Basic usage: /// - /// ```ignore - /// let val: *mut u8 = &mut 10u8 as *mut u8; + /// ``` + /// let ptr: *mut u8 = &mut 10u8 as *mut u8; /// /// unsafe { - /// if let Some(val_back) = val.as_ref() { + /// if let Some(val_back) = ptr.as_ref() { /// println!("We got back the value: {}!", val_back); /// } /// } diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 6a5edc9f9e90f..7412a01e11e1e 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -111,7 +111,7 @@ //! //! Output from first example (in `example1.dot`): //! -//! ```ignore +//! ```dot //! digraph example1 { //! N0[label="N0"]; //! N1[label="N1"]; diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 4d378b0bf7dd3..5e36bd8ec2772 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -198,7 +198,12 @@ impl Trait for u8 { Now, if we have the following code: -```ignore +```compile_fail,E0038 +# trait Trait { fn foo(&self, on: T); } +# impl Trait for String { fn foo(&self, on: T) {} } +# impl Trait for u8 { fn foo(&self, on: T) {} } +# impl Trait for bool { fn foo(&self, on: T) {} } +# // etc. fn call_foo(thing: Box) { thing.foo(true); // this could be any one of the 8 types above thing.foo(1); @@ -565,8 +570,9 @@ fn foo(argc: isize, argv: *const *const u8) -> isize { 0 } // ok! ``` "##, -// isn't thrown anymore E0139: r##" +#### Note: this error code is no longer emitted by the compiler. + There are various restrictions on transmuting between types in Rust; for example types being transmuted must have the same size. To apply all these restrictions, the compiler must know the exact types that may be transmuted. When type @@ -602,22 +608,24 @@ If it's possible, hand-monomorphize the code by writing the function for each possible type substitution. It's possible to use traits to do this cleanly, for example: -```ignore +``` +use std::mem::transmute; + struct Foo(Vec); -trait MyTransmutableType { +trait MyTransmutableType: Sized { fn transmute(Vec) -> Foo; } impl MyTransmutableType for u8 { - fn transmute(x: Foo) -> Vec { - transmute(x) + fn transmute(x: Vec) -> Foo { + unsafe { transmute(x) } } } impl MyTransmutableType for String { - fn transmute(x: Foo) -> Vec { - transmute(x) + fn transmute(x: Vec) -> Foo { + unsafe { transmute(x) } } } @@ -635,8 +643,14 @@ is a size mismatch in one of the impls. It is also possible to manually transmute: -```ignore -ptr::read(&v as *const _ as *const SomeType) // `v` transmuted to `SomeType` +``` +# use std::ptr; +# let v = Some("value"); +# type SomeType = &'static [u8]; +unsafe { + ptr::read(&v as *const _ as *const SomeType) // `v` transmuted to `SomeType` +} +# ; ``` Note that this does not move `v` (unlike `transmute`), and may need a @@ -662,7 +676,7 @@ them yourself. You can build a free-standing crate by adding `#![no_std]` to the crate attributes: -```ignore +```ignore (only-for-syntax-highlight) #![no_std] ``` @@ -764,7 +778,7 @@ foo(3_i8); Here is that same example again, with some explanatory comments: -```ignore +```compile_fail,E0271 trait Trait { type AssociatedType; } fn foo(t: T) where T: Trait { @@ -784,7 +798,7 @@ fn foo(t: T) where T: Trait { } impl Trait for i8 { type AssociatedType = &'static str; } -~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // | | // `i8` does have | // implementation | @@ -816,7 +830,7 @@ The above fails because of an analogous type mismatch, though may be harder to see. Again, here are some explanatory comments for the same example: -```ignore +```compile_fail { let vs = vec![1, 2, 3, 4]; @@ -1416,6 +1430,8 @@ trait SecondTrait : FirstTrait { "##, E0398: r##" +#### Note: this error code is no longer emitted by the compiler. + In Rust 1.3, the default object lifetime bounds are expected to change, as described in [RFC 1156]. You are getting a warning because the compiler thinks it is possible that this change will cause a compilation error in your @@ -1433,14 +1449,16 @@ time, this means that you will want to change the signature of a function that you are calling. For example, if the error is reported on a call like `foo(x)`, and `foo` is defined as follows: -```ignore -fn foo(arg: &Box) { ... } +``` +# trait SomeTrait {} +fn foo(arg: &Box) { /* ... */ } ``` You might change it to: -```ignore -fn foo<'a>(arg: &Box) { ... } +``` +# trait SomeTrait {} +fn foo<'a>(arg: &'a Box) { /* ... */ } ``` This explicitly states that you expect the trait object `SomeTrait` to contain @@ -1809,24 +1827,29 @@ specified exit code, use `std::process::exit`. E0591: r##" Per [RFC 401][rfc401], if you have a function declaration `foo`: -```rust,ignore +``` // For the purposes of this explanation, all of these // different kinds of `fn` declarations are equivalent: -fn foo(x: i32) { ... } -extern "C" fn foo(x: i32); -impl i32 { fn foo(x: self) { ... } } +struct S; +fn foo(x: S) { /* ... */ } +# #[cfg(for_demonstration_only)] +extern "C" { fn foo(x: S); } +# #[cfg(for_demonstration_only)] +impl S { fn foo(self) { /* ... */ } } ``` -the type of `foo` is **not** `fn(i32)`, as one might expect. +the type of `foo` is **not** `fn(S)`, as one might expect. Rather, it is a unique, zero-sized marker type written here as `typeof(foo)`. -However, `typeof(foo)` can be _coerced_ to a function pointer `fn(i32)`, +However, `typeof(foo)` can be _coerced_ to a function pointer `fn(S)`, so you rarely notice this: -```rust,ignore -let x: fn(i32) = foo; // OK, coerces +``` +# struct S; +# fn foo(_: S) {} +let x: fn(S) = foo; // OK, coerces ``` -The reason that this matter is that the type `fn(i32)` is not specific to +The reason that this matter is that the type `fn(S)` is not specific to any particular function: it's a function _pointer_. So calling `x()` results in a virtual call, whereas `foo()` is statically dispatched, because the type of `foo` tells us precisely what function is being called. @@ -1837,14 +1860,17 @@ when using **transmute** to convert a fn item into a fn pointer. This is sometimes done as part of an FFI: -```rust,ignore +```compile_fail,E0591 extern "C" fn foo(userdata: Box) { - ... + /* ... */ } +# fn callback(_: extern "C" fn(*mut i32)) {} +# use std::mem::transmute; +# unsafe { let f: extern "C" fn(*mut i32) = transmute(foo); callback(f); - +# } ``` Here, transmute is being used to convert the types of the fn arguments. @@ -1856,8 +1882,15 @@ This pattern should be rewritten. There are a few possible ways to do this: - change the original fn declaration to match the expected signature, and do the cast in the fn body (the prefered option) - cast the fn item fo a fn pointer before calling transmute, as shown here: - - `let f: extern "C" fn(*mut i32) = transmute(foo as extern "C" fn(_))` - - `let f: extern "C" fn(*mut i32) = transmute(foo as usize) /* works too */` + + ``` + # extern "C" fn foo(_: Box) {} + # use std::mem::transmute; + # unsafe { + let f: extern "C" fn(*mut i32) = transmute(foo as extern "C" fn(_)); + let f: extern "C" fn(*mut i32) = transmute(foo as usize); // works too + # } + ``` The same applies to transmutes to `*mut fn()`, which were observedin practice. Note though that use of this type is generally incorrect. @@ -1905,7 +1938,7 @@ An unknown lint was used on the command line. Erroneous example: -```ignore +```sh rustc -D bogus omse_file.rs ``` diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index ae2be28c198bf..b84cd212c4ab4 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -755,15 +755,20 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { /// /// For example: /// - /// ```ignore + /// ``` /// let a: i32; /// a = 10; // ok, even though a is uninitialized + /// ``` /// + /// ``` /// struct Point { x: u32, y: u32 } - /// let p: Point; + /// let mut p: Point; /// p.x = 22; // ok, even though `p` is uninitialized + /// ``` /// - /// let p: Box; + /// ```compile_fail,E0381 + /// # struct Point { x: u32, y: u32 } + /// let mut p: Box; /// (*p).x = 22; // not ok, p is uninitialized, can't deref /// ``` fn check_if_assigned_path_is_moved(&self, diff --git a/src/librustc_borrowck/diagnostics.rs b/src/librustc_borrowck/diagnostics.rs index c114c66559ff6..38dcc73123691 100644 --- a/src/librustc_borrowck/diagnostics.rs +++ b/src/librustc_borrowck/diagnostics.rs @@ -153,10 +153,13 @@ structure that is currently uninitialized. For example, this can happen when a drop has taken place: -```ignore +```compile_fail,E0383 struct Foo { a: u32, } +impl Drop for Foo { + fn drop(&mut self) { /* ... */ } +} let mut x = Foo { a: 1 }; drop(x); // `x` is now uninitialized @@ -169,6 +172,9 @@ This error can be fixed by fully reinitializing the structure in question: struct Foo { a: u32, } +impl Drop for Foo { + fn drop(&mut self) { /* ... */ } +} let mut x = Foo { a: 1 }; drop(x); @@ -944,10 +950,9 @@ fn main() { } ``` -Moving out of a member of a mutably borrowed struct is fine if you put something -back. `mem::replace` can be used for that: +Moving a member out of a mutably borrowed struct will also cause E0507 error: -```ignore +```compile_fail,E0507 struct TheDarkKnight; impl TheDarkKnight { @@ -959,18 +964,31 @@ struct Batcave { } fn main() { - use std::mem; - let mut cave = Batcave { knight: TheDarkKnight }; let borrowed = &mut cave; borrowed.knight.nothing_is_true(); // E0507 - mem::replace(&mut borrowed.knight, TheDarkKnight).nothing_is_true(); // ok! } ``` +It is fine only if you put something back. `mem::replace` can be used for that: + +``` +# struct TheDarkKnight; +# impl TheDarkKnight { fn nothing_is_true(self) {} } +# struct Batcave { knight: TheDarkKnight } +use std::mem; + +let mut cave = Batcave { + knight: TheDarkKnight +}; +let borrowed = &mut cave; + +mem::replace(&mut borrowed.knight, TheDarkKnight).nothing_is_true(); // ok! +``` + You can find more information about borrowing in the rust-book: http://doc.rust-lang.org/book/first-edition/references-and-borrowing.html "##, diff --git a/src/librustc_const_eval/diagnostics.rs b/src/librustc_const_eval/diagnostics.rs index 4fc7ef8035eb5..56d08184a0f17 100644 --- a/src/librustc_const_eval/diagnostics.rs +++ b/src/librustc_const_eval/diagnostics.rs @@ -436,17 +436,19 @@ that happens. Qualified names are good practice, and most code works well with them. But if you prefer them unqualified, you can import the variants into scope: -```ignore +``` use Method::*; enum Method { GET, POST } +# fn main() {} ``` If you want others to be able to import variants from your module directly, use `pub use`: -```ignore +``` pub use Method::*; -enum Method { GET, POST } +pub enum Method { GET, POST } +# fn main() {} ``` "##, diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index b4a4aaaaf5c81..54e7c398fe6a6 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -355,14 +355,21 @@ fn handle_explain(code: &str, }; match descriptions.find_description(&normalised) { Some(ref description) => { + let mut is_in_code_block = false; // Slice off the leading newline and print. - print!("{}", &(&description[1..]).split("\n").map(|x| { - format!("{}\n", if x.starts_with("```") { - "```" + for line in description[1..].lines() { + let indent_level = line.find(|c: char| !c.is_whitespace()) + .unwrap_or_else(|| line.len()); + let dedented_line = &line[indent_level..]; + if dedented_line.starts_with("```") { + is_in_code_block = !is_in_code_block; + println!("{}", &line[..(indent_level+3)]); + } else if is_in_code_block && dedented_line.starts_with("# ") { + continue; } else { - x - }) - }).collect::()); + println!("{}", line); + } + } } None => { early_error(output, &format!("no extended information for {}", code)); diff --git a/src/librustc_metadata/diagnostics.rs b/src/librustc_metadata/diagnostics.rs index 9a174e05eabd4..1fa1a896dd6b6 100644 --- a/src/librustc_metadata/diagnostics.rs +++ b/src/librustc_metadata/diagnostics.rs @@ -21,7 +21,7 @@ A link name was given with an empty name. Erroneous code example: The rust compiler cannot link to an external library if you don't give it its name. Example: -```ignore +```no_run #[link(name = "some_lib")] extern {} // ok! ``` "##, @@ -32,7 +32,7 @@ as frameworks are specific to that operating system. Erroneous code example: -```ignore +```ignore (should-compile_fail-but-cannot-doctest-conditionally-without-macos) #[link(name = "FooCoreServices", kind = "framework")] extern {} // OS used to compile is Linux for example ``` @@ -75,7 +75,7 @@ A link was used without a name parameter. Erroneous code example: Please add the name parameter to allow the rust compiler to find the library you want. Example: -```ignore +```no_run #[link(kind = "dylib", name = "some_lib")] extern {} // ok! ``` "##, diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 7a3575cb50bd7..ff74698deab3f 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -150,7 +150,7 @@ //! the compiler. For example, if crate A wanted to use Bv1 and Bv2, then it //! would look something like: //! -//! ```ignore +//! ```compile_fail,E0463 //! extern crate b1; //! extern crate b2; //! diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 2505e2f8211b0..54f285480ab53 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -471,7 +471,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// But there may also be candidates that the test just doesn't /// apply to. The classical example involves wildcards: /// - /// ```rust,ignore + /// ``` + /// # let (x, y, z) = (true, true, true); /// match (x, y, z) { /// (true, _, true) => true, // (0) /// (_, true, _) => true, // (1) diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 469fd5750a2f9..2244ffde3c9d0 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -47,11 +47,12 @@ set of scheduled drops up front, and so whenever we exit from the scope we only drop the values scheduled thus far. For example, consider the scope S corresponding to this loop: -```rust,ignore +``` +# let cond = true; loop { - let x = ...; + let x = ..; if cond { break; } - let y = ...; + let y = ..; } ``` diff --git a/src/librustc_passes/diagnostics.rs b/src/librustc_passes/diagnostics.rs index 036a52d5a3db3..464dd72e56986 100644 --- a/src/librustc_passes/diagnostics.rs +++ b/src/librustc_passes/diagnostics.rs @@ -154,7 +154,7 @@ E0449: r##" A visibility qualifier was used when it was unnecessary. Erroneous code examples: -```compile_fail +```compile_fail,E0449 struct Bar; trait Foo { @@ -171,7 +171,7 @@ pub impl Foo for Bar { // error: unnecessary visibility qualifier To fix this error, please remove the visibility qualifier when it is not required. Example: -```ignore +``` struct Bar; trait Foo { @@ -184,8 +184,8 @@ impl Bar {} // Trait methods share the visibility of the trait, so `pub` is // unnecessary in either case -pub impl Foo for Bar { - pub fn foo() {} +impl Foo for Bar { + fn foo() {} } ``` "##, diff --git a/src/librustc_plugin/lib.rs b/src/librustc_plugin/lib.rs index d43625e3c23ff..1de31c5d79154 100644 --- a/src/librustc_plugin/lib.rs +++ b/src/librustc_plugin/lib.rs @@ -20,21 +20,31 @@ //! To define a plugin, build a dylib crate with a //! `#[plugin_registrar]` function: //! -//! ```rust,ignore +//! ```no_run //! #![crate_name = "myplugin"] //! #![crate_type = "dylib"] //! #![feature(plugin_registrar)] +//! #![feature(rustc_private)] //! -//! extern crate rustc; +//! extern crate rustc_plugin; +//! extern crate syntax; +//! extern crate syntax_pos; //! //! use rustc_plugin::Registry; +//! use syntax::ext::base::{ExtCtxt, MacResult}; +//! use syntax_pos::Span; +//! use syntax::tokenstream::TokenTree; //! //! #[plugin_registrar] //! pub fn plugin_registrar(reg: &mut Registry) { //! reg.register_macro("mymacro", expand_mymacro); //! } //! -//! fn expand_mymacro(...) { // details elided +//! fn expand_mymacro(cx: &mut ExtCtxt, span: Span, tt: &[TokenTree]) -> Box { +//! unimplemented!() +//! } +//! +//! # fn main() {} //! ``` //! //! WARNING: We currently don't check that the registrar function diff --git a/src/librustc_privacy/diagnostics.rs b/src/librustc_privacy/diagnostics.rs index 49f2ccb7c57f5..f8559954db12b 100644 --- a/src/librustc_privacy/diagnostics.rs +++ b/src/librustc_privacy/diagnostics.rs @@ -32,7 +32,7 @@ To solve this error, please ensure that the trait is also public. The trait can be made inaccessible if necessary by placing it into a private inner module, but it still has to be marked with `pub`. Example: -```ignore +``` pub trait Foo { // we set the Foo trait public fn dummy(&self) { } } @@ -75,9 +75,11 @@ mod Foo { "##, E0447: r##" +#### Note: this error code is no longer emitted by the compiler. + The `pub` keyword was used inside a function. Erroneous code example: -```ignore +``` fn foo() { pub struct Bar; // error: visibility has no effect inside functions } @@ -100,7 +102,7 @@ pub enum Foo { Since the enum is already public, adding `pub` on one its elements is unnecessary. Example: -```compile_fail, +```compile_fail enum Foo { pub Bar, // not ok! } @@ -108,7 +110,7 @@ enum Foo { This is the correct syntax: -```ignore +``` pub enum Foo { Bar, // ok! } diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 87c85a5fc96b8..34f3ff276ccd9 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -50,7 +50,7 @@ variable declarations and expression statements. Here is an example that demonstrates the error: -```ignore +``` fn f() { // Variable declaration before import let x = 0; @@ -86,7 +86,7 @@ items under a new local name. An example of this error: -```ignore +``` use foo::baz; use bar::*; // error, do `use foo::baz as quux` instead on the previous line @@ -188,15 +188,15 @@ already been imported. Erroneous code example: ```compile_fail,E0254 -extern crate alloc; +extern crate core; mod foo { - pub trait alloc { + pub trait core { fn do_something(); } } -use foo::alloc; // error: an extern crate named `alloc` has already +use foo::core; // error: an extern crate named `core` has already // been imported in this module fn main() {} @@ -205,16 +205,16 @@ fn main() {} To fix issue issue, you have to rename at least one of the two imports. Example: -```ignore -extern crate alloc as liballoc; // ok! +``` +extern crate core as libcore; // ok! mod foo { - pub trait alloc { + pub trait core { fn do_something(); } } -use foo::alloc; +use foo::core; fn main() {} ``` @@ -295,8 +295,9 @@ that has been imported into the current module. Erroneous code example: ```compile_fail,E0259 -extern crate std; -extern crate libc as std; +# #![feature(libc)] +extern crate core; +extern crate libc as core; fn main() {} ``` @@ -306,9 +307,12 @@ external crate imported into the current module. Correct example: -```ignore -extern crate std; +``` +# #![feature(libc)] +extern crate core; extern crate libc as other_name; + +fn main() {} ``` "##, @@ -317,26 +321,26 @@ The name for an item declaration conflicts with an external crate's name. Erroneous code example: -```ignore,E0260 -extern crate abc; +```compile_fail,E0260 +extern crate core; -struct abc; +struct core; ``` There are two possible solutions: Solution #1: Rename the item. -```ignore -extern crate abc; +``` +extern crate core; struct xyz; ``` Solution #2: Import the crate with a different name. -```ignore -extern crate abc as xyz; +``` +extern crate core as xyz; struct abc; ``` @@ -509,7 +513,8 @@ This may require additional type hints in the function body. In case the item is a function inside an `impl`, defining a private helper function might be easier: -```ignore +``` +# struct Foo(T); impl Foo { pub fn foo(&self, x: T) { self.bar(x); @@ -584,7 +589,8 @@ impl SomeTrait for Foo {} // error: trait `SomeTrait` is not in scope Please verify that the name of the trait wasn't misspelled and ensure that it was imported. Example: -```ignore +``` +# #[cfg(for_demonstration_only)] // solution 1: use some_file::SomeTrait; @@ -721,7 +727,7 @@ Here, `y` is bound by-value in one case and by-reference in the other. To fix this error, just use the same mode in both cases. Generally using `ref` or `ref mut` where not already used will fix this: -```ignore +``` let x = (0, 2); match x { (0, ref y) | (ref y, 0) => { /* use y */} @@ -905,7 +911,8 @@ match (1, 2) { Or maybe did you mean to unify? Consider using a guard: -```ignore +``` +# let (A, B, C) = (1, 2, 3); match (A, B, C) { (x, x2, see) if x == x2 => { /* A and B are equal, do one thing */ } (y, z, see) => { /* A and B unequal; do another thing */ } @@ -1045,9 +1052,12 @@ let x = unknown_variable; // ok! If the item is not defined in the current module, it must be imported using a `use` statement, like so: -```ignore +``` +# mod foo { pub fn bar() {} } +# fn main() { use foo::bar; bar(); +# } ``` If the item you are importing is not defined in some super-module of the @@ -1130,8 +1140,11 @@ use something::{self, self}; // error: `self` import can only appear once in Please verify you didn't misspell the import name or remove the duplicated `self` import. Example: -```ignore -use something::self; // ok! +``` +# mod something {} +# fn main() { +use something::{self}; // ok! +# } ``` "##, @@ -1164,21 +1177,23 @@ prefixes, respectively. Also verify that you didn't misspell the import name and that the import exists in the module from where you tried to import it. Example: -```ignore +``` use self::something::Foo; // ok! mod something { pub struct Foo; } +# fn main() {} ``` Or, if you tried to use a module from an external crate, you may have missed the `extern crate` declaration (which is usually placed in the crate root): -```ignore -extern crate homura; // Required to use the `homura` crate +``` +extern crate core; // Required to use the `core` crate -use homura::Madoka; +use core::any; +# fn main() {} ``` "##, @@ -1339,7 +1354,7 @@ extern crate core as another_crate; This is a syntax error at the level of attribute declarations. The proper syntax for macro imports is the following: -```ignore +```ignore (cannot-doctest-multicrate-project) // In some_crate: #[macro_export] macro_rules! get_tacos { @@ -1383,7 +1398,7 @@ Decide which macros you would like to export and list them properly. These are proper reexport declarations: -```ignore +```ignore (cannot-doctest-multicrate-project) #[macro_reexport(some_macro, another_macro)] extern crate macros_for_good; ``` @@ -1396,9 +1411,9 @@ Example of erroneous code: ```compile_fail,E0468 mod foo { - #[macro_use(helpful_macro)] // error: must be at crate root to import + #[macro_use(debug_assert)] // error: must be at crate root to import extern crate core; // macros from another crate - helpful_macro!(...); + fn run_macro() { debug_assert!(true); } } ``` @@ -1408,13 +1423,14 @@ macros. Either move the macro import to crate root or do without the foreign macros. This will work: -```ignore -#[macro_use(helpful_macro)] -extern crate some_crate; +``` +#[macro_use(debug_assert)] +extern crate core; mod foo { - helpful_macro!(...) + fn run_macro() { debug_assert!(true); } } +# fn main() {} ``` "##, @@ -1442,7 +1458,7 @@ in question exports them. A working version would be: -```ignore +```ignore (cannot-doctest-multicrate-project) // In some_crate crate: #[macro_export] macro_rules! eat { @@ -1484,7 +1500,7 @@ in question exports them. A working version: -```ignore +```ignore (cannot-doctest-multicrate-project) // In some_crate crate: #[macro_export] macro_rules! eat { diff --git a/src/librustc_trans/diagnostics.rs b/src/librustc_trans/diagnostics.rs index 18d31448b1a24..df71fd4b19b6a 100644 --- a/src/librustc_trans/diagnostics.rs +++ b/src/librustc_trans/diagnostics.rs @@ -16,7 +16,7 @@ E0511: r##" Invalid monomorphization of an intrinsic function was used. Erroneous code example: -```ignore +```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail) #![feature(platform_intrinsics)] extern "platform-intrinsic" { diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index a898a75d0c976..5b8170d7ddee4 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -226,8 +226,10 @@ size of trait implementors isn't fixed, this type has no compile-time size. Therefore, all accesses to trait types must be through pointers. If you encounter this error you should try to avoid dereferencing the pointer. -```ignore -let trait_obj: &SomeTrait = ...; +```compile_fail,E0033 +# trait SomeTrait { fn method_one(&self){} fn method_two(&self){} } +# impl SomeTrait for T {} +let trait_obj: &SomeTrait = &"some_value"; // This tries to implicitly dereference to create an unsized local variable. let &invalid = trait_obj; @@ -407,7 +409,11 @@ fn main() { Please note on the last example that we could have called `method` like this: -```ignore +``` +# struct Test; +# impl Test { fn method(&self, v: &[T]) -> usize { v.len() } } +# let x = Test; +# let v = &[0]; x.method(v); ``` "##, @@ -684,9 +690,8 @@ External C functions are allowed to be variadic. However, a variadic function takes a minimum number of arguments. For example, consider C's variadic `printf` function: -```ignore -extern crate libc; -use libc::{ c_char, c_int }; +``` +use std::os::raw::{c_char, c_int}; extern "C" { fn printf(_: *const c_char, ...) -> c_int; @@ -696,16 +701,35 @@ extern "C" { Using this declaration, it must be called with at least one argument, so simply calling `printf()` is invalid. But the following uses are allowed: -```ignore +``` +# #![feature(static_nobundle)] +# use std::os::raw::{c_char, c_int}; +# #[cfg_attr(all(windows, target_env = "msvc"), +# link(name = "legacy_stdio_definitions", kind = "static-nobundle"))] +# extern "C" { fn printf(_: *const c_char, ...) -> c_int; } +# fn main() { unsafe { use std::ffi::CString; - printf(CString::new("test\n").unwrap().as_ptr()); - printf(CString::new("number = %d\n").unwrap().as_ptr(), 3); - printf(CString::new("%d, %d\n").unwrap().as_ptr(), 10, 5); + let fmt = CString::new("test\n").unwrap(); + printf(fmt.as_ptr()); + + let fmt = CString::new("number = %d\n").unwrap(); + printf(fmt.as_ptr(), 3); + + let fmt = CString::new("%d, %d\n").unwrap(); + printf(fmt.as_ptr(), 10, 5); } +# } ``` "##, +// ^ Note: On MSVC 2015, the `printf` function is "inlined" in the C code, and +// the C runtime does not contain the `printf` definition. This leads to linker +// error from the doc test (issue #42830). +// This can be fixed by linking to the static library +// `legacy_stdio_definitions.lib` (see https://stackoverflow.com/a/36504365/). +// If this compatibility library is removed in the future, consider changing +// `printf` in this example to another well-known variadic function. E0061: r##" The number of arguments passed to a function must match the number of arguments @@ -924,13 +948,15 @@ fn main() { "##, E0073: r##" +#### Note: this error code is no longer emitted by the compiler. + You cannot define a struct (or enum) `Foo` that requires an instance of `Foo` in order to make a new `Foo` value. This is because there would be no way a first instance of `Foo` could be made to initialize another instance! Here's an example of a struct that has this problem: -```ignore +``` struct Foo { x: Box } // error ``` @@ -944,6 +970,8 @@ Now it's possible to create at least one instance of `Foo`: `Foo { x: None }`. "##, E0074: r##" +#### Note: this error code is no longer emitted by the compiler. + When using the `#[simd]` attribute on a tuple struct, the components of the tuple struct must all be of a concrete, nongeneric type so the compiler can reason about how to use SIMD with them. This error will occur if the types @@ -951,7 +979,7 @@ are generic. This will cause an error: -```ignore +``` #![feature(repr_simd)] #[repr(simd)] @@ -1078,13 +1106,16 @@ encountered, so a conflict occurs. "##, E0082: r##" +#### Note: this error code is no longer emitted by the compiler. + When you specify enum discriminants with `=`, the compiler expects `isize` values by default. Or you can add the `repr` attibute to the enum declaration for an explicit choice of the discriminant type. In either cases, the discriminant values must fall within a valid range for the expected type; otherwise this error is raised. For example: -```ignore +```compile_fail +# #![deny(overflowing_literals)] #[repr(u8)] enum Thing { A = 1024, @@ -1095,7 +1126,8 @@ enum Thing { Here, 1024 lies outside the valid range for `u8`, so the discriminant for `A` is invalid. Here is another, more subtle example which depends on target word size: -```ignore +```compile_fail,E0080 +# #[repr(i32)] enum DependsOnPointerSize { A = 1 << 32, } @@ -1448,11 +1480,12 @@ impl Drop for u32 {} To avoid this kind of error, ensure that at least one local type is referenced by the `impl`: -```ignore +``` pub struct Foo; // you define your type in your crate impl Drop for Foo { // and you can implement the trait on it! // code of trait implementation here +# fn drop(&mut self) { } } impl From for i32 { // or you use a type from your crate as @@ -1644,7 +1677,8 @@ It is not possible to declare type parameters on a function that has the `start` attribute. Such a function must have the following type signature (for more information: http://doc.rust-lang.org/stable/book/first-edition/no-stdlib.html): -```ignore +``` +# let _: fn(isize, *const *const u8) -> isize; ``` @@ -1812,10 +1846,12 @@ information see the [opt-in builtin traits RFC][RFC 19]. "##, E0193: r##" +#### Note: this error code is no longer emitted by the compiler. + `where` clauses must use generic type parameters: it does not make sense to use them otherwise. An example causing this error: -```ignore +``` trait Foo { fn bar(&self); } @@ -2265,17 +2301,20 @@ If `ForeignTrait` is a trait defined in some external crate `foo`, then the following trait `impl` is an error: ```compile_fail,E0210 -extern crate alloc; -use alloc::range::RangeArgument; +# #[cfg(for_demonstration_only)] +extern crate foo; +# #[cfg(for_demonstration_only)] +use foo::ForeignTrait; +# use std::panic::UnwindSafe as ForeignTrait; -impl RangeArgument for T { } // error - -fn main() {} +impl ForeignTrait for T { } // error +# fn main() {} ``` To work around this, it can be covered with a local type, `MyType`: -```ignore +``` +# use std::panic::UnwindSafe as ForeignTrait; struct MyType(T); impl ForeignTrait for MyType { } // Ok ``` @@ -2286,7 +2325,7 @@ For another example of an error, suppose there's another trait defined in `foo` named `ForeignTrait2` that takes two type parameters. Then this `impl` results in the same rule violation: -```compile_fail +```ignore (cannot-doctest-multicrate-project) struct MyType2; impl ForeignTrait2> for MyType2 { } // error ``` @@ -2297,7 +2336,7 @@ is uncovered, and so runs afoul of the orphan rule. Consider one more example: -```ignore +```ignore (cannot-doctest-multicrate-project) impl ForeignTrait2, T> for MyType2 { } // Ok ``` @@ -2308,7 +2347,7 @@ violate the orphan rule; it is permitted. To see why that last example was allowed, you need to understand the general rule. Unfortunately this rule is a bit tricky to state. Consider an `impl`: -```ignore +```ignore (only-for-syntax-highlight) impl ForeignTrait for T0 { ... } ``` @@ -2590,13 +2629,17 @@ fn baz(x: &>::A) {} To solve this error, please move the type bindings in the type parameter declaration: -```ignore +``` +# struct Bar; +# trait Foo { type A; } fn baz>(x: &::A) {} // ok! ``` Or in the `where` clause: -```ignore +``` +# struct Bar; +# trait Foo { type A; } fn baz(x: &::A) where I: Foo {} ``` "##, @@ -2935,12 +2978,19 @@ impl CoerceUnsized> for MyType [`CoerceUnsized`]: https://doc.rust-lang.org/std/ops/trait.CoerceUnsized.html "##, +/* +// Associated consts can now be accessed through generic type parameters, and +// this error is no longer emitted. +// +// FIXME: consider whether to leave it in the error index, or remove it entirely +// as associated consts is not stabilized yet. + E0329: r##" An attempt was made to access an associated constant through either a generic type parameter or `Self`. This is not supported yet. An example causing this error is shown below: -```ignore +``` #![feature(associated_consts)] trait Foo { @@ -2961,7 +3011,7 @@ fn get_bar_bad(t: F) -> f64 { Currently, the value of `BAR` for a particular type can only be accessed through a concrete type, as shown below: -```ignore +``` #![feature(associated_consts)] trait Foo { @@ -2975,6 +3025,7 @@ fn get_bar_good() -> f64 { } ``` "##, +*/ E0366: r##" An attempt was made to implement `Drop` on a concrete specialization of a @@ -4349,14 +4400,20 @@ f.method; // error: attempted to take value of method `method` on type `Foo` If you want to use a method, add `()` after it: -```ignore +``` +# struct Foo { x: u32 } +# impl Foo { fn method(&self) {} } +# let f = Foo { x: 0 }; f.method(); ``` However, if you wanted to access a field of a struct check that the field name is spelled correctly. Example: -```ignore +``` +# struct Foo { x: u32 } +# impl Foo { fn method(&self) {} } +# let f = Foo { x: 0 }; println!("{}", f.x); ``` "##, diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index ec4a23b0417bc..bea13397eca4b 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -15,7 +15,7 @@ //! functionality through a unit-struct, `Markdown`, which has an implementation //! of `fmt::Display`. Example usage: //! -//! ```rust,ignore +//! ``` //! use rustdoc::html::markdown::Markdown; //! //! let s = "My *markdown* _text_"; diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 07417565e314f..dae0b5f01238b 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -36,7 +36,7 @@ //! Arrays are enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }). //! A simple JSON document encoding a person, their age, address and phone numbers could look like //! -//! ```ignore +//! ```json //! { //! "FirstName": "John", //! "LastName": "Doe", diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 82c4f0830a626..9a4c5ec8f6b2e 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -444,7 +444,7 @@ pub mod builtin { /// /// # Examples /// - /// ```rust,ignore + /// ```ignore (cannot-doctest-external-file-dependency) /// let secret_key = include_str!("secret-key.ascii"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] @@ -461,7 +461,7 @@ pub mod builtin { /// /// # Examples /// - /// ```rust,ignore + /// ```ignore (cannot-doctest-external-file-dependency) /// let secret_key = include_bytes!("secret-key.bin"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] @@ -530,13 +530,13 @@ pub mod builtin { /// /// File 'my_str.in': /// - /// ```ignore + /// ```ignore (only-for-syntax-highlight) /// "Hello World!" /// ``` /// /// File 'main.rs': /// - /// ```ignore + /// ```ignore (cannot-doctest-external-file-dependency) /// fn main() { /// let my_str = include!("my_str.in"); /// println!("{}", my_str); diff --git a/src/libstd/memchr.rs b/src/libstd/memchr.rs index 7c8c97a6caf9c..98642f86f4dc2 100644 --- a/src/libstd/memchr.rs +++ b/src/libstd/memchr.rs @@ -24,7 +24,7 @@ /// /// This shows how to find the first position of a byte in a byte string. /// -/// ```rust,ignore +/// ```ignore (cannot-doctest-private-modules) /// use memchr::memchr; /// /// let haystack = b"the quick brown fox"; @@ -44,7 +44,7 @@ pub fn memchr(needle: u8, haystack: &[u8]) -> Option { /// /// This shows how to find the last position of a byte in a byte string. /// -/// ```rust,ignore +/// ```ignore (cannot-doctest-private-modules) /// use memchr::memrchr; /// /// let haystack = b"the quick brown fox"; diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs index 195662637f013..49cdba21a1d37 100644 --- a/src/libstd/prelude/mod.rs +++ b/src/libstd/prelude/mod.rs @@ -22,13 +22,14 @@ //! //! On a technical level, Rust inserts //! -//! ```ignore +//! ``` //! extern crate std; //! ``` //! //! into the crate root of every crate, and //! -//! ```ignore +//! ``` +//! # #[allow(unused_imports)] //! use std::prelude::v1::*; //! ``` //! diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 61ff8daddf0a6..869299e21448a 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -320,7 +320,7 @@ mod prim_pointer { } /// /// An array itself is not iterable: /// -/// ```ignore +/// ```compile_fail,E0277 /// let array: [i32; 3] = [0; 3]; /// /// for x in array { } @@ -480,8 +480,10 @@ mod prim_str { } /// Tuples are *heterogeneous*. This means that each element of the tuple can /// have a different type. In that tuple above, it has the type: /// -/// ```rust,ignore +/// ``` +/// # let _: /// (&'static str, i32, char) +/// # = ("hello", 5, 'c'); /// ``` /// /// Tuples are a *sequence*. This means that they can be accessed by position; diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 4632c8a918e6e..df6a648b7b162 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -349,15 +349,19 @@ impl Command { /// /// Only one argument can be passed per use. So instead of: /// - /// ```ignore + /// ```no_run + /// # std::process::Command::new("sh") /// .arg("-C /path/to/repo") + /// # ; /// ``` /// /// usage would be: /// - /// ```ignore + /// ```no_run + /// # std::process::Command::new("sh") /// .arg("-C") /// .arg("/path/to/repo") + /// # ; /// ``` /// /// To pass multiple arguments see [`args`]. diff --git a/src/libstd/sys/redox/ext/fs.rs b/src/libstd/sys/redox/ext/fs.rs index fc81cc737d9f0..4437cf43920c5 100644 --- a/src/libstd/sys/redox/ext/fs.rs +++ b/src/libstd/sys/redox/ext/fs.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Unix-specific extensions to primitives in the `std::fs` module. +//! Redox-specific extensions to primitives in the `std::fs` module. #![stable(feature = "rust1", since = "1.0.0")] @@ -18,23 +18,25 @@ use path::Path; use sys; use sys_common::{FromInner, AsInner, AsInnerMut}; -/// Unix-specific extensions to `Permissions` +/// Redox-specific extensions to `Permissions` #[stable(feature = "fs_ext", since = "1.1.0")] pub trait PermissionsExt { - /// Returns the underlying raw `mode_t` bits that are the standard Unix + /// Returns the underlying raw `mode_t` bits that are the standard Redox /// permissions for this file. /// /// # Examples /// - /// ```rust,ignore + /// ```no_run /// use std::fs::File; - /// use std::os::unix::fs::PermissionsExt; + /// use std::os::redox::fs::PermissionsExt; /// + /// # fn run() -> std::io::Result<()> { /// let f = File::create("foo.txt")?; /// let metadata = f.metadata()?; /// let permissions = metadata.permissions(); /// /// println!("permissions: {}", permissions.mode()); + /// # Ok(()) } /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn mode(&self) -> u32; @@ -43,28 +45,30 @@ pub trait PermissionsExt { /// /// # Examples /// - /// ```rust,ignore + /// ```no_run /// use std::fs::File; - /// use std::os::unix::fs::PermissionsExt; + /// use std::os::redox::fs::PermissionsExt; /// + /// # fn run() -> std::io::Result<()> { /// let f = File::create("foo.txt")?; /// let metadata = f.metadata()?; /// let mut permissions = metadata.permissions(); /// /// permissions.set_mode(0o644); // Read/write for owner and read for others. /// assert_eq!(permissions.mode(), 0o644); + /// # Ok(()) } /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn set_mode(&mut self, mode: u32); - /// Creates a new instance of `Permissions` from the given set of Unix + /// Creates a new instance of `Permissions` from the given set of Redox /// permission bits. /// /// # Examples /// - /// ```rust,ignore + /// ``` /// use std::fs::Permissions; - /// use std::os::unix::fs::PermissionsExt; + /// use std::os::redox::fs::PermissionsExt; /// /// // Read/write for owner and read for others. /// let permissions = Permissions::from_mode(0o644); @@ -89,7 +93,7 @@ impl PermissionsExt for Permissions { } } -/// Unix-specific extensions to `OpenOptions` +/// Redox-specific extensions to `OpenOptions` #[stable(feature = "fs_ext", since = "1.1.0")] pub trait OpenOptionsExt { /// Sets the mode bits that a new file will be created with. @@ -102,14 +106,17 @@ pub trait OpenOptionsExt { /// /// # Examples /// - /// ```rust,ignore + /// ```no_run + /// # #![feature(libc)] /// extern crate libc; /// use std::fs::OpenOptions; - /// use std::os::unix::fs::OpenOptionsExt; + /// use std::os::redox::fs::OpenOptionsExt; /// + /// # fn main() { /// let mut options = OpenOptions::new(); /// options.mode(0o644); // Give read/write for owner and read for others. /// let file = options.open("foo.txt"); + /// # } /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn mode(&mut self, mode: u32) -> &mut Self; @@ -124,17 +131,20 @@ pub trait OpenOptionsExt { /// /// # Examples /// - /// ```rust,ignore + /// ```no_run + /// # #![feature(libc)] /// extern crate libc; /// use std::fs::OpenOptions; - /// use std::os::unix::fs::OpenOptionsExt; + /// use std::os::redox::fs::OpenOptionsExt; /// + /// # fn main() { /// let mut options = OpenOptions::new(); /// options.write(true); - /// if cfg!(unix) { + /// if cfg!(target_os = "redox") { /// options.custom_flags(libc::O_NOFOLLOW); /// } /// let file = options.open("foo.txt"); + /// # } /// ``` #[stable(feature = "open_options_ext", since = "1.10.0")] fn custom_flags(&mut self, flags: i32) -> &mut Self; @@ -226,7 +236,7 @@ impl MetadataExt for fs::Metadata { } } -/// Add special unix types (block/char device, fifo and socket) +/// Add special Redox types (block/char device, fifo and socket) #[stable(feature = "file_type_ext", since = "1.5.0")] pub trait FileTypeExt { /// Returns whether this file type is a block device. @@ -267,7 +277,7 @@ impl FileTypeExt for fs::FileType { /// # Examples /// /// ``` -/// use std::os::unix::fs; +/// use std::os::redox::fs; /// /// # fn foo() -> std::io::Result<()> { /// fs::symlink("a.txt", "b.txt")?; @@ -281,16 +291,16 @@ pub fn symlink, Q: AsRef>(src: P, dst: Q) -> io::Result<()> } #[stable(feature = "dir_builder", since = "1.6.0")] -/// An extension trait for `fs::DirBuilder` for unix-specific options. +/// An extension trait for `fs::DirBuilder` for Redox-specific options. pub trait DirBuilderExt { /// Sets the mode to create new directories with. This option defaults to /// 0o777. /// /// # Examples /// - /// ```ignore + /// ```no_run /// use std::fs::DirBuilder; - /// use std::os::unix::fs::DirBuilderExt; + /// use std::os::redox::fs::DirBuilderExt; /// /// let mut builder = DirBuilder::new(); /// builder.mode(0o755); diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index 17de46636b5c9..26710bf61d510 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -73,15 +73,17 @@ pub trait PermissionsExt { /// /// # Examples /// - /// ```rust,ignore + /// ```no_run /// use std::fs::File; /// use std::os::unix::fs::PermissionsExt; /// + /// # fn run() -> std::io::Result<()> { /// let f = File::create("foo.txt")?; /// let metadata = f.metadata()?; /// let permissions = metadata.permissions(); /// /// println!("permissions: {}", permissions.mode()); + /// # Ok(()) } /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn mode(&self) -> u32; @@ -90,16 +92,18 @@ pub trait PermissionsExt { /// /// # Examples /// - /// ```rust,ignore + /// ```no_run /// use std::fs::File; /// use std::os::unix::fs::PermissionsExt; /// + /// # fn run() -> std::io::Result<()> { /// let f = File::create("foo.txt")?; /// let metadata = f.metadata()?; /// let mut permissions = metadata.permissions(); /// /// permissions.set_mode(0o644); // Read/write for owner and read for others. /// assert_eq!(permissions.mode(), 0o644); + /// # Ok(()) } /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn set_mode(&mut self, mode: u32); @@ -109,7 +113,7 @@ pub trait PermissionsExt { /// /// # Examples /// - /// ```rust,ignore + /// ``` /// use std::fs::Permissions; /// use std::os::unix::fs::PermissionsExt; /// @@ -149,14 +153,17 @@ pub trait OpenOptionsExt { /// /// # Examples /// - /// ```rust,ignore + /// ```no_run + /// # #![feature(libc)] /// extern crate libc; /// use std::fs::OpenOptions; /// use std::os::unix::fs::OpenOptionsExt; /// + /// # fn main() { /// let mut options = OpenOptions::new(); /// options.mode(0o644); // Give read/write for owner and read for others. /// let file = options.open("foo.txt"); + /// # } /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn mode(&mut self, mode: u32) -> &mut Self; @@ -171,17 +178,20 @@ pub trait OpenOptionsExt { /// /// # Examples /// - /// ```rust,ignore + /// ```no_run + /// # #![feature(libc)] /// extern crate libc; /// use std::fs::OpenOptions; /// use std::os::unix::fs::OpenOptionsExt; /// + /// # fn main() { /// let mut options = OpenOptions::new(); /// options.write(true); /// if cfg!(unix) { /// options.custom_flags(libc::O_NOFOLLOW); /// } /// let file = options.open("foo.txt"); + /// # } /// ``` #[stable(feature = "open_options_ext", since = "1.10.0")] fn custom_flags(&mut self, flags: i32) -> &mut Self; @@ -353,7 +363,7 @@ pub trait DirBuilderExt { /// /// # Examples /// - /// ```ignore + /// ```no_run /// use std::fs::DirBuilder; /// use std::os::unix::fs::DirBuilderExt; /// diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs index 2d00cb38ec4fc..67348a0049417 100644 --- a/src/libstd/sys/windows/ext/fs.rs +++ b/src/libstd/sys/windows/ext/fs.rs @@ -169,8 +169,10 @@ pub trait OpenOptionsExt { /// /// # Examples /// - /// ```ignore + /// ```no_run + /// # #[cfg(for_demonstration_only)] /// extern crate winapi; + /// # mod winapi { pub const FILE_FLAG_DELETE_ON_CLOSE: u32 = 0x04000000; } /// /// use std::fs::OpenOptions; /// use std::os::windows::prelude::*; @@ -204,8 +206,10 @@ pub trait OpenOptionsExt { /// /// # Examples /// - /// ```ignore + /// ```no_run + /// # #[cfg(for_demonstration_only)] /// extern crate winapi; + /// # mod winapi { pub const FILE_ATTRIBUTE_HIDDEN: u32 = 2; } /// /// use std::fs::OpenOptions; /// use std::os::windows::prelude::*; diff --git a/src/libstd/sys_common/thread_local.rs b/src/libstd/sys_common/thread_local.rs index 0ade90e64c307..9ba023b57e6a3 100644 --- a/src/libstd/sys_common/thread_local.rs +++ b/src/libstd/sys_common/thread_local.rs @@ -33,7 +33,7 @@ //! Using a dynamically allocated TLS key. Note that this key can be shared //! among many threads via an `Arc`. //! -//! ```rust,ignore +//! ```ignore (cannot-doctest-private-modules) //! let key = Key::new(None); //! assert!(key.get().is_null()); //! key.set(1 as *mut u8); @@ -45,7 +45,7 @@ //! Sometimes a statically allocated key is either required or easier to work //! with, however. //! -//! ```rust,ignore +//! ```ignore (cannot-doctest-private-modules) //! static KEY: StaticKey = INIT; //! //! unsafe { @@ -74,7 +74,7 @@ use sys_common::mutex::Mutex; /// /// # Examples /// -/// ```ignore +/// ```ignore (cannot-doctest-private-modules) /// use tls::os::{StaticKey, INIT}; /// /// static KEY: StaticKey = INIT; @@ -105,7 +105,7 @@ pub struct StaticKey { /// /// # Examples /// -/// ```rust,ignore +/// ```ignore (cannot-doctest-private-modules) /// use tls::os::Key; /// /// let key = Key::new(None); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 2eb39bc26b5cb..8bd58ec7a52d5 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -775,10 +775,10 @@ pub struct Local { /// /// E.g. `0...10 => { println!("match!") }` as in /// -/// ```rust,ignore -/// match n { +/// ``` +/// match 123 { /// 0...10 => { println!("match!") }, -/// // .. +/// _ => { println!("no match!") }, /// } /// ``` #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] @@ -977,7 +977,7 @@ pub enum ExprKind { /// separately. `position` represents the index of the associated /// item qualified with this Self type. /// -/// ```rust,ignore +/// ```ignore (only-for-syntax-highlight) /// as a::b::Trait>::AssociatedItem /// ^~~~~ ~~~~~~~~~~~~~~^ /// ty position = 3 diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs index 01d1277ea6265..508feca9731f2 100644 --- a/src/libsyntax/diagnostic_list.rs +++ b/src/libsyntax/diagnostic_list.rs @@ -51,12 +51,14 @@ fn main() {} The parenthesized `inline` attribute requires the parameter to be specified: -```ignore +``` #[inline(always)] fn something() {} +``` -// or: +or: +``` #[inline(never)] fn something() {} ``` diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 0b145c54f619c..851a638e14842 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4436,7 +4436,7 @@ impl<'a> Parser<'a> { /// Parses an optional `where` clause and places it in `generics`. /// - /// ```ignore + /// ```ignore (only-for-syntax-highlight) /// where T : Trait + 'b, 'a : 'b /// ``` pub fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> { diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index e893c859247c6..82b5d7e284bc6 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -11,7 +11,7 @@ //! This pretty-printer is a direct reimplementation of Philip Karlton's //! Mesa pretty-printer, as described in appendix A of //! -//! ````ignore +//! ````text //! STAN-CS-79-770: "Pretty Printing", by Derek C. Oppen. //! Stanford Department of Computer Science, 1979. //! ```` diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs index 9d155c22ad031..33f742282c172 100644 --- a/src/libsyntax_ext/deriving/encodable.rs +++ b/src/libsyntax_ext/deriving/encodable.rs @@ -14,14 +14,15 @@ //! //! For example, a type like: //! -//! ```ignore +//! ``` //! #[derive(Encodable, Decodable)] //! struct Node { id: usize } //! ``` //! //! would generate two implementations like: //! -//! ```ignore +//! ``` +//! # struct Node { id: usize } //! impl, E> Encodable for Node { //! fn encode(&self, s: &mut S) -> Result<(), E> { //! s.emit_struct("Node", 1, |this| { @@ -48,14 +49,17 @@ //! Other interesting scenarios are when the item has type parameters or //! references other non-built-in types. A type definition like: //! -//! ```ignore +//! ``` +//! # #[derive(Encodable, Decodable)] struct Span; //! #[derive(Encodable, Decodable)] //! struct Spanned { node: T, span: Span } //! ``` //! //! would yield functions like: //! -//! ```ignore +//! ``` +//! # #[derive(Encodable, Decodable)] struct Span; +//! # struct Spanned { node: T, span: Span } //! impl< //! S: Encoder, //! E, diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index be7883cad5f38..3a15b82d19f69 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -456,7 +456,7 @@ impl<'a> TraitDef<'a> { /// Given that we are deriving a trait `DerivedTrait` for a type like: /// - /// ```ignore + /// ```ignore (only-for-syntax-highlight) /// struct Struct<'a, ..., 'z, A, B: DeclaredTrait, C, ..., Z> where C: WhereTrait { /// a: A, /// b: B::Item, @@ -469,7 +469,7 @@ impl<'a> TraitDef<'a> { /// /// create an impl like: /// - /// ```ignore + /// ```ignore (only-for-syntax-highlight) /// impl<'a, ..., 'z, A, B: DeclaredTrait, C, ... Z> where /// C: WhereTrait, /// A: DerivedTrait + B1 + ... + BN, @@ -933,8 +933,9 @@ impl<'a> MethodDef<'a> { } } - /// ```ignore + /// ``` /// #[derive(PartialEq)] + /// # struct Dummy; /// struct A { x: i32, y: i32 } /// /// // equivalent to: @@ -1040,8 +1041,9 @@ impl<'a> MethodDef<'a> { &StaticStruct(struct_def, summary)) } - /// ```ignore + /// ``` /// #[derive(PartialEq)] + /// # struct Dummy; /// enum A { /// A1, /// A2(i32) @@ -1624,7 +1626,7 @@ pub fn cs_fold(use_foldl: bool, /// Call the method that is being derived on all the fields, and then /// process the collected results. i.e. /// -/// ```ignore +/// ```ignore (only-for-syntax-highlight) /// f(cx, span, vec![self_1.method(__arg_1_1, __arg_2_1), /// self_2.method(__arg_1_2, __arg_2_2)]) /// ``` diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 24c1dfe289b1e..a6768c07fe13b 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -117,7 +117,8 @@ struct Context<'a, 'b: 'a> { /// expressions. /// /// If parsing succeeds, the return value is: -/// ```ignore +/// +/// ```text /// Some((fmtstr, parsed arguments, index map for named arguments)) /// ``` fn parse_args(ecx: &mut ExtCtxt, diff --git a/src/test/ui/explain.rs b/src/test/ui/explain.rs new file mode 100644 index 0000000000000..17fb59935dd16 --- /dev/null +++ b/src/test/ui/explain.rs @@ -0,0 +1,11 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --explain E0591 diff --git a/src/test/ui/explain.stdout b/src/test/ui/explain.stdout new file mode 100644 index 0000000000000..0bbbd95320a8c --- /dev/null +++ b/src/test/ui/explain.stdout @@ -0,0 +1,63 @@ +Per [RFC 401][rfc401], if you have a function declaration `foo`: + +``` +// For the purposes of this explanation, all of these +// different kinds of `fn` declarations are equivalent: +struct S; +fn foo(x: S) { /* ... */ } +extern "C" { fn foo(x: S); } +impl S { fn foo(self) { /* ... */ } } +``` + +the type of `foo` is **not** `fn(S)`, as one might expect. +Rather, it is a unique, zero-sized marker type written here as `typeof(foo)`. +However, `typeof(foo)` can be _coerced_ to a function pointer `fn(S)`, +so you rarely notice this: + +``` +let x: fn(S) = foo; // OK, coerces +``` + +The reason that this matter is that the type `fn(S)` is not specific to +any particular function: it's a function _pointer_. So calling `x()` results +in a virtual call, whereas `foo()` is statically dispatched, because the type +of `foo` tells us precisely what function is being called. + +As noted above, coercions mean that most code doesn't have to be +concerned with this distinction. However, you can tell the difference +when using **transmute** to convert a fn item into a fn pointer. + +This is sometimes done as part of an FFI: + +``` +extern "C" fn foo(userdata: Box) { + /* ... */ +} + +let f: extern "C" fn(*mut i32) = transmute(foo); +callback(f); +``` + +Here, transmute is being used to convert the types of the fn arguments. +This pattern is incorrect because, because the type of `foo` is a function +**item** (`typeof(foo)`), which is zero-sized, and the target type (`fn()`) +is a function pointer, which is not zero-sized. +This pattern should be rewritten. There are a few possible ways to do this: + +- change the original fn declaration to match the expected signature, + and do the cast in the fn body (the prefered option) +- cast the fn item fo a fn pointer before calling transmute, as shown here: + + ``` + let f: extern "C" fn(*mut i32) = transmute(foo as extern "C" fn(_)); + let f: extern "C" fn(*mut i32) = transmute(foo as usize); // works too + ``` + +The same applies to transmutes to `*mut fn()`, which were observedin practice. +Note though that use of this type is generally incorrect. +The intention is typically to describe a function pointer, but just `fn()` +alone suffices for that. `*mut fn()` is a pointer to a fn pointer. +(Since these values are typically just passed to C code, however, this rarely +makes a difference in practice.) + +[rfc401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index f5f1abc4b12a9..b42beb37821ce 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -18,6 +18,7 @@ //! * No CR characters //! * No `TODO` or `XXX` directives //! * A valid license header is at the top +//! * No unexplained ` ```ignore ` or ` ```rust,ignore ` doc tests //! //! A number of these checks can be opted-out of with various directives like //! `// ignore-tidy-linelength`. @@ -38,6 +39,17 @@ http://www.apache.org/licenses/LICENSE-2.0> or the MIT license option. This file may not be copied, modified, or distributed except according to those terms."; +const UNEXPLAINED_IGNORE_DOCTEST_INFO: &str = r#"unexplained "```ignore" doctest; try one: + +* make the test actually pass, by adding necessary imports and declarations, or +* use "```text", if the code is not Rust code, or +* use "```compile_fail,Ennnn", if the code is expected to fail at compile time, or +* use "```should_panic", if the code is expected to fail at run time, or +* use "```no_run", if the code should type-check but not necessary linkable/runnable, or +* explain it like "```ignore (cannot-test-this-because-xxxx)", if the annotation cannot be avoided. + +"#; + /// Parser states for line_is_url. #[derive(PartialEq)] #[allow(non_camel_case_types)] @@ -138,6 +150,9 @@ pub fn check(path: &Path, bad: &mut bool) { err("XXX is deprecated; use FIXME") } } + if line.ends_with("```ignore") || line.ends_with("```rust,ignore") { + err(UNEXPLAINED_IGNORE_DOCTEST_INFO); + } } if !licenseck(file, &contents) { tidy_error!(bad, "{}: incorrect license", file.display());