-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Trait alias. #1733
Trait alias. #1733
Changes from 2 commits
55de6a3
c0c4834
cf74fd5
042b8e4
88d3074
5d0b4fe
819d8f9
8a72471
554c4c1
7b63d30
6601146
b1be75b
90ce5c3
f04d4b2
f269f9a
3fc5568
8182509
83322de
310c7fe
eb24a49
4d99e23
54ca931
bf3414d
80dbc13
a2f8020
dcec407
b5ff949
2b14c14
5c94f49
2a1a5b2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
- Feature Name: Trait alias | ||
- Start Date: 2016-08-31 | ||
- RFC PR: | ||
- Rust Issue: | ||
|
||
# Summary | ||
[summary]: #summary | ||
|
||
Traits can be aliased the same way types can be aliased with the `type` keyword. | ||
|
||
# Motivation | ||
[motivation]: #motivation | ||
|
||
Sometimes, some traits are defined with parameters. For instance: | ||
|
||
```rust | ||
trait Foo<T> { | ||
// ... | ||
} | ||
``` | ||
|
||
It’s not uncommon to do that in *generic* crates and implement them in *backend* crates, where the | ||
`T` template parameter gets substituted with a *backend* type. | ||
|
||
If someone wants to write `Foo` code and be compatible with all backends, then they will use the | ||
*generic* crate’s `Foo<_>`. However, if someone wants to freeze the backend and keep using the same | ||
one for the whole project but want to keep the ease of backend switching, a good practice is that | ||
the backends should exporte a specific version of the trait so that it’s possible to use `Foo` | ||
instead of the more explicit and unwanted `Foo<BackendType>`. | ||
|
||
# Detailed design | ||
[design]: #detailed-design | ||
|
||
The idea is to add a new keyword or construct for enabling trait aliasing. One shouldn’t use the | ||
`type` keyword as a trait is not a type and that could be very confusing. | ||
|
||
The `trait TraitAlias = Trait` was adopted as the syntax for aliasing. It creates a new trait alias | ||
`TraitAlias` that will resolve to `Trait`. | ||
|
||
```rust | ||
trait TraitAlias = Debug; | ||
``` | ||
|
||
Optionnaly, if needed, one can provide a `where` clause to express *bounds*: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: typo. "Optionally" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optionally :-) |
||
|
||
```rust | ||
trait TraitAlias = Debug where Self: Default; | ||
``` | ||
|
||
Trait aliasing to combinations of traits is also provided with the standard `+` construct: | ||
|
||
```rust | ||
trait TraitAlias = Debug + Default; // same as the example above | ||
``` | ||
|
||
Trait aliases can be used in any place arbitrary bounds would be syntactically legal. However, you | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In terms of structure, the detailed design could probably be split into two sections - syntax and semantics. Everything above this paragraph would be syntax, whereas this paragraph should be expanded into the semantics secion. There are basically two cases semantically that we're allowing (and a third we're not - defining impls). The first is bounds, which is sort of straightforward, but has some question still around which bounds get elaborated as Niko discusses here. That is, in The other case is objects. You don't mention it, but an alias needs to be object safe in order for it to be used as an object. I believe this is the requirements for an alias to be object safe:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. I’ll draft something soon about that. :) |
||
cannot use them in `impl` place but can have them as *trait objects*, in *where-clauses* and *type | ||
parameters declarations* of course. | ||
|
||
# Drawbacks | ||
[drawbacks]: #drawbacks | ||
|
||
The syntax `trait TraitAlias as Trait` makes parsers need a lookhead (`=` or `as`?). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess this should say |
||
|
||
# Alternatives | ||
[alternatives]: #alternatives | ||
|
||
A keyword was planned, like `alias`: | ||
|
||
``` | ||
alias Foo = gen::Foo<Bck0>; | ||
``` | ||
|
||
However, it’s not a good idea as it might clash with already used `alias` in codebases. | ||
|
||
# Unresolved questions | ||
[unresolved]: #unresolved-questions | ||
|
||
The syntax `trait TraitAlias as Trait` is not yet stabilized and needs to be discussed. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be changed to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo fixed, but shall we just remove that part? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this summary still accurate? I think it should be s/
type
keyword/trait
keyword/, no?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The initial intention was to state that we can have alias the same way we already have with the
type
keyword and types. But you’re right, it’s confusing. I’m updating that.