Auto merge of #75538 - tmandry:rollup-i8miv8q, r=tmandry

Rollup of 17 pull requests

Successful merges:

 - #73943 (Document the unsafe keyword)
 - #74062 (deny(unsafe_op_in_unsafe_fn) in libstd/ffi/c_str.rs)
 - #74185 (Remove liballoc unneeded explicit link)
 - #74192 (Improve documentation on process::Child.std* fields)
 - #74409 (Change Debug impl of SocketAddr and IpAddr to match their Display output)
 - #75195 (BTreeMap: purge innocent use of into_kv_mut)
 - #75214 (Use intra-doc links in `mem::manually_drop` & `mem::maybe_uninit`)
 - #75432 (Switch to intra-doc links in `std::process`)
 - #75482 (Clean up E0752 explanation)
 - #75501 (Move to intra doc links in std::ffi)
 - #75509 (Tweak suggestion for `this` -> `self`)
 - #75511 (Do not emit E0228 when it is implied by E0106)
 - #75515 (Bump std's libc version to 0.2.74)
 - #75517 (Promotion and const interning comments)
 - #75519 (BTreeMap: refactor splitpoint and move testing over to unit test)
 - #75530 (Switch to intra-doc links in os/raw/*.md)
 - #75531 (Migrate unit tests of btree collections to their native breeding ground)

Failed merges:

r? @ghost
This commit is contained in:
bors 2020-08-14 22:52:57 +00:00
commit 95879ad961
49 changed files with 725 additions and 567 deletions

View File

@ -245,7 +245,7 @@ where
fn replace(&mut self, key: K) -> Option<K> {
let root = Self::ensure_is_owned(&mut self.root);
match search::search_tree::<marker::Mut<'_>, K, (), K>(root.node_as_mut(), &key) {
Found(handle) => Some(mem::replace(handle.into_kv_mut().0, key)),
Found(handle) => Some(mem::replace(handle.into_key_mut(), key)),
GoDown(handle) => {
VacantEntry { key, handle, length: &mut self.length, _marker: PhantomData }
.insert(());
@ -811,7 +811,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
{
let root_node = self.root.as_mut()?.node_as_mut();
match search::search_tree(root_node, key) {
Found(handle) => Some(handle.into_kv_mut().1),
Found(handle) => Some(handle.into_val_mut()),
GoDown(_) => None,
}
}
@ -2748,7 +2748,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_mut(self) -> &'a mut V {
self.handle.into_kv_mut().1
self.handle.into_val_mut()
}
/// Sets the value of the entry with the `OccupiedEntry`'s key,
@ -3024,3 +3024,6 @@ impl<K: Ord, V, I: Iterator<Item = (K, V)>> Iterator for MergeIter<K, V, I> {
}
}
}
#[cfg(test)]
mod tests;

View File

@ -1,16 +1,20 @@
use std::collections::btree_map::Entry::{Occupied, Vacant};
use std::collections::BTreeMap;
use crate::boxed::Box;
use crate::collections::btree_map::Entry::{Occupied, Vacant};
use crate::collections::BTreeMap;
use crate::fmt::Debug;
use crate::rc::Rc;
use crate::string::String;
use crate::string::ToString;
use crate::vec::Vec;
use std::convert::TryFrom;
use std::fmt::Debug;
use std::iter::FromIterator;
use std::mem;
use std::ops::Bound::{self, Excluded, Included, Unbounded};
use std::ops::RangeBounds;
use std::panic::{catch_unwind, AssertUnwindSafe};
use std::rc::Rc;
use std::sync::atomic::{AtomicUsize, Ordering};
use super::DeterministicRng;
use super::super::DeterministicRng;
// Value of node::CAPACITY, thus capacity of a tree with a single level,
// i.e. a tree who's root is a leaf node at height 0.

View File

@ -25,3 +25,30 @@ pub unsafe fn unwrap_unchecked<T>(val: Option<T>) -> T {
}
})
}
#[cfg(test)]
/// XorShiftRng
struct DeterministicRng {
x: u32,
y: u32,
z: u32,
w: u32,
}
#[cfg(test)]
impl DeterministicRng {
fn new() -> Self {
DeterministicRng { x: 0x193a6754, y: 0xa8a7d469, z: 0x97830e05, w: 0x113ba7bb }
}
fn next(&mut self) -> u32 {
let x = self.x;
let t = x ^ (x << 11);
self.x = self.y;
self.y = self.z;
self.z = self.w;
let w_ = self.w;
self.w = w_ ^ (w_ >> 19) ^ (t ^ (t >> 8));
self.w
}
}

View File

