diff --git a/src/tokens.md b/src/tokens.md
index 4482ffd100..78ec0539ad 100644
--- a/src/tokens.md
+++ b/src/tokens.md
@@ -548,7 +548,7 @@ usages and meanings are defined in the linked pages.
| `>=` | Ge | [Greater than or equal to][comparison], [Generics]
| `<=` | Le | [Less than or equal to][comparison]
| `@` | At | [Subpattern binding]
-| `_` | Underscore | [Wildcard patterns], Inferred types
+| `_` | Underscore | [Wildcard patterns], [Inferred types]
| `.` | Dot | [Field access][field], [Tuple index]
| `..` | DotDot | [Range][range], [Struct expressions], [Patterns]
| `...` | DotDotDot | [Variadic functions][extern], [Range patterns]
@@ -576,6 +576,7 @@ them are referred to as "token trees" in [macros]. The three types of brackets
| `(` `)` | Parentheses |
+[Inferred types]: types.html#inferred-type
[Operator expressions]: expressions/operator-expr.html
[Range patterns]: patterns.html#range-patterns
[Reference patterns]: patterns.html#reference-patterns
diff --git a/src/types.md b/src/types.md
index ec7e221134..0f3a0adaa5 100644
--- a/src/types.md
+++ b/src/types.md
@@ -1,5 +1,26 @@
# Types
+> **Syntax**\
+> _Type_ :\
+> _TypeNoBounds_\
+> | [_ImplTraitType_]\
+> | [_TraitObjectType_]
+>
+> _TypeNoBounds_ :\
+> [_ParenthesizedType_]\
+> | [_ImplTraitTypeOneBound_]\
+> | [_TraitObjectTypeOneBound_]\
+> | [_TypePath_]\
+> | [_TupleType_]\
+> | [_NeverType_]\
+> | [_RawPointerType_]\
+> | [_ReferenceType_]\
+> | [_ArrayType_]\
+> | [_SliceType_]\
+> | [_InferredType_]\
+> | [_QualifiedPathInType_]\
+> | [_BareFunctionType_]
+
Every variable, item and value in a Rust program has a type. The _type_ of a
*value* defines the interpretation of the memory holding it.
@@ -107,12 +128,20 @@ instantiated through a pointer type, such as `&str`.
## Never type
+> **Syntax**\
+> _NeverType_ : `!`
+
The never type `!` is a type with no values, representing the result of
computations that never complete. Expressions of type `!` can be coerced into
any other type.
## Tuple types
+> **Syntax**\
+> _TupleType_ :\
+> `(` `)`\
+> | `(` ( [_Type_] `,` )+ [_Type_]? `)`
+
A tuple *type* is a heterogeneous product of other types, called the *elements*
of the tuple. It has no nominal name and is instead structurally typed.
@@ -139,15 +168,41 @@ assert_eq!(p.1, "ten");
For historical reasons and convenience, the tuple type with no elements (`()`)
is often called ‘unit’ or ‘the unit type’.
+## Parenthesized types
+
+> _ParenthesizedType_ :\
+> `(` [_Type_] `)`
+
+In some situations the combination of types may be ambiguous. Use parentheses
+around a type to avoid ambiguity. For example, the `+` operator for [type
+boundaries] within a [reference type][_ReferenceType_] is unclear where the
+boundary applies, so the use of parentheses is required. Grammar rules that
+require this disambiguation use the [_TypeNoBounds_] rule instead of
+[_Type_].
+
+
+```rust
+# use std::any::Any;
+type T<'a> = &'a(Any + Send);
+```
+
## Array, and Slice types
-Rust has two different types for a list of items:
+> **Syntax**\
+> _ArrayType_ :\
+> `[` [_Type_] `;` [_Expression_] `]`
+>
+> _SliceType_ :\
+> `[` [_Type_] `]`
+
+Rust has two different types for a list of items of the same type:
* `[T; N]`, an 'array'
* `[T]`, a 'slice'
An array has a fixed size, and can be allocated on either the stack or the
-heap.
+heap. The size is an expression that evaluates to a
+[`usize`](#machine-dependent-integer-types).
A slice is a [dynamically sized type] representing a 'view' into an array. To
use a slice type it generally has to be used behind a pointer for example as
@@ -276,6 +331,10 @@ copied, stored into data structs, and returned from functions.
### Shared references (`&`)
+> **Syntax**\
+> _ReferenceType_ :\
+> `&` [_Lifetime_]? `mut`? [_TypeNoBounds_]
+
These point to memory _owned by some other value_. When a shared reference to a
value is created it prevents direct mutation of the value. [Interior
mutability](interior-mutability.html) provides an exception for this in certain
@@ -295,6 +354,10 @@ borrowed) is the only way to access the value it points to, so is not `Copy`.
### Raw pointers (`*const` and `*mut`)
+> **Syntax**\
+> _RawPointerType_ :\
+> `*` ( `mut` | `const` ) [_TypeNoBounds_]
+
Raw pointers are pointers without safety or liveness guarantees. Raw pointers
are written as `*const T` or `*mut T`, for example `*const i32` means a raw
pointer to a 32-bit integer. Copying or dropping a raw pointer has no effect on
@@ -366,6 +429,26 @@ All function items implement [`Fn`], [`FnMut`], [`FnOnce`], [`Copy`],
## Function pointer types
+> **Syntax**\
+> _BareFunctionType_ :\
+> [_ForLifetimes_]? [_FunctionFront_] `fn`\
+> `(` _FunctionParametersMaybeNamedVariadic_? `)` _BareFunctionReturnType_?
+>
+> _BareFunctionReturnType_:\
+> `->` [_TypeNoBounds_]
+>
+> _FunctionParametersMaybeNamedVariadic_ :\
+> _MaybeNamedFunctionParameters_ | _MaybeNamedFunctionParametersVariadic_
+>
+> _MaybeNamedFunctionParameters_ :\
+> _MaybeNamedParam_ ( `,` _MaybeNamedParam_ )\* `,`?
+>
+> _MaybeNamedParam_ :\
+> ( ( [IDENTIFIER] | `_` ) `:` )? [_Type_]
+>
+> _MaybeNamedFunctionParametersVariadic_ :\
+> ( _MaybeNamedParam_ `,` )\* _MaybeNamedParam_ `,` `...`
+
Function pointer types, written using the `fn` keyword, refer to a function
whose identity is not necessarily known at compile-time. They can be created
via a coercion from both [function items](#function-item-types) and
@@ -375,6 +458,9 @@ A function pointer type consists of a possibly-empty set of function-type
modifiers (such as `unsafe` or `extern`), a sequence of input types and an
output type.
+Variadic parameters can only be specified with [`extern`] function types with
+the `"C"` or `"cdecl"` calling convention.
+
An example where `Binop` is defined as a function pointer type:
```rust
@@ -560,7 +646,10 @@ Because captures are often by reference, the following general rules arise:
> **Syntax**\
> _TraitObjectType_ :\
-> `dyn`? _TypeParamBounds_
+> `dyn`? [_TypeParamBounds_]
+>
+> _TraitObjectTypeOneBound_ :\
+> `dyn`? [_TraitBound_]
A *trait object* is an opaque value of another type that implements a set of
traits. The set of traits is made up of an [object safe] *base trait* plus any
@@ -658,6 +747,24 @@ inferred with a sensible choice.
[defaults]: lifetime-elision.html#default-trait-object-lifetimes
+## Inferred type
+> **Syntax**\
+> _InferredType_ : `_`
+
+The inferred type asks the compiler to infer the type if possible based on the
+surrounding information available. It cannot be used in item signatures. It is
+often used in generic arguments:
+
+```rust
+let x: Vec<_> = (0..10).collect();
+```
+
+
+
## Type parameters
Within the body of an item that has type parameter declarations, the names of
@@ -678,7 +785,14 @@ fn to_vec(xs: &[A]) -> Vec {
Here, `first` has type `A`, referring to `to_vec`'s `A` type parameter; and
`rest` has type `Vec`, a vector with element type `A`.
-## Anonymous type parameters
+## Impl trait
+
+> **Syntax**\
+> _ImplTraitType_ : `impl` [_TypeParamBounds_]
+>
+> _ImplTraitTypeOneBound_ : `impl` [_TraitBound_]
+
+### Anonymous type parameters
> Note: This section is a placeholder for more comprehensive reference
> material.
@@ -692,7 +806,7 @@ bounds of the anonymous type parameter.
They are written as `impl` followed by a set of trait bounds.
-## Abstract return types
+### Abstract return types
> Note: This section is a placeholder for more comprehensive reference
> material.
@@ -740,6 +854,31 @@ impl Printable for String {
> Note: The notation `&self` is a shorthand for `self: &Self`.
+[IDENTIFIER]: identifiers.html
+[_ArrayType_]: #array-and-slice-types
+[_BareFunctionType_]: #function-pointer-types
+[_Expression_]: expressions.html
+[_ForLifetimes_]: items/generics.html#where-clauses
+[_FunctionFront_]: items/functions.html
+[_FunctionParametersMaybeNamed_]: items/functions.html
+[_ImplTraitTypeOneBound_]: #impl-trait
+[_ImplTraitType_]: #impl-trait
+[_InferredType_]: #inferred-type
+[_Lifetime_]: trait-bounds.html
+[_NeverType_]: #never-type
+[_ParenthesizedType_]: #parenthesized-types
+[_QualifiedPathInType_]: paths.html#qualified-paths
+[_RawPointerType_]: #raw-pointers-const-and-mut
+[_ReferenceType_]: #shared-references-
+[_SliceType_]: #array-and-slice-types
+[_TraitBound_]: trait-bounds.html
+[_TraitObjectTypeOneBound_]: #trait-objects
+[_TraitObjectType_]: #trait-objects
+[_TupleType_]: #tuple-types
+[_TypeNoBounds_]: #types
+[_TypeParamBounds_]: trait-bounds.html
+[_TypePath_]: paths.html#paths-in-types
+[_Type_]: #types
[`Fn`]: ../std/ops/trait.Fn.html
[`FnMut`]: ../std/ops/trait.FnMut.html
[`FnOnce`]: ../std/ops/trait.FnOnce.html
@@ -748,6 +887,7 @@ impl Printable for String {
[`Send`]: special-types-and-traits.html#send
[`Sync`]: special-types-and-traits.html#sync
[`Sized`]: special-types-and-traits.html#sized
+[`extern`]: items/external-blocks.html
[derive]: attributes.html#derive
[`Vec`]: ../std/vec/struct.Vec.html
[dynamically sized type]: dynamically-sized-types.html
@@ -759,3 +899,4 @@ impl Printable for String {
[issue 47010]: https://github.com/rust-lang/rust/issues/47010
[issue 33140]: https://github.com/rust-lang/rust/issues/33140
[supertraits]: items/traits.html#supertraits
+[type boundaries]: trait-bounds.html