Merge 489c271792 into 4c6d66ccb0
This commit is contained in:
commit
478e660d59
|
|
@ -12,15 +12,16 @@ type Foo = impl Bar;
|
||||||
|
|
||||||
This declares an opaque type named `Foo`, of which the only information is that
|
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`,
|
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,
|
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".
|
by using the opaque type in a "defining use site".
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
struct Struct;
|
struct Struct;
|
||||||
impl Bar for Struct { /* stuff */ }
|
impl Bar for Struct { /* stuff */ }
|
||||||
|
#[define_opaque(Foo)]
|
||||||
fn foo() -> Foo {
|
fn foo() -> Foo {
|
||||||
Struct
|
Struct
|
||||||
}
|
}
|
||||||
|
|
@ -28,6 +29,27 @@ fn foo() -> Foo {
|
||||||
|
|
||||||
Any other "defining use site" needs to produce the exact same type.
|
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)
|
## Defining use site(s)
|
||||||
|
|
||||||
Currently only the return value of a function can be a defining use site
|
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 { ... }
|
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 }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue