@@ -1870,9 +1870,100 @@ mod use_keyword {}
18701870//
18711871/// Add constraints that must be upheld to use an item.
18721872///
1873- /// The documentation for this keyword is [not yet complete]. Pull requests welcome!
1873+ /// `where` allows specifying constraints on lifetime and generic parameters.
1874+ /// The [RFC] introducing `where` contains detailed informations about the
1875+ /// keyword.
18741876///
1875- /// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
1877+ /// # Examples
1878+ ///
1879+ /// `where` can be used for constraints with traits:
1880+ ///
1881+ /// ```rust
1882+ /// fn new<T: Default>() -> T {
1883+ /// T::default()
1884+ /// }
1885+ ///
1886+ /// fn new_where<T>() -> T
1887+ /// where
1888+ /// T: Default,
1889+ /// {
1890+ /// T::default()
1891+ /// }
1892+ ///
1893+ /// assert_eq!(0.0, new());
1894+ /// assert_eq!(0.0, new_where());
1895+ ///
1896+ /// assert_eq!(0, new());
1897+ /// assert_eq!(0, new_where());
1898+ /// ```
1899+ ///
1900+ /// `where` can also be used for lifetimes.
1901+ ///
1902+ /// This compiles because `longer` outlives `shorter`, thus the constraint is
1903+ /// respected:
1904+ ///
1905+ /// ```rust
1906+ /// fn select<'short, 'long>(s1: &'short str, s2: &'long str, second: bool) -> &'short str
1907+ /// where
1908+ /// 'long: 'short,
1909+ /// {
1910+ /// if second { s2 } else { s1 }
1911+ /// }
1912+ ///
1913+ /// let outer = String::from("Long living ref");
1914+ /// let longer = &outer;
1915+ /// {
1916+ /// let inner = String::from("Short living ref");
1917+ /// let shorter = &inner;
1918+ ///
1919+ /// assert_eq!(select(shorter, longer, false), shorter);
1920+ /// assert_eq!(select(shorter, longer, true), longer);
1921+ /// }
1922+ /// ```
1923+ ///
1924+ /// On the other hand, this will not compile because the `where 'b: 'a` clause
1925+ /// is missing: the `'b` lifetime is not known to live at least as long as `'a`
1926+ /// which means this function cannot ensure it always returns a valid reference:
1927+ ///
1928+ /// ```rust,compile_fail,E0623
1929+ /// fn select<'a, 'b>(s1: &'a str, s2: &'b str, second: bool) -> &'a str
1930+ /// {
1931+ /// if second { s2 } else { s1 }
1932+ /// }
1933+ /// ```
1934+ ///
1935+ /// `where` can also be used to express more complicated constraints that cannot
1936+ /// be written with the `<T: Trait>` syntax:
1937+ ///
1938+ /// ```rust
1939+ /// fn first_or_default<I>(mut i: I) -> I::Item
1940+ /// where
1941+ /// I: Iterator,
1942+ /// I::Item: Default,
1943+ /// {
1944+ /// i.next().unwrap_or_else(I::Item::default)
1945+ /// }
1946+ ///
1947+ /// assert_eq!(first_or_default(vec![1, 2, 3].into_iter()), 1);
1948+ /// assert_eq!(first_or_default(Vec::<i32>::new().into_iter()), 0);
1949+ /// ```
1950+ ///
1951+ /// `where` is available anywhere generic and lifetime parameters are available,
1952+ /// as can be seen with the [`Cow`](crate::borrow::Cow) type from the standard
1953+ /// library:
1954+ ///
1955+ /// ```rust
1956+ /// # #![allow(dead_code)]
1957+ /// pub enum Cow<'a, B>
1958+ /// where
1959+ /// B: 'a + ToOwned + ?Sized,
1960+ /// {
1961+ /// Borrowed(&'a B),
1962+ /// Owned(<B as ToOwned>::Owned),
1963+ /// }
1964+ /// ```
1965+ ///
1966+ /// [RFC]: https://github.com/rust-lang/rfcs/blob/master/text/0135-where.md
18761967mod where_keyword { }
18771968
18781969// 2018 Edition keywords
0 commit comments