Skip to content

Commit 430994c

Browse files
committed
rust-timer simulated merge of f305b20
Original message: Rollup merge of rust-lang#74021 - 1011X:master, r=dtolnay impl Index<RangeFrom> for CStr This change implements (partial) slicing for `CStr`. Since a `CStr` must end in a null byte, it's not possible to trim from the right and still have a valid `CStr`. But, it *is* possible to trim from the left. This lets us be a bit more flexible and treat them more like strings. ```rust let string = CStr::from_bytes_with_nul(b"Hello World!\0"); let result = CStr::from_bytes_with_nul(b"World!\0"); assert_eq!(&string[6..], result); ```
1 parent 669cfad commit 430994c

File tree

5 files changed

+283
-3
lines changed

5 files changed

+283
-3
lines changed

src/libcore/task/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@ pub use self::poll::Poll;
99
mod wake;
1010
#[stable(feature = "futures_api", since = "1.36.0")]
1111
pub use self::wake::{Context, RawWaker, RawWakerVTable, Waker};
12+
13+
mod ready;
14+
#[unstable(feature = "ready_macro", issue = "70922")]
15+
pub use ready::ready;

src/libcore/task/ready.rs

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/// Extracts the successful type of a `Poll<T>`.
2+
///
3+
/// This macro bakes in propagation of `Pending` signals by returning early.
4+
///
5+
/// # Examples
6+
///
7+
/// ```
8+
/// #![feature(future_readiness_fns)]
9+
/// #![feature(ready_macro)]
10+
///
11+
/// use core::task::{ready, Context, Poll};
12+
/// use core::future::{self, Future};
13+
/// use core::pin::Pin;
14+
///
15+
/// pub fn do_poll(cx: &mut Context<'_>) -> Poll<()> {
16+
/// let mut fut = future::ready(42);
17+
/// let fut = Pin::new(&mut fut);
18+
///
19+
/// let num = ready!(fut.poll(cx));
20+
/// # drop(num);
21+
/// // ... use num
22+
///
23+
/// Poll::Ready(())
24+
/// }
25+
/// ```
26+
///
27+
/// The `ready!` call expands to:
28+
///
29+
/// ```
30+
/// # #![feature(future_readiness_fns)]
31+
/// # #![feature(ready_macro)]
32+
/// #
33+
/// # use core::task::{Context, Poll};
34+
/// # use core::future::{self, Future};
35+
/// # use core::pin::Pin;
36+
/// #
37+
/// # pub fn do_poll(cx: &mut Context<'_>) -> Poll<()> {
38+
/// # let mut fut = future::ready(42);
39+
/// # let fut = Pin::new(&mut fut);
40+
/// #
41+
/// let num = match fut.poll(cx) {
42+
/// Poll::Ready(t) => t,
43+
/// Poll::Pending => return Poll::Pending,
44+
/// };
45+
/// # drop(num);
46+
/// # // ... use num
47+
/// #
48+
/// # Poll::Ready(())
49+
/// # }
50+
/// ```
51+
#[unstable(feature = "ready_macro", issue = "70922")]
52+
#[rustc_macro_transparency = "semitransparent"]
53+
pub macro ready($e:expr) {
54+
match $e {
55+
$crate::task::Poll::Ready(t) => t,
56+
$crate::task::Poll::Pending => {
57+
return $crate::task::Poll::Pending;
58+
}
59+
}
60+
}

src/libstd/ffi/c_str.rs

+38
Original file line numberDiff line numberDiff line change
@@ -1551,6 +1551,27 @@ impl ops::Index<ops::RangeFull> for CString {
15511551
}
15521552
}
15531553

