Opaque type

Opaque types are types that implement certain traits, but their concrete, underlying type is not exposed to the programmer. In contrast to trait objects, opaque types are zero-cost; even though they are opaque to the programmer, the compiler knows their concrete type.

Opaque types are declared with the  syntax, which can currently be used in parameters and in return types.

Example
The above code doesn't compile. The compiler complains that the types don't match: It expected a reference, but found an opaque type.

Trait bounds
Opaque types allow arbitrarily many trait bounds, which are separated with a, e.g.  . Opaque types can only use the functions and operations declared in their traits:

Note that trait objects allow only one trait bound that isn't an auto trait; this is not the case with opaque types.

Use cases
There are several situations where opaque types are useful or even necessary:

Types that can't be named
Some types don't have a name, e.g. closures. When the compiler prints the type of a closure, it might looks something like. However, this syntax is not available in Rust source code. To refer to a closure, an opaque type must be used, e.g. . The traits that are usually used are,  and , because they allow calling the closure.