Skip to main content
The * operator in Rust serves two distinct semantic purposes depending on its arity: as a unary prefix operator, it performs pointer dereferencing, and as a binary infix operator, it performs arithmetic multiplication.

Unary *: Dereference Operator

As a unary operator, * resolves a reference or pointer to its underlying memory location. Evaluating *expr yields a place expression (lvalue) of type T from a pointer or reference of type &T, &mut T, *const T, or *mut T. It only yields a value (via copy or move) when this place expression is evaluated in a value context. Trait Implementation and Desugaring For built-in reference types and the intrinsic Box<T> type, dereferencing is a compiler intrinsic operation. Notably, dereferencing a Box<T> is a special intrinsic that allows moving the underlying value out of the heap allocation, provided the underlying type does not implement the Copy trait. For user-defined smart pointers (e.g., String, Rc<T>), the * operator acts as syntactic sugar that invokes the std::ops::Deref or std::ops::DerefMut traits. Because standard Deref desugaring returns a reference, moving a value out of these types via * is not possible.
  • In an immutable context, *x desugars to *(std::ops::Deref::deref(&x)).
  • In a mutable context, *x desugars to *(std::ops::DerefMut::deref_mut(&mut x)).
Raw Pointers When applied to raw pointers (*const T or *mut T), the * operator bypasses Rust’s borrow checker guarantees. Because the compiler cannot guarantee the validity of the memory address, dereferencing a raw pointer is strictly an unsafe operation.

Binary *: Multiplication Operator

As a binary operator, * computes the arithmetic product of its left and right operands. Trait Implementation and Desugaring The binary * operator is backed by the std::ops::Mul trait. An expression like a * b is syntactic sugar for std::ops::Mul::mul(a, b). The compound assignment variant, *=, is backed by the std::ops::MulAssign trait.

Syntactic Token Contexts

While not functioning as an expression operator, the * symbol is also parsed by the compiler in three specific declaration and syntax contexts:
  1. Raw Pointer Types: Used in type signatures to denote raw pointers (*const T and *mut T).
  2. Glob Imports: Used in use statements to bind all public items from a module into the current namespace (use std::collections::*;).
  3. Macro Repetitions: Used in macro_rules! definitions as a Kleene star to indicate zero or more repetitions of a token tree (e.g., $( $x:expr ),*).
Tired of Poor Rust Skills? Fix That With Deep Grasping!Learn More