Skip to content

Commit ba6857d

Browse files
committed
Document the trait keyword
1 parent e093b65 commit ba6857d

File tree

1 file changed

+172
-3
lines changed

1 file changed

+172
-3
lines changed

src/libstd/keyword_docs.rs

Lines changed: 172 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,11 +1353,180 @@ mod super_keyword {}
13531353

13541354
#[doc(keyword = "trait")]
13551355
//
1356-
/// A common interface for a class of types.
1356+
/// A common interface for a group of types.
13571357
///
1358-
/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
1358+
/// A `trait` is an interface that types can implement. It is said they
1359+
/// "implement" the trait or "conform" to the trait.
13591360
///
1360-
/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
1361+
/// This interface is made up of three varieties of items:
1362+
///
1363+
/// - functions
1364+
/// - types
1365+
/// - constants
1366+
///
1367+
/// Traits may also contain additional type parameters. Those type parameters
1368+
/// or the trait itself can be constrained by other traits.
1369+
///
1370+
/// See the [Reference][Ref-Traits] for a lot more information on traits.
1371+
///
1372+
/// # Examples
1373+
///
1374+
/// Traits are declared using the `trait` keyword. Types can implement them
1375+
/// using [`impl`] `Trait` [`for`] `Type`:
1376+
///
1377+
/// ```rust
1378+
/// trait Zero {
1379+
/// const ZERO: Self;
1380+
/// fn is_zero(&self) -> bool;
1381+
/// }
1382+
///
1383+
/// impl Zero for i32 {
1384+
/// const ZERO: Self = 0;
1385+
///
1386+
/// fn is_zero(&self) -> bool {
1387+
/// *self == Self::ZERO
1388+
/// }
1389+
/// }
1390+
///
1391+
/// assert_eq!(i32::ZERO, 0);
1392+
/// assert!(i32::ZERO.is_zero());
1393+
/// assert!(!4.is_zero());
1394+
/// ```
1395+
///
1396+
/// With an associated type:
1397+
///
1398+
/// ```rust
1399+
/// trait Builder {
1400+
/// type Built;
1401+
///
1402+
/// fn build(&self) -> Self::Built;
1403+
/// }
1404+
/// ```
1405+
///
1406+
/// Traits can be generic, with constraints or without:
1407+
///
1408+
/// ```rust
1409+
/// trait MaybeFrom<T> {
1410+
/// fn maybe_from(value: T) -> Option<Self>
1411+
/// where
1412+
/// Self: Sized;
1413+
/// }
1414+
/// ```
1415+
///
1416+
/// Traits can build upon the requirements of other traits. In the example
1417+
/// below `Iterator` is a **supertrait** and `ThreeIterator` is a **subtrait**:
1418+
///
1419+
/// ```rust
1420+
/// trait ThreeIterator: std::iter::Iterator {
1421+
/// fn next_three(&mut self) -> Option<[Self::Item; 3]>;
1422+
/// }
1423+
/// ```
1424+
///
1425+
/// Traits can be used in functions, as parameters:
1426+
///
1427+
/// ```rust
1428+
/// # #![allow(dead_code)]
1429+
/// fn debug_iter<I: Iterator>(it: I) where I::Item: std::fmt::Debug {
1430+
/// for elem in it {
1431+
/// println!("{:#?}", elem);
1432+
/// }
1433+
/// }
1434+
///
1435+
/// // u8_len_1, u8_len_2 and u8_len_3 are equivalent
1436+
///
1437+
/// fn u8_len_1(val: impl Into<Vec<u8>>) -> usize {
1438+
/// val.into().len()
1439+
/// }
1440+
///
1441+
/// fn u8_len_2<T: Into<Vec<u8>>>(val: T) -> usize {
1442+
/// val.into().len()
1443+
/// }
1444+
///
1445+
/// fn u8_len_3<T>(val: T) -> usize
1446+
/// where
1447+
/// T: Into<Vec<u8>>,
1448+
/// {
1449+
/// val.into().len()
1450+
/// }
1451+
/// ```
1452+
///
1453+
/// Or as return types:
1454+
///
1455+
/// ```rust
1456+
/// # #![allow(dead_code)]
1457+
/// fn from_zero_to(v: u8) -> impl Iterator<Item = u8> {
1458+
/// (0..v).into_iter()
1459+
/// }
1460+
/// ```
1461+
///
1462+
/// The use of the [`impl`] keyword in this position allows the function writer
1463+
/// to hide the concrete type as an implementation detail which can change
1464+
/// without breaking user's code.
1465+
///
1466+
/// # Trait objects
1467+
///
1468+
/// A *trait object* is an opaque value of another type that implements a set of
1469+
/// traits. A trait object implements all specified traits as well as their
1470+
/// supertraits (if any).
1471+
///
1472+
/// The syntax is the following: `dyn BaseTrait + AutoTrait1 + ... AutoTraitN`.
1473+
/// Only one `BaseTrait` can be used so this will not compile:
1474+
///
1475+
/// ```rust,compile_fail,E0225
1476+
/// trait A {}
1477+
/// trait B {}
1478+
///
1479+
/// let _: Box<dyn A + B>;
1480+
/// ```
1481+
///
1482+
/// Neither will this, which is a syntax error:
1483+
///
1484+
/// ```rust,compile_fail
1485+
/// trait A {}
1486+
/// trait B {}
1487+
///
1488+
/// let _: Box<dyn A + dyn B>;
1489+
/// ```
1490+
///
1491+
/// On the other hand, this is correct:
1492+
///
1493+
/// ```rust
1494+
/// trait A {}
1495+
///
1496+
/// let _: Box<dyn A + Send + Sync>;
1497+
/// ```
1498+
///
1499+
/// The [Reference][Ref-Trait-Objects] has more information about trait objects,
1500+
/// their limitations and the differences between editions.
1501+
///
1502+
/// # Unsafe traits
1503+
///
1504+
/// Some traits may be unsafe to implement. Using the [`unsafe`] keyword in
1505+
/// front of the trait's declaration is used to mark this:
1506+
///
1507+
/// ```rust
1508+
/// unsafe trait UnsafeTrait {}
1509+
///
1510+
/// unsafe impl UnsafeTrait for i32 {}
1511+
/// ```
1512+
///
1513+
/// # Differences between the 2015 and 2018 editions
1514+
///
1515+
/// In the 2015 edition parameters pattern where not needed for traits:
1516+
///
1517+
/// ```rust,edition2015
1518+
/// trait Tr {
1519+
/// fn f(i32);
1520+
/// }
1521+
/// ```
1522+
///
1523+
/// This behavior is no longer valid in edition 2018.
1524+
///
1525+
/// [`for`]: keyword.for.html
1526+
/// [`impl`]: keyword.impl.html
1527+
/// [`unsafe`]: keyword.unsafe.html
1528+
/// [Ref-Traits]: ../reference/items/traits.html
1529+
/// [Ref-Trait-Objects]: ../reference/types/trait-object.html
13611530
mod trait_keyword {}
13621531

13631532
#[doc(keyword = "true")]

0 commit comments

Comments
 (0)