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

Generic function parameters
Generic parameters and opaque parameters are conceptually the same:

However, the  syntax is is a bit more succinct and easier to type. You might also find it easier to read, since it involves fewer sigils.

Forward compatibility
In the return type of a function, an opaque type is often used even if the actual return type could be named. For example:

The return type could just as well be written as, but the opaque type guarantees that it can be replaced with a different concrete type in the future, without breaking backwards compatibility. The downside is of course that users of this function are restricted to certain operations. For example, the returned  can't be indexed. However, this is sometimes desirable to allow forwards compatibility.

Other uses of the term opaque
Structs that don't expose any implementation details and extern types are sometimes called opaque types (even in the original RFC). This is discouraged, since it is ambiguous and can cause confusion.