Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Update opaque-types-type-alias-impl-trait.md #2429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
smanilov wants to merge 1 commit into rust-lang:master
base: master
Choose a base branch
Loading
from smanilov:patch-18
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 49 additions & 2 deletions src/opaque-types-type-alias-impl-trait.md
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,44 @@ 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 <!-- date-check --> January 2021) express that type
you can (as of <!-- date-check --> 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
}
```

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
Expand Down Expand Up @@ -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 }
}
```

AltStyle によって変換されたページ (->オリジナル) /