Skip to content
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

Implement equality constraints in where clauses #22074

Closed
wants to merge 5 commits into from

Conversation

jroesch
Copy link
Member

@jroesch jroesch commented Feb 8, 2015

This fixes #20041. I was thinking that the necessary machinery this required must be in place for associated types. So I went ahead and implemented the parsing and translation in collect when I was bored last night.

I currently have syntax of the form: where A = T since it seemed cleaner, as well as consistent with the associated types syntax of Foo<A=T> while not introducing ambiguity. If that is not what we want I'm happy to use the == syntax originally present in the RFC.

r? @nikomatsakis

I think this should cover everything let me know otherwise.

cc @darinmorrison

@sfackler
Copy link
Member

sfackler commented Feb 8, 2015

@jroesch
Copy link
Member Author

jroesch commented Feb 8, 2015

@sfackler yeah I just saw them, waiting on a local make check and I will push all my touch ups.

@nikomatsakis
Copy link
Contributor

@jroesch so this looks great, as far as it goes. The reason though that I've been avoiding implementing (or suggesting we implement) this feature goes a bit beyond the parsing. In particular, there are several scenarios that will not (I think) work as expected with this patch.

One is that this will not affect the normalization code, so something like:

fn foo<T:Iterator>(t: T) -> u32
    where T::Item = u32
{
    t.next().unwrap()
}

will fail to type-check.

Similarly, this won't work if you equate random type parameters:

fn foo<A,B>(a: A) -> B
    where A = B
{
    a
}

I'm not necessarily opposed to landing this patch: it's still a handy feature and it's good to have the parsing code etc in place. But I would at minimum want to land it feature-gated.

I've been doing research into the best way to restructure our code so that we can support examples like the ones above, but changes in that area are beyond the scope of the present release milestones, I think.

@jroesch
Copy link
Member Author

jroesch commented Feb 10, 2015

@nikomatsakis I has a suspicion this may be true, but couldn't sleep the other night and needed something to work on ;). I will feature gate this and we can land it in its imperfect form if that works.

@Stebalien
Copy link
Contributor

I read Foo<A=T> as an instantiation of the generic Foo, not an equality check.

@jroesch
Copy link
Member Author

jroesch commented Feb 17, 2015

@Stebalien internally Foo<A=T> is shorthand for <SomeFoo as Foo>::A = T so it seemed more consistent to have a single way to write equality in the type grammar.

The above example:

where T::Item = u32

when fully expanded is really:

where <T as Iterator>::Item = u32

which is the same as:

where T : Iterator<Item=u32>

@Stebalien
Copy link
Contributor

where F: Foo<A=T> is equivalent to where F: Foo, Foo::A =(=) T however, that doesn't mean that Foo<A=T> is simply short for <SomeFoo as Foo>::A = T. For example, type T = &Foo<A=T>; is legal but there is no equivalent that uses <SomeFoo as Foo>::A = T because you can't use a where clause here. Additionally, If Foo<A=T> where short hand for <SomeFoo as Foo>::A = T, I'd expect Foo<A: T> to be a legal constraint. The key difference is that the <SomeFoo as Foo>::A = T syntax is a constraint and can only be used to constrain a type parameter to a set of traits while Foo<A=T> can additionally be used to fully specify a specific trait (i.e. instantiate a generic trait).

@steveklabnik
Copy link
Member

@nikomatsakis are you still in favor of landing this with a gate?

@jnicklas
Copy link

The change from == to = would make it more awkward to express negative type equality bounds, which might be desirable in the future. where T != Foo reads quite nicely, but if we go with a single equals sign here, we'd have to do something strange like where T = !Foo.

@nikomatsakis
Copy link
Contributor

This is old so going to close. I'll be in touch with @jroesch with respect to rebasing and reimplementing this work.

@spinda
Copy link

spinda commented Jan 26, 2017

@nikomatsakis @jroesch Did this go anywhere?

@jroesch
Copy link
Member Author

jroesch commented Jan 26, 2017

I haven't had a ton of cycles to work on Rust lately. I did just catch up with @nikomatsakis in Paris, and we talked about this issue briefly. I think this should be implementable in the new forthcoming trait engine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Parse and accept type equality constraints in where clauses
7 participants