1554+
#[stable(feature = "cstr_range_from", since = "1.47.0")]
1555+
impl ops::Index<ops::RangeFrom<usize>> for CStr {
1556+
type Output = CStr;
1557+
1558+
fn index(&self, index: ops::RangeFrom<usize>) -> &CStr {
1559+
let bytes = self.to_bytes_with_nul();
1560+
// we need to manually check the starting index to account for the null
1561+
// byte, since otherwise we could get an empty string that doesn't end
1562+
// in a null.
1563+
if index.start < bytes.len() {
1564+
unsafe { CStr::from_bytes_with_nul_unchecked(&bytes[index.start..]) }
1565+
} else {
1566+
panic!(
1567+
"index out of bounds: the len is {} but the index is {}",
1568+
bytes.len(),
1569+
index.start
1570+
);
1571+
}
1572+
}
1573+
}
1574+
15541575
#[stable(feature = "cstring_asref", since = "1.7.0")]
15551576
impl AsRef<CStr> for CStr {
15561577
#[inline]
@@ -1747,4 +1768,21 @@ mod tests {
17471768

17481769
assert_eq!(CSTR.to_str().unwrap(), "Hello, world!");
17491770
}
1771+
1772+
#[test]
1773+
fn cstr_index_from() {
1774+
let original = b"Hello, world!\0";
1775+
let cstr = CStr::from_bytes_with_nul(original).unwrap();
1776+
let result = CStr::from_bytes_with_nul(&original[7..]).unwrap();
1777+
1778+
assert_eq!(&cstr[7..], result);
1779+
}
1780+
1781+
#[test]
1782+
#[should_panic]
1783+
fn cstr_index_from_empty() {
1784+
let original = b"Hello, world!\0";
1785+
let cstr = CStr::from_bytes_with_nul(original).unwrap();
1786+
let _ = &cstr[original.len()..];
1787+
}
17501788
}

src/libstd/keyword_docs.rs

+180-3
Original file line numberDiff line numberDiff line change
@@ -1497,11 +1497,188 @@ mod super_keyword {}
14971497

