Skip to content

Commit 6612590

Browse files
committed
Add docs for never primitive
1 parent 45594d5 commit 6612590

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

src/librustdoc/clean/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,6 +1783,7 @@ pub enum PrimitiveType {
17831783
RawPointer,
17841784
Reference,
17851785
Fn,
1786+
Never,
17861787
}
17871788

17881789
#[derive(Clone, RustcEncodable, RustcDecodable, Copy, Debug)]
@@ -1824,6 +1825,7 @@ impl Type {
18241825
RawPointer(..) => Some(PrimitiveType::RawPointer),
18251826
BorrowedRef { type_: box Generic(..), .. } => Some(PrimitiveType::Reference),
18261827
BareFunction(..) => Some(PrimitiveType::Fn),
1828+
Never => Some(PrimitiveType::Never),
18271829
_ => None,
18281830
}
18291831
}
@@ -1872,6 +1874,7 @@ impl GetDefId for Type {
18721874
Primitive(PrimitiveType::Tuple).def_id()
18731875
},
18741876
BareFunction(..) => Primitive(PrimitiveType::Fn).def_id(),
1877+
Never => Primitive(PrimitiveType::Never).def_id(),
18751878
Slice(..) => Primitive(PrimitiveType::Slice).def_id(),
18761879
Array(..) => Primitive(PrimitiveType::Array).def_id(),
18771880
RawPointer(..) => Primitive(PrimitiveType::RawPointer).def_id(),
@@ -1908,6 +1911,7 @@ impl PrimitiveType {
19081911
"pointer" => Some(PrimitiveType::RawPointer),
19091912
"reference" => Some(PrimitiveType::Reference),
19101913
"fn" => Some(PrimitiveType::Fn),
1914+
"never" => Some(PrimitiveType::Never),
19111915
_ => None,
19121916
}
19131917
}
@@ -1939,6 +1943,7 @@ impl PrimitiveType {
19391943
RawPointer => "pointer",
19401944
Reference => "reference",
19411945
Fn => "fn",
1946+
Never => "never",
19421947
}
19431948
}
19441949

@@ -2873,6 +2878,7 @@ fn build_deref_target_impls(cx: &DocContext,
28732878
RawPointer => tcx.lang_items().const_ptr_impl(),
28742879
Reference => None,
28752880
Fn => None,
2881+
Never => None,
28762882
};
28772883
if let Some(did) = did {
28782884
if !did.is_local() {

src/libstd/primitive_docs.rs

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,110 @@
6767
#[stable(feature = "rust1", since = "1.0.0")]
6868
mod prim_bool { }
6969

70+
#[doc(primitive = "never")]
71+
//
72+
/// The `!` type, also called "never".
73+
///
74+
/// `!` represents the type of computations which never resolve to any value at all. For example,
75+
/// the [`exit`] function `fn exit(code: i32) -> !` exits the process without ever returning, and
76+
/// so returns `!`.
77+
///
78+
/// `break`, `continue` and `return` expressions also have type `!`. For example we are allowed to
79+
/// write
80+
///
81+
/// ```
82+
/// let x: ! = {
83+
/// return 123;
84+
/// };
85+
/// ```
86+
///
87+
/// Although the `let` is pointless here, it illustrates the meaning of `!`. Since `x` is never
88+
/// assigned a value (because `return` returns from the entire function), `x` can be given type
89+
/// `!`. We could also replace `return 123` with a `panic!` or a never-ending `loop` and this code
90+
/// would still be valid.
91+
///
92+
/// A more realistic usage of `!` is in this code:
93+
///
94+
/// ```
95+
/// let num: u32 = match get_a_number() {
96+
/// Some(num) => num,
97+
/// None => break,
98+
/// }
99+
/// ```
100+
///
101+
/// Both match arms must produce values of type `u32`, but since `break` never produces a value at
102+
/// all we know it can never produce a value which isn't a `u32`. This illustrates another
103+
/// behaviour of the `!` type - expressions with type `!` will coerce into any other type.
104+
///
105+
/// [`exit`]: process/fn.exit.html
106+
///
107+
/// # `!` and generics
108+
///
109+
/// The main place you'll see `!` used explicitly is in generic code. Consider the [`FromStr`]
110+
/// trait:
111+
///
112+
/// ```
113+
/// trait FromStr {
114+
/// type Error;
115+
/// fn from_str(s: &str) -> Result<Self, Self::Error>;
116+
/// }
117+
/// ```
118+
///
119+
/// When implementing this trait for `String` we need to pick a type for `Error`. And since
120+
/// converting a string into a string will never result in an error, the appropriate type is `!`.
121+
/// If we have to call `String::from_str` for some reason, the result will be a
122+
/// `Result<String, !>`, which we can unpack like this:
123+
///
124+
/// ```
125+
/// let Ok(s) = String::from_str("hello");
126+
/// ```
127+
///
128+
/// Since the `Err` variant contains a `!`, it can never occur. So we can exhaustively match on
129+
/// `Result<T, !>` by just taking the `Ok` variant. This illustrates another behaviour of `!` - it
130+
/// can be used to "delete" certain enum variants from generic types like `Result`.
131+
///
132+
/// [`FromStr`]: str/trait.FromStr.html
133+
///
134+
/// # `!` and traits
135+
///
136+
/// When writing your own traits, `!` should have an `impl` whenever there is an obvious `impl`
137+
/// which doesn't `panic!`. As is turns out, most traits can have an `impl` for `!`. Take [`Debug`]
138+
/// for example:
139+
///
140+
/// ```
141+
/// impl Debug for ! {
142+
/// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
143+
/// *self
144+
/// }
145+
/// }
146+
/// ```
147+
///
148+
/// Once again we're using `!`'s ability to coerce into any other type, in this case `fmt::Result`.
149+
/// Since this method takes a `&!` as an argument we know that it can never be called (because
150+
/// there is no value of type `!` for it to be called with). Writing `*self` essentially tells the
151+
/// compiler "We know that this code can never be run, so just treat the entire function body has
152+
/// having type `fmt::Result`". This pattern can be used a lot when implementing traits for `!`.
153+
/// Generally, any trait which only has methods which take a `self` parameter should have such as
154+
/// impl.
155+
///
156+
/// On the other hand, one trait which would not be appropriate to implement is [`Default`]:
157+
///
158+
/// ```
159+
/// trait Default {
160+
/// fn default() -> Self;
161+
/// }
162+
/// ```
163+
///
164+
/// Since `!` has no values, it has no default value either. It's true that we could write an
165+
/// `impl` for this which simply panics, but the same is true for any type (we could `impl
166+
/// Default` for (eg.) `File` by just making `default()` panic.)
167+
///
168+
/// [`Debug`]: fmt/trait.Debug.html
169+
/// [`Default`]: default/trait.Default.html
170+
///
171+
#[stable(feature = "rust1", since = "1.23.0")]
172+
mod prim_never { }
173+
70174
#[doc(primitive = "char")]
71175
//
72176
/// A character type.

0 commit comments

Comments
 (0)