Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upDefault impls cannot reliably expose type inequality #29499
Comments
This comment has been minimized.
This comment has been minimized.
|
I think that being able to express type inequality at all is just a side-effect. Default impls like that aren't stable and the semantics aren't concrete right now. @rust-lang/lang might have some input? |
This comment has been minimized.
This comment has been minimized.
|
It looks like this just interacts badly with type inference. |
This comment has been minimized.
This comment has been minimized.
|
If it would compile, type inequality gives you ad-hoc specialization (code example). The specialization passes trait coherence checks, and both can be called, but indeed it does not infer to the right implementation in a regular method call. Edit: Oh wow, making the iterator the Self type instead, the “dream specialization” for extend works. |
This comment has been minimized.
This comment has been minimized.
|
I believe that the fact that that impl is accepted is a known bug. (In particular, the first point of #13231.) |
This comment has been minimized.
This comment has been minimized.
|
I agree with Aatch, this is a side effect. I do wish we had a way of expressing type inequality, but this isn't the way to go about it. |
This comment has been minimized.
This comment has been minimized.
|
Additionally, this lead to an ICE when I tried to take it to the next step: tuples where every type is different. #![feature(optin_builtin_traits)]
trait NotSame {}
impl NotSame for .. {}
impl<A> !NotSame for (A, A) {}
trait OneOfEach {}
impl <A> OneOfEach for (A) { }
impl <A, B> OneOfEach for (A, B) where (B): OneOfEach, (A, B): NotSame { }
impl <A, B, C> OneOfEach for (A, B, C) where (B, C): OneOfEach, (A, B): NotSame,
(A, C): NotSame {}
fn main() {}
On rustc 1.6.0-nightly (1a2eaff 2015-10-31) |
This comment has been minimized.
This comment has been minimized.
|
File a separate bug? |
rphmeier
referenced this issue
Nov 2, 2015
Closed
ICE: Conflicting trait impls with custom default-implemented trait bound #29516
This comment has been minimized.
This comment has been minimized.
|
Will default impls will be expressive enough if they aren't capable of expressing type inequality in this way? It seemed like a no-brainer when I wrote it. Obviously the language should support it with native syntax as well-- sooner rather than later, to avoid hacks like this from becoming commonplace. |
steveklabnik
added
the
A-lang
label
Nov 3, 2015
This comment has been minimized.
This comment has been minimized.
|
I don't think that this impl:
is intended to work. I thought we had some restrictions to this effect, but perhaps we only placed them on positive impls. This is in a sense a kind of coherence violation -- there is a default, builtin impl for tuples that this interacts with. But in general the expressive power of negative impls is not firmly settled and will be changing. It's something that we need to make firmer decisions on (and there is also clear interaction with ongoing design, such as specialization, rust-lang/rfcs#1148, and catch panic). |
This comment has been minimized.
This comment has been minimized.
Did you mean |
This comment has been minimized.
This comment has been minimized.
|
You don't exactly have specialization, because you can't have a generic method use extend. Anyway, OIBITs were basically intended as "structural impls with negative impls for opt-out". |
This comment has been minimized.
This comment has been minimized.
|
@Ms2ger As I addressed in the separate issue, I am aware that (A) is not correct, strictly speaking. When you compile it with the trailing comma, it works (mostly) as expected. The important point is that the ICE occurs at all. |
ebfull commentedNov 1, 2015
If I understand default impls right, it should be possible to express
S != Tusing(S, T): NotSame. In fact this does work in some situations, but not generally.doesn't work:
but this does:
Perhaps it only works when trying to ensure there are no conflicting impls? Perhaps it's not meant to work, and the second example is a hole?