@@ -1651,9 +1651,142 @@ mod use_keyword {}
1651
1651
//
1652
1652
/// Add constraints that must be upheld to use an item.
1653
1653
///
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.
1655
1657
///
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
1657
1790
mod where_keyword { }
1658
1791
1659
1792
// 2018 Edition keywords
0 commit comments