14981498
#[doc(keyword = "trait")]
14991499
//
1500-
/// A common interface for a class of types.
1500+
/// A common interface for a group of types.
15011501
///
1502-
/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
1502+
/// A `trait` is like an interface that data types can implement. When a type
1503+
/// implements a trait it can be treated abstractly as that trait using generics
1504+
/// or trait objects.
15031505
///
1504-
/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
1506+
/// Traits can be made up of three varieties of associated items:
1507+
///
1508+
/// - functions and methods
1509+
/// - types
1510+
/// - constants
1511+
///
1512+
/// Traits may also contain additional type parameters. Those type parameters
1513+
/// or the trait itself can be constrained by other traits.
1514+
///
1515+
/// Traits can serve as markers or carry other logical semantics that
1516+
/// aren't expressed through their items. When a type implements that
1517+
/// trait it is promising to uphold its contract. [`Send`] and [`Sync`] are two
1518+
/// such marker traits present in the standard library.
1519+
///
1520+
/// See the [Reference][Ref-Traits] for a lot more information on traits.
1521+
///
1522+
/// # Examples
1523+
///
1524+
/// Traits are declared using the `trait` keyword. Types can implement them
1525+
/// using [`impl`] `Trait` [`for`] `Type`:
1526+
///
1527+
/// ```rust
1528+
/// trait Zero {
1529+
/// const ZERO: Self;
1530+
/// fn is_zero(&self) -> bool;
1531+
/// }
1532+
///
1533+
/// impl Zero for i32 {
1534+
/// const ZERO: Self = 0;
1535+
///
1536+
/// fn is_zero(&self) -> bool {
1537+
/// *self == Self::ZERO
1538+
/// }
1539+
/// }
1540+
///
1541+
/// assert_eq!(i32::ZERO, 0);
1542+
/// assert!(i32::ZERO.is_zero());
1543+
/// assert!(!4.is_zero());
1544+
/// ```
1545+
///
1546+
/// With an associated type:
1547+
///
1548+
/// ```rust
1549+
/// trait Builder {
1550+
/// type Built;
1551+
///
1552+
/// fn build(&self) -> Self::Built;
1553+
/// }
1554+
/// ```
1555+
///
1556+
/// Traits can be generic, with constraints or without:
1557+
///
1558+
/// ```rust
1559+
/// trait MaybeFrom<T> {
1560+
/// fn maybe_from(value: T) -> Option<Self>
1561+
/// where
1562+
/// Self: Sized;
1563+
/// }
1564+
/// ```
1565+
///
1566+
/// Traits can build upon the requirements of other traits. In the example
1567+
/// below `Iterator` is a **supertrait** and `ThreeIterator` is a **subtrait**:
1568+
///
1569+
/// ```rust
1570+
/// trait ThreeIterator: std::iter::Iterator {
1571+
/// fn next_three(&mut self) -> Option<[Self::Item; 3]>;
1572+
/// }
1573+
/// ```
1574+
///
1575+
/// Traits can be used in functions, as parameters:
1576+
///
1577+
/// ```rust
1578+
/// # #![allow(dead_code)]
1579+
/// fn debug_iter<I: Iterator>(it: I) where I::Item: std::fmt::Debug {
1580+
/// for elem in it {
1581+
/// println!("{:#?}", elem);
1582+
/// }
1583+
/// }
1584+
///
1585+
/// // u8_len_1, u8_len_2 and u8_len_3 are equivalent
1586+
///
1587+
/// fn u8_len_1(val: impl Into<Vec<u8>>) -> usize {
1588+
/// val.into().len()
1589+
/// }
1590+
///
1591+
/// fn u8_len_2<T: Into<Vec<u8>>>(val: T) -> usize {
1592+
/// val.into().len()
1593+
/// }
1594+
///
1595+
/// fn u8_len_3<T>(val: T) -> usize
1596+
/// where
1597+
/// T: Into<Vec<u8>>,
1598+
/// {
1599+
/// val.into().len()
1600+
/// }
1601+
/// ```
1602+
///
1603+
/// Or as return types:
1604+
///
1605+
/// ```rust
1606+
/// # #![allow(dead_code)]
1607+
/// fn from_zero_to(v: u8) -> impl Iterator<Item = u8> {
1608+
/// (0..v).into_iter()
1609+
/// }
1610+
/// ```
1611+
///
1612+
/// The use of the [`impl`] keyword in this position allows the function writer
1613+
/// to hide the concrete type as an implementation detail which can change
1614+
/// without breaking user's code.
1615+
///
1616+
/// # Trait objects
1617+
///
1618+
/// A *trait object* is an opaque value of another type that implements a set of
1619+
/// traits. A trait object implements all specified traits as well as their
1620+
/// supertraits (if any).
1621+
///
1622+
/// The syntax is the following: `dyn BaseTrait + AutoTrait1 + ... AutoTraitN`.
1623+
/// Only one `BaseTrait` can be used so this will not compile:
1624+
///
1625+
/// ```rust,compile_fail,E0225
1626+
/// trait A {}
1627+
/// trait B {}
1628+
///
1629+
/// let _: Box<dyn A + B>;
1630+
/// ```
1631+
///
1632+
/// Neither will this, which is a syntax error:
1633+
///
1634+
/// ```rust,compile_fail
1635+
/// trait A {}
1636+
/// trait B {}
1637+
///
1638+
/// let _: Box<dyn A + dyn B>;
1639+
/// ```
1640+
///
1641+
/// On the other hand, this is correct:
1642+
///
1643+
/// ```rust
1644+
/// trait A {}
1645+
///
1646+
/// let _: Box<dyn A + Send + Sync>;
1647+
/// ```
1648+
///
1649+
/// The [Reference][Ref-Trait-Objects] has more information about trait objects,
1650+
/// their limitations and the differences between editions.
1651+
///
1652+
/// # Unsafe traits
1653+
///
1654+
/// Some traits may be unsafe to implement. Using the [`unsafe`] keyword in
1655+
/// front of the trait's declaration is used to mark this:
1656+
///
1657+
/// ```rust
1658+
/// unsafe trait UnsafeTrait {}
1659+
///
1660+
/// unsafe impl UnsafeTrait for i32 {}
1661+
/// ```
1662+
///
1663+
/// # Differences between the 2015 and 2018 editions
1664+
///
1665+
/// In the 2015 edition parameters pattern where not needed for traits:
1666+
///
1667+
/// ```rust,edition2015
1668+
/// trait Tr {
1669+
/// fn f(i32);
1670+
/// }
1671+
/// ```
1672+
///
1673+
/// This behavior is no longer valid in edition 2018.
1674+
///
1675+
/// [`for`]: keyword.for.html
1676+
/// [`impl`]: keyword.impl.html
1677+
/// [`unsafe`]: keyword.unsafe.html
1678+
/// [`Send`]: marker/trait.Send.html
1679+
/// [`Sync`]: marker/trait.Sync.html
1680+
/// [Ref-Traits]: ../reference/items/traits.html
1681+
/// [Ref-Trait-Objects]: ../reference/types/trait-object.html
15051682
mod trait_keyword {}
15061683

15071684
#[doc(keyword = "true")]

src/libstd/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@
305305
#![feature(ptr_internals)]
306306
#![feature(raw)]
307307
#![feature(raw_ref_macros)]
308+
#![feature(ready_macro)]
308309
#![feature(renamed_spin_loop)]
309310
#![feature(rustc_attrs)]
310311
#![feature(rustc_private)]

0 commit comments

Comments
 (0)