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 upPrivacy for enum variants and trait items #2028
Conversation
petrochenkov
referenced this pull request
Jun 11, 2017
Merged
Future-proofing enums/structs with #[non_exhaustive] attribute #2008
This comment has been minimized.
This comment has been minimized.
le-jzr
commented
Jun 12, 2017
|
Marking non-exhaustiveness with a dummy variant seems like a step in the wrong direction to me. It feels weird. One of the reason it feels weird to me is that I have trouble imagining a case where this is useful for things you actually want to match on. Is it possible to show extant code where matchable private variants would be helpful? |
This comment has been minimized.
This comment has been minimized.
|
From the RFC: pub trait Trait1 {
fn method1();
pub(crate) fn method_without_default();
}This feels strange to me. Under this RFC, the "package private" method here is |
withoutboats
added
the
T-lang
label
Jun 12, 2017
This comment has been minimized.
This comment has been minimized.
You can read |
nikomatsakis
self-assigned this
Jun 13, 2017
This comment has been minimized.
This comment has been minimized.
ssokolow
commented
Jun 13, 2017
•
I think the issue being raised is that Especially since it can easily muddy the waters and side-track someone into wondering whether TL;DR: It's bad for teachability if you have to explain that to everyone who concluded that |
This comment has been minimized.
This comment has been minimized.
|
Oh, I get your point now. The issue is that the defaults are swapped here. Struct members are private by default while enum variants and trait items are pub by default. That's a valid point. |
This comment has been minimized.
This comment has been minimized.
|
Maybe we could require explicit |
This comment has been minimized.
This comment has been minimized.
ssokolow
commented
Jun 13, 2017
•
|
@glaebhoerl To be honest, that really screams "we wanted this so badly that we're making a hack everyone will recognize as ugly in order to circumvent our backwards-compatibility requirement". In fact, that "you've gotta retroactively annotate all your old variants/items with default behaviour in order to start annotating non-default behaviour" pattern which appears nowhere else in the language feels like enough of a hack that I worry people I'm teaching/mentoring might count it against my credibility as an experienced authority unless I explicitly throw the language under the bus on that point as part of teaching them. |
This comment has been minimized.
This comment has been minimized.
|
To be clear, I think inherited privacy for |
This comment has been minimized.
This comment has been minimized.
burdges
commented
Jun 13, 2017
|
You could add a |
This comment has been minimized.
This comment has been minimized.
ssokolow
commented
Jun 13, 2017
|
|
This comment has been minimized.
This comment has been minimized.
bjorn3
commented
Jun 13, 2017
|
|
This comment has been minimized.
This comment has been minimized.
|
We can change the default in a Rust 2.0 future, and requiring it just in the types using the new features is fairly small churn. I think not doing things simply because they are deemed to give impression that we're admitting mistakes is rather obnoxious. Better to come clean than sweep under the rug. |
This comment has been minimized.
This comment has been minimized.
ssokolow
commented
Jun 13, 2017
•
|
I'm not by any means saying that admitting to a mistake is bad. I'm saying that, from my perspective, the " If |
This comment has been minimized.
This comment has been minimized.
I don't think it's a mistake, so far this scheme served us with almost no complaints, and this is indeed what you want in most cases. |
This comment has been minimized.
This comment has been minimized.
le-jzr
commented
Jun 13, 2017
•
|
I'm still waiting for that example of a public enum in existing crate that would benefit from non-public variants. :) |
This comment has been minimized.
This comment has been minimized.
Please, wait some more, I haven't even looked through all the comments yet! Do you mean in addition to exhaustiveness checks? I can imagine cases when private variants could be useful. For example the enum is a state machine with some states that can be observed externally, and some states that are purely internal/intermediate. |
This comment has been minimized.
This comment has been minimized.
|
My primary argument in support of the private variant idiom is that making non-exhaustive enums is not a dire everyday need and doesn't worth extending the language, there's just need to be some way to do it. |
This comment has been minimized.
This comment has been minimized.
Not going to bother finding a crate with such a situation, but here's a very plausible example: You could make use of an pub enum Source {
Utf8(String),
Binary(Vec<u8>),
pub(crate) PartiallyUtf8(Vec<u8>, usize),
}
pub fn encode(src: Source) -> EncodedString {
}
fn grow_and_encode(s: String, more: &[u8]) -> EncodedString {
let index = s.len();
let mut vec = s.into_bytes();
vec.extend_from_slice(more);
encode(Source::PartiallyUtf8(vec, index))
} |
This comment has been minimized.
This comment has been minimized.
burdges
commented
Jun 13, 2017
|
I've kinda wanted non-public variant several times. I even learned the private-in-public when trying to create them. I run into them when trying to use a polymorphic That said, I think non-public variants look weaker than being able to circumvent the private-in-public rules, so maybe one should work towards that instead. If there was a
I could use this enum in several ways : I can use it for internal state. I can pass it in as a configuration option, usually using the two You might argue against abusing polymorphic tl;dr I think the case against non-public variants is ultimately stylistic and subtle, but I also think mechanisms for breaking the private-in-public rules look more powerful. |
This comment has been minimized.
This comment has been minimized.
crumblingstatue
commented
Jun 17, 2017
•
|
If this RFC establishes the |
This comment has been minimized.
This comment has been minimized.
|
#2008 was merged, so I'm closing this as not having sufficient motivation. |
petrochenkov
closed this
Aug 26, 2017
petrochenkov
deleted the
petrochenkov:morevis
branch
Sep 10, 2017
This comment has been minimized.
This comment has been minimized.
|
@petrochenkov I don't understand how #2008 solves the issues raised by this issue, in particular as it relates to |
petrochenkov commentedJun 11, 2017
•
edited
Support
pub/pub(restricted)on enum variants and trait items, it helps with controlling matching exhaustiveness and trait implementability.cc rust-lang/rust#32770 #943 #2008
Rendered