Skip to content

Commit a6266e2

Browse files
authored
Rollup merge of #73762 - poliorcetics:trait-keyword, r=KodrAus
Document the trait keyword Partial fix of #34601. This document the trait keyword. To avoid doing too much and forcing more updates as functionalities evolve, I put two links to the reference, especially for trait objects. This mainly documents the "big" parts, not so much the small details that might trip someone experimenting. @rustbot modify labels: T-doc,C-enhancement
2 parents 479c8ad + 8a2f147 commit a6266e2

File tree

1 file changed

+180
-3
lines changed

1 file changed

+180
-3
lines changed

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")]

0 commit comments

Comments
 (0)