Skip to content

Commit 837a761

Browse files
committed
Document the where keyword
1 parent f844ea1 commit 837a761

File tree

1 file changed

+135
-2
lines changed

1 file changed

+135
-2
lines changed

src/libstd/keyword_docs.rs

+135-2
Original file line numberDiff line numberDiff line change
@@ -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
16571790
mod where_keyword {}
16581791

16591792
// 2018 Edition keywords

0 commit comments

Comments
 (0)