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.

Built-in types are tightly integrated into the language, in nontrivial ways that are not possible to emulate in user-defined types. User-defined types have limited capabilities.

The list of types is:

Type expressions

Type :
| ImplTraitType
| TraitObjectType

TypeNoBounds :
| ImplTraitTypeOneBound
| TraitObjectTypeOneBound
| TypePath
| TupleType
| NeverType
| RawPointerType
| ReferenceType
| ArrayType
| SliceType
| InferredType
| QualifiedPathInType
| BareFunctionType
| MacroInvocation

A type expression as defined in the Type grammar rule above is the syntax for referring to a type. It may refer to:

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 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.

# #![allow(unused_variables)]
#fn main() {
# use std::any::Any;
type T<'a> = &'a (dyn Any + Send);

Recursive types

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. 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.
  • Recursive type definitions can cross module boundaries, but not module visibility boundaries, or crate boundaries (in order to simplify the module system and type checker).

An example of a recursive type and its use:

# #![allow(unused_variables)]
#fn main() {
enum List<T> {
    Cons(T, Box<List<T>>)

let a: List<i32> = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil))));

© 2010 The Rust Project Developers
Licensed under the Apache License, Version 2.0 or the MIT license, at your option.