From 489c271792fc86ff776411fcef754be4e21fdd95 Mon Sep 17 00:00:00 2001 From: Stan Manilov Date: Fri, 30 May 2025 15:32:46 +0300 Subject: [PATCH 1/2] Update opaque-types-type-alias-impl-trait.md 1. Clarify that there is a single concrete type for an opaque type 2. Clarify that defining a type alias to an opaque type is an unstable feature 3. Add complete example 4. Clarify that defining an associate type as opaque is an unstable feature 5. Add another complete example --- src/opaque-types-type-alias-impl-trait.md | 51 ++++++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/src/opaque-types-type-alias-impl-trait.md b/src/opaque-types-type-alias-impl-trait.md index 956f56828..0f0e8e87c 100644 --- a/src/opaque-types-type-alias-impl-trait.md +++ b/src/opaque-types-type-alias-impl-trait.md @@ -12,15 +12,16 @@ type Foo = impl Bar; This declares an opaque type named `Foo`, of which the only information is that it implements `Bar`. Therefore, any of `Bar`'s interface can be used on a `Foo`, -but nothing else (regardless of whether it implements any other traits). +but nothing else (regardless of whether the concrete type implements any other traits). Since there needs to be a concrete background type, -you can (as of January 2021) express that type +you can (as of May 2025) express that type by using the opaque type in a "defining use site". ```rust,ignore struct Struct; impl Bar for Struct { /* stuff */ } +#[define_opaque(Foo)] fn foo() -> Foo { Struct } @@ -28,6 +29,27 @@ fn foo() -> Foo { Any other "defining use site" needs to produce the exact same type. +Note that defining a type alias to an opaque type is an unstable feature. +To use it, you need `nightly` and the annotations `#![feature(type_alias_impl_trait)]` on the file and `#[define_opaque(Foo)]` on the method that links the opaque type to the concrete type. +Complete example: + +```rust +#![feature(type_alias_impl_trait)] + +trait Bar { /* stuff */ } + +type Foo = impl Bar; + +struct Struct; + +impl Bar for Struct { /* stuff */ } + +#[define_opaque(Foo)] +fn foo() -> Foo { + Struct +} +``` + ## Defining use site(s) Currently only the return value of a function can be a defining use site @@ -61,3 +83,28 @@ impl Baz for Quux { fn foo() -> Self::Foo { ... } } ``` + +For this you would also need to use `nightly` and the (different) `#![feature(impl_trait_in_assoc_type)]` annotation. +Note that you don't need a `#[define_opaque(Foo)]` on the method anymore. +Complete example: + +``` +#![feature(impl_trait_in_assoc_type)] + +trait Bar {} +struct Zap; + +impl Bar for Zap {} + +trait Baz { + type Foo; + fn foo() -> Self::Foo; +} + +struct Quux; + +impl Baz for Quux { + type Foo = impl Bar; + fn foo() -> Self::Foo { Zap } +} +``` From 93a5254c64a05fe3a63688cf3637f0ae12d9ea21 Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 11 Dec 2025 21:18:21 +0000 Subject: [PATCH 2/2] clarify why define_opaque isnt needed --- src/opaque-types-type-alias-impl-trait.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opaque-types-type-alias-impl-trait.md b/src/opaque-types-type-alias-impl-trait.md index 0f0e8e87c..9f20bfc70 100644 --- a/src/opaque-types-type-alias-impl-trait.md +++ b/src/opaque-types-type-alias-impl-trait.md @@ -85,7 +85,7 @@ impl Baz for Quux { ``` For this you would also need to use `nightly` and the (different) `#![feature(impl_trait_in_assoc_type)]` annotation. -Note that you don't need a `#[define_opaque(Foo)]` on the method anymore. +Note that you don't need a `#[define_opaque(Foo)]` on the method anymore as the opaque type is mentioned in the function signature (behind the associated type). Complete example: ```