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:
commit
95879ad961
@ -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;
|
||||
|
@ -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.
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
25
library/alloc/src/collections/btree/node/tests.rs
Normal file
25
library/alloc/src/collections/btree/node/tests.rs
Normal 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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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();
|
@ -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)]
|
||||
|
@ -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> {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
19
library/alloc/tests/btree_set_hash.rs
Normal file
19
library/alloc/tests/btree_set_hash.rs
Normal 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));
|
||||
}
|
@ -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;
|
||||
|
@ -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>) {
|
||||
|
@ -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
|
||||
///
|
||||
|
@ -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" }
|
||||
|
@ -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
|
||||
///
|
||||
/// ```
|
||||
|
@ -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")]
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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")]
|
||||
|
@ -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 {
|
||||
|
@ -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`.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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(())
|
||||
}
|
||||
```
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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]`.
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -6,6 +6,10 @@ impl Foo {
|
||||
fn foo() {
|
||||
self.bar(); //~ ERROR E0424
|
||||
}
|
||||
|
||||
fn baz(_: i32) {
|
||||
self.bar(); //~ ERROR E0424
|
||||
}
|
||||
}
|
||||
|
||||
fn main () {
|
||||
|
@ -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`.
|
||||
|
@ -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() {}
|
||||
|
@ -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`.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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`.
|
||||
|
Loading…
Reference in New Issue
Block a user