@@ -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
15051682mod trait_keyword { }
15061683
15071684#[ doc( keyword = "true" ) ]
0 commit comments