Auto merge of #37337 - GuillaumeGomez:rollup, r=GuillaumeGomez
Rollup of 10 pull requests - Successful merges: #37043, #37209, #37211, #37219, #37244, #37253, #37286, #37297, #37309, #37314 - Failed merges:
This commit is contained in:
commit
f136e9e299
14 changed files with 263 additions and 133 deletions
|
|
@ -36,8 +36,9 @@ fn main() {
|
|||
let args = env::args_os().skip(1).collect::<Vec<_>>();
|
||||
// Detect whether or not we're a build script depending on whether --target
|
||||
// is passed (a bit janky...)
|
||||
let target = args.windows(2).find(|w| &*w[0] == "--target")
|
||||
.and_then(|w| w[1].to_str());
|
||||
let target = args.windows(2)
|
||||
.find(|w| &*w[0] == "--target")
|
||||
.and_then(|w| w[1].to_str());
|
||||
let version = args.iter().find(|w| &**w == "-vV");
|
||||
|
||||
// Build scripts always use the snapshot compiler which is guaranteed to be
|
||||
|
|
@ -64,9 +65,10 @@ fn main() {
|
|||
|
||||
let mut cmd = Command::new(rustc);
|
||||
cmd.args(&args)
|
||||
.arg("--cfg").arg(format!("stage{}", stage))
|
||||
.env(bootstrap::util::dylib_path_var(),
|
||||
env::join_paths(&dylib_path).unwrap());
|
||||
.arg("--cfg")
|
||||
.arg(format!("stage{}", stage))
|
||||
.env(bootstrap::util::dylib_path_var(),
|
||||
env::join_paths(&dylib_path).unwrap());
|
||||
|
||||
if let Some(target) = target {
|
||||
// The stage0 compiler has a special sysroot distinct from what we
|
||||
|
|
@ -101,9 +103,8 @@ fn main() {
|
|||
// This... is a bit of a hack how we detect this. Ideally this
|
||||
// information should be encoded in the crate I guess? Would likely
|
||||
// require an RFC amendment to RFC 1513, however.
|
||||
let is_panic_abort = args.windows(2).any(|a| {
|
||||
&*a[0] == "--crate-name" && &*a[1] == "panic_abort"
|
||||
});
|
||||
let is_panic_abort = args.windows(2)
|
||||
.any(|a| &*a[0] == "--crate-name" && &*a[1] == "panic_abort");
|
||||
if is_panic_abort {
|
||||
cmd.arg("-C").arg("panic=abort");
|
||||
}
|
||||
|
|
@ -116,7 +117,7 @@ fn main() {
|
|||
cmd.arg("-Cdebuginfo=1");
|
||||
}
|
||||
let debug_assertions = match env::var("RUSTC_DEBUG_ASSERTIONS") {
|
||||
Ok(s) => if s == "true" {"y"} else {"n"},
|
||||
Ok(s) => if s == "true" { "y" } else { "n" },
|
||||
Err(..) => "n",
|
||||
};
|
||||
cmd.arg("-C").arg(format!("debug-assertions={}", debug_assertions));
|
||||
|
|
|
|||
|
|
@ -29,10 +29,12 @@ fn main() {
|
|||
|
||||
let mut cmd = Command::new(rustdoc);
|
||||
cmd.args(&args)
|
||||
.arg("--cfg").arg(format!("stage{}", stage))
|
||||
.arg("--cfg").arg("dox")
|
||||
.env(bootstrap::util::dylib_path_var(),
|
||||
env::join_paths(&dylib_path).unwrap());
|
||||
.arg("--cfg")
|
||||
.arg(format!("stage{}", stage))
|
||||
.arg("--cfg")
|
||||
.arg("dox")
|
||||
.env(bootstrap::util::dylib_path_var(),
|
||||
env::join_paths(&dylib_path).unwrap());
|
||||
std::process::exit(match cmd.status() {
|
||||
Ok(s) => s.code().unwrap_or(1),
|
||||
Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e),
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@ pub fn run_silent(cmd: &mut Command) {
|
|||
};
|
||||
if !status.success() {
|
||||
fail(&format!("command did not execute successfully: {:?}\n\
|
||||
expected success, got: {}", cmd, status));
|
||||
expected success, got: {}",
|
||||
cmd,
|
||||
status));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +67,9 @@ pub fn output(cmd: &mut Command) -> String {
|
|||
};
|
||||
if !output.status.success() {
|
||||
panic!("command did not execute successfully: {:?}\n\
|
||||
expected success, got: {}", cmd, output.status);
|
||||
expected success, got: {}",
|
||||
cmd,
|
||||
output.status);
|
||||
}
|
||||
String::from_utf8(output.stdout).unwrap()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ displaying the message.
|
|||
[expect]: ../std/result/enum.Result.html#method.expect
|
||||
[panic]: error-handling.html
|
||||
|
||||
If we leave off calling this method, our program will compile, but
|
||||
If we do not call `expect()`, our program will compile, but
|
||||
we’ll get a warning:
|
||||
|
||||
```bash
|
||||
|
|
|
|||
|
|
@ -57,11 +57,7 @@ impl<T> RawVec<T> {
|
|||
pub fn new() -> Self {
|
||||
unsafe {
|
||||
// !0 is usize::MAX. This branch should be stripped at compile time.
|
||||
let cap = if mem::size_of::<T>() == 0 {
|
||||
!0
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
|
||||
|
||||
// heap::EMPTY doubles as "unallocated" and "zero-sized allocation"
|
||||
RawVec {
|
||||
|
|
@ -209,11 +205,7 @@ impl<T> RawVec<T> {
|
|||
|
||||
let (new_cap, ptr) = if self.cap == 0 {
|
||||
// skip to 4 because tiny Vec's are dumb; but not if that would cause overflow
|
||||
let new_cap = if elem_size > (!0) / 8 {
|
||||
1
|
||||
} else {
|
||||
4
|
||||
};
|
||||
let new_cap = if elem_size > (!0) / 8 { 1 } else { 4 };
|
||||
let ptr = heap::allocate(new_cap * elem_size, align);
|
||||
(new_cap, ptr)
|
||||
} else {
|
||||
|
|
@ -347,7 +339,7 @@ impl<T> RawVec<T> {
|
|||
let elem_size = mem::size_of::<T>();
|
||||
// Nothing we can really do about these checks :(
|
||||
let required_cap = used_cap.checked_add(needed_extra_cap)
|
||||
.expect("capacity overflow");
|
||||
.expect("capacity overflow");
|
||||
// Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`.
|
||||
let double_cap = self.cap * 2;
|
||||
// `double_cap` guarantees exponential growth.
|
||||
|
|
|
|||
|
|
@ -35,12 +35,8 @@ fn main() {
|
|||
// that the feature set used by std is the same across all
|
||||
// targets, which means we have to build the alloc_jemalloc crate
|
||||
// for targets like emscripten, even if we don't use it.
|
||||
if target.contains("rumprun") ||
|
||||
target.contains("bitrig") ||
|
||||
target.contains("openbsd") ||
|
||||
target.contains("msvc") ||
|
||||
target.contains("emscripten")
|
||||
{
|
||||
if target.contains("rumprun") || target.contains("bitrig") || target.contains("openbsd") ||
|
||||
target.contains("msvc") || target.contains("emscripten") {
|
||||
println!("cargo:rustc-cfg=dummy_jemalloc");
|
||||
return;
|
||||
}
|
||||
|
|
@ -64,16 +60,16 @@ fn main() {
|
|||
// only msvc returns None for ar so unwrap is okay
|
||||
let ar = build_helper::cc2ar(compiler.path(), &target).unwrap();
|
||||
let cflags = compiler.args()
|
||||
.iter()
|
||||
.map(|s| s.to_str().unwrap())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
.iter()
|
||||
.map(|s| s.to_str().unwrap())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ");
|
||||
|
||||
let mut stack = src_dir.join("../jemalloc")
|
||||
.read_dir()
|
||||
.unwrap()
|
||||
.map(|e| e.unwrap())
|
||||
.collect::<Vec<_>>();
|
||||
.read_dir()
|
||||
.unwrap()
|
||||
.map(|e| e.unwrap())
|
||||
.collect::<Vec<_>>();
|
||||
while let Some(entry) = stack.pop() {
|
||||
let path = entry.path();
|
||||
if entry.file_type().unwrap().is_dir() {
|
||||
|
|
@ -155,10 +151,10 @@ fn main() {
|
|||
|
||||
run(&mut cmd);
|
||||
run(Command::new("make")
|
||||
.current_dir(&build_dir)
|
||||
.arg("build_lib_static")
|
||||
.arg("-j")
|
||||
.arg(env::var("NUM_JOBS").expect("NUM_JOBS was not set")));
|
||||
.current_dir(&build_dir)
|
||||
.arg("build_lib_static")
|
||||
.arg("-j")
|
||||
.arg(env::var("NUM_JOBS").expect("NUM_JOBS was not set")));
|
||||
|
||||
if target.contains("windows") {
|
||||
println!("cargo:rustc-link-lib=static=jemalloc");
|
||||
|
|
|
|||
|
|
@ -221,11 +221,7 @@ mod imp {
|
|||
HEAP_REALLOC_IN_PLACE_ONLY,
|
||||
ptr as LPVOID,
|
||||
size as SIZE_T) as *mut u8;
|
||||
if new.is_null() {
|
||||
old_size
|
||||
} else {
|
||||
size
|
||||
}
|
||||
if new.is_null() { old_size } else { size }
|
||||
} else {
|
||||
old_size
|
||||
}
|
||||
|
|
|
|||
|
|
@ -335,9 +335,8 @@ mod tests {
|
|||
|
||||
let arena = Wrap(TypedArena::new());
|
||||
|
||||
let result = arena.alloc_outer(|| {
|
||||
Outer { inner: arena.alloc_inner(|| Inner { value: 10 }) }
|
||||
});
|
||||
let result =
|
||||
arena.alloc_outer(|| Outer { inner: arena.alloc_inner(|| Inner { value: 10 }) });
|
||||
|
||||
assert_eq!(result.inner.value, 10);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@
|
|||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! You can explicitly create a `Vec<T>` with `new()`:
|
||||
//! You can explicitly create a [`Vec<T>`] with [`new()`]:
|
||||
//!
|
||||
//! ```
|
||||
//! let v: Vec<i32> = Vec::new();
|
||||
//! ```
|
||||
//!
|
||||
//! ...or by using the `vec!` macro:
|
||||
//! ...or by using the [`vec!`] macro:
|
||||
//!
|
||||
//! ```
|
||||
//! let v: Vec<i32> = vec![];
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
//! let v = vec![0; 10]; // ten zeroes
|
||||
//! ```
|
||||
//!
|
||||
//! You can `push` values onto the end of a vector (which will grow the vector
|
||||
//! You can [`push`] values onto the end of a vector (which will grow the vector
|
||||
//! as needed):
|
||||
//!
|
||||
//! ```
|
||||
|
|
@ -49,13 +49,20 @@
|
|||
//! let two = v.pop();
|
||||
//! ```
|
||||
//!
|
||||
//! Vectors also support indexing (through the `Index` and `IndexMut` traits):
|
||||
//! Vectors also support indexing (through the [`Index`] and [`IndexMut`] traits):
|
||||
//!
|
||||
//! ```
|
||||
//! let mut v = vec![1, 2, 3];
|
||||
//! let three = v[2];
|
||||
//! v[1] = v[1] + 5;
|
||||
//! ```
|
||||
//!
|
||||
//! [`Vec<T>`]: ../../std/vec/struct.Vec.html
|
||||
//! [`new()`]: ../../std/vec/struct.Vec.html#method.new
|
||||
//! [`push`]: ../../std/vec/struct.Vec.html#method.push
|
||||
//! [`Index`]: ../../std/ops/trait.Index.html
|
||||
//! [`IndexMut`]: ../../std/ops/trait.IndexMut.html
|
||||
//! [`vec!`]: ../../std/macro.vec.html
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
|
|
@ -79,7 +86,7 @@ use core::slice;
|
|||
use super::SpecExtend;
|
||||
use super::range::RangeArgument;
|
||||
|
||||
/// A contiguous growable array type, written `Vec<T>` but pronounced 'vector.'
|
||||
/// A contiguous growable array type, written `Vec<T>` but pronounced 'vector'.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
@ -105,7 +112,7 @@ use super::range::RangeArgument;
|
|||
/// assert_eq!(vec, [7, 1, 2, 3]);
|
||||
/// ```
|
||||
///
|
||||
/// The `vec!` macro is provided to make initialization more convenient:
|
||||
/// The [`vec!`] macro is provided to make initialization more convenient:
|
||||
///
|
||||
/// ```
|
||||
/// let mut vec = vec![1, 2, 3];
|
||||
|
|
@ -137,15 +144,15 @@ use super::range::RangeArgument;
|
|||
///
|
||||
/// # Indexing
|
||||
///
|
||||
/// The Vec type allows to access values by index, because it implements the
|
||||
/// `Index` trait. An example will be more explicit:
|
||||
/// The `Vec` type allows to access values by index, because it implements the
|
||||
/// [`Index`] trait. An example will be more explicit:
|
||||
///
|
||||
/// ```
|
||||
/// let v = vec!(0, 2, 4, 6);
|
||||
/// println!("{}", v[1]); // it will display '2'
|
||||
/// ```
|
||||
///
|
||||
/// However be careful: if you try to access an index which isn't in the Vec,
|
||||
/// 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
|
||||
|
|
@ -158,7 +165,7 @@ use super::range::RangeArgument;
|
|||
///
|
||||
/// # Slicing
|
||||
///
|
||||
/// A Vec can be mutable. Slices, on the other hand, are read-only objects.
|
||||
/// A `Vec` can be mutable. Slices, on the other hand, are read-only objects.
|
||||
/// To get a slice, use "&". Example:
|
||||
///
|
||||
/// ```
|
||||
|
|
@ -175,8 +182,8 @@ use super::range::RangeArgument;
|
|||
/// ```
|
||||
///
|
||||
/// In Rust, it's more common to pass slices as arguments rather than vectors
|
||||
/// when you just want to provide a read access. The same goes for String and
|
||||
/// &str.
|
||||
/// when you just want to provide a read access. The same goes for [`String`] and
|
||||
/// [`&str`].
|
||||
///
|
||||
/// # Capacity and reallocation
|
||||
///
|
||||
|
|
@ -191,7 +198,7 @@ use super::range::RangeArgument;
|
|||
/// with space for 10 more elements. Pushing 10 or fewer elements onto the
|
||||
/// vector will not change its capacity or cause reallocation to occur. However,
|
||||
/// if the vector's length is increased to 11, it will have to reallocate, which
|
||||
/// can be slow. For this reason, it is recommended to use `Vec::with_capacity`
|
||||
/// can be slow. For this reason, it is recommended to use [`Vec::with_capacity`]
|
||||
/// whenever possible to specify how big the vector is expected to get.
|
||||
///
|
||||
/// # Guarantees
|
||||
|
|
@ -209,65 +216,83 @@ use super::range::RangeArgument;
|
|||
/// The pointer will never be null, so this type is null-pointer-optimized.
|
||||
///
|
||||
/// However, the pointer may not actually point to allocated memory. In particular,
|
||||
/// if you construct a Vec with capacity 0 via `Vec::new()`, `vec![]`,
|
||||
/// `Vec::with_capacity(0)`, or by calling `shrink_to_fit()` on an empty Vec, it
|
||||
/// will not allocate memory. Similarly, if you store zero-sized types inside
|
||||
/// a Vec, it will not allocate space for them. *Note that in this case the
|
||||
/// Vec may not report a `capacity()` of 0*. Vec will allocate if and only
|
||||
/// if `mem::size_of::<T>() * capacity() > 0`. In general, Vec's allocation
|
||||
/// if you construct a Vec with capacity 0 via [`Vec::new()`], [`vec![]`][`vec!`],
|
||||
/// [`Vec::with_capacity(0)`][`Vec::with_capacity`], or by calling [`shrink_to_fit()`]
|
||||
/// on an empty Vec, it will not allocate memory. Similarly, if you store zero-sized
|
||||
/// types inside a `Vec`, it will not allocate space for them. *Note that in this case
|
||||
/// the `Vec` may not report a [`capacity()`] of 0*. Vec will allocate if and only
|
||||
/// if [`mem::size_of::<T>()`]` * capacity() > 0`. In general, `Vec`'s allocation
|
||||
/// details are subtle enough that it is strongly recommended that you only
|
||||
/// free memory allocated by a Vec by creating a new Vec and dropping it.
|
||||
///
|
||||
/// If a Vec *has* allocated memory, then the memory it points to is on the heap
|
||||
/// If a `Vec` *has* allocated memory, then the memory it points to is on the heap
|
||||
/// (as defined by the allocator Rust is configured to use by default), and its
|
||||
/// pointer points to `len()` initialized elements in order (what you would see
|
||||
/// if you coerced it to a slice), followed by `capacity() - len()` logically
|
||||
/// uninitialized elements.
|
||||
/// pointer points to [`len()`] initialized elements in order (what you would see
|
||||
/// if you coerced it to a slice), followed by `[capacity()][`capacity()`] -
|
||||
/// [len()][`len()`]` logically uninitialized elements.
|
||||
///
|
||||
/// Vec will never perform a "small optimization" where elements are actually
|
||||
/// `Vec` will never perform a "small optimization" where elements are actually
|
||||
/// stored on the stack for two reasons:
|
||||
///
|
||||
/// * It would make it more difficult for unsafe code to correctly manipulate
|
||||
/// a Vec. The contents of a Vec wouldn't have a stable address if it were
|
||||
/// only moved, and it would be more difficult to determine if a Vec had
|
||||
/// a `Vec`. The contents of a `Vec` wouldn't have a stable address if it were
|
||||
/// only moved, and it would be more difficult to determine if a `Vec` had
|
||||
/// actually allocated memory.
|
||||
///
|
||||
/// * It would penalize the general case, incurring an additional branch
|
||||
/// on every access.
|
||||
///
|
||||
/// Vec will never automatically shrink itself, even if completely empty. This
|
||||
/// ensures no unnecessary allocations or deallocations occur. Emptying a Vec
|
||||
/// and then filling it back up to the same `len()` should incur no calls to
|
||||
/// the allocator. If you wish to free up unused memory, use `shrink_to_fit`.
|
||||
/// `Vec` will never automatically shrink itself, even if completely empty. This
|
||||
/// ensures no unnecessary allocations or deallocations occur. Emptying a `Vec`
|
||||
/// and then filling it back up to the same [`len()`] should incur no calls to
|
||||
/// the allocator. If you wish to free up unused memory, use
|
||||
/// [`shrink_to_fit`][`shrink_to_fit()`].
|
||||
///
|
||||
/// `push` and `insert` will never (re)allocate if the reported capacity is
|
||||
/// sufficient. `push` and `insert` *will* (re)allocate if `len() == capacity()`.
|
||||
/// That is, the reported capacity is completely accurate, and can be relied on.
|
||||
/// It can even be used to manually free the memory allocated by a Vec if
|
||||
/// desired. Bulk insertion methods *may* reallocate, even when not necessary.
|
||||
/// [`push`] and [`insert`] will never (re)allocate if the reported capacity is
|
||||
/// sufficient. [`push`] and [`insert`] *will* (re)allocate if `[len()][`len()`]
|
||||
/// == [capacity()][`capacity()`]`. That is, the reported capacity is completely
|
||||
/// accurate, and can be relied on. It can even be used to manually free the memory
|
||||
/// allocated by a `Vec` if desired. Bulk insertion methods *may* reallocate, even
|
||||
/// when not necessary.
|
||||
///
|
||||
/// Vec does not guarantee any particular growth strategy when reallocating
|
||||
/// when full, nor when `reserve` is called. The current strategy is basic
|
||||
/// `Vec` does not guarantee any particular growth strategy when reallocating
|
||||
/// when full, nor when [`reserve`] is called. The current strategy is basic
|
||||
/// and it may prove desirable to use a non-constant growth factor. Whatever
|
||||
/// strategy is used will of course guarantee `O(1)` amortized `push`.
|
||||
/// strategy is used will of course guarantee `O(1)` amortized [`push`].
|
||||
///
|
||||
/// `vec![x; n]`, `vec![a, b, c, d]`, and `Vec::with_capacity(n)`, will all
|
||||
/// produce a Vec with exactly the requested capacity. If `len() == capacity()`,
|
||||
/// (as is the case for the `vec!` macro), then a `Vec<T>` can be converted
|
||||
/// to and from a `Box<[T]>` without reallocating or moving the elements.
|
||||
/// `vec![x; n]`, `vec![a, b, c, d]`, and
|
||||
/// [`Vec::with_capacity(n)`][`Vec::with_capacity`], will all
|
||||
/// produce a `Vec` with exactly the requested capacity. If `[len()][`len()`] ==
|
||||
/// [capacity()][`capacity()`]`, (as is the case for the [`vec!`] macro), then a
|
||||
/// `Vec<T>` can be converted to and from a [`Box<[T]>`] without reallocating or
|
||||
/// moving the elements.
|
||||
///
|
||||
/// Vec will not specifically overwrite any data that is removed from it,
|
||||
/// `Vec` will not specifically overwrite any data that is removed from it,
|
||||
/// but also won't specifically preserve it. Its uninitialized memory is
|
||||
/// scratch space that it may use however it wants. It will generally just do
|
||||
/// whatever is most efficient or otherwise easy to implement. Do not rely on
|
||||
/// removed data to be erased for security purposes. Even if you drop a Vec, its
|
||||
/// buffer may simply be reused by another Vec. Even if you zero a Vec's memory
|
||||
/// removed data to be erased for security purposes. Even if you drop a `Vec`, its
|
||||
/// buffer may simply be reused by another `Vec`. Even if you zero a `Vec`'s memory
|
||||
/// first, that may not actually happen because the optimizer does not consider
|
||||
/// this a side-effect that must be preserved.
|
||||
///
|
||||
/// Vec does not currently guarantee the order in which elements are dropped
|
||||
/// `Vec` does not currently guarantee the order in which elements are dropped
|
||||
/// (the order has changed in the past, and may change again).
|
||||
///
|
||||
/// [`vec!`]: ../../std/macro.vec.html
|
||||
/// [`Index`]: ../../std/ops/trait.Index.html
|
||||
/// [`String`]: ../../std/string/struct.String.html
|
||||
/// [`&str`]: ../../std/primitive.str.html
|
||||
/// [`Vec::with_capacity`]: ../../std/vec/struct.Vec.html#method.with_capacity
|
||||
/// [`Vec::new()`]: ../../std/vec/struct.Vec.html#method.new
|
||||
/// [`shrink_to_fit()`]: ../../std/vec/struct.Vec.html#method.shrink_to_fit
|
||||
/// [`capacity()`]: ../../std/vec/struct.Vec.html#method.capacity
|
||||
/// [`mem::size_of::<T>()`]: ../../std/mem/fn.size_of.html
|
||||
/// [`len()`]: ../../std/vec/struct.Vec.html#method.len
|
||||
/// [`push`]: ../../std/vec/struct.Vec.html#method.push
|
||||
/// [`insert`]: ../../std/vec/struct.Vec.html#method.insert
|
||||
/// [`reserve`]: ../../std/vec/struct.Vec.html#method.reserve
|
||||
/// [`Box<[T]>`]: ../../std/boxed/struct.Box.html
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Vec<T> {
|
||||
buf: RawVec<T>,
|
||||
|
|
@ -340,7 +365,7 @@ impl<T> Vec<T> {
|
|||
/// This is highly unsafe, due to the number of invariants that aren't
|
||||
/// checked:
|
||||
///
|
||||
/// * `ptr` needs to have been previously allocated via `String`/`Vec<T>`
|
||||
/// * `ptr` needs to have been previously allocated via [`String`]/`Vec<T>`
|
||||
/// (at least, it's highly likely to be incorrect if it wasn't).
|
||||
/// * `length` needs to be less than or equal to `capacity`.
|
||||
/// * `capacity` needs to be the capacity that the pointer was allocated with.
|
||||
|
|
@ -354,6 +379,8 @@ impl<T> Vec<T> {
|
|||
/// that nothing else uses the pointer after calling this
|
||||
/// function.
|
||||
///
|
||||
/// [`String`]: ../../std/string/struct.String.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
|
|
@ -470,11 +497,15 @@ impl<T> Vec<T> {
|
|||
self.buf.shrink_to_fit(self.len);
|
||||
}
|
||||
|
||||
/// Converts the vector into Box<[T]>.
|
||||
/// Converts the vector into [`Box<[T]>`].
|
||||
///
|
||||
/// Note that this will drop any excess capacity. Calling this and
|
||||
/// converting back to a vector with `into_vec()` is equivalent to calling
|
||||
/// `shrink_to_fit()`.
|
||||
/// converting back to a vector with [`into_vec()`] is equivalent to calling
|
||||
/// [`shrink_to_fit()`].
|
||||
///
|
||||
/// [`Box<[T]>`]: ../../std/boxed/struct.Box.html
|
||||
/// [`into_vec()`]: ../../std/primitive.slice.html#method.into_vec
|
||||
/// [`shrink_to_fit()`]: #method.shrink_to_fit
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
@ -673,7 +704,7 @@ impl<T> Vec<T> {
|
|||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `index` is greater than the vector's length.
|
||||
/// Panics if `index` is out of bounds.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
@ -933,9 +964,11 @@ impl<T> Vec<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Removes the last element from a vector and returns it, or `None` if it
|
||||
/// Removes the last element from a vector and returns it, or [`None`] if it
|
||||
/// is empty.
|
||||
///
|
||||
/// [`None`]: ../../std/option/enum.Option.html#variant.None
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
|
|
|
|||
|
|
@ -195,13 +195,9 @@ pub trait Iterator {
|
|||
last
|
||||
}
|
||||
|
||||
/// Consumes the `n` first elements of the iterator, then returns the
|
||||
/// `next()` one.
|
||||
/// Returns the `n`th element of the iterator.
|
||||
///
|
||||
/// This method will evaluate the iterator `n` times, discarding those elements.
|
||||
/// After it does so, it will call [`next()`] and return its value.
|
||||
///
|
||||
/// [`next()`]: #tymethod.next
|
||||
/// Note that all preceding elements will be consumed (i.e. discarded).
|
||||
///
|
||||
/// Like most indexing operations, the count starts from zero, so `nth(0)`
|
||||
/// returns the first value, `nth(1)` the second, and so on.
|
||||
|
|
|
|||
|
|
@ -18,36 +18,50 @@
|
|||
|
||||
// Reexported core operators
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)] pub use marker::{Copy, Send, Sized, Sync};
|
||||
#[doc(no_inline)]
|
||||
pub use marker::{Copy, Send, Sized, Sync};
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)] pub use ops::{Drop, Fn, FnMut, FnOnce};
|
||||
#[doc(no_inline)]
|
||||
pub use ops::{Drop, Fn, FnMut, FnOnce};
|
||||
|
||||
// Reexported functions
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)] pub use mem::drop;
|
||||
#[doc(no_inline)]
|
||||
pub use mem::drop;
|
||||
|
||||
// Reexported types and traits
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)] pub use clone::Clone;
|
||||
#[doc(no_inline)]
|
||||
pub use clone::Clone;
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
|
||||
#[doc(no_inline)]
|
||||
pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)] pub use convert::{AsRef, AsMut, Into, From};
|
||||
#[doc(no_inline)]
|
||||
pub use convert::{AsRef, AsMut, Into, From};
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)] pub use default::Default;
|
||||
#[doc(no_inline)]
|
||||
pub use default::Default;
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)] pub use iter::{Iterator, Extend, IntoIterator};
|
||||
#[doc(no_inline)]
|
||||
pub use iter::{Iterator, Extend, IntoIterator};
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)] pub use iter::{DoubleEndedIterator, ExactSizeIterator};
|
||||
#[doc(no_inline)]
|
||||
pub use iter::{DoubleEndedIterator, ExactSizeIterator};
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)] pub use option::Option::{self, Some, None};
|
||||
#[doc(no_inline)]
|
||||
pub use option::Option::{self, Some, None};
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)] pub use result::Result::{self, Ok, Err};
|
||||
#[doc(no_inline)]
|
||||
pub use result::Result::{self, Ok, Err};
|
||||
|
||||
// Reexported extension traits for primitive types
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)] pub use slice::SliceExt;
|
||||
#[doc(no_inline)]
|
||||
pub use slice::SliceExt;
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)] pub use str::StrExt;
|
||||
#[doc(no_inline)]
|
||||
pub use str::StrExt;
|
||||
#[stable(feature = "core_prelude", since = "1.4.0")]
|
||||
#[doc(no_inline)] pub use char::CharExt;
|
||||
#[doc(no_inline)]
|
||||
pub use char::CharExt;
|
||||
|
|
|
|||
|
|
@ -380,7 +380,7 @@ impl<'g, N: Debug, E: Debug> DepthFirstTraversal<'g, N, E> {
|
|||
graph: graph,
|
||||
stack: vec![],
|
||||
visited: visited,
|
||||
direction: direction
|
||||
direction: direction,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -394,7 +394,7 @@ impl<'g, N: Debug, E: Debug> DepthFirstTraversal<'g, N, E> {
|
|||
graph: graph,
|
||||
stack: vec![start_node],
|
||||
visited: visited,
|
||||
direction: direction
|
||||
direction: direction,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1915,6 +1915,45 @@ More details can be found in [RFC 438].
|
|||
[RFC 438]: https://github.com/rust-lang/rfcs/pull/438
|
||||
"##,
|
||||
|
||||
E0182: r##"
|
||||
You bound an associated type in an expression path which is not
|
||||
allowed.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0182
|
||||
trait Foo {
|
||||
type A;
|
||||
fn bar() -> isize;
|
||||
}
|
||||
|
||||
impl Foo for isize {
|
||||
type A = usize;
|
||||
fn bar() -> isize { 42 }
|
||||
}
|
||||
|
||||
// error: unexpected binding of associated item in expression path
|
||||
let x: isize = Foo::<A=usize>::bar();
|
||||
```
|
||||
|
||||
To give a concrete type when using the Universal Function Call Syntax,
|
||||
use "Type as Trait". Example:
|
||||
|
||||
```
|
||||
trait Foo {
|
||||
type A;
|
||||
fn bar() -> isize;
|
||||
}
|
||||
|
||||
impl Foo for isize {
|
||||
type A = usize;
|
||||
fn bar() -> isize { 42 }
|
||||
}
|
||||
|
||||
let x: isize = <isize as Foo>::bar(); // ok!
|
||||
```
|
||||
"##,
|
||||
|
||||
E0184: r##"
|
||||
Explicitly implementing both Drop and Copy for a type is currently disallowed.
|
||||
This feature can make some sense in theory, but the current implementation is
|
||||
|
|
@ -2752,6 +2791,30 @@ fn main() {
|
|||
```
|
||||
"##,
|
||||
|
||||
E0230: r##"
|
||||
The trait has more type parameters specified than appear in its definition.
|
||||
|
||||
Erroneous example code:
|
||||
|
||||
```compile_fail,E0230
|
||||
#![feature(on_unimplemented)]
|
||||
#[rustc_on_unimplemented = "Trait error on `{Self}` with `<{A},{B},{C}>`"]
|
||||
// error: there is no type parameter C on trait TraitWithThreeParams
|
||||
trait TraitWithThreeParams<A,B>
|
||||
{}
|
||||
```
|
||||
|
||||
Include the correct number of type parameters and the compilation should
|
||||
proceed:
|
||||
|
||||
```
|
||||
#![feature(on_unimplemented)]
|
||||
#[rustc_on_unimplemented = "Trait error on `{Self}` with `<{A},{B},{C}>`"]
|
||||
trait TraitWithThreeParams<A,B,C> // ok!
|
||||
{}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0232: r##"
|
||||
The attribute must have a value. Erroneous code example:
|
||||
|
||||
|
|
@ -3587,6 +3650,44 @@ fn together_we_will_rule_the_galaxy(son: &A<i32>) {} // Ok!
|
|||
```
|
||||
"##,
|
||||
|
||||
E0399: r##"
|
||||
You implemented a trait, overriding one or more of its associated types but did
|
||||
not reimplement its default methods.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail,E0399
|
||||
#![feature(associated_type_defaults)]
|
||||
|
||||
pub trait Foo {
|
||||
type Assoc = u8;
|
||||
fn bar(&self) {}
|
||||
}
|
||||
|
||||
impl Foo for i32 {
|
||||
// error - the following trait items need to be reimplemented as
|
||||
// `Assoc` was overridden: `bar`
|
||||
type Assoc = i32;
|
||||
}
|
||||
```
|
||||
|
||||
To fix this, add an implementation for each default method from the trait:
|
||||
|
||||
```
|
||||
#![feature(associated_type_defaults)]
|
||||
|
||||
pub trait Foo {
|
||||
type Assoc = u8;
|
||||
fn bar(&self) {}
|
||||
}
|
||||
|
||||
impl Foo for i32 {
|
||||
type Assoc = i32;
|
||||
fn bar(&self) {} // ok!
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0439: r##"
|
||||
The length of the platform-intrinsic function `simd_shuffle`
|
||||
wasn't specified. Erroneous code example:
|
||||
|
|
@ -4074,7 +4175,6 @@ register_diagnostics! {
|
|||
// E0168,
|
||||
// E0173, // manual implementations of unboxed closure traits are experimental
|
||||
// E0174,
|
||||
E0182,
|
||||
E0183,
|
||||
// E0187, // can't infer the kind of the closure
|
||||
// E0188, // can not cast an immutable reference to a mutable pointer
|
||||
|
|
@ -4098,7 +4198,6 @@ register_diagnostics! {
|
|||
E0226, // only a single explicit lifetime bound is permitted
|
||||
E0227, // ambiguous lifetime bound, explicit lifetime bound required
|
||||
E0228, // explicit lifetime bound required
|
||||
E0230, // there is no type parameter on trait
|
||||
E0231, // only named substitution parameters are allowed
|
||||
// E0233,
|
||||
// E0234,
|
||||
|
|
@ -4120,8 +4219,6 @@ register_diagnostics! {
|
|||
// E0372, // coherence not object safe
|
||||
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
|
||||
// between structures with the same definition
|
||||
E0399, // trait items need to be implemented because the associated
|
||||
// type `{}` was overridden
|
||||
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
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@
|
|||
|
||||
#![feature(libc)]
|
||||
|
||||
#[crate_id = "check_static_recursion_foreign_helper"]
|
||||
#[crate_type = "lib"]
|
||||
#![crate_name = "check_static_recursion_foreign_helper"]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue