-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
What's the reasoning for E0225? #32220
Comments
The main reason why is that we don't have upcasting, and while it's considered a little odd that you can't do |
Is that not the case for built in traits as well? |
@sgrif well the built-in traits have no methods, so therefore no vtable, so the vtable for |
I guess I didn't realize that "built-in traits" meant marker traits. Can we not expand this to traits without methods that aren't built in? |
@sgrif this would make going from no methods to some methods a breaking change (although I agree having some way to do this would be nice). |
I think that it would be nice to have a language item of //This is a regular trait to enforce a single implementation per type
trait Cons {
type Head;
type Tail;
}
marker Contains<T>;
impl<N, T, Hstck: Cons<Head=N, Tail=T>> Contains<N> for Hstck;
impl<N, H, T, Hstck: Cons<Head=H, Tail=T>> Contains<N> for Hstck where T: Contains<N>; Which is currently disallowed in Rust because there's no way to ensure that a method won't be added, and then it would be unclear which implementation to choose for I want this in a current project to allow filtering of types (so I can create a type that takes any type from a given set and violations are caught at compile time, but it can use Any internally). In my opinion, I would far rather that ambiguities are caught at resolution-time, at least on an opt-in basis. Like, it could fail with an error by default, but you would be able to annotate with |
Can Rust do what C++ does in at least some of these situations? e.g. the vtable layout of That would imply some arbitrary-seeming restrictions on upcasting, though - +1 on the marker trait idea too. |
E0225 prevents from using multiple trait bounds of non standard types. See rust-lang/rust#32220 for details.
@steveklabnik Currently, explanation mentions |
I was not sure that it was marker traits either. @rust-lang/lang what should we do here? |
There are long-term plans to do something a bit like @comex suggests in order to handle the full downcasting experience (one possible solution uses 'custom DST' with multiple vtable pointers), but that is probably some way off. I agree this should probably apply to all zero-method traits, not built-in traits, in fact I'm surprised the compiler even has a concept of built-in trait now that we've moved to lang items + auto traits (nee OIBIT). |
Also the workaround from the ticket head does not work for std types: trait FooAndBar: Eq + Ord {}
impl<T> FooAndBar for T where T: Eq + Ord {}
fn main() {
let x: Box<FooAndBar> = unimplemented!();
}
Which makes a task of auto-sortable container of trait implementations (f.i. BTreeMap) really non-trivial. |
At this point we are basically waiting on an RFC to lay out how this should work. Probably this should issue should be moved to the RFC repository. |
Sounds good to me |
The following code fails to compile:
You can only box multiple traits when the additional bounds are built in. This seems like an extremely odd restriction. Is there an intention to remove it at some point? The workaround is incredibly annoying:
The number of these traits grows quite rapidly as you need multiple combinations of various traits. In Diesel's case, many of these will end up needing to be part of the public API which is leading to a lot of confusing and hard to discover types.
The text was updated successfully, but these errors were encountered: