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

Namespaced enums are weird in regard to generic paramters #22486

Closed
Kimundi opened this issue Feb 18, 2015 · 12 comments
Closed

Namespaced enums are weird in regard to generic paramters #22486

Kimundi opened this issue Feb 18, 2015 · 12 comments
Assignees
Labels
I-needs-decision Issue: In need of a decision.
Milestone

Comments

@Kimundi
Copy link
Member

Kimundi commented Feb 18, 2015

Enum variants are namespaced now, but applying generic paramters to them in expressions still works as before, which means the correct way to type annotate a Option in a expression is to do this:

enum Option<T> {
    Some(T),
    None
}
let x = Option::Some::<u32>(1);

However, this is inconsistent with other namespaced constructs, like this:

struct Foo<T>(T);
impl<T> Foo<T> { fn new(t:T) -> Foo<T> { Foo(t) } }

let x = Foo::<u32>::new(1);

// With UFCS
let f = Option::<u32>::and as fn(Option<u32>, Option<u32>) -> Option<u32>;

Generally, type parameters of an item are supposed to go on that item in a path, but for enum variants this is not the case.

As a backward compatible solution to this, enum variants could be made to work similar to associated items of traits:

Option::Some      // Generic item fn<T>(T) -> Option<T>
Option::<T>::Some // Concrete instantiated item fn(T) -> Option<T>
@pnkfelix
Copy link
Member

nominating for discussion at triage meeting. Sounds like there might be a 1.0 issue to address here.

@pnkfelix
Copy link
Member

@alexcrichton points out that it is nice to write None::<T>

But it does seem like an inconsistency, i.e. a wart.

P-backcompat-lang, 1.0 beta, I-needs-decision.

@pnkfelix pnkfelix added this to the 1.0 beta milestone Feb 26, 2015
@pnkfelix pnkfelix added I-needs-decision Issue: In need of a decision. P-backcompat-lang and removed I-nominated labels Feb 26, 2015
@Kimundi
Copy link
Member Author

Kimundi commented Feb 26, 2015

Yeah, the ability to have None::<T> doesn't really need to go, but Option::<T>::None should also work for consistency... Tricky decision.

@nikomatsakis
Copy link
Contributor

This is not clearly an inconsistency. It depends on how you view enums. In particular, at least under some of the "virtual struct" proposals, enums were kind of "shorthand" for something like:

abstract enum Option<T>;
enum Some<T> : Option<T>;
enum None<T> : Option<T>;

in which case the current behavior seems perfectly consistent.

@pnkfelix
Copy link
Member

We are going to keep our current syntax/semantics, largely because we like being able to write e.g. None::<T>, and we are not convinced supporting a second way via Option::<T>::None is worth blocking 1.0 or 1.0 beta, and if there is a good argument for supporting it, we can add it backwards compatibly via the RFC process.

@U007D
Copy link

U007D commented May 28, 2017

I just spent some time running into this issue. I agree it was the right decision not to block 1.0 on it, but does that mean the issue will never be addressed?

I think the turbofish syntax should also be supported for orthogonality, since it is not at all clear to new Rustaceans such as myself that an enum should be thought of differently.

@nikomatsakis
Copy link
Contributor

I would be open to an RFC proposing a solution, but I don't think it's a priority for us on the lang-team -- happy to discuss it a bit though if you'd like to drive it! Maybe open a thread on internals?

@U007D
Copy link

U007D commented Jun 2, 2017

@nikomatsakis I would love to land a feature (even a tiny one)!

Question: does it not being a priority for the lang team (understandable, given all the work going on) mean that even if we hash out a solution and I am able to implement it (neither being a given, you understand ;)) that it would still be unlikely to make it into the codebase?

Or does it simply mean the team has limited available cycles for hashing out the feature and implementing it themselves?

Thank you for the invitation, @nikomatsakis. 👍

@nikomatsakis
Copy link
Contributor

@U-007D

Or does it simply mean the team has limited available cycles for hashing out the feature and implementing it themselves?

This is what I meant, in this case.

@Boscop
Copy link

Boscop commented Jul 28, 2018

I'd also be very interested in additionally allowing the normal turbofish syntax for variants of generic enums (e.g. Option::<T>::None).
I've been using Rust a lot for the past years and was always wondering why the normal turbofish doesn't work for enums (because you'd expect it to)..

And it's very inconsistent/weird having to write MyGenericEnum::MyVariant::<i32, usize>(x)
(when the types can't be inferred from the args passed to this variant constructor).

I want to be able to write MyGenericEnum::<i32, usize>::MyVariant(x) instead.

I'd be willing to write a RFC for this. I haven't written a RFC before, but read a lot of RFCs, this one seems to be a good "first RFC" to write, right?


Btw, I also wish accessing variants would work for aliased (monomorphized) enums, e.g.:

type Foo = MyGenericEnum<i32, usize>;

...

let x = Foo::MyVariant(y);

And also for aliased (still generic) enums, e.g.:

type Foo = MyGenericEnum;

...

let x = Foo::<i32, usize>::MyVariant(y);

@U007D
Copy link

U007D commented Jul 30, 2018

@Boscop agreed--it would be nice for this to be consistent. I'm wrapping up another small Rust feature and have started a new job, so this is all yours, if you want it. Thanks for taking this on!

@QuineDot
Copy link

See here for some updates on this topic.

  • Option::<T>::None has worked since Rust 1.33
  • Alias::<T>::None has worked since Rust 1.37
  • Alias::None::<T> doesn't work so far (Rust 1.73) and is now arguably the inconsistent case

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I-needs-decision Issue: In need of a decision.
Projects
None yet
Development

No branches or pull requests

6 participants