mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
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:
commit
229d0d3266
@ -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());
|
||||
|
@ -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");
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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") &&
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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`.
|
||||
///
|
||||
|
@ -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!!!
|
||||
|
@ -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!
|
||||
/// ```
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
//! ```
|
||||
//!
|
||||
|
@ -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,
|
||||
|
@ -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];
|
||||
///
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
/// // ...
|
||||
/// }
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
/// }
|
||||
/// }
|
||||
|
@ -111,7 +111,7 @@
|
||||
//!
|
||||
//! Output from first example (in `example1.dot`):
|
||||
//!
|
||||
//! ```ignore
|
||||
//! ```dot
|
||||
//! digraph example1 {
|
||||
//! N0[label="N0"];
|
||||
//! N1[label="N1"];
|
||||
|
@ -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
|
||||
```
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
"##,
|
||||
|
@ -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() {}
|
||||
```
|
||||
"##,
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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!
|
||||
```
|
||||
"##,
|
||||
|
@ -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;
|
||||
//!
|
||||
|
@ -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)
|
||||
|
@ -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 = ..;
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -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() {}
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
@ -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
|
||||
|
@ -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!
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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) => {
|
||||
|
@ -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 {
|
||||
|
@ -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 {:?}",
|
||||
|
@ -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" {
|
||||
|
@ -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 `{}`
|
||||
|
@ -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_";
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
|
@ -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::*;
|
||||
//! ```
|
||||
//!
|
||||
|
@ -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;
|
||||
|
@ -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`].
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)?;
|
||||
}
|
||||
|
@ -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;
|
||||
///
|
||||
|
@ -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::*;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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() {}
|
||||
```
|
||||
|
@ -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> {
|
||||
|
@ -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.
|
||||
//! ````
|
||||
|
@ -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,
|
||||
|
@ -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)])
|
||||
/// ```
|
||||
|
@ -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,
|
||||
|
@ -11,5 +11,5 @@
|
||||
fn main () {
|
||||
let foo = 42u32;
|
||||
let _: [u8; foo]; //~ ERROR E0435
|
||||
//~| NOTE non-constant used with constant
|
||||
//~| NOTE non-constant value
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
63
src/test/ui/explain.stdout
Normal file
63
src/test/ui/explain.stdout
Normal 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
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user