Skip to content

Commit 8cbcecd

Browse files
authored
Merge pull request #99 from arielb1/modern-functions
modernize the function sections in the reference
2 parents 0168b9f + b40e519 commit 8cbcecd

File tree

3 files changed

+82
-41
lines changed

3 files changed

+82
-41
lines changed

src/expressions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ assert_eq!(unit_x.0, 1.0);
503503
A _call expression_ consists of an expression followed by a parenthesized
504504
expression-list. It invokes a function, providing zero or more input variables.
505505
If the function eventually returns, then the expression completes. For
506-
[non-function types](types.html#function-types), the expression f(...) uses the
506+
[non-function types](types.html#function-item-types), the expression f(...) uses the
507507
method on one of the `std::ops::Fn`, `std::ops::FnMut` or `std::ops::FnOnce`
508508
traits, which differ in whether they take the type by reference, mutable
509509
reference, or take ownership respectively. An automatic borrow will be taken if
@@ -962,7 +962,7 @@ well as the following additional casts. Here `*T` means either `*const T` or
962962
| `*T` where `T: Sized` | Numeric type | Pointer to address cast |
963963
| Integer type | `*V` where `V: Sized` | Address to pointer cast |
964964
| `&[T; n]` | `*const T` | Array to pointer cast |
965-
| [Function pointer](types.html#function-types) | `*V` where `V: Sized` | Function pointer to pointer cast |
965+
| [Function pointer](types.html#function-pointer-types) | `*V` where `V: Sized` | Function pointer to pointer cast |
966966
| Function pointer | Integer | Function pointer to address cast |
967967

968968
\* or `T` and `V` are compatible unsized types, e.g., both slices, both the

src/items.md

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -270,46 +270,52 @@ fn main() {}
270270

271271
## Functions
272272

273-
A _function item_ defines a sequence of [statements] and a
274-
final [expression], along with a name and a set of
273+
A _function_ consists of a [block], along with a name and a set of
275274
parameters. Other than a name, all these are optional.
276275
Functions are declared with the keyword `fn`. Functions may declare a
277276
set of *input* [*variables*][variables] as parameters, through which the caller
278277
passes arguments into the function, and the *output* [*type*][type]
279278
of the value the function will return to its caller on completion.
280279

281-
[statements]: statements.html
282-
[expression]: expressions.html
280+
[block]: expressions.html#block-expressions
283281
[variables]: variables.html
284282
[type]: types.html
285283

286-
A function may also be copied into a first-class *value*, in which case the
287-
value has the corresponding [*function type*][function type], and can be used
288-
otherwise exactly as a function item (with a minor additional cost of calling
289-
the function indirectly).
284+
When referred to, a _function_ yields a first-class *value* of the
285+
corresponding zero-sized [*function item type*][function item type], which
286+
when called evaluates to a direct call to the function.
290287

291-
[function type]: types.html#function-types
292-
293-
Every control path in a function logically ends with a `return` expression or a
294-
diverging expression. If the outermost block of a function has a
295-
value-producing expression in its final-expression position, that expression is
296-
interpreted as an implicit `return` expression applied to the final-expression.
297-
298-
An example of a function:
288+
[function item type]: types.html#function-item-types
299289

290+
For example, this is a simple function:
300291
```rust
301-
fn add(x: i32, y: i32) -> i32 {
302-
x + y
292+
fn answer_to_life_the_universe_and_everything() -> i32 {
293+
return 42;
303294
}
304295
```
305296

306297
As with `let` bindings, function arguments are irrefutable patterns, so any
307-
pattern that is valid in a let binding is also valid as an argument.
298+
pattern that is valid in a let binding is also valid as an argument:
308299

309300
```rust
310301
fn first((value, _): (i32, i32)) -> i32 { value }
311302
```
312303

304+
The block of a function is conceptually wrapped in a block that binds the
305+
argument patterns and then `return`s the value of the function's block. This
306+
means that the tail expression of the block, if evaluated, ends up being
307+
returned to the caller. As usual, an explicit return expression within
308+
the body of the function will short-cut that implicit return, if reached.
309+
310+
For example, the function above behaves as if it was written as:
311+
312+
```rust,ignore
313+
// argument_0 is the actual first argument passed from the caller
314+
let (value, _) = argument_0;
315+
return {
316+
value
317+
};
318+
```
313319

314320
### Generic functions
315321

src/types.md

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,62 @@ varieties of pointer in Rust:
230230
The standard library contains additional 'smart pointer' types beyond references
231231
and raw pointers.
232232

233-
## Function types
233+
## Function item types
234234

235-
The function type constructor `fn` forms new function types. A function type
236-
consists of a possibly-empty set of function-type modifiers (such as `unsafe`
237-
or `extern`), a sequence of input types and an output type.
235+
When referred to, a function item yields a zero-sized value of its
236+
_function item type_. That type explicitly identifies the function - its name,
237+
its type arguments, and its early-bound lifetime arguments (but not its
238+
late-bound lifetime arguments, which are only assigned when the function
239+
is called) - so the value does not need to contain an actual function pointer,
240+
and no indirection is needed when the function is called.
241+
242+
There is currently no syntax that directly refers to a function item type, but
243+
the compiler will display the type as something like `fn() {foo::<u32>}` in error
244+
messages.
245+
246+
Because the function item type explicitly identifies the function, the item
247+
types of different functions - different items, or the same item with different
248+
generics - are distinct, and mixing them will create a type error:
249+
250+
```rust,ignore
251+
fn foo<T>() { }
252+
let x = &mut foo::<i32>;
253+
*x = foo::<u32>; //~ ERROR mismatched types
254+
```
255+
256+
However, there is a [coercion] from function items to [function pointers](#function-pointer-types)
257+
with the same signature, which is triggered not only when a function item
258+
is used when a function pointer is directly expected, but also when different
259+
function item types with the same signature meet in different arms of the same
260+
`if` or `match`:
261+
262+
[coercion]: type-coercions.html
263+
264+
```rust
265+
# let want_i32 = false;
266+
# fn foo<T>() { }
267+
268+
// `foo_ptr_1` has function pointer type `fn()` here
269+
let foo_ptr_1: fn() = foo::<i32>;
270+
271+
// ... and so does `foo_ptr_2` - this type-checks.
272+
let foo_ptr_2 = if want_i32 {
273+
foo::<i32>
274+
} else {
275+
foo::<u32>
276+
};
277+
```
278+
279+
## Function pointer types
280+
281+
Function pointer types, created using the `fn` type constructor, refer
282+
to a function whose identity is not necessarily known at compile-time. They
283+
can be created via a coercion from both [function items](#function-item-types)
284+
and non-capturing [closures](#closure-types).
285+
286+
A function pointer type consists of a possibly-empty set of function-type
287+
modifiers (such as `unsafe` or `extern`), a sequence of input types and an
288+
output type.
238289

239290
An example of a `fn` type:
240291

@@ -250,22 +301,6 @@ let bo: Binop = add;
250301
x = bo(5,7);
251302
```
252303

253-
### Function types for specific items
254-
255-
Internal to the compiler, there are also function types that are specific to a particular
256-
function item. In the following snippet, for example, the internal types of the functions
257-
`foo` and `bar` are different, despite the fact that they have the same signature:
258-
259-
```rust
260-
fn foo() { }
261-
fn bar() { }
262-
```
263-
264-
The types of `foo` and `bar` can both be implicitly coerced to the fn
265-
pointer type `fn()`. There is currently no syntax for unique fn types,
266-
though the compiler will emit a type like `fn() {foo}` in error
267-
messages to indicate "the unique fn type for the function `foo`".
268-
269304
## Closure types
270305

271306
A [closure expression](expressions.html#closure-expressions) produces a closure

0 commit comments

Comments
 (0)