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 upParse and accept type equality constraints in where clauses #20041
Comments
This was referenced Dec 19, 2014
jroesch
added a commit
to jroesch/rust
that referenced
this issue
Dec 23, 2014
jroesch
added a commit
to jroesch/rust
that referenced
this issue
Dec 23, 2014
jroesch
referenced this issue
Dec 23, 2014
Merged
Support all variants of WherePredicate in clean/mod.rs #20180
jroesch
added a commit
to jroesch/rust
that referenced
this issue
Dec 23, 2014
bors
added a commit
that referenced
this issue
Dec 25, 2014
This comment was marked as outdated.
This comment was marked as outdated.
|
Edit: Obsoleted, see the next few comments. Now that associated type for common traits has been landed on nightly while this issue is still open, it becomes impossible to use an iterator of a concrete type. Before this is fixed, here is a workaround (but I think this could be simplified): #![feature(associated_types)]
struct CustomStruct {
this: int,
that: int,
}
fn do_something(i: int) {
println!("{}", i);
}
// Old code
#[cfg(target_os="none")]
fn foo_old<I>(mut iter: I) where I: Iterator<CustomStruct> {
for obj in iter {
do_something(obj.this + obj.that);
}
}
// New code, but doesn't work due to #20041.
/*
fn foo_new<I>(mut iter: I) where I: Iterator, <I as Iterator>::Item = CustomStruct {
for obj in iter {
do_something(obj.this + obj.that);
}
}
*/
// Workaround code, inspired by http://redd.it/2r2fbl
trait Is<Sized? A> { fn this(&self) -> &A; }
impl<Sized? A> Is<A> for A { fn this(&self) -> &A { self } }
fn workaround_20041<A, B: Is<A>>(a: &B) -> &A { a.this() }
fn foo_workaround<I>(mut iter: I) where I: Iterator, <I as Iterator>::Item: Is<CustomStruct> {
for obj in iter {
let obj = workaround_20041::<CustomStruct, _>(&obj);
do_something(obj.this + obj.that);
}
}
fn main() {
foo_workaround(vec![CustomStruct { this: 11111, that: 22222 }].into_iter());
} |
This comment has been minimized.
This comment has been minimized.
|
@kennytm You can use "associated type bindings": fn foo<I>(it: I) where I: Iterator<Item=Foo> {} |
This comment has been minimized.
This comment has been minimized.
|
@japaric : Oh nice, thanks. Found this buried deeply in https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md#constraining-associated-types (hintupdate guidehint) |
This comment has been minimized.
This comment has been minimized.
|
@kennytm @steveklabnik would the one to talk to about the docs. It is probably a good idea to do that. Full equality constraints should be coming soon after 1.0. |
This comment has been minimized.
This comment has been minimized.
|
Yes, we don't have any associated type documentation, I plan on tackling that soon. |
kmcallister
added
the
A-typesystem
label
Jan 16, 2015
jroesch
referenced this issue
Feb 8, 2015
Closed
Implement equality constraints in where clauses #22074
This comment has been minimized.
This comment has been minimized.
|
I don't think associated type bindings are quite the same as this, since they aren't taken into account for determining overlapping impls (which appears to have been intentional) http://is.gd/em2JNT |
This comment has been minimized.
This comment has been minimized.
|
@sgrif Doesn't that make this a kind of duplicate of rust-lang/rfcs#1672? Edit: obviously with semantic differences, but I believe they allow for expressing the same types of bounds. |
This comment has been minimized.
This comment has been minimized.
tupshin
commented
Feb 4, 2017
|
I just ran into this limitation pretty hard while trying to do type level operations on HLists. Any work planned? The only possible workaround I see is this bitrotted brilliant abomination |
tupshin
referenced this issue
Feb 7, 2017
Closed
No def'n found for DefId { krate: CrateNum(0), node: DefIndex(176) #39607
Mark-Simulacrum
added
the
C-tracking-issue
label
Jul 22, 2017
Mark-Simulacrum
referenced this issue
Jul 24, 2017
Open
rustdoc generates `where` clauses that are not valid Rust #28360
This comment has been minimized.
This comment has been minimized.
|
Taking this idea further (
The latter trait on its own does all the work. The first one is just there to make the following work without explicitly specifying the type implementing
|
This comment has been minimized.
This comment has been minimized.
|
@dhardy What you want is just |
This comment has been minimized.
This comment has been minimized.
|
@sgrif that actually works, thanks! |
dhardy
added a commit
to dhardy/rand
that referenced
this issue
Aug 5, 2017
This comment has been minimized.
This comment has been minimized.
|
I would very much like to see this happen. Writing highly generic code is a pain, if you can't rename associated types inside traits, and this helps to do it, by asserting that a simple associated type is the same type as some monstrous thing: |
This comment has been minimized.
This comment has been minimized.
spease
commented
Sep 3, 2017
|
I recently ran into this:
I don't fully understand the difference here Issue I filed for num that helped me: |
This comment has been minimized.
This comment has been minimized.
|
The difference is that direct equals assertions between types are not allowed, but it's possible to write trait bounds like "type Foo must have trait Qux, and that Qux's associated type must be this type Bar". This allows writing equals relations in an indirect way. I don't know if there is any expressivity difference, but direct equality would be certainly easier to grasp. |
ebfull
referenced this issue
Nov 12, 2017
Merged
Enforce that Fr of Engine is the scalar for curve points #66
This comment has been minimized.
This comment has been minimized.
Tarmean
commented
Jan 20, 2018
•
|
I'd like to add an additional use case. Currently this code compiles:
However if another implementation for string is added anywhere we get an inference error:
I think this is a pretty strong sign that the code should have required a type annotation in the first place. Type equality constraints would be a good solution to proof that there will be no implementations for String, giving the nicer type inference:
Iirc it isn't possible to solve this via a library because the inferred type would be something like |
This comment has been minimized.
This comment has been minimized.
|
This currently seems blocked on some issues with the trait system (see #22074 (comment) and #39158 (comment)). Barring that, there seem to be a few places where type equality constraints are not handled properly (they're actually mostly accounted for already, so it may not be a huge task to finish them off). Here are the steps I can see that need to be taken to implement this feature once the normalisation issues are sorted out:
|
This comment has been minimized.
This comment has been minimized.
Ekleog
commented
Aug 21, 2018
•
|
I think this can be more or less emulated with a helper trait (didn't check all possible variations of it, though): trait Is {
type Type;
fn into(self) -> Self::Type;
}
impl<T> Is for T {
type Type = T;
fn into(self) -> Self::Type {
self
}
}
fn foo<T, U>(t: T) -> U
where T: Is<Type = U>
{ t.into() }
fn main() {
let _: u8 = foo(1u8);
// Doesn't compile:
//let _: u16 = foo(1u8);
} |
This comment has been minimized.
This comment has been minimized.
ZerothLaw
commented
Oct 18, 2018
|
I'd like to work on this. From my understanding, before beginning work, I'll need to consider the type system implications and effects, and detail those for approval, correct? |
This comment has been minimized.
This comment has been minimized.
|
I suspect it's better to wait until the chalk integration has been completed, as this is easily implemented in chalk but is nontrivial with the current trait system (see #22074 (comment) and #39158 (comment) for some details). |
This comment has been minimized.
This comment has been minimized.
Avi-D-coder
commented
Feb 28, 2019
•
|
Any news? Now that chalk has largely landed. |
This comment has been minimized.
This comment has been minimized.
|
chalk hasn't largely landed. There's still significant integration work to be done. |
This comment has been minimized.
This comment has been minimized.
Boiethios
commented
Feb 28, 2019
•
|
And what about inequality constraint? trait Trait {
type Foo;
type Bar;
}
struct Struct<T>(T) where T: Trait, T::Foo != T::Bar; |
jroesch commentedDec 19, 2014
Implement the missing type equality constraint specified in the RFC.
The example from the RFC: