diff options
| author | bors <bors@rust-lang.org> | 2020-07-19 04:03:54 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-07-19 04:03:54 +0000 |
| commit | 0701419e96d94e5493c7ebfcecb66511ab0aa778 (patch) | |
| tree | c8c859bd81bc547333c6f68d56990b9a859c4d20 /src/libstd | |
| parent | 1fa54ad9680cc82e7301f8ed4e9b7402dfd6ce0e (diff) | |
| parent | a83e294f7778c3643005dc0567fe47767fab6508 (diff) | |
| download | rust-0701419e96d94e5493c7ebfcecb66511ab0aa778.tar.gz rust-0701419e96d94e5493c7ebfcecb66511ab0aa778.zip | |
Auto merge of #74493 - Manishearth:rollup-ust7yr4, r=Manishearth
Rollup of 7 pull requests Successful merges: - #70817 (Add core::task::ready! macro) - #73762 (Document the trait keyword) - #74021 (impl Index<RangeFrom> for CStr) - #74071 (rustc_metadata: Make crate loading fully speculative) - #74445 (add test for #62878) - #74459 (Make unreachable_unchecked a const fn) - #74478 (Revert "Use an UTF-8 locale for the linker.") Failed merges: r? @ghost
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/ffi/c_str.rs | 38 | ||||
| -rw-r--r-- | src/libstd/keyword_docs.rs | 183 | ||||
| -rw-r--r-- | src/libstd/lib.rs | 1 |
3 files changed, 219 insertions, 3 deletions
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index dca1fdde482..da25a0ede72 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -1551,6 +1551,27 @@ impl ops::Index<ops::RangeFull> for CString { } } +#[stable(feature = "cstr_range_from", since = "1.47.0")] +impl ops::Index<ops::RangeFrom<usize>> for CStr { + type Output = CStr; + + fn index(&self, index: ops::RangeFrom<usize>) -> &CStr { + let bytes = self.to_bytes_with_nul(); + // we need to manually check the starting index to account for the null + // byte, since otherwise we could get an empty string that doesn't end + // in a null. + if index.start < bytes.len() { + unsafe { CStr::from_bytes_with_nul_unchecked(&bytes[index.start..]) } + } else { + panic!( + "index out of bounds: the len is {} but the index is {}", + bytes.len(), + index.start + ); + } + } +} + #[stable(feature = "cstring_asref", since = "1.7.0")] impl AsRef<CStr> for CStr { #[inline] @@ -1747,4 +1768,21 @@ mod tests { assert_eq!(CSTR.to_str().unwrap(), "Hello, world!"); } + + #[test] + fn cstr_index_from() { + let original = b"Hello, world!\0"; + let cstr = CStr::from_bytes_with_nul(original).unwrap(); + let result = CStr::from_bytes_with_nul(&original[7..]).unwrap(); + + assert_eq!(&cstr[7..], result); + } + + #[test] + #[should_panic] + fn cstr_index_from_empty() { + let original = b"Hello, world!\0"; + let cstr = CStr::from_bytes_with_nul(original).unwrap(); + let _ = &cstr[original.len()..]; + } } diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs index a53e7f5cf57..d985f10ccb4 100644 --- a/src/libstd/keyword_docs.rs +++ b/src/libstd/keyword_docs.rs @@ -1497,11 +1497,188 @@ mod super_keyword {} #[doc(keyword = "trait")] // -/// A common interface for a class of types. +/// A common interface for a group of types. /// -/// The documentation for this keyword is [not yet complete]. Pull requests welcome! +/// A `trait` is like an interface that data types can implement. When a type +/// implements a trait it can be treated abstractly as that trait using generics +/// or trait objects. /// -/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601 +/// Traits can be made up of three varieties of associated items: +/// +/// - functions and methods +/// - types +/// - constants +/// +/// Traits may also contain additional type parameters. Those type parameters +/// or the trait itself can be constrained by other traits. +/// +/// Traits can serve as markers or carry other logical semantics that +/// aren't expressed through their items. When a type implements that +/// trait it is promising to uphold its contract. [`Send`] and [`Sync`] are two +/// such marker traits present in the standard library. +/// +/// See the [Reference][Ref-Traits] for a lot more information on traits. +/// +/// # Examples +/// +/// Traits are declared using the `trait` keyword. Types can implement them +/// using [`impl`] `Trait` [`for`] `Type`: +/// +/// ```rust +/// trait Zero { +/// const ZERO: Self; +/// fn is_zero(&self) -> bool; +/// } +/// +/// impl Zero for i32 { +/// const ZERO: Self = 0; +/// +/// fn is_zero(&self) -> bool { +/// *self == Self::ZERO +/// } +/// } +/// +/// assert_eq!(i32::ZERO, 0); +/// assert!(i32::ZERO.is_zero()); +/// assert!(!4.is_zero()); +/// ``` +/// +/// With an associated type: +/// +/// ```rust +/// trait Builder { +/// type Built; +/// +/// fn build(&self) -> Self::Built; +/// } +/// ``` +/// +/// Traits can be generic, with constraints or without: +/// +/// ```rust +/// trait MaybeFrom<T> { +/// fn maybe_from(value: T) -> Option<Self> +/// where +/// Self: Sized; +/// } +/// ``` +/// +/// Traits can build upon the requirements of other traits. In the example +/// below `Iterator` is a **supertrait** and `ThreeIterator` is a **subtrait**: +/// +/// ```rust +/// trait ThreeIterator: std::iter::Iterator { +/// fn next_three(&mut self) -> Option<[Self::Item; 3]>; +/// } +/// ``` +/// +/// Traits can be used in functions, as parameters: +/// +/// ```rust +/// # #![allow(dead_code)] +/// fn debug_iter<I: Iterator>(it: I) where I::Item: std::fmt::Debug { +/// for elem in it { +/// println!("{:#?}", elem); +/// } +/// } +/// +/// // u8_len_1, u8_len_2 and u8_len_3 are equivalent +/// +/// fn u8_len_1(val: impl Into<Vec<u8>>) -> usize { +/// val.into().len() +/// } +/// +/// fn u8_len_2<T: Into<Vec<u8>>>(val: T) -> usize { +/// val.into().len() +/// } +/// +/// fn u8_len_3<T>(val: T) -> usize +/// where +/// T: Into<Vec<u8>>, +/// { +/// val.into().len() +/// } +/// ``` +/// +/// Or as return types: +/// +/// ```rust +/// # #![allow(dead_code)] +/// fn from_zero_to(v: u8) -> impl Iterator<Item = u8> { +/// (0..v).into_iter() +/// } +/// ``` +/// +/// The use of the [`impl`] keyword in this position allows the function writer +/// to hide the concrete type as an implementation detail which can change +/// without breaking user's code. +/// +/// # Trait objects +/// +/// A *trait object* is an opaque value of another type that implements a set of +/// traits. A trait object implements all specified traits as well as their +/// supertraits (if any). +/// +/// The syntax is the following: `dyn BaseTrait + AutoTrait1 + ... AutoTraitN`. +/// Only one `BaseTrait` can be used so this will not compile: +/// +/// ```rust,compile_fail,E0225 +/// trait A {} +/// trait B {} +/// +/// let _: Box<dyn A + B>; +/// ``` +/// +/// Neither will this, which is a syntax error: +/// +/// ```rust,compile_fail +/// trait A {} +/// trait B {} +/// +/// let _: Box<dyn A + dyn B>; +/// ``` +/// +/// On the other hand, this is correct: +/// +/// ```rust +/// trait A {} +/// +/// let _: Box<dyn A + Send + Sync>; +/// ``` +/// +/// The [Reference][Ref-Trait-Objects] has more information about trait objects, +/// their limitations and the differences between editions. +/// +/// # Unsafe traits +/// +/// Some traits may be unsafe to implement. Using the [`unsafe`] keyword in +/// front of the trait's declaration is used to mark this: +/// +/// ```rust +/// unsafe trait UnsafeTrait {} +/// +/// unsafe impl UnsafeTrait for i32 {} +/// ``` +/// +/// # Differences between the 2015 and 2018 editions +/// +/// In the 2015 edition parameters pattern where not needed for traits: +/// +/// ```rust,edition2015 +/// trait Tr { +/// fn f(i32); +/// } +/// ``` +/// +/// This behavior is no longer valid in edition 2018. +/// +/// [`for`]: keyword.for.html +/// [`impl`]: keyword.impl.html +/// [`unsafe`]: keyword.unsafe.html +/// [`Send`]: marker/trait.Send.html +/// [`Sync`]: marker/trait.Sync.html +/// [Ref-Traits]: ../reference/items/traits.html +/// [Ref-Trait-Objects]: ../reference/types/trait-object.html mod trait_keyword {} #[doc(keyword = "true")] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 0397153098c..11b8f953be4 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -305,6 +305,7 @@ #![feature(ptr_internals)] #![feature(raw)] #![feature(raw_ref_macros)] +#![feature(ready_macro)] #![feature(renamed_spin_loop)] #![feature(rustc_attrs)] #![feature(rustc_private)] |
