| r[type] | |
| # Types | |
| r[type.intro] | |
| 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 and the operations that may be performed on the value. | |
| r[type.builtin] | |
| Built-in types are tightly integrated into the language, in nontrivial ways that are not possible to emulate in user-defined types. | |
| r[type.user-defined] | |
| User-defined types have limited capabilities. | |
| r[type.kinds] | |
| The list of types is: | |
| * Primitive types: | |
| * [Boolean] --- `bool` | |
| * [Numeric] --- integer and float | |
| * [`char`] | |
| * [`str`] | |
| * [Never] --- `!` --- a type with no values | |
| * Sequence types: | |
| * [Tuple] | |
| * [Array] | |
| * [Slice] | |
| * User-defined types: | |
| * [Struct] | |
| * [Enum] | |
| * [Union] | |
| * Function types: | |
| * [Functions] | |
| * [Closures] | |
| * Pointer types: | |
| * [References] | |
| * [Raw pointers] | |
| * [Function pointers] | |
| * Trait types: | |
| * [Trait objects] | |
| * [Impl trait] | |
| r[type.name] | |
| ## Type expressions | |
| r[type.name.syntax] | |
| ```grammar,types | |
| Type -> | |
| TypeNoBounds | |
| | ImplTraitType | |
| | TraitObjectType | |
| TypeNoBounds -> | |
| ParenthesizedType | |
| | ImplTraitTypeOneBound | |
| | TraitObjectTypeOneBound | |
| | TypePath | |
| | TupleType | |
| | NeverType | |
| | RawPointerType | |
| | ReferenceType | |
| | ArrayType | |
| | SliceType | |
| | InferredType | |
| | QualifiedPathInType | |
| | BareFunctionType | |
| | MacroInvocation | |
| ``` | |
| r[type.name.intro] | |
| A _type expression_ as defined in the [Type] grammar rule above is the syntax for referring to a type. It may refer to: | |
| r[type.name.sequence] | |
| * Sequence types ([tuple], [array], [slice]). | |
| r[type.name.path] | |
| * [Type paths] which can reference: | |
| * Primitive types ([boolean], [numeric], [`char`], [`str`]). | |
| * Paths to an [item] ([struct], [enum], [union], [type alias], [trait]). | |
| * [`Self` path] where `Self` is the implementing type. | |
| * Generic [type parameters]. | |
| r[type.name.pointer] | |
| * Pointer types ([reference], [raw pointer], [function pointer]). | |
| r[type.name.inference] | |
| * The [inferred type] which asks the compiler to determine the type. | |
| r[type.name.grouped] | |
| * [Parentheses] which are used for disambiguation. | |
| r[type.name.trait] | |
| * Trait types: [Trait objects] and [impl trait]. | |
| r[type.name.never] | |
| * The [never] type. | |
| r[type.name.macro-expansion] | |
| * [Macros] which expand to a type expression. | |
| r[type.name.parenthesized] | |
| ### Parenthesized types | |
| r[type.name.parenthesized.syntax] | |
| ```grammar,types | |
| ParenthesizedType -> `(` Type `)` | |
| ``` | |
| r[type.name.parenthesized.intro] | |
| 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] 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][grammar-Type]. | |
| ```rust | |
| # use std::any::Any; | |
| type T<'a> = &'a (dyn Any + Send); | |
| ``` | |
| r[type.recursive] | |
| ## Recursive types | |
| r[type.recursive.intro] | |
| Nominal types — [structs], [enumerations], and [unions] — may be recursive. That is, each `enum` variant or `struct` or `union` field may refer, directly or indirectly, to the enclosing `enum` or `struct` type itself. | |
| r[type.recursive.constraint] | |
| Such recursion has restrictions: | |
| * Recursive types must include a nominal type in the recursion (not mere [type aliases], or other structural types such as [arrays] or [tuples]). So `type Rec = &'static [Rec]` is not allowed. | |
| * The size of a recursive type must be finite; in other words the recursive fields of the type must be [pointer types]. | |
| An example of a *recursive* type and its use: | |
| ```rust | |
| enum List<T> { | |
| Nil, | |
| Cons(T, Box<List<T>>) | |
| } | |
| let a: List<i32> = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil)))); | |
| ``` | |
| [`char`]: types/char.md | |
| [`str`]: types/str.md | |
| [Array]: types/array.md | |
| [Boolean]: types/boolean.md | |
| [Closures]: types/closure.md | |
| [Enum]: types/enum.md | |
| [Function pointers]: types/function-pointer.md | |
| [Functions]: types/function-item.md | |
| [Impl trait]: types/impl-trait.md | |
| [Macros]: macros.md | |
| [Numeric]: types/numeric.md | |
| [Parentheses]: #parenthesized-types | |
| [Raw pointers]: types/pointer.md#raw-pointers-const-and-mut | |
| [References]: types/pointer.md#shared-references- | |
| [Slice]: types/slice.md | |
| [Struct]: types/struct.md | |
| [Trait objects]: types/trait-object.md | |
| [Tuple]: types/tuple.md | |
| [Type paths]: paths.md#paths-in-types | |
| [Union]: types/union.md | |
| [`Self` path]: paths.md#self-1 | |
| [arrays]: types/array.md | |
| [enumerations]: types/enum.md | |
| [function pointer]: types/function-pointer.md | |
| [inferred type]: types/inferred.md | |
| [item]: items.md | |
| [never]: types/never.md | |
| [pointer types]: types/pointer.md | |
| [raw pointer]: types/pointer.md#raw-pointers-const-and-mut | |
| [reference type]: types/pointer.md#shared-references- | |
| [reference]: types/pointer.md#shared-references- | |
| [structs]: types/struct.md | |
| [trait]: types/trait-object.md | |
| [tuples]: types/tuple.md | |
| [type alias]: items/type-aliases.md | |
| [type aliases]: items/type-aliases.md | |
| [type boundaries]: trait-bounds.md | |
| [type parameters]: types/parameters.md | |
| [unions]: types/union.md |