Auto merge of #42856 - Mark-Simulacrum:rollup, r=Mark-Simulacrum

Rollup of 8 pull requests

- Successful merges: #42777, #42783, #42787, #42821, #42822, #42825, #42829, #42833
- Failed merges:
This commit is contained in:
bors 2017-06-23 13:46:43 +00:00
commit 229d0d3266
68 changed files with 668 additions and 286 deletions

View File

@ -265,7 +265,7 @@ pub fn compiletest(build: &Build,
let llvm_components = output(Command::new(&llvm_config).arg("--components"));
let llvm_cxxflags = output(Command::new(&llvm_config).arg("--cxxflags"));
cmd.arg("--cc").arg(build.cc(target))
.arg("--cxx").arg(build.cxx(target))
.arg("--cxx").arg(build.cxx(target).unwrap())
.arg("--cflags").arg(build.cflags(target).join(" "))
.arg("--llvm-components").arg(llvm_components.trim())
.arg("--llvm-cxxflags").arg(llvm_cxxflags.trim());

View File

@ -291,7 +291,7 @@ pub fn rustc(build: &Build, target: &str, compiler: &Compiler) {
!target.contains("windows") &&
!target.contains("apple") {
cargo.env("LLVM_STATIC_STDCPP",
compiler_file(build.cxx(target), "libstdc++.a"));
compiler_file(build.cxx(target).unwrap(), "libstdc++.a"));
}
if build.config.llvm_link_shared {
cargo.env("LLVM_LINK_SHARED", "1");

View File

@ -452,6 +452,10 @@ impl Build {
cargo.env(format!("CC_{}", target), self.cc(target))
.env(format!("AR_{}", target), self.ar(target).unwrap()) // only msvc is None
.env(format!("CFLAGS_{}", target), self.cflags(target).join(" "));
if let Ok(cxx) = self.cxx(target) {
cargo.env(format!("CXX_{}", target), cxx);
}
}
if self.config.extended && compiler.is_final_stage(self) {
@ -838,13 +842,13 @@ impl Build {
self.cc[target].1.as_ref().map(|p| &**p)
}
/// Returns the path to the C++ compiler for the target specified, may panic
/// if no C++ compiler was configured for the target.
fn cxx(&self, target: &str) -> &Path {
/// Returns the path to the C++ compiler for the target specified.
fn cxx(&self, target: &str) -> Result<&Path, String> {
match self.cxx.get(target) {
Some(p) => p.path(),
None => panic!("\n\ntarget `{}` is not configured as a host,
only as a target\n\n", target),
Some(p) => Ok(p.path()),
None => Err(format!(
"target `{}` is not configured as a host, only as a target",
target))
}
}

View File

@ -155,7 +155,7 @@ pub fn llvm(build: &Build, target: &str) {
}
let cc = build.cc(target);
let cxx = build.cxx(target);
let cxx = build.cxx(target).unwrap();
// Handle msvc + ninja + ccache specially (this is what the bots use)
if target.contains("msvc") &&

View File

@ -139,7 +139,7 @@ pub fn check(build: &mut Build) {
}
}
for host in build.config.host.iter() {
need_cmd(build.cxx(host).as_ref());
need_cmd(build.cxx(host).unwrap().as_ref());
}
// The msvc hosts don't use jemalloc, turn it off globally to

View File

@ -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<T> {
//! Cons(T, List<T>),
//! # }
//! ```
//!
//! It wouldn't work. This is because the size of a `List` depends on how many

View File

@ -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

View File

@ -244,7 +244,11 @@ impl<T, A: Alloc> RawVec<T, A> {
///
/// # Examples
///
/// ```ignore
/// ```
/// # #![feature(alloc)]
/// # extern crate alloc;
/// # use std::ptr;
/// # use alloc::raw_vec::RawVec;
/// struct MyVec<T> {
/// buf: RawVec<T>,
/// len: usize,
@ -261,6 +265,10 @@ impl<T, A: Alloc> RawVec<T, A> {
/// 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<T, A: Alloc> RawVec<T, A> {
///
/// # Examples
///
/// ```ignore
/// ```
/// # #![feature(alloc)]
/// # extern crate alloc;
/// # use std::ptr;
/// # use alloc::raw_vec::RawVec;
/// struct MyVec<T> {
/// buf: RawVec<T>,
/// len: usize,
/// }
///
/// impl<T> MyVec<T> {
/// impl<T: Clone> MyVec<T> {
/// 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<T, A: Alloc> RawVec<T, A> {
/// }
/// }
/// }
/// # 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 {

View File

@ -273,7 +273,7 @@ struct RcBox<T: ?Sized> {
/// See the [module-level documentation](./index.html) for more details.
///
/// The inherent methods of `Rc` are all associated functions, which means
/// that you have to call them as e.g. [`Rc::get_mut(&value)`][get_mut] instead of
/// that you have to call them as e.g. [`Rc::get_mut(&mut value)`][get_mut] instead of
/// `value.get_mut()`. This avoids conflicts with methods of the inner
/// type `T`.
///

View File

@ -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!!!

View File

@ -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!
/// ```

View File

@ -942,6 +942,13 @@ impl<'b, T: ?Sized> Ref<'b, T> {
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Ref<'b, U>> for Ref<'b, T> {}
#[stable(feature = "std_guard_impls", since = "1.20")]
impl<'a, T: ?Sized + fmt::Display> fmt::Display for Ref<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.value.fmt(f)
}
}
impl<'b, T: ?Sized> RefMut<'b, T> {
/// Make a new `RefMut` for a component of the borrowed data, e.g. an enum
/// variant.
@ -1034,6 +1041,13 @@ impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> {
#[unstable(feature = "coerce_unsized", issue = "27732")]
impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<RefMut<'b, U>> for RefMut<'b, T> {}
#[stable(feature = "std_guard_impls", since = "1.20")]
impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.value.fmt(f)
}
}
/// The core primitive for interior mutability in Rust.
///
/// `UnsafeCell<T>` is a type that wraps some `T` and indicates unsafe interior operations on the

View File

@ -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<I: Iterator> IntoIterator for I
//! ```
//!

View File

@ -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,

View File

@ -328,11 +328,18 @@ pub fn align_of_val<T: ?Sized>(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<T> { /* ... */ }
/// pub struct MyCollection<T> {
/// # data: [T; 1],
/// /* ... */
/// }
/// # impl<T> MyCollection<T> {
/// # fn iter_mut(&mut self) -> &mut [T] { &mut self.data }
/// # fn free_buffer(&mut self) {}
/// # }
///
/// impl<T> Drop for MyCollection<T> {
/// fn drop(&mut self) {
@ -575,7 +582,7 @@ pub fn swap<T>(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<T> { buf: Vec<T> }
///
/// impl<T> Buffer<T> {
@ -645,7 +652,7 @@ pub fn replace<T>(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];
///

View File

@ -38,7 +38,13 @@ pub trait Place<Data: ?Sized> {
///
/// `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<Data: ?Sized> {
/// 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<Data: ?Sized>: Place<Data> {
///
/// `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

View File

@ -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<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
/// 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<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
/// 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 {
/// // ...
/// }

View File

@ -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

View File

@ -408,11 +408,11 @@ impl<T: ?Sized> *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<T: ?Sized> *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);
/// }
/// }

View File

@ -111,7 +111,7 @@
//!
//! Output from first example (in `example1.dot`):
//!
//! ```ignore
//! ```dot
//! digraph example1 {
//! N0[label="N0"];
//! N1[label="N1"];

View File

@ -198,7 +198,12 @@ impl Trait for u8 {
Now, if we have the following code:
```ignore
```compile_fail,E0038
# trait Trait { fn foo<T>(&self, on: T); }
# impl Trait for String { fn foo<T>(&self, on: T) {} }
# impl Trait for u8 { fn foo<T>(&self, on: T) {} }
# impl Trait for bool { fn foo<T>(&self, on: T) {} }
# // etc.
fn call_foo(thing: Box<Trait>) {
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<T>(Vec<T>);
trait MyTransmutableType {
trait MyTransmutableType: Sized {
fn transmute(Vec<Self>) -> Foo<Self>;
}
impl MyTransmutableType for u8 {
fn transmute(x: Foo<u8>) -> Vec<u8> {
transmute(x)
fn transmute(x: Vec<u8>) -> Foo<u8> {
unsafe { transmute(x) }
}
}
impl MyTransmutableType for String {
fn transmute(x: Foo<String>) -> Vec<String> {
transmute(x)
fn transmute(x: Vec<String>) -> Foo<String> {
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: T) where T: Trait<AssociatedType=u32> {
@ -784,7 +798,7 @@ fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
}
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<SomeTrait>) { ... }
```
# trait SomeTrait {}
fn foo(arg: &Box<SomeTrait>) { /* ... */ }
```
You might change it to:
```ignore
fn foo<'a>(arg: &Box<SomeTrait+'a>) { ... }
```
# trait SomeTrait {}
fn foo<'a>(arg: &'a Box<SomeTrait+'a>) { /* ... */ }
```
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<i32>) {
...
/* ... */
}
# 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<i32>) {}
# 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
```

View File

@ -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<Point>;
/// ```compile_fail,E0381
/// # struct Point { x: u32, y: u32 }
/// let mut p: Box<Point>;
/// (*p).x = 22; // not ok, p is uninitialized, can't deref
/// ```
fn check_if_assigned_path_is_moved(&self,

View File

@ -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
"##,

View File

@ -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() {}
```
"##,

View File

@ -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::<String>());
println!("{}", line);
}
}
}
None => {
early_error(output, &format!("no extended information for {}", code));

View File

@ -117,9 +117,9 @@ fn report_format_mismatch(sess: &Session, file: &Path, message: &str) {
debug!("read_file: {}", message);
if sess.opts.debugging_opts.incremental_info {
println!("incremental: ignoring cache artifact `{}`: {}",
file.file_name().unwrap().to_string_lossy(),
message);
eprintln!("incremental: ignoring cache artifact `{}`: {}",
file.file_name().unwrap().to_string_lossy(),
message);
}
}

View File

@ -435,8 +435,8 @@ fn copy_files(target_dir: &Path,
}
if print_stats_on_success {
println!("incremental: session directory: {} files hard-linked", files_linked);
println!("incremental: session directory: {} files copied", files_copied);
eprintln!("incremental: session directory: {} files hard-linked", files_linked);
eprintln!("incremental: session directory: {} files copied", files_copied);
}
Ok(files_linked > 0 || files_copied == 0)

View File

@ -151,8 +151,8 @@ pub fn decode_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
if prev_commandline_args_hash != tcx.sess.opts.dep_tracking_hash() {
if tcx.sess.opts.debugging_opts.incremental_info {
println!("incremental: completely ignoring cache because of \
differing commandline arguments");
eprintln!("incremental: completely ignoring cache because of \
differing commandline arguments");
}
// We can't reuse the cache, purge it.
debug!("decode_dep_graph: differing commandline arg hashes");
@ -309,8 +309,8 @@ fn reconcile_work_products<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
all_files_exist = false;
if tcx.sess.opts.debugging_opts.incremental_info {
println!("incremental: could not find file for up-to-date work product: {}",
path.display());
eprintln!("incremental: could not find file for \
up-to-date work product: {}", path.display());
}
}
}
@ -418,10 +418,10 @@ fn process_edge<'a, 'tcx, 'edges>(
format!("{:?}", blame)
};
println!("incremental: module {:?} is dirty because {:?} \
changed or was removed",
wp_id,
blame_str);
eprintln!("incremental: module {:?} is dirty because {:?} \
changed or was removed",
wp_id,
blame_str);
}
}
}

View File

@ -47,8 +47,8 @@ pub fn save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let query = tcx.dep_graph.query();
if tcx.sess.opts.debugging_opts.incremental_info {
println!("incremental: {} nodes in dep-graph", query.graph.len_nodes());
println!("incremental: {} edges in dep-graph", query.graph.len_edges());
eprintln!("incremental: {} nodes in dep-graph", query.graph.len_nodes());
eprintln!("incremental: {} edges in dep-graph", query.graph.len_edges());
}
let mut hcx = HashContext::new(tcx, incremental_hashes_map);
@ -258,9 +258,9 @@ pub fn encode_dep_graph(tcx: TyCtxt,
graph.encode(encoder)?;
if tcx.sess.opts.debugging_opts.incremental_info {
println!("incremental: {} nodes in reduced dep-graph", graph.nodes.len());
println!("incremental: {} edges in serialized dep-graph", graph.edge_list_data.len());
println!("incremental: {} hashes in serialized dep-graph", graph.hashes.len());
eprintln!("incremental: {} nodes in reduced dep-graph", graph.nodes.len());
eprintln!("incremental: {} edges in serialized dep-graph", graph.edge_list_data.len());
eprintln!("incremental: {} hashes in serialized dep-graph", graph.hashes.len());
}
if tcx.sess.opts.debugging_opts.incremental_dump_hash {

View File

@ -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!
```
"##,

View File

@ -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;
//!

View File

@ -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)

View File

@ -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 = ..;
}
```

View File

@ -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() {}
}
```
"##,

View File

@ -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<MacResult> {
//! unimplemented!()
//! }
//!
//! # fn main() {}
//! ```
//!
//! WARNING: We currently don't check that the registrar function

View File

@ -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!
}

View File

@ -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>(T);
impl<T> Foo<T> {
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 {

View File

@ -325,7 +325,7 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver,
span,
E0435,
"attempt to use a non-constant value in a constant");
err.span_label(span, "non-constant used with constant");
err.span_label(span, "non-constant value");
err
}
ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => {

View File

@ -893,7 +893,7 @@ fn dump_incremental_data(trans: &CrateTranslation) {
ModuleSource::Translated(..) => (),
}
}
println!("incremental: re-using {} out of {} modules", reuse, trans.modules.len());
eprintln!("incremental: re-using {} out of {} modules", reuse, trans.modules.len());
}
struct WorkItem {

View File

@ -1150,9 +1150,9 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
Some(work_product)
} else {
if scx.sess().opts.debugging_opts.incremental_info {
println!("incremental: CGU `{}` invalidated because of \
changed partitioning hash.",
cgu.name());
eprintln!("incremental: CGU `{}` invalidated because of \
changed partitioning hash.",
cgu.name());
}
debug!("trans_reuse_previous_work_products: \
not reusing {:?} because hash changed to {:?}",

View File

@ -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" {

View File

@ -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<T> 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<T>(&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<Foo> } // 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<Foo> 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<T> RangeArgument<T> for T { } // error
fn main() {}
impl<T> 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>(T);
impl<T> ForeignTrait for MyType<T> { } // 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<T> ForeignTrait2<T, MyType<T>> 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<T> ForeignTrait2<MyType<T>, 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<P1, ..., Pm> ForeignTrait<T1, ..., Tn> for T0 { ... }
```
@ -2590,13 +2629,17 @@ fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
To solve this error, please move the type bindings in the type parameter
declaration:
```ignore
```
# struct Bar;
# trait Foo { type A; }
fn baz<I: Foo<A=Bar>>(x: &<I as Foo>::A) {} // ok!
```
Or in the `where` clause:
```ignore
```
# struct Bar;
# trait Foo { type A; }
fn baz<I>(x: &<I as Foo>::A) where I: Foo<A=Bar> {}
```
"##,
@ -2935,12 +2978,19 @@ impl<T, U> CoerceUnsized<MyType<U>> for MyType<T>
[`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<F: Foo>(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
@ -3938,6 +3989,46 @@ let s = Simba { mother: 1, father: 0 }; // ok!
```
"##,
E0562: r##"
Abstract return types (written `impl Trait` for some trait `Trait`) are only
allowed as function return types.
Erroneous code example:
```compile_fail,E0562
#![feature(conservative_impl_trait)]
fn main() {
let count_to_ten: impl Iterator<Item=usize> = 0..10;
// error: `impl Trait` not allowed outside of function and inherent method
// return types
for i in count_to_ten {
println!("{}", i);
}
}
```
Make sure `impl Trait` only appears in return-type position.
```
#![feature(conservative_impl_trait)]
fn count_to_n(n: usize) -> impl Iterator<Item=usize> {
0..n
}
fn main() {
for i in count_to_n(10) { // ok!
println!("{}", i);
}
}
```
See [RFC 1522] for more details.
[RFC 1522]: https://github.com/rust-lang/rfcs/blob/master/text/1522-conservative-impl-trait.md
"##,
E0570: r##"
The requested ABI is unsupported by the current target.
@ -4349,14 +4440,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);
```
"##,
@ -4534,8 +4631,6 @@ register_diagnostics! {
E0436, // functional record update requires a struct
E0521, // redundant default implementations of trait
E0533, // `{}` does not name a unit variant, unit struct or a constant
E0562, // `impl Trait` not allowed outside of function
// and inherent method return types
E0563, // cannot determine a type for this `impl Trait`: {}
E0564, // only named lifetimes are allowed in `impl Trait`,
// but `{}` was found in the type `{}`

View File

@ -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_";

View File

@ -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",

View File

@ -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);

View File

@ -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<usize> {
///
/// 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";

View File

@ -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::*;
//! ```
//!

View File

@ -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;

View File

@ -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`].

View File

@ -440,6 +440,13 @@ impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'a, T> {
}
}
#[stable(feature = "std_guard_impls", since = "1.20")]
impl<'a, T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
(**self).fmt(f)
}
}
pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
&guard.__lock.inner
}

View File

@ -370,6 +370,13 @@ impl<'a, T: fmt::Debug> fmt::Debug for RwLockReadGuard<'a, T> {
}
}
#[stable(feature = "std_guard_impls", since = "1.20")]
impl<'a, T: ?Sized + fmt::Display> fmt::Display for RwLockReadGuard<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
(**self).fmt(f)
}
}
#[stable(feature = "std_debug", since = "1.16.0")]
impl<'a, T: fmt::Debug> fmt::Debug for RwLockWriteGuard<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@ -379,6 +386,13 @@ impl<'a, T: fmt::Debug> fmt::Debug for RwLockWriteGuard<'a, T> {
}
}
#[stable(feature = "std_guard_impls", since = "1.20")]
impl<'a, T: ?Sized + fmt::Display> fmt::Display for RwLockWriteGuard<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
(**self).fmt(f)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'rwlock, T: ?Sized> Deref for RwLockReadGuard<'rwlock, T> {
type Target = T;

View File

@ -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<P: AsRef<Path>, Q: AsRef<Path>>(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);

View File

@ -179,7 +179,7 @@ pub fn getenv(key: &OsStr) -> io::Result<Option<OsString>> {
pub fn setenv(key: &OsStr, value: &OsStr) -> io::Result<()> {
if ! key.is_empty() {
let mut file = ::fs::File::open(&("env:".to_owned() + key.to_str().unwrap()))?;
let mut file = ::fs::File::create(&("env:".to_owned() + key.to_str().unwrap()))?;
file.write_all(value.as_bytes())?;
file.set_len(value.len() as u64)?;
}

View File

@ -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;
///

View File

@ -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::*;

View File

@ -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);

View File

@ -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)
/// <Vec<T> as a::b::Trait>::AssociatedItem
/// ^~~~~ ~~~~~~~~~~~~~~^
/// ty position = 3

View File

@ -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() {}
```

View File

@ -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<U, V> + 'b, 'a : 'b
/// ```
pub fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> {

View File

@ -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.
//! ````

View File

@ -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<S: Encoder<E>, E> Encodable<S, E> 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<T> { node: T, span: Span }
//! ```
//!
//! would yield functions like:
//!
//! ```ignore
//! ```
//! # #[derive(Encodable, Decodable)] struct Span;
//! # struct Spanned<T> { node: T, span: Span }
//! impl<
//! S: Encoder<E>,
//! E,

View File

@ -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<F>(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)])
/// ```

View File

@ -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,

View File

@ -11,5 +11,5 @@
fn main () {
let foo = 42u32;
let _: [u8; foo]; //~ ERROR E0435
//~| NOTE non-constant used with constant
//~| NOTE non-constant value
}

View File

@ -8,12 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Check that non constant exprs fail for vector repeat syntax
// Check that non constant exprs fail for array repeat syntax
fn main() {
fn bar(n: usize) {
let _x = [0; n];
//~^ ERROR attempt to use a non-constant value in a constant [E0435]
//~| NOTE non-constant used with constant
//~| NOTE non-constant value
}
}

View File

@ -1,4 +1,4 @@
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// 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.
//
@ -8,11 +8,4 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Check that non-constant exprs do fail as count in fixed length vec type
fn main() {
fn bar(n: isize) {
let _x: [isize; n];
//~^ ERROR attempt to use a non-constant value in a constant [E0435]
}
}
// compile-flags: --explain E0591

View File

@ -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<i32>) {
/* ... */
}
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

View File

@ -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());