Skip to content

Commit b57707c

Browse files
committed
---
yaml --- r: 2743 b: refs/heads/master c: ac3fd91 h: refs/heads/master i: 2741: 37023ab 2739: 671093f 2735: 7bafdc6 v: v3
1 parent ac0dea8 commit b57707c

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: db7611c4c9b8a0ad84d8e69930d237b74211ceb1
2+
refs/heads/master: ac3fd914b9227069b616b5b997620e8d001bd2ca

trunk/doc/rust.texi

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1800,8 +1800,9 @@ the value has the corresponding @emph{function type}, and can be used
18001800
otherwise exactly as a function item (with a minor additional cost of calling
18011801
the function, as such a call is indirect). @xref{Ref.Type.Fn}.
18021802

1803-
Every control path in a function ends with either a @code{ret} or @code{be}
1804-
expression. If a control path lacks a @code{ret} expression in source code, an
1803+
Every control path in a function ends with a @code{ret} or @code{be}
1804+
expression or with a diverging expression (described later in this
1805+
section). If a control path lacks a @code{ret} expression in source code, an
18051806
implicit @code{ret} expression is appended to the end of the control path
18061807
during compilation, returning the implicit @code{()} value.
18071808

@@ -1812,6 +1813,44 @@ fn add(int x, int y) -> int @{
18121813
@}
18131814
@end example
18141815

1816+
A special kind of function can be declared with a @code{!} character where the
1817+
output slot type would normally be. For example:
1818+
@example
1819+
fn my_err(str s) -> ! @{
1820+
log s;
1821+
fail;
1822+
@}
1823+
@end example
1824+
1825+
We call such functions ``diverging'' because they never return a value to the
1826+
caller. Every control path in a diverging function must end with a @code{fail}
1827+
or a call to another diverging function on every control path. The @code{!}
1828+
annotation does @emph{not} denote a type. Rather, the result type
1829+
of a diverging function is a special type called @math{\bot} (``bottom'') that
1830+
unifies with any type. Rust has no syntax for @math{\bot}.
1831+
1832+
It might be necessary to declare a diverging function because as mentioned
1833+
previously, the typechecker checks that every control path in a function ends
1834+
with a @code{ret}, @code{be}, or diverging expression. So, if @code{my_err}
1835+
were declared without the @code{!} annotation, the following code would not
1836+
typecheck:
1837+
@example
1838+
fn f(int i) -> int @{
1839+
if (i == 42) {
1840+
ret 42;
1841+
}
1842+
else {
1843+
my_err("Bad number!");
1844+
}
1845+
@}
1846+
@end example
1847+
1848+
The typechecker would complain that @code{f} doesn't return a value in the
1849+
@code{else} branch. Adding the @code{!} annotation on @code{my_err} would
1850+
express that @code{f} requires no explicit @code{ret}, as if it returns
1851+
control to the caller, it returns a value (true because it never returns
1852+
control).
1853+
18151854
@node Ref.Item.Pred
18161855
@subsection Ref.Item.Pred
18171856
@c * Ref.Item.Pred:: Items defining predicates.

0 commit comments

Comments
 (0)