@@ -1651,9 +1651,142 @@ mod use_keyword {}
16511651//
16521652/// Add constraints that must be upheld to use an item.
16531653///
1654- /// The documentation for this keyword is [not yet complete]. Pull requests welcome!
1654+ /// `where` allows specifying constraints on lifetime and generic parameters.
1655+ /// The [RFC] introducing `where` contains detailed informations about the
1656+ /// keyword.
16551657///
1656- /// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
1658+ /// # Examples
1659+ ///
1660+ /// `where` can be used for constraints with traits:
1661+ ///
1662+ /// ```rust
1663+ /// fn new<T: Default>() -> T {
1664+ /// T::default()
1665+ /// }
1666+ ///
1667+ /// fn new_where<T>() -> T
1668+ /// where
1669+ /// T: Default,
1670+ /// {
1671+ /// T::default()
1672+ /// }
1673+ ///
1674+ /// assert_eq!(0.0, new());
1675+ /// assert_eq!(0.0, new_where());
1676+ ///
1677+ /// assert_eq!(0, new());
1678+ /// assert_eq!(0, new_where());
1679+ /// ```
1680+ ///
1681+ /// `where` can also be used for lifetimes.
1682+ ///
1683+ /// This compiles because the lifetime of `longer` is superior to the lifetime
1684+ /// of `shorter`, thus the constraint is respected:
1685+ ///
1686+ /// ```rust
1687+ /// fn select<'a, 'b: 'a>(s1: &'a str, s2: &'b str, second: bool) -> &'a str {
1688+ /// if second {
1689+ /// s2
1690+ /// } else {
1691+ /// s1
1692+ /// }
1693+ /// }
1694+ ///
1695+ /// fn select_where<'a, 'b>(s1: &'a str, s2: &'b str, second: bool) -> &'a str
1696+ /// where
1697+ /// 'b: 'a,
1698+ /// {
1699+ /// if second {
1700+ /// s2
1701+ /// } else {
1702+ /// s1
1703+ /// }
1704+ /// }
1705+ ///
1706+ /// let outer = String::from("Long living ref");
1707+ /// let longer = &outer;
1708+ /// {
1709+ /// let inner = String::from("Long living ref");
1710+ /// let shorter = &inner;
1711+ ///
1712+ /// assert_eq!(select(shorter, longer, false), shorter);
1713+ /// assert_eq!(select(shorter, longer, true), longer);
1714+ ///
1715+ /// assert_eq!(select_where(shorter, longer, false), shorter);
1716+ /// assert_eq!(select_where(shorter, longer, true), longer);
1717+ /// }
1718+ /// ```
1719+ ///
1720+ /// On the other hand, this will not compile: `shorter` does not have a lifetime
1721+ /// that respects the constraint imposed by the `select` and `select_where`
1722+ /// functions.
1723+ ///
1724+ /// ```rust,compile_fail,E0597
1725+ /// # fn select<'a, 'b: 'a>(s1: &'a str, s2: &'b str, second: bool) -> &'a str {
1726+ /// # if second {
1727+ /// # s2
1728+ /// # } else {
1729+ /// # s1
1730+ /// # }
1731+ /// # }
1732+ /// #
1733+ /// # fn select_where<'a, 'b>(s1: &'a str, s2: &'b str, second: bool) -> &'a str
1734+ /// # where
1735+ /// # 'b: 'a,
1736+ /// # {
1737+ /// # if second {
1738+ /// # s2
1739+ /// # } else {
1740+ /// # s1
1741+ /// # }
1742+ /// # }
1743+ /// let outer = String::from("Long living ref");
1744+ /// let longer = &outer;
1745+ /// let res1;
1746+ /// let res2;
1747+ /// {
1748+ /// let inner = String::from("Long living ref");
1749+ /// let shorter = &inner;
1750+ ///
1751+ /// res1 = select(longer, shorter, false);
1752+ /// res2 = select_where(longer, shorter, false);
1753+ /// }
1754+ /// assert_eq!(res1, &outer);
1755+ /// assert_eq!(res2, &outer);
1756+ /// ```
1757+ ///
1758+ /// `where` can also be used to express more complicated constraints that cannot
1759+ /// be written with the `<T: Trait>` syntax:
1760+ ///
1761+ /// ```rust
1762+ /// fn first_or_default<I>(mut i: I) -> I::Item
1763+ /// where
1764+ /// I: Iterator,
1765+ /// I::Item: Default,
1766+ /// {
1767+ /// i.next().unwrap_or_else(I::Item::default)
1768+ /// }
1769+ ///
1770+ /// assert_eq!(first_or_default(vec![1, 2, 3].into_iter()), 1);
1771+ /// assert_eq!(first_or_default(Vec::<i32>::new().into_iter()), 0);
1772+ /// ```
1773+ ///
1774+ /// `where` is available anywhere generic and lifetime parameters are available:
1775+ ///
1776+ /// ```rust
1777+ /// # #![allow(dead_code)]
1778+ /// // The Cow type from the standard library uses where to impose constraints
1779+ /// // on its parameters.
1780+ /// pub enum Cow<'a, B>
1781+ /// where
1782+ /// B: 'a + ToOwned + ?Sized,
1783+ /// {
1784+ /// Borrowed(&'a B),
1785+ /// Owned(<B as ToOwned>::Owned),
1786+ /// }
1787+ /// ```
1788+ ///
1789+ /// [RFC]: https://github.com/rust-lang/rfcs/blob/master/text/0135-where.md
16571790mod where_keyword { }
16581791
16591792// 2018 Edition keywords
0 commit comments