-
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
Allow enum variants to be used through a type alias of the enum #31179
Conversation
r? @pnkfelix (rust_highfive has picked a reviewer for you, use r? to override) |
b81d753
to
b10df54
Compare
I think this may fix #31168 as well - if it does, could you add a test for the |
Could you add a test with variant's name "conflicting" with some associated item's name?
|
b10df54
to
6729479
Compare
@sfackler yeah it does fix that issue, I just added a test for the |
@petrochenkov done. |
Cc @rust-lang/lang does a change like this need an RFC first? Seems borderline at least. .. |
(Or it may be an obvious language bug fix. But I want other eyeballs on it either way to help decide. ) |
Some more questions:
|
@petrochenkov Good questions. I had been incorrectly assuming that variants behaved more like methods and associated constants. Right now the type parameters for the alias get ignored and the type parameters for the variant are the only ones that matter, which is a fatal flaw in this PR as it stands. I think it would be best to allow Another possibility would be to only allow access to variants through a type alias if the enum has no type parameters, which would be future-proof with respect to the previous idea and would fix the issues referenced in this PR, but this feels a little hacky. |
The lang team discussed this PR, and felt that, given some of the thornier questions here, we want to see a full design presented as an RFC before accepting these changes. Thanks @jseyfried for the PR, and feel free to reach out to me or others on the lang team if you'd like help putting together an RFC! |
I ran into a related case of this bug: a type alias of a tuple struct doesn't work as a constructor either. Minimal test case: struct Generic<T>(T);
type Specific = Generic<usize>;
fn main() {
let x = Generic::<usize>(42);
let y = Specific(42);
} This produces:
I had hoped to use this when converting an existing tuple struct to an alias for a generic tuple struct, with the type parameter specified. That would provide source compatibility with code written for the old version of the crate. This behavior seems inconsistent with other uses of type aliases. A type alias for a non-tuple struct works for type construction: (I ended up working around this by declaring a function with the same name as the tuple struct to act as a constructor.) Has anyone written the associated RFC for this? If not, I'd be happy to write it or to collaborate on it. |
@joshtriplett this seems like expected behaviour to me. A tuple struct is two things - a type and a ctor function. The type alias makes an alias of the type but not the function. A struct is just a type, there is no ctor function, the struct literal syntax expects a type in it, which is why the type alias is fine (though I wonder about the behaviour when the type alias fixes generic parameters). |
@nrc It's not expected if you expect a type alias to work anywhere the original type name would, which seems like a reasonable expectation. |
@joshtriplett I agree. But still, the next step here is going to be to open an RFC laying out a coherent vision of how aliasing should work in these respects. |
@jseyfried Do you plan to submit an RFC for this? Would you like any help doing so? |
@joshtriplett I don't have plans to write up an RFC, but I think it'd be a good idea -- I'd be happy to help. I agree with @nrc's comment that your example isn't a bug. In For example, fn Specific() {}
type Specific = Generic<usize>;
fn f() {
Specific(42) // Should `Specific` resolve to the function or the constructor?
} The original intent of this PR was to allow this, i.e. to allow an enum variant to be used via a type aliases of the enum as if it were an associated const ( However, as @petrochenkov pointed out here, we can't use enum variants as if they were associated consts even without aliases. For example, consider |
I wrote up a pre-RFC for this over the holidays, which seemingly converges after some comments. https://internals.rust-lang.org/t/pre-rfc-enum-variants-through-type-aliases/6433 Please have a look! |
@jseyfried / anyone else – plans to re-open this now that the RFC has landed? There's been a little discussion on the tracking issue lately. |
This allows enum variants to be used as constructors and patterns though a type alias of the enum (including the alias
Self
when in an impl for an enum). For example,Fixes #28556 and fixes #31168.