@ -43,6 +43,9 @@ use crate::boxed::Box;
const B: usize = 6;
pub const MIN_LEN: usize = B - 1;
pub const CAPACITY: usize = 2 * B - 1;
const KV_IDX_CENTER: usize = B - 1;
const EDGE_IDX_LEFT_OF_CENTER: usize = B - 1;
const EDGE_IDX_RIGHT_OF_CENTER: usize = B;
/// The underlying representation of leaf nodes.
#[repr(C)]
@ -834,38 +837,12 @@ enum InsertionPlace {
fn splitpoint(edge_idx: usize) -> (usize, InsertionPlace) {
debug_assert!(edge_idx <= CAPACITY);
// Rust issue #74834 tries to explain these symmetric rules.
let middle_kv_idx;
let insertion;
if edge_idx <= B - 2 {
middle_kv_idx = B - 2;
insertion = InsertionPlace::Left(edge_idx);
} else if edge_idx == B - 1 {
middle_kv_idx = B - 1;
insertion = InsertionPlace::Left(edge_idx);
} else if edge_idx == B {
middle_kv_idx = B - 1;
insertion = InsertionPlace::Right(0);
} else {
middle_kv_idx = B;
let new_edge_idx = edge_idx - (B + 1);
insertion = InsertionPlace::Right(new_edge_idx);
match edge_idx {
0..EDGE_IDX_LEFT_OF_CENTER => (KV_IDX_CENTER - 1, InsertionPlace::Left(edge_idx)),
EDGE_IDX_LEFT_OF_CENTER => (KV_IDX_CENTER, InsertionPlace::Left(edge_idx)),
EDGE_IDX_RIGHT_OF_CENTER => (KV_IDX_CENTER, InsertionPlace::Right(0)),
_ => (KV_IDX_CENTER + 1, InsertionPlace::Right(edge_idx - (KV_IDX_CENTER + 1 + 1))),
}
let mut left_len = middle_kv_idx;
let mut right_len = CAPACITY - middle_kv_idx - 1;
match insertion {
InsertionPlace::Left(edge_idx) => {
debug_assert!(edge_idx <= left_len);
left_len += 1;
}
InsertionPlace::Right(edge_idx) => {
debug_assert!(edge_idx <= right_len);
right_len += 1;
}
}
debug_assert!(left_len >= MIN_LEN);
debug_assert!(right_len >= MIN_LEN);
debug_assert!(left_len + right_len == CAPACITY);
(middle_kv_idx, insertion)
}
impl<'a, K, V, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::Edge> {
@ -1067,6 +1044,16 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Immut<'a>, K, V, NodeTyp
}
impl<'a, K: 'a, V: 'a, NodeType> Handle<NodeRef<marker::Mut<'a>, K, V, NodeType>, marker::KV> {
pub fn into_key_mut(self) -> &'a mut K {
let keys = self.node.into_key_slice_mut();
unsafe { keys.get_unchecked_mut(self.idx) }
}
pub fn into_val_mut(self) -> &'a mut V {
let vals = self.node.into_val_slice_mut();
unsafe { vals.get_unchecked_mut(self.idx) }
}
pub fn into_kv_mut(self) -> (&'a mut K, &'a mut V) {
unsafe {
let (keys, vals) = self.node.into_slices_mut();
@ -1261,8 +1248,8 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
unsafe {
let (k, v, edge) = self.reborrow_mut().left_edge().descend().pop();
let k = mem::replace(self.reborrow_mut().into_kv_mut().0, k);
let v = mem::replace(self.reborrow_mut().into_kv_mut().1, v);
let k = mem::replace(self.kv_mut().0, k);
let v = mem::replace(self.kv_mut().1, v);
match self.reborrow_mut().right_edge().descend().force() {
ForceResult::Leaf(mut leaf) => leaf.push_front(k, v),
@ -1278,8 +1265,8 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
unsafe {
let (k, v, edge) = self.reborrow_mut().right_edge().descend().pop_front();
let k = mem::replace(self.reborrow_mut().into_kv_mut().0, k);
let v = mem::replace(self.reborrow_mut().into_kv_mut().1, v);
let k = mem::replace(self.kv_mut().0, k);
let v = mem::replace(self.kv_mut().1, v);
match self.reborrow_mut().left_edge().descend().force() {
ForceResult::Leaf(mut leaf) => leaf.push(k, v),
@ -1307,7 +1294,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
let left_kv = left_node.reborrow_mut().into_kv_pointers_mut();
let right_kv = right_node.reborrow_mut().into_kv_pointers_mut();
let parent_kv = {
let kv = self.reborrow_mut().into_kv_mut();
let kv = self.kv_mut();
(kv.0 as *mut K, kv.1 as *mut V)
};
@ -1364,7 +1351,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
let left_kv = left_node.reborrow_mut().into_kv_pointers_mut();
let right_kv = right_node.reborrow_mut().into_kv_pointers_mut();
let parent_kv = {
let kv = self.reborrow_mut().into_kv_mut();
let kv = self.kv_mut();
(kv.0 as *mut K, kv.1 as *mut V)
};
@ -1590,3 +1577,6 @@ unsafe fn slice_remove<T>(slice: &mut [T], idx: usize) -> T {
ret
}
}
#[cfg(test)]
mod tests;

View File

@ -0,0 +1,25 @@
use super::*;
#[test]
fn test_splitpoint() {
for idx in 0..=CAPACITY {
let (middle_kv_idx, insertion) = splitpoint(idx);
// Simulate performing the split:
let mut left_len = middle_kv_idx;
let mut right_len = CAPACITY - middle_kv_idx - 1;
match insertion {
InsertionPlace::Left(edge_idx) => {
assert!(edge_idx <= left_len);
left_len += 1;
}
InsertionPlace::Right(edge_idx) => {
assert!(edge_idx <= right_len);
right_len += 1;
}
}
assert!(left_len >= MIN_LEN);
assert!(right_len >= MIN_LEN);
assert!(left_len + right_len == CAPACITY);
}
}

View File

@ -1572,3 +1572,6 @@ impl<'a, T: Ord> Iterator for Union<'a, T> {
#[stable(feature = "fused", since = "1.26.0")]
impl<T: Ord> FusedIterator for Union<'_, T> {}
#[cfg(test)]
mod tests;

View File

@ -1,9 +1,10 @@
use std::collections::BTreeSet;
use crate::collections::BTreeSet;
use crate::vec::Vec;
use std::iter::FromIterator;
use std::panic::{catch_unwind, AssertUnwindSafe};
use std::sync::atomic::{AtomicU32, Ordering};
use super::DeterministicRng;
use super::super::DeterministicRng;
#[test]
fn test_clone_eq() {
@ -15,24 +16,6 @@ fn test_clone_eq() {
assert_eq!(m.clone(), m);
}
#[test]
fn test_hash() {
use crate::hash;
let mut x = BTreeSet::new();
let mut y = BTreeSet::new();
x.insert(1);
x.insert(2);
x.insert(3);
y.insert(3);
y.insert(2);
y.insert(1);
assert_eq!(hash(&x), hash(&y));
}
#[test]
fn test_iter_min_max() {
let mut a = BTreeSet::new();

View File

@ -80,6 +80,7 @@
#![feature(arbitrary_self_types)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(btree_drain_filter)]
#![feature(cfg_sanitize)]
#![feature(cfg_target_has_atomic)]
#![feature(coerce_unsized)]
@ -93,6 +94,7 @@
#![feature(container_error_extra)]
#![feature(dropck_eyepatch)]
#![feature(exact_size_is_empty)]
#![feature(exclusive_range_pattern)]
#![feature(extend_one)]
#![feature(fmt_internals)]
#![feature(fn_traits)]
@ -101,6 +103,8 @@
#![feature(lang_items)]
#![feature(layout_for_ptr)]
#![feature(libc)]
#![feature(map_first_last)]
#![feature(map_into_keys_values)]
#![feature(negative_impls)]
#![feature(new_uninit)]
#![feature(nll)]

View File

@ -2620,9 +2620,6 @@ where
///
/// This `struct` is created by the `into_iter` method on [`Vec`] (provided
/// by the [`IntoIterator`] trait).
///
/// [`Vec`]: struct.Vec.html
/// [`IntoIterator`]: ../../std/iter/trait.IntoIterator.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IntoIter<T> {
buf: NonNull<T>,
@ -2802,10 +2799,7 @@ unsafe impl<#[may_dangle] T> Drop for IntoIter<T> {
/// A draining iterator for `Vec<T>`.
///
/// This `struct` is created by the [`drain`] method on [`Vec`].
///
/// [`drain`]: struct.Vec.html#method.drain
/// [`Vec`]: struct.Vec.html
/// This `struct` is created by [`Vec::drain`].
#[stable(feature = "drain", since = "1.6.0")]
pub struct Drain<'a, T: 'a> {
/// Index of tail to preserve
@ -2933,11 +2927,8 @@ impl<T> FusedIterator for Drain<'_, T> {}
/// A splicing iterator for `Vec`.
///
/// This struct is created by the [`splice()`] method on [`Vec`]. See its
/// documentation for more.
///
/// [`splice()`]: struct.Vec.html#method.splice
/// [`Vec`]: struct.Vec.html
/// This struct is created by [`Vec::splice()`].
/// See its documentation for more.
#[derive(Debug)]
#[stable(feature = "vec_splice", since = "1.21.0")]
pub struct Splice<'a, I: Iterator + 'a> {

View File

@ -1,27 +0,0 @@
mod map;
mod set;
/// XorShiftRng
struct DeterministicRng {
x: u32,
y: u32,
z: u32,
w: u32,
}
impl DeterministicRng {
fn new() -> Self {
DeterministicRng { x: 0x193a6754, y: 0xa8a7d469, z: 0x97830e05, w: 0x113ba7bb }
}
fn next(&mut self) -> u32 {
let x = self.x;
let t = x ^ (x << 11);
self.x = self.y;
self.y = self.z;
self.z = self.w;
let w_ = self.w;
self.w = w_ ^ (w_ >> 19) ^ (t ^ (t >> 8));
self.w
}
}

View File

@ -0,0 +1,19 @@
use std::collections::BTreeSet;
#[test]
fn test_hash() {
use crate::hash;
let mut x = BTreeSet::new();
let mut y = BTreeSet::new();
x.insert(1);
x.insert(2);
x.insert(3);
y.insert(3);
y.insert(2);
y.insert(1);
assert_eq!(hash(&x), hash(&y));
}

View File

@ -1,10 +1,7 @@
#![feature(allocator_api)]
#![feature(box_syntax)]
#![feature(btree_drain_filter)]
#![feature(drain_filter)]
#![feature(exact_size_is_empty)]
#![feature(map_first_last)]
#![feature(map_into_keys_values)]
#![feature(new_uninit)]
#![feature(pattern)]
#![feature(str_split_once)]
@ -25,7 +22,7 @@ mod arc;
mod binary_heap;
mod borrow;
mod boxed;
mod btree;
mod btree_set_hash;
mod cow_str;
mod fmt;
mod heap;

View File

@ -56,9 +56,9 @@ use crate::ptr;
/// working with [pinned] data, where reusing the memory without calling the destructor could lead
/// to Undefined Behaviour.
///
/// [`mem::zeroed`]: fn.zeroed.html
/// [`MaybeUninit<T>`]: union.MaybeUninit.html
/// [pinned]: ../pin/index.html
/// [`mem::zeroed`]: crate::mem::zeroed
/// [`MaybeUninit<T>`]: crate::mem::MaybeUninit
/// [pinned]: crate::pin
#[stable(feature = "manually_drop", since = "1.20.0")]
#[lang = "manually_drop"]
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
@ -116,8 +116,6 @@ impl<T> ManuallyDrop<T> {
/// leaving the state of this container unchanged.
/// It is your responsibility to ensure that this `ManuallyDrop` is not used again.
///
/// [`ManuallyDrop::drop`]: #method.drop
/// [`ManuallyDrop::into_inner`]: #method.into_inner
#[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"]
#[stable(feature = "manually_drop_take", since = "1.42.0")]
#[inline]
@ -148,9 +146,7 @@ impl<T: ?Sized> ManuallyDrop<T> {
/// This is normally prevented by the type system, but users of `ManuallyDrop` must
/// uphold those guarantees without assistance from the compiler.
///
/// [`ManuallyDrop::into_inner`]: #method.into_inner
/// [`ptr::drop_in_place`]: ../ptr/fn.drop_in_place.html
/// [pinned]: ../pin/index.html
/// [pinned]: crate::pin
#[stable(feature = "manually_drop", since = "1.20.0")]
#[inline]
pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {

View File

@ -247,7 +247,7 @@ impl<T> MaybeUninit<T> {
/// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
/// It is your responsibility to make sure `T` gets dropped if it got initialized.
///
/// [`assume_init`]: #method.assume_init
/// [`assume_init`]: MaybeUninit::assume_init
#[stable(feature = "maybe_uninit", since = "1.36.0")]
#[rustc_const_stable(feature = "const_maybe_uninit", since = "1.36.0")]
#[inline(always)]
@ -525,7 +525,7 @@ impl<T> MaybeUninit<T> {
/// to ensure that that data may indeed be duplicated.
///
/// [inv]: #initialization-invariant
/// [`assume_init`]: #method.assume_init
/// [`assume_init`]: MaybeUninit::assume_init
///
/// # Examples
///

View File

@ -16,7 +16,7 @@ cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core" }
libc = { version = "0.2.51", default-features = false, features = ['rustc-dep-of-std'] }
libc = { version = "0.2.74", default-features = false, features = ['rustc-dep-of-std'] }
compiler_builtins = { version = "0.1.32" }
profiler_builtins = { path = "../profiler_builtins", optional = true }
unwind = { path = "../unwind" }

View File

@ -1,3 +1,4 @@
#![deny(unsafe_op_in_unsafe_fn)]
use crate::ascii;
use crate::borrow::{Borrow, Cow};
use crate::cmp::Ordering;
@ -35,23 +36,23 @@ use crate::sys;
/// example, you can build a `CString` straight out of a [`String`] or
/// a [`&str`], since both implement that trait).
///
/// The [`new`] method will actually check that the provided `&[u8]`
/// The [`CString::new`] method will actually check that the provided `&[u8]`
/// does not have 0 bytes in the middle, and return an error if it
/// finds one.
///
/// # Extracting a raw pointer to the whole C string
///
/// `CString` implements a [`as_ptr`] method through the [`Deref`]
/// `CString` implements a [`as_ptr`][`CStr::as_ptr`] method through the [`Deref`]
/// trait. This method will give you a `*const c_char` which you can
/// feed directly to extern functions that expect a nul-terminated
/// string, like C's `strdup()`. Notice that [`as_ptr`] returns a
/// string, like C's `strdup()`. Notice that [`as_ptr`][`CStr::as_ptr`] returns a
/// read-only pointer; if the C code writes to it, that causes
/// undefined behavior.
///
/// # Extracting a slice of the whole C string
///
/// Alternatively, you can obtain a `&[`[`u8`]`]` slice from a
/// `CString` with the [`as_bytes`] method. Slices produced in this
/// `CString` with the [`CString::as_bytes`] method. Slices produced in this
/// way do *not* contain the trailing nul terminator. This is useful
/// when you will be calling an extern function that takes a `*const
/// u8` argument which is not necessarily nul-terminated, plus another
@ -60,7 +61,7 @@ use crate::sys;
/// [`len`][slice.len] method.
///
/// If you need a `&[`[`u8`]`]` slice *with* the nul terminator, you
/// can use [`as_bytes_with_nul`] instead.
/// can use [`CString::as_bytes_with_nul`] instead.
///
/// Once you have the kind of slice you need (with or without a nul
/// terminator), you can call the slice's own
@ -68,20 +69,11 @@ use crate::sys;
/// extern functions. See the documentation for that function for a
/// discussion on ensuring the lifetime of the raw pointer.
///
/// [`Into`]: ../convert/trait.Into.html
/// [`Vec`]: ../vec/struct.Vec.html
/// [`String`]: ../string/struct.String.html
/// [`&str`]: ../primitive.str.html
/// [`u8`]: ../primitive.u8.html
/// [`new`]: #method.new
/// [`as_bytes`]: #method.as_bytes
/// [`as_bytes_with_nul`]: #method.as_bytes_with_nul
/// [`as_ptr`]: #method.as_ptr
/// [`&str`]: str
/// [slice.as_ptr]: ../primitive.slice.html#method.as_ptr
/// [slice.len]: ../primitive.slice.html#method.len
/// [`Deref`]: ../ops/trait.Deref.html
/// [`CStr`]: struct.CStr.html
/// [`&CStr`]: struct.CStr.html
/// [`Deref`]: ops::Deref
/// [`&CStr`]: CStr
///
/// # Examples
///
@ -113,7 +105,6 @@ use crate::sys;
/// documentation of `CString` before use, as improper ownership management
/// of `CString` instances can lead to invalid memory accesses, memory leaks,
/// and other memory errors.
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct CString {
@ -137,8 +128,8 @@ pub struct CString {
///
/// Note that this structure is **not** `repr(C)` and is not recommended to be
/// placed in the signatures of FFI functions. Instead, safe wrappers of FFI
/// functions may leverage the unsafe [`from_ptr`] constructor to provide a safe
/// interface to other consumers.
/// functions may leverage the unsafe [`CStr::from_ptr`] constructor to provide
/// a safe interface to other consumers.
///
/// # Examples
///
@ -189,11 +180,7 @@ pub struct CString {
/// println!("string: {}", my_string_safe());
/// ```
///
/// [`u8`]: ../primitive.u8.html
/// [`&str`]: ../primitive.str.html
/// [`String`]: ../string/struct.String.html
/// [`CString`]: struct.CString.html
/// [`from_ptr`]: #method.from_ptr
/// [`&str`]: str
#[derive(Hash)]
#[stable(feature = "rust1", since = "1.0.0")]
// FIXME:
@ -218,9 +205,6 @@ pub struct CStr {
/// This error is created by the [`new`][`CString::new`] method on
/// [`CString`]. See its documentation for more.
///
/// [`CString`]: struct.CString.html
/// [`CString::new`]: struct.CString.html#method.new
///
/// # Examples
///
/// ```
@ -237,12 +221,9 @@ pub struct NulError(usize, Vec<u8>);
/// The slice used to create a [`CStr`] must have one and only one nul byte,
/// positioned at the end.
///
/// This error is created by the [`from_bytes_with_nul`] method on [`CStr`].
/// This error is created by the [`CStr::from_bytes_with_nul`] method.
/// See its documentation for more.
///
/// [`CStr`]: struct.CStr.html
/// [`from_bytes_with_nul`]: struct.CStr.html#method.from_bytes_with_nul
///
/// # Examples
///
/// ```
@ -261,12 +242,9 @@ pub struct FromBytesWithNulError {
/// The vector used to create a [`CString`] must have one and only one nul byte,
/// positioned at the end.
///
/// This error is created by the [`from_vec_with_nul`] method on [`CString`].
/// This error is created by the [`CString::from_vec_with_nul`] method.
/// See its documentation for more.
///
/// [`CString`]: struct.CString.html
/// [`from_vec_with_nul`]: struct.CString.html#method.from_vec_with_nul
///
/// # Examples
///
/// ```
@ -316,8 +294,6 @@ impl FromVecWithNulError {
///
/// assert_eq!(&bytes[..], value.unwrap_err().as_bytes());
/// ```
///
/// [`CString`]: struct.CString.html
pub fn as_bytes(&self) -> &[u8] {
&self.bytes[..]
}
@ -343,8 +319,6 @@ impl FromVecWithNulError {
///
/// assert_eq!(bytes, value.unwrap_err().into_bytes());
/// ```
///
/// [`CString`]: struct.CString.html
pub fn into_bytes(self) -> Vec<u8> {
self.bytes
}
@ -352,17 +326,12 @@ impl FromVecWithNulError {
/// An error indicating invalid UTF-8 when converting a [`CString`] into a [`String`].
///
/// `CString` is just a wrapper over a buffer of bytes with a nul
/// terminator; [`into_string`][`CString::into_string`] performs UTF-8
/// validation on those bytes and may return this error.
/// `CString` is just a wrapper over a buffer of bytes with a nul terminator;
/// [`CString::into_string`] performs UTF-8 validation on those bytes and may
/// return this error.
///
/// This `struct` is created by the
/// [`into_string`][`CString::into_string`] method on [`CString`]. See
/// This `struct` is created by [`CString::into_string()`]. See
/// its documentation for more.
///
/// [`String`]: ../string/struct.String.html
/// [`CString`]: struct.CString.html
/// [`CString::into_string`]: struct.CString.html#method.into_string
#[derive(Clone, PartialEq, Eq, Debug)]
#[stable(feature = "cstring_into", since = "1.7.0")]
pub struct IntoStringError {
@ -398,8 +367,6 @@ impl CString {
/// This function will return an error if the supplied bytes contain an
/// internal 0 byte. The [`NulError`] returned will contain the bytes as well as
/// the position of the nul byte.
///
/// [`NulError`]: struct.NulError.html
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError> {
trait SpecIntoVec {
@ -439,11 +406,9 @@ impl CString {
/// Creates a C-compatible string by consuming a byte vector,
/// without checking for interior 0 bytes.
///
/// This method is equivalent to [`new`] except that no runtime assertion
/// is made that `v` contains no 0 bytes, and it requires an actual
/// byte vector, not anything that can be converted to one with Into.
///
/// [`new`]: #method.new
/// This method is equivalent to [`CString::new`] except that no runtime
/// assertion is made that `v` contains no 0 bytes, and it requires an
/// actual byte vector, not anything that can be converted to one with Into.
///
/// # Examples
///
@ -462,21 +427,22 @@ impl CString {
CString { inner: v.into_boxed_slice() }
}
/// Retakes ownership of a `CString` that was transferred to C via [`into_raw`].
/// Retakes ownership of a `CString` that was transferred to C via
/// [`CString::into_raw`].
///
/// Additionally, the length of the string will be recalculated from the pointer.
///
/// # Safety
///
/// This should only ever be called with a pointer that was earlier
/// obtained by calling [`into_raw`] on a `CString`. Other usage (e.g., trying to take
/// obtained by calling [`CString::into_raw`]. Other usage (e.g., trying to take
/// ownership of a string that was allocated by foreign code) is likely to lead
/// to undefined behavior or allocator corruption.
///
/// It should be noted that the length isn't just "recomputed," but that
/// the recomputed length must match the original length from the
/// [`into_raw`] call. This means the [`into_raw`]/`from_raw` methods
/// should not be used when passing the string to C functions that can
/// [`CString::into_raw`] call. This means the [`CString::into_raw`]/`from_raw`
/// methods should not be used when passing the string to C functions that can
/// modify the string's length.
///
/// > **Note:** If you need to borrow a string that was allocated by
@ -485,9 +451,6 @@ impl CString {
/// > make your own provisions for freeing it appropriately, likely
/// > with the foreign code's API to do that.
///
/// [`into_raw`]: #method.into_raw
/// [`CStr`]: struct.CStr.html
///
/// # Examples
///
/// Creates a `CString`, pass ownership to an `extern` function (via raw pointer), then retake
@ -510,26 +473,31 @@ impl CString {
/// ```
#[stable(feature = "cstr_memory", since = "1.4.0")]
pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
let len = sys::strlen(ptr) + 1; // Including the NUL byte
let slice = slice::from_raw_parts_mut(ptr, len as usize);
CString { inner: Box::from_raw(slice as *mut [c_char] as *mut [u8]) }
// SAFETY: This is called with a pointer that was obtained from a call
// to `CString::into_raw` and the length has not been modified. As such,
// we know there is a NUL byte (and only one) at the end and that the
// information about the size of the allocation is correct on Rust's
// side.
unsafe {
let len = sys::strlen(ptr) + 1; // Including the NUL byte
let slice = slice::from_raw_parts_mut(ptr, len as usize);
CString { inner: Box::from_raw(slice as *mut [c_char] as *mut [u8]) }
}
}
/// Consumes the `CString` and transfers ownership of the string to a C caller.
///
/// The pointer which this function returns must be returned to Rust and reconstituted using
/// [`from_raw`] to be properly deallocated. Specifically, one
/// [`CString::from_raw`] to be properly deallocated. Specifically, one
/// should *not* use the standard C `free()` function to deallocate
/// this string.
///
/// Failure to call [`from_raw`] will lead to a memory leak.
/// Failure to call [`CString::from_raw`] will lead to a memory leak.
///
/// The C side must **not** modify the length of the string (by writing a
/// `NULL` somewhere inside the string or removing the final one) before
/// it makes it back into Rust using [`from_raw`]. See the safety section
/// in [`from_raw`].
///
/// [`from_raw`]: #method.from_raw
/// it makes it back into Rust using [`CString::from_raw`]. See the safety section
/// in [`CString::from_raw`].
///
/// # Examples
///
@ -560,8 +528,6 @@ impl CString {
///
/// On failure, ownership of the original `CString` is returned.
///
/// [`String`]: ../string/struct.String.html
///
/// # Examples
///
/// ```
@ -608,10 +574,8 @@ impl CString {
vec
}
/// Equivalent to the [`into_bytes`] function except that the returned vector
/// includes the trailing nul terminator.
///
/// [`into_bytes`]: #method.into_bytes
/// Equivalent to [`CString::into_bytes()`] except that the
/// returned vector includes the trailing nul terminator.
///
/// # Examples
///
@ -632,9 +596,7 @@ impl CString {
/// The returned slice does **not** contain the trailing nul
/// terminator, and it is guaranteed to not have any interior nul
/// bytes. If you need the nul terminator, use
/// [`as_bytes_with_nul`] instead.
///
/// [`as_bytes_with_nul`]: #method.as_bytes_with_nul
/// [`CString::as_bytes_with_nul`] instead.
///
/// # Examples
///
@ -651,10 +613,8 @@ impl CString {
&self.inner[..self.inner.len() - 1]
}
/// Equivalent to the [`as_bytes`] function except that the returned slice
/// includes the trailing nul terminator.
///
/// [`as_bytes`]: #method.as_bytes
/// Equivalent to [`CString::as_bytes()`] except that the
/// returned slice includes the trailing nul terminator.
///
/// # Examples
///
@ -673,8 +633,6 @@ impl CString {
/// Extracts a [`CStr`] slice containing the entire string.
///
/// [`CStr`]: struct.CStr.html
///
/// # Examples
///
/// ```
@ -693,8 +651,6 @@ impl CString {
/// Converts this `CString` into a boxed [`CStr`].
///
/// [`CStr`]: struct.CStr.html
///
/// # Examples
///
/// ```
@ -711,8 +667,6 @@ impl CString {
}
/// Bypass "move out of struct which implements [`Drop`] trait" restriction.
///
/// [`Drop`]: ../ops/trait.Drop.html
fn into_inner(self) -> Box<[u8]> {
// Rationale: `mem::forget(self)` invalidates the previous call to `ptr::read(&self.inner)`
// so we use `ManuallyDrop` to ensure `self` is not dropped.
@ -722,12 +676,12 @@ impl CString {
unsafe { ptr::read(&this.inner) }
}
/// Converts a `Vec` of `u8` to a `CString` without checking the invariants
/// on the given `Vec`.
/// Converts a [`Vec`]`<u8>` to a [`CString`] without checking the
/// invariants on the given [`Vec`].
///
/// # Safety
///
/// The given `Vec` **must** have one nul byte as its last element.
/// The given [`Vec`] **must** have one nul byte as its last element.
/// This means it cannot be empty nor have any other nul byte anywhere else.
///
/// # Example
@ -745,10 +699,10 @@ impl CString {
Self { inner: v.into_boxed_slice() }
}
/// Attempts to converts a `Vec` of `u8` to a `CString`.
/// Attempts to converts a [`Vec`]`<u8>` to a [`CString`].
///
/// Runtime checks are present to ensure there is only one nul byte in the
/// `Vec`, its last element.
/// [`Vec`], its last element.
///
/// # Errors
///
@ -757,8 +711,8 @@ impl CString {
///
/// # Examples
///
/// A successful conversion will produce the same result as [`new`] when
/// called without the ending nul byte.
/// A successful conversion will produce the same result as [`CString::new`]
/// when called without the ending nul byte.
///
/// ```
/// #![feature(cstring_from_vec_with_nul)]
@ -770,7 +724,7 @@ impl CString {
/// );
/// ```
///
/// A incorrectly formatted vector will produce an error.
/// A incorrectly formatted [`Vec`] will produce an error.
///
/// ```
/// #![feature(cstring_from_vec_with_nul)]
@ -780,8 +734,6 @@ impl CString {
/// // No nul byte
/// let _: FromVecWithNulError = CString::from_vec_with_nul(b"abc".to_vec()).unwrap_err();
/// ```
///
/// [`new`]: #method.new
#[unstable(feature = "cstring_from_vec_with_nul", issue = "73179")]
pub fn from_vec_with_nul(v: Vec<u8>) -> Result<Self, FromVecWithNulError> {
let nul_pos = memchr::memchr(0, &v);
@ -838,9 +790,6 @@ impl From<CString> for Vec<u8> {
/// Converts a [`CString`] into a [`Vec`]`<u8>`.
///
/// The conversion consumes the [`CString`], and removes the terminating NUL byte.
///
/// [`Vec`]: ../vec/struct.Vec.html
/// [`CString`]: ../ffi/struct.CString.html
#[inline]
fn from(s: CString) -> Vec<u8> {
s.into_bytes()
@ -913,9 +862,6 @@ impl From<Cow<'_, CStr>> for Box<CStr> {
#[stable(feature = "c_string_from_box", since = "1.18.0")]
impl From<Box<CStr>> for CString {
/// Converts a [`Box`]`<CStr>` into a [`CString`] without copying or allocating.
///
/// [`Box`]: ../boxed/struct.Box.html
/// [`CString`]: ../ffi/struct.CString.html
#[inline]
fn from(s: Box<CStr>) -> CString {
s.into_c_string()
@ -926,10 +872,6 @@ impl From<Box<CStr>> for CString {
impl From<Vec<NonZeroU8>> for CString {
/// Converts a [`Vec`]`<`[`NonZeroU8`]`>` into a [`CString`] without
/// copying nor checking for inner null bytes.
///
/// [`CString`]: ../ffi/struct.CString.html
/// [`NonZeroU8`]: ../num/struct.NonZeroU8.html
/// [`Vec`]: ../vec/struct.Vec.html
#[inline]
fn from(v: Vec<NonZeroU8>) -> CString {
unsafe {
@ -959,9 +901,6 @@ impl Clone for Box<CStr> {
#[stable(feature = "box_from_c_string", since = "1.20.0")]
impl From<CString> for Box<CStr> {
/// Converts a [`CString`] into a [`Box`]`<CStr>` without copying or allocating.
///
/// [`CString`]: ../ffi/struct.CString.html
/// [`Box`]: ../boxed/struct.Box.html
#[inline]
fn from(s: CString) -> Box<CStr> {
s.into_boxed_c_str()
@ -995,9 +934,6 @@ impl<'a> From<&'a CString> for Cow<'a, CStr> {
#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl From<CString> for Arc<CStr> {
/// Converts a [`CString`] into a [`Arc`]`<CStr>` without copying or allocating.
///
/// [`CString`]: ../ffi/struct.CString.html
/// [`Arc`]: ../sync/struct.Arc.html
#[inline]
fn from(s: CString) -> Arc<CStr> {
let arc: Arc<[u8]> = Arc::from(s.into_inner());
@ -1017,9 +953,6 @@ impl From<&CStr> for Arc<CStr> {
#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl From<CString> for Rc<CStr> {
/// Converts a [`CString`] into a [`Rc`]`<CStr>` without copying or allocating.
///
/// [`CString`]: ../ffi/struct.CString.html
/// [`Rc`]: ../rc/struct.Rc.html
#[inline]
fn from(s: CString) -> Rc<CStr> {
let rc: Rc<[u8]> = Rc::from(s.into_inner());
@ -1048,8 +981,6 @@ impl NulError {
/// Returns the position of the nul byte in the slice that caused
/// [`CString::new`] to fail.
///
/// [`CString::new`]: struct.CString.html#method.new
///
/// # Examples
///
/// ```
@ -1101,9 +1032,6 @@ impl fmt::Display for NulError {
#[stable(feature = "rust1", since = "1.0.0")]
impl From<NulError> for io::Error {
/// Converts a [`NulError`] into a [`io::Error`].
///
/// [`NulError`]: ../ffi/struct.NulError.html
/// [`io::Error`]: ../io/struct.Error.html
fn from(_: NulError) -> io::Error {
io::Error::new(io::ErrorKind::InvalidInput, "data provided contains a nul byte")
}
@ -1154,8 +1082,6 @@ impl fmt::Display for FromVecWithNulError {
impl IntoStringError {
/// Consumes this error, returning original [`CString`] which generated the
/// error.
///
/// [`CString`]: struct.CString.html
#[stable(feature = "cstring_into", since = "1.7.0")]
pub fn into_cstring(self) -> CString {
self.inner
@ -1228,9 +1154,21 @@ impl CStr {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
let len = sys::strlen(ptr);
let ptr = ptr as *const u8;
CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))
// SAFETY: The caller has provided a pointer that points to a valid C
// string with a NUL terminator of size less than `isize::MAX`, whose
// content remain valid and doesn't change for the lifetime of the
// returned `CStr`.
//
// Thus computing the length is fine (a NUL byte exists), the call to
// from_raw_parts is safe because we know the length is at most `isize::MAX`, meaning
// the call to `from_bytes_with_nul_unchecked` is correct.
//
// The cast from c_char to u8 is ok because a c_char is always one byte.
unsafe {
let len = sys::strlen(ptr);
let ptr = ptr as *const u8;
CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))
}
}
/// Creates a C string wrapper from a byte slice.
@ -1299,7 +1237,12 @@ impl CStr {
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
#[rustc_const_unstable(feature = "const_cstr_unchecked", issue = "none")]
pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
&*(bytes as *const [u8] as *const CStr)
// SAFETY: Casting to CStr is safe because its internal representation
// is a [u8] too (safe only inside std).
// Dereferencing the obtained pointer is safe because it comes from a
// reference. Making a reference is then safe because its lifetime
// is bound by the lifetime of the given `bytes`.
unsafe { &*(bytes as *const [u8] as *const CStr) }
}
/// Returns the inner pointer to this C string.
@ -1330,7 +1273,8 @@ impl CStr {
///
/// This happens because the pointer returned by `as_ptr` does not carry any
/// lifetime information and the [`CString`] is deallocated immediately after
/// the `CString::new("Hello").expect("CString::new failed").as_ptr()` expression is evaluated.
/// the `CString::new("Hello").expect("CString::new failed").as_ptr()`
/// expression is evaluated.
/// To fix the problem, bind the `CString` to a local variable:
///
/// ```no_run
@ -1345,10 +1289,8 @@ impl CStr {
/// }
/// ```
///
/// This way, the lifetime of the `CString` in `hello` encompasses
/// This way, the lifetime of the [`CString`] in `hello` encompasses
/// the lifetime of `ptr` and the `unsafe` block.
///
/// [`CString`]: struct.CString.html
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_str_as_ptr", since = "1.32.0")]
@ -1382,15 +1324,13 @@ impl CStr {
/// Converts this C string to a byte slice containing the trailing 0 byte.
///
/// This function is the equivalent of [`to_bytes`] except that it will retain
/// the trailing nul terminator instead of chopping it off.
/// This function is the equivalent of [`CStr::to_bytes`] except that it
/// will retain the trailing nul terminator instead of chopping it off.
///
/// > **Note**: This method is currently implemented as a 0-cost cast, but
/// > it is planned to alter its definition in the future to perform the
/// > length calculation whenever this method is called.
///
/// [`to_bytes`]: #method.to_bytes
///
/// # Examples
///
/// ```
@ -1411,7 +1351,7 @@ impl CStr {
/// function will return the corresponding [`&str`] slice. Otherwise,
/// it will return an error with details of where UTF-8 validation failed.
///
/// [`&str`]: ../primitive.str.html
/// [`&str`]: str
///
/// # Examples
///
@ -1439,12 +1379,9 @@ impl CStr {
/// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD] and return a
/// [`Cow`]`::`[`Owned`]`(`[`String`]`)` with the result.
///
/// [`Cow`]: ../borrow/enum.Cow.html
/// [`Borrowed`]: ../borrow/enum.Cow.html#variant.Borrowed
/// [`Owned`]: ../borrow/enum.Cow.html#variant.Owned
/// [`str`]: ../primitive.str.html
/// [`String`]: ../string/struct.String.html
/// [U+FFFD]: ../char/constant.REPLACEMENT_CHARACTER.html
/// [`Borrowed`]: Cow::Borrowed
/// [`Owned`]: Cow::Owned
/// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER
///
/// # Examples
///
@ -1479,9 +1416,6 @@ impl CStr {
/// Converts a [`Box`]`<CStr>` into a [`CString`] without copying or allocating.
///
/// [`Box`]: ../boxed/struct.Box.html
/// [`CString`]: struct.CString.html
///
/// # Examples
///
/// ```

View File

@ -88,7 +88,7 @@
//! [`env::var_os()`] is used to query environment variables; it
//! returns an [`Option`]`<`[`OsString`]`>`. If the environment variable
//! exists you will get a [`Some`]`(os_string)`, which you can *then* try to
//! convert to a Rust string. This yields a [`Result<>`], so that
//! convert to a Rust string. This yields a [`Result`], so that
//! your code can detect errors in case the environment variable did
//! not in fact contain valid Unicode data.
//!
@ -124,34 +124,22 @@
//! method is an [`OsString`] which can be round-tripped to a Windows
//! string losslessly.
//!
//! [`String`]: ../string/struct.String.html
//! [`str`]: ../primitive.str.html
//! [`char`]: ../primitive.char.html
//! [`u8`]: ../primitive.u8.html
//! [`u16`]: ../primitive.u16.html
//! [Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value
//! [Unicode code point]: http://www.unicode.org/glossary/#code_point
//! [`CString`]: struct.CString.html
//! [`CStr`]: struct.CStr.html
//! [`OsString`]: struct.OsString.html
//! [`OsStr`]: struct.OsStr.html
//! [`env::set_var()`]: ../env/fn.set_var.html
//! [`env::var_os()`]: ../env/fn.var_os.html
//! [`Result<>`]: ../result/enum.Result.html
//! [unix.OsStringExt]: ../os/unix/ffi/trait.OsStringExt.html
//! [`from_vec`]: ../os/unix/ffi/trait.OsStringExt.html#tymethod.from_vec
//! [`into_vec`]: ../os/unix/ffi/trait.OsStringExt.html#tymethod.into_vec
//! [unix.OsStrExt]: ../os/unix/ffi/trait.OsStrExt.html
//! [`from_bytes`]: ../os/unix/ffi/trait.OsStrExt.html#tymethod.from_bytes
//! [`as_bytes`]: ../os/unix/ffi/trait.OsStrExt.html#tymethod.as_bytes
//! [`OsStrExt`]: ../os/unix/ffi/trait.OsStrExt.html
//! [windows.OsStrExt]: ../os/windows/ffi/trait.OsStrExt.html
//! [`encode_wide`]: ../os/windows/ffi/trait.OsStrExt.html#tymethod.encode_wide
//! [`collect`]: ../iter/trait.Iterator.html#method.collect
//! [windows.OsStringExt]: ../os/windows/ffi/trait.OsStringExt.html
//! [`from_wide`]: ../os/windows/ffi/trait.OsStringExt.html#tymethod.from_wide
//! [`Option`]: ../option/enum.Option.html
//! [`Some`]: ../option/enum.Option.html#variant.Some
//! [`env::set_var()`]: crate::env::set_var
//! [`env::var_os()`]: crate::env::var_os
//! [unix.OsStringExt]: crate::os::unix::ffi::OsStringExt
//! [`from_vec`]: crate::os::unix::ffi::OsStringExt::from_vec
//! [`into_vec`]: crate::os::unix::ffi::OsStringExt::into_vec
//! [unix.OsStrExt]: crate::os::unix::ffi::OsStrExt
//! [`from_bytes`]: crate::os::unix::ffi::OsStrExt::from_bytes
//! [`as_bytes`]: crate::os::unix::ffi::OsStrExt::as_bytes
//! [`OsStrExt`]: crate::os::unix::ffi::OsStrExt
//! [windows.OsStrExt]: crate::os::windows::ffi::OsStrExt
//! [`encode_wide`]: crate::os::windows::ffi::OsStrExt::encode_wide
//! [`collect`]: crate::iter::Iterator::collect
//! [windows.OsStringExt]: crate::os::windows::ffi::OsStringExt
//! [`from_wide`]: crate::os::windows::ffi::OsStringExt::from_wide
#![stable(feature = "rust1", since = "1.0.0")]

View File

@ -47,14 +47,14 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
/// create an `OsString` from a normal Rust string.
///
/// **From slices:** Just like you can start with an empty Rust
/// [`String`] and then [`push_str`][String.push_str] `&str`
/// [`String`] and then [`String::push_str`] `&str`
/// sub-string slices into it, you can create an empty `OsString` with
/// the [`new`] method and then push string slices into it with the
/// [`push`] method.
/// the [`OsString::new`] method and then push string slices into it with the
/// [`OsString::push`] method.
///
/// # Extracting a borrowed reference to the whole OS string
///
/// You can use the [`as_os_str`] method to get an `&`[`OsStr`] from
/// You can use the [`OsString::as_os_str`] method to get an `&`[`OsStr`] from
/// an `OsString`; this is effectively a borrowed reference to the
/// whole string.
///
@ -63,18 +63,9 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
/// See the [module's toplevel documentation about conversions][conversions] for a discussion on
/// the traits which `OsString` implements for [conversions] from/to native representations.
///
/// [`OsStr`]: struct.OsStr.html
/// [`&OsStr`]: struct.OsStr.html
/// [`CStr`]: struct.CStr.html
/// [`From`]: ../convert/trait.From.html
/// [`String`]: ../string/struct.String.html
/// [`&str`]: ../primitive.str.html
/// [`u8`]: ../primitive.u8.html
/// [`u16`]: ../primitive.u16.html
/// [String.push_str]: ../string/struct.String.html#method.push_str
/// [`new`]: #method.new
/// [`push`]: #method.push
/// [`as_os_str`]: #method.as_os_str
/// [`&OsStr`]: OsStr
/// [`&str`]: str
/// [`CStr`]: crate::ffi::CStr
/// [conversions]: index.html#conversions
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
@ -93,9 +84,7 @@ pub struct OsString {
/// See the [module's toplevel documentation about conversions][conversions] for a discussion on
/// the traits which `OsStr` implements for [conversions] from/to native representations.
///
/// [`OsString`]: struct.OsString.html
/// [`&str`]: ../primitive.str.html
/// [`String`]: ../string/struct.String.html
/// [`&str`]: str
/// [conversions]: index.html#conversions
#[stable(feature = "rust1", since = "1.0.0")]
// FIXME:
@ -125,8 +114,6 @@ impl OsString {
/// Converts to an [`OsStr`] slice.
///
/// [`OsStr`]: struct.OsStr.html
///
/// # Examples
///
/// ```
@ -145,8 +132,6 @@ impl OsString {
///
/// On failure, ownership of the original `OsString` is returned.
///
/// [`String`]: ../../std/string/struct.String.html
///
/// # Examples
///
/// ```
@ -163,7 +148,7 @@ impl OsString {
/// Extends the string with the given [`&OsStr`] slice.
///
/// [`&OsStr`]: struct.OsStr.html
/// [`&OsStr`]: OsStr
///
/// # Examples
///
@ -333,8 +318,6 @@ impl OsString {
/// Converts this `OsString` into a boxed [`OsStr`].
///
/// [`OsStr`]: struct.OsStr.html
///
/// # Examples
///
/// ```
@ -356,8 +339,6 @@ impl From<String> for OsString {
/// Converts a [`String`] into a [`OsString`].
///
/// The conversion copies the data, and includes an allocation on the heap.
///
/// [`OsString`]: ../../std/ffi/struct.OsString.html
fn from(s: String) -> OsString {
OsString { inner: Buf::from_string(s) }
}
@ -544,7 +525,7 @@ impl OsStr {
///
/// This conversion may entail doing a check for UTF-8 validity.
///
/// [`&str`]: ../../std/primitive.str.html
/// [`&str`]: str
///
/// # Examples
///
@ -564,9 +545,7 @@ impl OsStr {
/// Any non-Unicode sequences are replaced with
/// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD].
///
/// [`Cow`]: ../../std/borrow/enum.Cow.html
/// [`str`]: ../../std/primitive.str.html
/// [U+FFFD]: ../../std/char/constant.REPLACEMENT_CHARACTER.html
/// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER
///
/// # Examples
///
@ -613,8 +592,6 @@ impl OsStr {
/// Copies the slice into an owned [`OsString`].
///
/// [`OsString`]: struct.OsString.html
///
/// # Examples
///
/// ```
@ -662,9 +639,6 @@ impl OsStr {
/// This number is simply useful for passing to other methods, like
/// [`OsString::with_capacity`] to avoid reallocations.
///
/// [`OsString`]: struct.OsString.html
/// [`OsString::with_capacity`]: struct.OsString.html#method.with_capacity
///
/// # Examples
///
/// ```
@ -682,9 +656,6 @@ impl OsStr {
}
/// Converts a [`Box`]`<OsStr>` into an [`OsString`] without copying or allocating.
///
/// [`Box`]: ../boxed/struct.Box.html
/// [`OsString`]: struct.OsString.html
#[stable(feature = "into_boxed_os_str", since = "1.20.0")]
pub fn into_os_string(self: Box<OsStr>) -> OsString {
let boxed = unsafe { Box::from_raw(Box::into_raw(self) as *mut Slice) };
@ -706,9 +677,7 @@ impl OsStr {
/// but non-ASCII letters are unchanged.
///
/// To return a new lowercased value without modifying the existing one, use
/// [`to_ascii_lowercase`].
///
/// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
/// [`OsStr::to_ascii_lowercase`].
///
/// # Examples
///
@ -733,9 +702,7 @@ impl OsStr {
/// but non-ASCII letters are unchanged.
///
/// To return a new uppercased value without modifying the existing one, use
/// [`to_ascii_uppercase`].
///
/// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
/// [`OsStr::to_ascii_uppercase`].
///
/// # Examples
///
@ -760,9 +727,7 @@ impl OsStr {
/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
/// but non-ASCII letters are unchanged.
///
/// To lowercase the value in-place, use [`make_ascii_lowercase`].
///
/// [`make_ascii_lowercase`]: #method.make_ascii_lowercase
/// To lowercase the value in-place, use [`OsStr::make_ascii_lowercase`].
///
/// # Examples
///
@ -784,9 +749,7 @@ impl OsStr {
/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
/// but non-ASCII letters are unchanged.
///
/// To uppercase the value in-place, use [`make_ascii_uppercase`].
///
/// [`make_ascii_uppercase`]: #method.make_ascii_uppercase
/// To uppercase the value in-place, use [`OsStr::make_ascii_uppercase`].
///
/// # Examples
///
@ -865,9 +828,6 @@ impl From<Cow<'_, OsStr>> for Box<OsStr> {
impl From<Box<OsStr>> for OsString {
/// Converts a [`Box`]`<`[`OsStr`]`>` into a `OsString` without copying or
/// allocating.
///
/// [`Box`]: ../boxed/struct.Box.html
/// [`OsStr`]: ../ffi/struct.OsStr.html
fn from(boxed: Box<OsStr>) -> OsString {
boxed.into_os_string()
}
@ -876,9 +836,6 @@ impl From<Box<OsStr>> for OsString {
#[stable(feature = "box_from_os_string", since = "1.20.0")]
impl From<OsString> for Box<OsStr> {
/// Converts a [`OsString`] into a [`Box`]`<OsStr>` without copying or allocating.
///
/// [`Box`]: ../boxed/struct.Box.html
/// [`OsString`]: ../ffi/struct.OsString.html
fn from(s: OsString) -> Box<OsStr> {
s.into_boxed_os_str()
}
@ -895,9 +852,6 @@ impl Clone for Box<OsStr> {
#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl From<OsString> for Arc<OsStr> {
/// Converts a [`OsString`] into a [`Arc`]`<OsStr>` without copying or allocating.
///
/// [`Arc`]: ../sync/struct.Arc.html
/// [`OsString`]: ../ffi/struct.OsString.html
#[inline]
fn from(s: OsString) -> Arc<OsStr> {
let arc = s.inner.into_arc();
@ -917,9 +871,6 @@ impl From<&OsStr> for Arc<OsStr> {
#[stable(feature = "shared_from_slice2", since = "1.24.0")]
impl From<OsString> for Rc<OsStr> {
/// Converts a [`OsString`] into a [`Rc`]`<OsStr>` without copying or allocating.
///
/// [`Rc`]: ../rc/struct.Rc.html
/// [`OsString`]: ../ffi/struct.OsString.html
#[inline]
fn from(s: OsString) -> Rc<OsStr> {
let rc = s.inner.into_rc();

View File

@ -1813,12 +1813,190 @@ mod type_keyword {}
#[doc(keyword = "unsafe")]
//
/// Code or interfaces whose [memory safety] cannot be verified by the type system.
/// Code or interfaces whose [memory safety] cannot be verified by the type
/// system.
///
/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
/// The `unsafe` keyword has two uses: to declare the existence of contracts the
/// compiler can't check (`unsafe fn` and `unsafe trait`), and to declare that a
/// programmer has checked that these contracts have been upheld (`unsafe {}`
/// and `unsafe impl`, but also `unsafe fn` -- see below). They are not mutually
/// exclusive, as can be seen in `unsafe fn`.
///
/// # Unsafe abilities
///
/// **No matter what, Safe Rust can't cause Undefined Behavior**. This is
/// referred to as [soundness]: a well-typed program actually has the desired
/// properties. The [Nomicon][nomicon-soundness] has a more detailed explanation
/// on the subject.
///
/// To ensure soundness, Safe Rust is restricted enough that it can be
/// automatically checked. Sometimes, however, it is necessary to write code
/// that is correct for reasons which are too clever for the compiler to
/// understand. In those cases, you need to use Unsafe Rust.
///
/// Here are the abilities Unsafe Rust has in addition to Safe Rust:
///
/// - Dereference [raw pointers]
/// - Implement `unsafe` [`trait`]s
/// - Call `unsafe` functions
/// - Mutate [`static`]s (including [`extern`]al ones)
/// - Access fields of [`union`]s
///
/// However, this extra power comes with extra responsibilities: it is now up to
/// you to ensure soundness. The `unsafe` keyword helps by clearly marking the
/// pieces of code that need to worry about this.
///
/// ## The different meanings of `unsafe`
///
/// Not all uses of `unsafe` are equivalent: some are here to mark the existence
/// of a contract the programmer must check, others are to say "I have checked
/// the contract, go ahead and do this". The following
/// [discussion on Rust Internals] has more in-depth explanations about this but
/// here is a summary of the main points:
///
/// - `unsafe fn`: calling this function means abiding by a contract the
/// compiler cannot enforce.
/// - `unsafe trait`: implementing the [`trait`] means abiding by a
/// contract the compiler cannot enforce.
/// - `unsafe {}`: the contract necessary to call the operations inside the
/// block has been checked by the programmer and is guaranteed to be respected.
/// - `unsafe impl`: the contract necessary to implement the trait has been
/// checked by the programmer and is guaranteed to be respected.
///
/// `unsafe fn` also acts like an `unsafe {}` block
/// around the code inside the function. This means it is not just a signal to
/// the caller, but also promises that the preconditions for the operations
/// inside the function are upheld. Mixing these two meanings can be confusing
/// and [proposal]s exist to use `unsafe {}` blocks inside such functions when
/// making `unsafe` operations.
///
/// See the [Rustnomicon] and the [Reference] for more informations.
///
/// # Examples
///
/// ## Marking elements as `unsafe`
///
/// `unsafe` can be used on functions. Note that functions and statics declared
/// in [`extern`] blocks are implicitly marked as `unsafe` (but not functions
/// declared as `extern "something" fn ...`). Mutable statics are always unsafe,
/// wherever they are declared. Methods can also be declared as `unsafe`:
///
/// ```rust
/// # #![allow(dead_code)]
/// static mut FOO: &str = "hello";
///
/// unsafe fn unsafe_fn() {}
///
/// extern "C" {
/// fn unsafe_extern_fn();
/// static BAR: *mut u32;
/// }
///
/// trait SafeTraitWithUnsafeMethod {
/// unsafe fn unsafe_method(&self);
/// }
///
/// struct S;
///
/// impl S {
/// unsafe fn unsafe_method_on_struct() {}
/// }
/// ```
///
/// Traits can also be declared as `unsafe`:
///
/// ```rust
/// unsafe trait UnsafeTrait {}
/// ```
///
/// Since `unsafe fn` and `unsafe trait` indicate that there is a safety
/// contract that the compiler cannot enforce, documenting it is important. The
/// standard library has many examples of this, like the following which is an
/// extract from [`Vec::set_len`]. The `# Safety` section explains the contract
/// that must be fulfilled to safely call the function.
///
/// ```rust,ignore (stub-to-show-doc-example)
/// /// Forces the length of the vector to `new_len`.
/// ///
/// /// This is a low-level operation that maintains none of the normal
/// /// invariants of the type. Normally changing the length of a vector
/// /// is done using one of the safe operations instead, such as
/// /// `truncate`, `resize`, `extend`, or `clear`.
/// ///
/// /// # Safety
/// ///
/// /// - `new_len` must be less than or equal to `capacity()`.
/// /// - The elements at `old_len..new_len` must be initialized.
/// pub unsafe fn set_len(&mut self, new_len: usize)
/// ```
///
/// ## Using `unsafe {}` blocks and `impl`s
///
/// Performing `unsafe` operations requires an `unsafe {}` block:
///
/// ```rust
/// # #![allow(dead_code)]
/// /// Dereference the given pointer.
/// ///
/// /// # Safety
/// ///
/// /// `ptr` must be aligned and must not be dangling.
/// unsafe fn deref_unchecked(ptr: *const i32) -> i32 {
/// *ptr
/// }
///
/// let a = 3;
/// let b = &a as *const _;
/// // SAFETY: `a` has not been dropped and references are always aligned,
/// // so `b` is a valid address.
/// unsafe { assert_eq!(*b, deref_unchecked(b)); };
/// ```
///
/// Traits marked as `unsafe` must be [`impl`]emented using `unsafe impl`. This
/// makes a guarantee to other `unsafe` code that the implementation satisfies
/// the trait's safety contract. The [Send] and [Sync] traits are examples of
/// this behaviour in the standard library.
///
/// ```rust
/// /// Implementors of this trait must guarantee an element is always
/// /// accessible with index 3.
/// unsafe trait ThreeIndexable<T> {
/// /// Returns a reference to the element with index 3 in `&self`.
/// fn three(&self) -> &T;
/// }
///
/// // The implementation of `ThreeIndexable` for `[T; 4]` is `unsafe`
/// // because the implementor must abide by a contract the compiler cannot
/// // check but as a programmer we know there will always be a valid element
/// // at index 3 to access.
/// unsafe impl<T> ThreeIndexable<T> for [T; 4] {
/// fn three(&self) -> &T {
/// // SAFETY: implementing the trait means there always is an element
/// // with index 3 accessible.
/// unsafe { self.get_unchecked(3) }
/// }
/// }
///
/// let a = [1, 2, 4, 8];
/// assert_eq!(a.three(), &8);
/// ```
///
/// [`extern`]: keyword.extern.html
/// [`trait`]: keyword.trait.html
/// [`static`]: keyword.static.html
/// [`union`]: keyword.union.html
/// [`impl`]: keyword.impl.html
/// [Send]: marker/trait.Send.html
/// [Sync]: marker/trait.Sync.html
/// [`Vec::set_len`]: vec/struct.Vec.html#method.set_len
/// [raw pointers]: ../reference/types/pointer.html
/// [memory safety]: ../book/ch19-01-unsafe-rust.html
/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
/// [Rustnomicon]: ../nomicon/index.html
/// [nomicon-soundness]: ../nomicon/safe-unsafe-meaning.html
/// [soundness]: https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#soundness-of-code--of-a-library
/// [Reference]: ../reference/unsafety.html
/// [proposal]: https://github.com/rust-lang/rfcs/pull/2585
/// [discussion on Rust Internals]: https://internals.rust-lang.org/t/what-does-unsafe-mean/6696
mod unsafe_keyword {}
#[doc(keyword = "use")]

View File

@ -37,7 +37,7 @@ use crate::vec;
/// assert_eq!(socket.port(), 8080);
/// assert_eq!(socket.is_ipv4(), true);
/// ```
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[stable(feature = "rust1", since = "1.0.0")]
pub enum SocketAddr {
/// An IPv4 socket address.
@ -597,6 +597,13 @@ impl fmt::Display for SocketAddr {
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for SocketAddr {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, fmt)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Display for SocketAddrV4 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

View File

@ -40,7 +40,7 @@ use crate::sys_common::{AsInner, FromInner};
/// assert_eq!(localhost_v4.is_ipv4(), true);
/// ```
#[stable(feature = "ip_addr", since = "1.7.0")]
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
pub enum IpAddr {
/// An IPv4 address.
#[stable(feature = "ip_addr", since = "1.7.0")]
@ -802,6 +802,13 @@ impl fmt::Display for IpAddr {
}
}
#[stable(feature = "ip_addr", since = "1.7.0")]
impl fmt::Debug for IpAddr {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, fmt)
}
}
#[stable(feature = "ip_from_ip", since = "1.16.0")]
impl From<Ipv4Addr> for IpAddr {
/// Copies this address to a new `IpAddr::V4`.

View File

@ -5,7 +5,5 @@ Equivalent to C's `char` type.
C chars are most commonly used to make C strings. Unlike Rust, where the length of a string is included alongside the string, C strings mark the end of a string with the character `'\0'`. See [`CStr`] for more information.
[C's `char` type]: https://en.wikipedia.org/wiki/C_data_types#Basic_types
[Rust's `char` type]: ../../primitive.char.html
[`CStr`]: ../../ffi/struct.CStr.html
[`i8`]: ../../primitive.i8.html
[`u8`]: ../../primitive.u8.html
[Rust's `char` type]: char
[`CStr`]: crate::ffi::CStr

View File

@ -3,5 +3,4 @@ Equivalent to C's `double` type.
This type will almost always be [`f64`], which is guaranteed to be an [IEEE-754 double-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number with at least the precision of a [`float`], and it may be `f32` or something entirely different from the IEEE-754 standard.
[IEEE-754 double-precision float]: https://en.wikipedia.org/wiki/IEEE_754
[`float`]: type.c_float.html
[`f64`]: ../../primitive.f64.html
[`float`]: c_float

View File

@ -3,4 +3,3 @@ Equivalent to C's `float` type.
This type will almost always be [`f32`], which is guaranteed to be an [IEEE-754 single-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number, and it may have less precision than `f32` or not follow the IEEE-754 standard at all.
[IEEE-754 single-precision float]: https://en.wikipedia.org/wiki/IEEE_754
[`f32`]: ../../primitive.f32.html

View File

@ -2,6 +2,4 @@ Equivalent to C's `signed int` (`int`) type.
This type will almost always be [`i32`], but may differ on some esoteric systems. The C standard technically only requires that this type be a signed integer that is at least the size of a [`short`]; some systems define it as an [`i16`], for example.
[`short`]: type.c_short.html
[`i32`]: ../../primitive.i32.html
[`i16`]: ../../primitive.i16.html
[`short`]: c_short

View File

@ -2,6 +2,4 @@ Equivalent to C's `signed long` (`long`) type.
This type will always be [`i32`] or [`i64`]. Most notably, many Linux-based systems assume an `i64`, but Windows assumes `i32`. The C standard technically only requires that this type be a signed integer that is at least 32 bits and at least the size of an [`int`], although in practice, no system would have a `long` that is neither an `i32` nor `i64`.
[`int`]: type.c_int.html
[`i32`]: ../../primitive.i32.html
[`i64`]: ../../primitive.i64.html
[`int`]: c_int

View File

@ -2,6 +2,4 @@ Equivalent to C's `signed long long` (`long long`) type.
This type will almost always be [`i64`], but may differ on some systems. The C standard technically only requires that this type be a signed integer that is at least 64 bits and at least the size of a [`long`], although in practice, no system would have a `long long` that is not an `i64`, as most systems do not have a standardised [`i128`] type.
[`long`]: type.c_int.html
[`i64`]: ../../primitive.i64.html
[`i128`]: ../../primitive.i128.html
[`long`]: c_int

View File

@ -2,5 +2,4 @@ Equivalent to C's `signed char` type.
This type will always be [`i8`], but is included for completeness. It is defined as being a signed integer the same size as a C [`char`].
[`char`]: type.c_char.html
[`i8`]: ../../primitive.i8.html
[`char`]: c_char

View File

@ -2,5 +2,4 @@ Equivalent to C's `signed short` (`short`) type.
This type will almost always be [`i16`], but may differ on some esoteric systems. The C standard technically only requires that this type be a signed integer with at least 16 bits; some systems may define it as `i32`, for example.
[`char`]: type.c_char.html
[`i16`]: ../../primitive.i16.html
[`char`]: c_char

View File

@ -2,5 +2,4 @@ Equivalent to C's `unsigned char` type.
This type will always be [`u8`], but is included for completeness. It is defined as being an unsigned integer the same size as a C [`char`].
[`char`]: type.c_char.html
[`u8`]: ../../primitive.u8.html
[`char`]: c_char

View File

@ -2,6 +2,4 @@ Equivalent to C's `unsigned int` type.
This type will almost always be [`u32`], but may differ on some esoteric systems. The C standard technically only requires that this type be an unsigned integer with the same size as an [`int`]; some systems define it as a [`u16`], for example.
[`int`]: type.c_int.html
[`u32`]: ../../primitive.u32.html
[`u16`]: ../../primitive.u16.html
[`int`]: c_int

View File

@ -2,6 +2,4 @@ Equivalent to C's `unsigned long` type.
This type will always be [`u32`] or [`u64`]. Most notably, many Linux-based systems assume an `u64`, but Windows assumes `u32`. The C standard technically only requires that this type be an unsigned integer with the size of a [`long`], although in practice, no system would have a `ulong` that is neither a `u32` nor `u64`.
[`long`]: type.c_long.html
[`u32`]: ../../primitive.u32.html
[`u64`]: ../../primitive.u64.html
[`long`]: c_long

View File

@ -2,6 +2,4 @@ Equivalent to C's `unsigned long long` type.
This type will almost always be [`u64`], but may differ on some systems. The C standard technically only requires that this type be an unsigned integer with the size of a [`long long`], although in practice, no system would have a `long long` that is not a `u64`, as most systems do not have a standardised [`u128`] type.
[`long long`]: type.c_longlong.html
[`u64`]: ../../primitive.u64.html
[`u128`]: ../../primitive.u128.html
[`long long`]: c_longlong

View File

@ -2,5 +2,4 @@ Equivalent to C's `unsigned short` type.
This type will almost always be [`u16`], but may differ on some esoteric systems. The C standard technically only requires that this type be an unsigned integer with the same size as a [`short`].
[`short`]: type.c_short.html
[`u16`]: ../../primitive.u16.html
[`short`]: c_short

View File

@ -84,25 +84,15 @@
//! assert_eq!(b"test", output.stdout.as_slice());
//! ```
//!
//! [`abort`]: fn.abort.html
//! [`exit`]: fn.exit.html
//! [`spawn`]: Command::spawn
//! [`output`]: Command::output
//!
//! [`Command`]: struct.Command.html
//! [`spawn`]: struct.Command.html#method.spawn
//! [`output`]: struct.Command.html#method.output
//! [`stdout`]: Command::stdout
//! [`stdin`]: Command::stdin
//! [`stderr`]: Command::stderr
//!
//! [`Child`]: struct.Child.html
//! [`ChildStdin`]: struct.ChildStdin.html
//! [`ChildStdout`]: struct.ChildStdout.html
//! [`ChildStderr`]: struct.ChildStderr.html
//! [`Stdio`]: struct.Stdio.html
//!
//! [`stdout`]: struct.Command.html#method.stdout
//! [`stdin`]: struct.Command.html#method.stdin
//! [`stderr`]: struct.Command.html#method.stderr
//!
//! [`Write`]: ../io/trait.Write.html
//! [`Read`]: ../io/trait.Read.html
//! [`Write`]: io::Write
//! [`Read`]: io::Read
#![stable(feature = "process", since = "1.0.0")]
@ -130,7 +120,7 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
/// run, even after the `Child` handle to the child process has gone out of
/// scope.
///
/// Calling [`wait`](#method.wait) (or other functions that wrap around it) will make
/// Calling [`wait`] (or other functions that wrap around it) will make
/// the parent process wait until the child has actually exited before
/// continuing.
///
@ -162,25 +152,44 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
/// assert!(ecode.success());
/// ```
///
/// [`Command`]: struct.Command.html
/// [`Drop`]: ../../core/ops/trait.Drop.html
/// [`wait`]: #method.wait
/// [`wait`]: Child::wait
#[stable(feature = "process", since = "1.0.0")]
pub struct Child {
handle: imp::Process,
/// The handle for writing to the child's standard input (stdin), if it has
/// been captured.
/// been captured. To avoid partially moving
/// the `child` and thus blocking yourself from calling
/// functions on `child` while using `stdin`,
/// you might find it helpful:
///
/// ```compile_fail,E0425
/// let stdin = child.stdin.take().unwrap();
/// ```
#[stable(feature = "process", since = "1.0.0")]
pub stdin: Option<ChildStdin>,
/// The handle for reading from the child's standard output (stdout), if it
/// has been captured.
/// has been captured. You might find it helpful to do
///
/// ```compile_fail,E0425
/// let stdout = child.stdout.take().unwrap();
/// ```
///
/// to avoid partially moving the `child` and thus blocking yourself from calling
/// functions on `child` while using `stdout`.
#[stable(feature = "process", since = "1.0.0")]
pub stdout: Option<ChildStdout>,
/// The handle for reading from the child's standard error (stderr), if it
/// has been captured.
/// has been captured. You might find it helpful to do
///
/// ```compile_fail,E0425
/// let stderr = child.stderr.take().unwrap();
/// ```
///
/// to avoid partially moving the `child` and thus blocking yourself from calling
/// functions on `child` while using `stderr`.
#[stable(feature = "process", since = "1.0.0")]
pub stderr: Option<ChildStderr>,
}
@ -227,9 +236,8 @@ impl fmt::Debug for Child {
/// file handle will be closed. If the child process was blocked on input prior
/// to being dropped, it will become unblocked after dropping.
///
/// [`Child`]: struct.Child.html
/// [`stdin`]: struct.Child.html#structfield.stdin
/// [dropped]: ../ops/trait.Drop.html
/// [`stdin`]: Child::stdin
/// [dropped]: Drop
#[stable(feature = "process", since = "1.0.0")]
pub struct ChildStdin {
inner: AnonPipe,
@ -286,9 +294,8 @@ impl fmt::Debug for ChildStdin {
/// When an instance of `ChildStdout` is [dropped], the `ChildStdout`'s
/// underlying file handle will be closed.
///
/// [`Child`]: struct.Child.html
/// [`stdout`]: struct.Child.html#structfield.stdout
/// [dropped]: ../ops/trait.Drop.html
/// [`stdout`]: Child::stdout
/// [dropped]: Drop
#[stable(feature = "process", since = "1.0.0")]
pub struct ChildStdout {
inner: AnonPipe,
@ -347,9 +354,8 @@ impl fmt::Debug for ChildStdout {
/// When an instance of `ChildStderr` is [dropped], the `ChildStderr`'s
/// underlying file handle will be closed.
///
/// [`Child`]: struct.Child.html
/// [`stderr`]: struct.Child.html#structfield.stderr
/// [dropped]: ../ops/trait.Drop.html
/// [`stderr`]: Child::stderr
/// [dropped]: Drop
#[stable(feature = "process", since = "1.0.0")]
pub struct ChildStderr {
inner: AnonPipe,
@ -522,7 +528,7 @@ impl Command {
///
/// To pass multiple arguments see [`args`].
///
/// [`args`]: #method.args
/// [`args`]: Command::args
///
/// # Examples
///
@ -547,7 +553,7 @@ impl Command {
///
/// To pass a single argument see [`arg`].
///
/// [`arg`]: #method.arg
/// [`arg`]: Command::arg
///
/// # Examples
///
@ -700,7 +706,7 @@ impl Command {
/// .expect("ls command failed to start");
/// ```
///
/// [`canonicalize`]: ../fs/fn.canonicalize.html
/// [`canonicalize`]: crate::fs::canonicalize
#[stable(feature = "process", since = "1.0.0")]
pub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command {
self.inner.cwd(dir.as_ref().as_ref());
@ -712,8 +718,8 @@ impl Command {
/// Defaults to [`inherit`] when used with `spawn` or `status`, and
/// defaults to [`piped`] when used with `output`.
///
/// [`inherit`]: struct.Stdio.html#method.inherit
/// [`piped`]: struct.Stdio.html#method.piped
/// [`inherit`]: Stdio::inherit
/// [`piped`]: Stdio::piped
///
/// # Examples
///
@ -738,8 +744,8 @@ impl Command {
/// Defaults to [`inherit`] when used with `spawn` or `status`, and
/// defaults to [`piped`] when used with `output`.
///
/// [`inherit`]: struct.Stdio.html#method.inherit
/// [`piped`]: struct.Stdio.html#method.piped
/// [`inherit`]: Stdio::inherit
/// [`piped`]: Stdio::piped
///
/// # Examples
///
@ -764,8 +770,8 @@ impl Command {
/// Defaults to [`inherit`] when used with `spawn` or `status`, and
/// defaults to [`piped`] when used with `output`.
///
/// [`inherit`]: struct.Stdio.html#method.inherit
/// [`piped`]: struct.Stdio.html#method.piped
/// [`inherit`]: Stdio::inherit
/// [`piped`]: Stdio::piped
///
/// # Examples
///
@ -893,10 +899,8 @@ impl AsInnerMut<imp::Command> for Command {
/// [`Command`], or the [`wait_with_output`] method of a [`Child`]
/// process.
///
/// [`Command`]: struct.Command.html
/// [`Child`]: struct.Child.html
/// [`output`]: struct.Command.html#method.output
/// [`wait_with_output`]: struct.Child.html#method.wait_with_output
/// [`output`]: Command::output
/// [`wait_with_output`]: Child::wait_with_output
#[derive(PartialEq, Eq, Clone)]
#[stable(feature = "process", since = "1.0.0")]
pub struct Output {
@ -939,10 +943,9 @@ impl fmt::Debug for Output {
/// Describes what to do with a standard I/O stream for a child process when
/// passed to the [`stdin`], [`stdout`], and [`stderr`] methods of [`Command`].
///
/// [`stdin`]: struct.Command.html#method.stdin
/// [`stdout`]: struct.Command.html#method.stdout
/// [`stderr`]: struct.Command.html#method.stderr
/// [`Command`]: struct.Command.html
/// [`stdin`]: Command::stdin
/// [`stdout`]: Command::stdout
/// [`stderr`]: Command::stderr
#[stable(feature = "process", since = "1.0.0")]
pub struct Stdio(imp::Stdio);
@ -1206,10 +1209,8 @@ impl From<fs::File> for Stdio {
/// status is exposed through the [`status`] method, or the [`wait`] method
/// of a [`Child`] process.
///
/// [`Command`]: struct.Command.html
/// [`Child`]: struct.Child.html
/// [`status`]: struct.Command.html#method.status
/// [`wait`]: struct.Child.html#method.wait
/// [`status`]: Command::status
/// [`wait`]: Child::wait
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
#[stable(feature = "process", since = "1.0.0")]
pub struct ExitStatus(imp::ExitStatus);
@ -1294,8 +1295,8 @@ impl fmt::Display for ExitStatus {
/// For the platform's canonical successful and unsuccessful codes, see
/// the [`SUCCESS`] and [`FAILURE`] associated items.
///
/// [`SUCCESS`]: #associatedconstant.SUCCESS
/// [`FAILURE`]: #associatedconstant.FAILURE
/// [`SUCCESS`]: ExitCode::SUCCESS
/// [`FAILURE`]: ExitCode::FAILURE
///
/// **Warning**: While various forms of this were discussed in [RFC #1937],
/// it was ultimately cut from that RFC, and thus this type is more subject
@ -1349,9 +1350,9 @@ impl Child {
/// }
/// ```
///
/// [`ErrorKind`]: ../io/enum.ErrorKind.html
/// [`InvalidInput`]: ../io/enum.ErrorKind.html#variant.InvalidInput
/// [`Other`]: ../io/enum.ErrorKind.html#variant.Other
/// [`ErrorKind`]: io::ErrorKind
/// [`InvalidInput`]: io::ErrorKind::InvalidInput
/// [`Other`]: io::ErrorKind::Other
#[stable(feature = "process", since = "1.0.0")]
pub fn kill(&mut self) -> io::Result<()> {
self.handle.kill()
@ -1616,8 +1617,7 @@ pub fn exit(code: i32) -> ! {
/// }
/// ```
///
/// [`panic!`]: ../../std/macro.panic.html
/// [panic hook]: ../../std/panic/fn.set_hook.html
/// [panic hook]: crate::panic::set_hook
#[stable(feature = "process_abort", since = "1.17.0")]
pub fn abort() -> ! {
crate::sys::abort_internal();

View File

@ -50,6 +50,13 @@ impl<'a> FnKind<'a> {
}
}
pub fn ident(&self) -> Option<&Ident> {
match self {
FnKind::Fn(_, ident, ..) => Some(ident),
_ => None,
}
}
pub fn decl(&self) -> &'a FnDecl {
match self {
FnKind::Fn(_, _, sig, _, _) => &sig.decl,

View File

@ -1,11 +1,19 @@
`fn main()` or the specified start function is not allowed to be
async. You might be seeing this error because your async runtime
library is not set up correctly.
The entry point of the program was marked as `async`.
Erroneous code example:
```compile_fail,E0752
async fn main() -> Result<i32, ()> {
Ok(1)
async fn main() -> Result<(), ()> { // error!
Ok(())
}
```
`fn main()` or the specified start function is not allowed to be `async`. Not
having a correct async runtime library setup may cause this error. To fix it,
declare the entry point without `async`:
```
fn main() -> Result<(), ()> { // ok!
Ok(())
}
```

View File

@ -57,6 +57,12 @@ fn eval_body_using_ecx<'mir, 'tcx>(
ecx.run()?;
// Intern the result
// FIXME: since the DefId of a promoted is the DefId of its owner, this
// means that promoteds in statics are actually interned like statics!
// However, this is also currently crucial because we promote mutable
// non-empty slices in statics to extend their lifetime, and this
// ensures that they are put into a mutable allocation.
// For other kinds of promoteds in statics (like array initializers), this is rather silly.
let intern_kind = match tcx.static_mutability(cid.instance.def_id()) {
Some(m) => InternKind::Static(m),
None if cid.promoted.is_some() => InternKind::Promoted,

View File

@ -312,7 +312,8 @@ pub fn intern_const_alloc_recursive<M: CompileTimeMachine<'mir, 'tcx>>(
let tcx = ecx.tcx;
let base_intern_mode = match intern_kind {
InternKind::Static(mutbl) => InternMode::Static(mutbl),
// FIXME: what about array lengths, array initializers?
// `Constant` includes array lengths.
// `Promoted` includes non-`Copy` array initializers and `rustc_args_required_const` arguments.
InternKind::Constant | InternKind::Promoted => InternMode::ConstBase,
};

View File

@ -101,7 +101,7 @@ impl TempState {
/// of a larger candidate.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Candidate {
/// Borrow of a constant temporary.
/// Borrow of a constant temporary, candidate for lifetime extension.
Ref(Location),
/// Promotion of the `x` in `[x; 32]`.

View File

@ -7,6 +7,7 @@ use crate::{PathResult, PathSource, Segment};
use rustc_ast::ast::{self, Expr, ExprKind, Item, ItemKind, NodeId, Path, Ty, TyKind};
use rustc_ast::util::lev_distance::find_best_match_for_name;
use rustc_ast::visit::FnKind;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
@ -175,16 +176,40 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
let code = source.error_code(res.is_some());
let mut err = self.r.session.struct_span_err_with_code(base_span, &base_msg, code);
let is_assoc_fn = self.self_type_is_available(span);
// Emit help message for fake-self from other languages (e.g., `this` in Javascript).
if ["this", "my"].contains(&&*item_str.as_str())
&& self.self_value_is_available(path[0].ident.span, span)
{
if ["this", "my"].contains(&&*item_str.as_str()) && is_assoc_fn {
err.span_suggestion_short(
span,
"you might have meant to use `self` here instead",
"self".to_string(),
Applicability::MaybeIncorrect,
);
if !self.self_value_is_available(path[0].ident.span, span) {
if let Some((FnKind::Fn(_, _, sig, ..), fn_span)) =
&self.diagnostic_metadata.current_function
{
let (span, sugg) = if let Some(param) = sig.decl.inputs.get(0) {
(param.span.shrink_to_lo(), "&self, ")
} else {
(
self.r
.session
.source_map()
.span_through_char(*fn_span, '(')
.shrink_to_hi(),
"&self",
)
};
err.span_suggestion_verbose(
span,
"if you meant to use `self`, you are also missing a `self` receiver \
argument",
sugg.to_string(),
Applicability::MaybeIncorrect,
);
}
}
}
// Emit special messages for unresolved `Self` and `self`.
@ -213,7 +238,38 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
if fn_kind.decl().inputs.get(0).map(|p| p.is_self()).unwrap_or(false) {
err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters");
} else {
err.span_label(*span, "this function doesn't have a `self` parameter");
let doesnt = if is_assoc_fn {
let (span, sugg) = fn_kind
.decl()
.inputs
.get(0)
.map(|p| (p.span.shrink_to_lo(), "&self, "))
.unwrap_or_else(|| {
(
self.r
.session
.source_map()
.span_through_char(*span, '(')
.shrink_to_hi(),
"&self",
)
});
err.span_suggestion_verbose(
span,
"add a `self` receiver parameter to make the associated `fn` a method",
sugg.to_string(),
Applicability::MaybeIncorrect,
);
"doesn't"
} else {
"can't"
};
if let Some(ident) = fn_kind.ident() {
err.span_label(
ident.span,
&format!("this function {} have a `self` parameter", doesnt),
);
}
}
}
return (err, Vec::new());

View File

@ -1623,6 +1623,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
span: Span,
trait_bounds: &[hir::PolyTraitRef<'_>],
lifetime: &hir::Lifetime,
borrowed: bool,
) -> Ty<'tcx> {
let tcx = self.tcx();
@ -1837,15 +1838,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self.ast_region_to_region(lifetime, None)
} else {
self.re_infer(None, span).unwrap_or_else(|| {
// FIXME: these can be redundant with E0106, but not always.
struct_span_err!(
let mut err = struct_span_err!(
tcx.sess,
span,
E0228,
"the lifetime bound for this object type cannot be deduced \
from context; please supply an explicit bound"
)
.emit();
);
if borrowed {
// We will have already emitted an error E0106 complaining about a
// missing named lifetime in `&dyn Trait`, so we elide this one.
err.delay_as_bug();
} else {
err.emit();
}
tcx.lifetimes.re_static
})
}
@ -2873,6 +2879,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// Parses the programmer's textual representation of a type into our
/// internal notion of a type.
pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
self.ast_ty_to_ty_inner(ast_ty, false)
}
/// Turns a `hir::Ty` into a `Ty`. For diagnostics' purposes we keep track of whether trait
/// objects are borrowed like `&dyn Trait` to avoid emitting redundant errors.
fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool) -> Ty<'tcx> {
debug!("ast_ty_to_ty(id={:?}, ast_ty={:?} ty_ty={:?})", ast_ty.hir_id, ast_ty, ast_ty.kind);
let tcx = self.tcx();
@ -2885,7 +2897,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
hir::TyKind::Rptr(ref region, ref mt) => {
let r = self.ast_region_to_region(region, None);
debug!("ast_ty_to_ty: r={:?}", r);
let t = self.ast_ty_to_ty(&mt.ty);
let t = self.ast_ty_to_ty_inner(&mt.ty, true);
tcx.mk_ref(r, ty::TypeAndMut { ty: t, mutbl: mt.mutbl })
}
hir::TyKind::Never => tcx.types.never,
@ -2903,7 +2915,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
))
}
hir::TyKind::TraitObject(ref bounds, ref lifetime) => {
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime)
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed)
}
hir::TyKind::Path(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);

View File

@ -6,6 +6,10 @@ impl Foo {
fn foo() {
self.bar(); //~ ERROR E0424
}
fn baz(_: i32) {
self.bar(); //~ ERROR E0424
}
}
fn main () {

View File

@ -1,21 +1,37 @@
error[E0424]: expected value, found module `self`
--> $DIR/E0424.rs:7:9
|
LL | / fn foo() {
LL | | self.bar();
| | ^^^^ `self` value is a keyword only available in methods with a `self` parameter
LL | | }
| |_____- this function doesn't have a `self` parameter
LL | fn foo() {
| --- this function doesn't have a `self` parameter
LL | self.bar();
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
|
help: add a `self` receiver parameter to make the associated `fn` a method
|
LL | fn foo(&self) {
| ^^^^^
error[E0424]: expected value, found module `self`
--> $DIR/E0424.rs:11:9
|
LL | fn baz(_: i32) {
| --- this function doesn't have a `self` parameter
LL | self.bar();
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
|
help: add a `self` receiver parameter to make the associated `fn` a method
|
LL | fn baz(&self, _: i32) {
| ^^^^^^
error[E0424]: expected unit struct, unit variant or constant, found module `self`
--> $DIR/E0424.rs:12:9
--> $DIR/E0424.rs:16:9
|
LL | / fn main () {
LL | | let self = "self";
| | ^^^^ `self` value is a keyword and may not be bound to variables or shadowed
LL | | }
| |_- this function doesn't have a `self` parameter
LL | fn main () {
| ---- this function can't have a `self` parameter
LL | let self = "self";
| ^^^^ `self` value is a keyword and may not be bound to variables or shadowed
error: aborting due to 2 previous errors
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0424`.

View File

@ -1,3 +1,10 @@
trait B < A > { fn a() -> A { this.a } } //~ ERROR cannot find value `this` in this scope
trait B <A> {
fn a() -> A {
this.a //~ ERROR cannot find value `this` in this scope
}
fn b(x: i32) {
this.b(x); //~ ERROR cannot find value `this` in this scope
}
}
fn main() {}

View File

@ -1,9 +1,33 @@
error[E0425]: cannot find value `this` in this scope
--> $DIR/issue-5099.rs:1:31
--> $DIR/issue-5099.rs:3:9
|
LL | trait B < A > { fn a() -> A { this.a } }
| ^^^^ not found in this scope
LL | this.a
| ^^^^ not found in this scope
|
help: you might have meant to use `self` here instead
|
LL | self.a
| ^^^^
help: if you meant to use `self`, you are also missing a `self` receiver argument
|
LL | fn a(&self) -> A {
| ^^^^^
error: aborting due to previous error
error[E0425]: cannot find value `this` in this scope
--> $DIR/issue-5099.rs:6:9
|
LL | this.b(x);
| ^^^^ not found in this scope
|
help: you might have meant to use `self` here instead
|
LL | self.b(x);
| ^^^^
help: if you meant to use `self`, you are also missing a `self` receiver argument
|
LL | fn b(&self, x: i32) {
| ^^^^^^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0425`.

View File

@ -70,14 +70,15 @@ LL | purr();
error[E0424]: expected value, found module `self`
--> $DIR/issue-2356.rs:65:8
|
LL | / fn meow() {
LL | | if self.whiskers > 3 {
| | ^^^^ `self` value is a keyword only available in methods with a `self` parameter
LL | |
LL | | println!("MEOW");
LL | | }
LL | | }
| |___- this function doesn't have a `self` parameter
LL | fn meow() {
| ---- this function doesn't have a `self` parameter
LL | if self.whiskers > 3 {
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
|
help: add a `self` receiver parameter to make the associated `fn` a method
|
LL | fn meow(&self) {
| ^^^^^
error[E0425]: cannot find function `grow_older` in this scope
--> $DIR/issue-2356.rs:72:5
@ -112,12 +113,10 @@ LL | purr_louder();
error[E0424]: expected value, found module `self`
--> $DIR/issue-2356.rs:92:5
|
LL | / fn main() {
LL | | self += 1;
| | ^^^^ `self` value is a keyword only available in methods with a `self` parameter
LL | |
LL | | }
| |_- this function doesn't have a `self` parameter
LL | fn main() {
| ---- this function can't have a `self` parameter
LL | self += 1;
| ^^^^ `self` value is a keyword only available in methods with a `self` parameter
error: aborting due to 17 previous errors

View File

@ -25,8 +25,6 @@ thread_local! {
//~| ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
//~| ERROR the lifetime bound for this object type cannot be deduced from context
//~| ERROR the lifetime bound for this object type cannot be deduced from context
}
thread_local! {
static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
@ -39,8 +37,6 @@ thread_local! {
//~| ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
//~| ERROR the lifetime bound for this object type cannot be deduced from context
//~| ERROR the lifetime bound for this object type cannot be deduced from context
}
thread_local! {
@ -52,9 +48,7 @@ thread_local! {
}
thread_local! {
static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
//~^ ERROR the lifetime bound for this object type cannot be deduced from context
//~| ERROR the lifetime bound for this object type cannot be deduced from context
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
//~^ ERROR wrong number of lifetime arguments: expected 2, found 1
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
//~| ERROR wrong number of lifetime arguments: expected 2, found 1

View File

@ -71,7 +71,7 @@ LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar<'static, 'static>>>>> = Ref
| ^^^^^^^^^^^^^^^^^^^^^
error[E0106]: missing lifetime specifiers
--> $DIR/missing-lifetime-specifier.rs:32:48
--> $DIR/missing-lifetime-specifier.rs:30:48
|
LL | static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
| ^ expected 2 lifetime parameters
@ -83,7 +83,7 @@ LL | static c: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> =
| ^^^^^^^^^^^^^^^^^
error[E0106]: missing lifetime specifiers
--> $DIR/missing-lifetime-specifier.rs:32:48
--> $DIR/missing-lifetime-specifier.rs:30:48
|
LL | static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
| ^ expected 2 lifetime parameters
@ -95,7 +95,7 @@ LL | static c: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> =
| ^^^^^^^^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/missing-lifetime-specifier.rs:37:44
--> $DIR/missing-lifetime-specifier.rs:35:44
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
| ^ expected named lifetime parameter
@ -107,7 +107,7 @@ LL | static d: RefCell<HashMap<i32, Vec<Vec<&'static Tar<i32>>>>> = RefCell:
| ^^^^^^^^
error[E0106]: missing lifetime specifiers
--> $DIR/missing-lifetime-specifier.rs:37:49
--> $DIR/missing-lifetime-specifier.rs:35:49
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
| ^ expected 2 lifetime parameters
@ -119,7 +119,7 @@ LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>>
| ^^^^^^^^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/missing-lifetime-specifier.rs:37:44
--> $DIR/missing-lifetime-specifier.rs:35:44
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
| ^ expected named lifetime parameter
@ -131,7 +131,7 @@ LL | static d: RefCell<HashMap<i32, Vec<Vec<&'static Tar<i32>>>>> = RefCell:
| ^^^^^^^^
error[E0106]: missing lifetime specifiers
--> $DIR/missing-lifetime-specifier.rs:37:49
--> $DIR/missing-lifetime-specifier.rs:35:49
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
| ^ expected 2 lifetime parameters
@ -143,7 +143,7 @@ LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>>
| ^^^^^^^^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/missing-lifetime-specifier.rs:54:44
--> $DIR/missing-lifetime-specifier.rs:50:44
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^ expected named lifetime parameter
@ -155,7 +155,7 @@ LL | static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> =
| ^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/missing-lifetime-specifier.rs:54:44
--> $DIR/missing-lifetime-specifier.rs:50:44
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^ expected named lifetime parameter
@ -166,91 +166,55 @@ help: consider using the `'static` lifetime
LL | static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:23:45
|
LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
| ^^^
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:23:45
|
LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
| ^^^
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:37:45
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:37:45
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
--> $DIR/missing-lifetime-specifier.rs:47:44
--> $DIR/missing-lifetime-specifier.rs:43:44
|
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
--> $DIR/missing-lifetime-specifier.rs:47:44
--> $DIR/missing-lifetime-specifier.rs:43:44
|
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
--> $DIR/missing-lifetime-specifier.rs:47:44
--> $DIR/missing-lifetime-specifier.rs:43:44
|
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
--> $DIR/missing-lifetime-specifier.rs:47:44
--> $DIR/missing-lifetime-specifier.rs:43:44
|
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
--> $DIR/missing-lifetime-specifier.rs:54:45
--> $DIR/missing-lifetime-specifier.rs:50:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
--> $DIR/missing-lifetime-specifier.rs:54:45
--> $DIR/missing-lifetime-specifier.rs:50:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:54:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
--> $DIR/missing-lifetime-specifier.rs:54:45
--> $DIR/missing-lifetime-specifier.rs:50:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:54:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
--> $DIR/missing-lifetime-specifier.rs:54:45
--> $DIR/missing-lifetime-specifier.rs:50:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
error: aborting due to 28 previous errors
error: aborting due to 22 previous errors
Some errors have detailed explanations: E0106, E0107, E0228.
Some errors have detailed explanations: E0106, E0107.
For more information about an error, try `rustc --explain E0106`.