-
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
Conversation
text/0000-trait-alias.md
Outdated
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 as Trait` is suggested as a starter construct for the discussion. |
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.
Why not trait TraitAlias = Trait
similar to the type
keyword's syntax?
If I came across trait Foo as Bar
I would probably read it as Bar
being an alias for Foo
.
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.
I like the =
syntax to mirror type aliases as well.
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.
Yeah, I think it’s a good idea as well, as
would read the other way around, yeah.
Note that this is sugar for trait Foo: gen::Foo<Bck0> {}
impl<T: gen::Foo<Bck0>> Foo for T {} So since the functionality is already supported, it makes sense to add syntax. The |
@durka, hm, are you sure it safely desugars to that? It creates a brand new trait, not really an alias. |
@durka You can't implement |
You're right, the trait aliasing that I demonstrated only works for bounds. I didn't realize that this RFC would allow impl blocks as well. The RFC could benefit from an example! |
@durka More importantly, the I prefer the Also, will this be able to support multiple traits, ie. can I do |
I think |
The thing about In the simpler case of But Rust currently doesn't have any way to make a trait object of two non-builtin traits, like Sure, we could have the same syntax do two different things, but that seems weird. It seems to me that for now we should just do |
@durka You're forgetting that traits are not just used as trait objects. |
@Diggsey I didn't forget, but I glossed over it :) For all purposes besides trait objects, my desugaring works and |
|
What about HRTB? Would this be viable? trait Bar<'a> { }
trait Foo = for<'a> Bar<'a>; |
@withoutboats From an implementation standpoint, it shouldn't be more difficult than other trait aliases. |
A concrete example for hiding HRTB came up in #rust: trait FromRef<T> = for<'a> From<&'a T>; |
Would Could the compiler auto-translate it to |
I don't know how implementing Here's impl<'a> From<&'a u32> for u32 {
fn from(x: &'a u32) -> u32 { *x }
} Note that the impl FromRef<u32> for u32 {
fn from(x: &u32) -> u32 { *x }
} The normal meaning of this would be to elide a lifetime parameter on the Special elisions for implementing HRTB trait aliases don't seem like a good idea to me (and AFAICT can't scale to an HRTB trait alias with multiple higher ranked lifetimes), but not being able to implement a trait alias transparently also seems like a problem. |
@withoutboats I don't see a problem with not being able to implement a trait alias if you can't implement what it aliases to to start with. It's not like you can |
|
@withoutboats that's already the case for trait inheritance. For example, you can't implement |
Sure, but in that case its relatively easy to learn what trait you need to implement. I'm concerned that using this feature to obscure HRTB will lead to a situation where a less expert Rust user sees that they need to implement I don't have a solution; HRTB just present a pretty serious accessibility problem in general. |
Current situation:
|
Is |
@durka The point is to hide the |
I think I'm generally in favor of adding some kind of shorthand for "trait aliases" (or "where-clause aliases", depending on your POV). @aturon and I talked about it recently and we felt like the syntax ought to be modeled on the syntax for declaring a new trait with supertraits, but with trait SymPartialEq<T> = PartialEq<T> where T: PartialEq<Self>; then you could do: fn foo<T, U>() where T: SymPartialEq<U> and it would be equivalent to fn foo<T, U>() where T: PartialEq<U>, U: PartialEq<T> I'm not sure what to do about the case where you want just a where-clause though, and no Not sure if I love the precise syntax here, but there is something nice about the symmetry with supertrait clauses, and the "bias" to always have a It seems good for the more common cases that don't require where clauses, e.g. trait Foo = Bar + Baz; |
Maybe |
What would be the difference between On Wed, Nov 2, 2016 at 4:48 PM, Josh Stone notifications@github.com wrote:
|
How are associated types handled? I commonly use things like |
Also: * Avoid unhelpful compiler warnings * Capture common code in a macro Note: it would have been nice to alias the closure type, but rust-lang/rfcs#1733 is not yet implemented and macros can't cope (rust-lang/rust#24010).
Also: * Avoid unhelpful compiler warnings * Capture common code in a macro Note: it would have been nice to alias the closure type, but rust-lang/rfcs#1733 is not yet implemented and macros can't cope (rust-lang/rust#24010).
Also: * Avoid unhelpful compiler warnings * Capture common code in a macro Note: it would have been nice to alias the closure type, but rust-lang/rfcs#1733 is not yet implemented and macros can't cope (rust-lang/rust#24010).
Also: * Avoid unhelpful compiler warnings * Capture common code in a macro Note: it would have been nice to alias the closure type, but rust-lang/rfcs#1733 is not yet implemented and macros can't cope (rust-lang/rust#24010).
Also: * Avoid unhelpful compiler warnings * Capture common code in a macro Note: it would have been nice to alias the closure type, but rust-lang/rfcs#1733 is not yet implemented and macros can't cope (rust-lang/rust#24010).
Also: * Avoid unhelpful compiler warnings * Capture common code in a macro Note: it would have been nice to alias the closure type, but rust-lang/rfcs#1733 is not yet implemented and macros can't cope (rust-lang/rust#24010).
Also: * Avoid unhelpful compiler warnings * Capture common code in a macro Note: it would have been nice to alias the closure type, but rust-lang/rfcs#1733 is not yet implemented and macros can't cope (rust-lang/rust#24010).
Also: * Avoid unhelpful compiler warnings * Capture common code in a macro Note: it would have been nice to alias the closure type, but rust-lang/rfcs#1733 is not yet implemented and macros can't cope (rust-lang/rust#24010).
Also: * Avoid unhelpful compiler warnings * Capture common code in a macro Note: it would have been nice to alias the closure type, but rust-lang/rfcs#1733 is not yet implemented and macros can't cope (rust-lang/rust#24010).
Haven't read all the comments, but by the existing grammar is |
It's allowed by the implemented parser and I guess it'll mean the same as
`trait Trait {}`.
…On Tue, Feb 27, 2018 at 1:02 AM, Clar Roʒe ***@***.***> wrote:
Haven't read all the comments, but by the existing grammar is trait Trait
= ; allowed?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1733 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAC3n6PztcUX_tH3XNbrQXb_NLJIXejkks5tY5psgaJpZM4JxjCo>
.
|
I'd have guessed it would be a bound which accepted all types. If that works, I'd also expect |
That makes more sense, yes.
…On Tue, Feb 27, 2018 at 3:01 AM, Taylor Cramer ***@***.***> wrote:
Hm? I'd have guessed it would be a bound which accepted all types. If that
works, I'd also expect trait Static = 'static; to be a bound which
accepted all 'static types.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1733 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAC3n75MvU_6vy55rh8CKcnRB-xW5CJtks5tY7ZFgaJpZM4JxjCo>
.
|
Would this also work? trait Foo<'a> = Bar<'a> + 'a; It should! |
@Boscop The RFC enables it, yes. |
Implement trait aliases (RFC 1733) Extends groundwork done in #45047, and fully implements rust-lang/rfcs#1733. CC @durka @nikomatsakis
Implement trait aliases (RFC 1733) Extends groundwork done in #45047, and fully implements rust-lang/rfcs#1733. CC @durka @nikomatsakis
Rendered
Trait alias would enable aliasing traits.
Useful especially when we want to lift the name from generic to specific (a bit like
Result
on a lot of modules, but for traits):