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 up[RFC accepted] add wrapper for discriminant_value intrinsic #34785
Conversation
rust-highfive
assigned
brson
Jul 12, 2016
This was referenced Jul 12, 2016
durka
force-pushed the
durka:discriminant_value
branch
3 times, most recently
from
38a41cb
to
609c17e
Jul 12, 2016
This comment has been minimized.
This comment has been minimized.
|
I just realized the wrapper should be safe. Another commit incoming... |
sfackler
reviewed
Jul 12, 2016
| pub struct TraitObject { | ||
| pub data: *mut (), | ||
| pub vtable: *mut (), | ||
| } | ||
|
|
||
| /// Returns the value of the discriminant for the enum variant in `v`. |
This comment has been minimized.
This comment has been minimized.
sfackler
Jul 12, 2016
•
Member
It is probably worth adding a warning that discriminants may not compare in the correct order if the enum is #[repr(i64)] due to overflow.
This comment has been minimized.
This comment has been minimized.
durka
Jul 12, 2016
Author
Contributor
Will do.
On Tue, Jul 12, 2016 at 1:43 PM, Steven Fackler notifications@github.com
wrote:
In src/libcore/raw.rs
#34785 (comment):pub struct TraitObject {
pub data: *mut (),
pub vtable: *mut (),
}
+
+/// Returns the value of the discriminant for the enum variant inv.It is probably worth adding a warning that discriminants may not compare
in the correct order if the enum is #[repr(u64)] due to overflow.—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/rust-lang/rust/pull/34785/files/609c17e8d0ceac437261df2c6b4231225f1faf08#r70485187,
or mute the thread
https://github.com/notifications/unsubscribe/AAC3n4IaNbDuCLcSiYjaKILI3yho7yvLks5qU9IrgaJpZM4JKnnt
.
This comment has been minimized.
This comment has been minimized.
durka
Jul 12, 2016
Author
Contributor
Wait, I don't understand. You mean if the enum is not #[repr(u64)]?
On Tue, Jul 12, 2016 at 1:46 PM, Alex Burka durka42@gmail.com wrote:
Will do.
On Tue, Jul 12, 2016 at 1:43 PM, Steven Fackler notifications@github.com
wrote:In src/libcore/raw.rs
#34785 (comment):pub struct TraitObject {
pub data: *mut (),
pub vtable: *mut (),
}
+
+/// Returns the value of the discriminant for the enum variant inv.It is probably worth adding a warning that discriminants may not compare
in the correct order if the enum is #[repr(u64)] due to overflow.—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/rust-lang/rust/pull/34785/files/609c17e8d0ceac437261df2c6b4231225f1faf08#r70485187,
or mute the thread
https://github.com/notifications/unsubscribe/AAC3n4IaNbDuCLcSiYjaKILI3yho7yvLks5qU9IrgaJpZM4JKnnt
.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
I might personally prefer this being located in the Also, could the actual stabilization be deferred to a later date? The libs team tends to not apply stabilizations mid-cycle but instead places issues into final comment period at the end of which we decide on the stabilization outcome (as a result of the discussion, if any, that happened). cc @rust-lang/libs, any objections on moving this to FCP though? Seems good to me! |
This comment has been minimized.
This comment has been minimized.
|
OK, I had previously asked at the tracking issue if this should be insta-stable (since it is basically stabilizing the intrinsic, even though it doesn't actually do that) and @brson said yes. But I'm happy to mark it unstable for now. I'll move it to |
durka
force-pushed the
durka:discriminant_value
branch
2 times, most recently
from
29e3b0d
to
1001205
Jul 12, 2016
This comment has been minimized.
This comment has been minimized.
|
@sfackler's comment was hidden, but I added a note about comparisons. |
durka
force-pushed the
durka:discriminant_value
branch
2 times, most recently
from
eb26969
to
3a88d88
Jul 12, 2016
alexcrichton
reviewed
Jul 12, 2016
| /// enum Foo { A(String), B(i32) } | ||
| /// | ||
| /// # fn main() { | ||
| /// assert!(mem::discriminant(Foo::A("bar")) != mem::discriminant(Foo::A("baz"))); |
This comment has been minimized.
This comment has been minimized.
alexcrichton
Jul 12, 2016
Member
I think these examples may not compile, the discriminants should be the same here, right? Additionally, shouldn't a shared reference be passed in?
This comment has been minimized.
This comment has been minimized.
durka
Jul 12, 2016
Author
Contributor
Yeah, I just noticed that and fixed it.
On Tue, Jul 12, 2016 at 2:19 PM, Alex Crichton notifications@github.com
wrote:
In src/libcore/mem.rs
#34785 (comment):+/// same order as actual enum variants would under
#[derive(PartialOrd)].
+///
+/// IfTis not an enum, the return value is unspecified.
+///
+/// # Example
+///
+/// This can be used to compare enums that carry data, while disregarding
+/// the actual data:
+///
+/// ```
+/// use std::mem;
+///
+/// enum Foo { A(String), B(i32) }
+///
+/// # fn main() {
+/// assert!(mem::discriminant(Foo::A("bar")) != mem::discriminant(Foo::A("baz")));I think these examples may not compile, the discriminants should be the
same here, right? Additionally, shouldn't a shared reference be passed in?—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/rust-lang/rust/pull/34785/files/3a88d8811ae23af836e8ed4349e4a96656303878#r70492383,
or mute the thread
https://github.com/notifications/unsubscribe/AAC3n1nIqX5ydVTZ2ue3rNp94IPEA-khks5qU9qggaJpZM4JKnnt
.
alexcrichton
reviewed
Jul 12, 2016
| /// the discriminant values returned by this function will not compare in the | ||
| /// same order as actual enum variants would under `#[derive(PartialOrd)]`. | ||
| /// | ||
| /// If `T` is not an enum, the return value is unspecified. |
This comment has been minimized.
This comment has been minimized.
alexcrichton
Jul 12, 2016
Member
Could this clarify though that it's not like undefined behavior will happen, it's just that the actual value returned cannot be relied on?
This comment has been minimized.
This comment has been minimized.
alexcrichton
Jul 12, 2016
Member
It may also be worth explaining that the returned value only really makes sense to compare with other discriminants generated from values of the same type? That is, comparing the discriminants of types A and B won't result in anything meaningful
This comment has been minimized.
This comment has been minimized.
durka
Jul 12, 2016
•
Author
Contributor
Could this clarify though that it's not like undefined behavior will happen, it's just that the actual value returned cannot be relied on?
Done.
It may also be worth explaining that the returned value only really makes sense to compare with other discriminants generated from values of the same type? That is, comparing the discriminants of types A and B won't result in anything meaningful
Not sure about this one. You can choose discriminants by hand (in the enum definition I mean), so you could for example set up certain error enums to have known discriminants corresponding to the errors produced by a -sys crate or something.
durka
force-pushed the
durka:discriminant_value
branch
3 times, most recently
from
987979d
to
c35ec62
Jul 12, 2016
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton I want to stabilize type_name or something like it, so we might want to keep std::raw around for things like that. |
This comment has been minimized.
This comment has been minimized.
|
Is it the case that a discriminant can never be larger than |
This comment has been minimized.
This comment has been minimized.
|
For the record (on the theme of my previous comment) I still think it would be better to use the type system to make this function's return type better. But I also understand we want to stabilize something. |
durka
changed the title
add stable wrapper for discriminant_value intrinsic
add soon-to-be-stable wrapper for discriminant_value intrinsic
Jul 12, 2016
This comment has been minimized.
This comment has been minimized.
|
@sfackler hm that's a good point about |
brson
added
the
relnotes
label
Jul 12, 2016
durka
force-pushed the
durka:discriminant_value
branch
from
c35ec62
to
90e4530
Jul 13, 2016
This comment has been minimized.
This comment has been minimized.
|
I wasn't initially a fan of |
tbu-
reviewed
Jul 13, 2016
| assert_eq!(mem::discriminant(&NullablePointer::Something(&CONST)), 0); | ||
|
|
||
| // unlike the test for the intrinsic, there are no tests with non-enums here | ||
| // because the result is documented to be unspecified |
This comment has been minimized.
This comment has been minimized.
tbu-
Jul 13, 2016
Contributor
You could still call it on a struct, just to check that it doesn't panic.
This comment has been minimized.
This comment has been minimized.
ollie27
reviewed
Jul 13, 2016
|
|
||
| /// Returns the value of the discriminant for the enum variant in `v`. | ||
| /// | ||
| /// The returned discriminant is cast to `u64`, no matter what the actual |
This comment has been minimized.
This comment has been minimized.
ollie27
Jul 13, 2016
Contributor
I would like to see more explanation about where the value comes from, along with examples if possible.
Also what stability guarantees do the returned values have. For example is discriminant_value(&Some(123)) == 1 guaranteed to always be true?
This comment has been minimized.
This comment has been minimized.
durka
Jul 13, 2016
Author
Contributor
Added an example.
Also what stability guarantees do the returned values have.
Hmm... this is a tough one. Since the discriminant depends on the order of enum variants, stability would imply that libraries following semver may not shuffle the order of variants, or add new ones except at the end, in minor versions (actually, they already can't add new variants, unless they have a hack like std::io::ErrorKind::__Nonexhaustive). This seems OK to me (needs to be documented of course), but others might have thoughts?
This comment has been minimized.
This comment has been minimized.
sfackler
Jul 13, 2016
Member
I think we should say that consumers shouldn't depend on discriminants being stable across versions of a dependency unless otherwise documented on the enum.
I think it's probably reasonable to state that discriminants will be stable for a given enum definition though across compilations. Maybe compiler versions as well?
This comment has been minimized.
This comment has been minimized.
durka
Jul 13, 2016
•
Author
Contributor
Quoth the reference:
If a discriminant isn't specified, they start at zero, and add one for each variant, in order.
So I think they must be stable across compiler minor versions.
This comment has been minimized.
This comment has been minimized.
nagisa
Jul 14, 2016
•
Contributor
If a discriminant isn't specified, they start at zero, and add one for each variant, in order.
This is for C-like (i.e. numeric/data-less) enums only. We do not specify anything for sum-types. I would like to not guarantee anything other than discriminant(Enum::Variant) == discriminant(Enum::Variant) within the crates compiled by the same version of rustc, except for C-like enums, where the usual increment-by-one rules apply.
This comment has been minimized.
This comment has been minimized.
nagisa
Jul 14, 2016
Contributor
Seems problematic with #[repr(i/u128)] potentially happening once we get i/u128 primitives. Are we gonna forbid such attribute?
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
durka
Jul 14, 2016
•
Author
Contributor
This is for C-like (i.e. numeric/data-less) enums only.
The reference does not restrict or qualify this statement in any way. It is in a section called "Enumerations". If you want to remove this as a guarantee for all enums, then change the reference. I do understand the reluctance to make guarantees, but this is a bit ridiculous. What would the motivation be for changing discriminants according to the phase of the moon?
This comment has been minimized.
This comment has been minimized.
|
RFC posted at rust-lang/rfcs#1696. |
nikomatsakis
removed
the
I-nominated
label
Aug 4, 2016
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
Waiting to rebase until the RFC process concludes. |
durka
changed the title
[WIP] add wrapper for discriminant_value intrinsic
[RFC accepted] add wrapper for discriminant_value intrinsic
Sep 16, 2016
durka
force-pushed the
durka:discriminant_value
branch
from
a7de3ad
to
a8c3cf6
Sep 16, 2016
This comment has been minimized.
This comment has been minimized.
|
Rebased and updated. I removed the I updated the stability section of the documentation to say (again, nobody opined during FCP):
|
oli-obk
referenced this pull request
Sep 19, 2016
Closed
Add as_borrow() generic method for Value #153
This comment has been minimized.
This comment has been minimized.
|
@nagisa Can you take over this review, given that you've already looked at the PR? |
nagisa
reviewed
Sep 27, 2016
| /// | ||
| /// # Stability | ||
| /// | ||
| /// Discriminants can change if enum variants are reordered, if a new variant is added |
This comment has been minimized.
This comment has been minimized.
nagisa
Sep 27, 2016
Contributor
As the return value of this wrapper is a opaque value Discriminant<T>, this section reads weird. Namely it changing makes little sense because you aren’t supposed to be able to inspect it directly. Rather the stability and behaviour should be described in terms of PartialEq and Hash.
This comment has been minimized.
This comment has been minimized.
| #[unstable(feature = "discriminant_value", reason = "recently added, follows RFC", issue = "24263")] | ||
| impl<T> fmt::Debug for Discriminant<T> { | ||
| fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||
| self.0.fmt(fmt) |
This comment has been minimized.
This comment has been minimized.
nagisa
Sep 27, 2016
•
Contributor
This probably wants to use a debug builder and output something along the lines of Discriminant(<number>), rather than outputting a plain number.
This comment has been minimized.
This comment has been minimized.
nagisa
reviewed
Sep 27, 2016
| pub struct Discriminant<T>(u64, PhantomData<*const T>); | ||
|
|
||
| #[unstable(feature = "discriminant_value", reason = "recently added, follows RFC", issue = "24263")] | ||
| impl<T> Copy for Discriminant<T> {} |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
durka
Sep 27, 2016
Author
Contributor
I thought I'd included a comment to this effect. I'll add one.
durka
force-pushed the
durka:discriminant_value
branch
from
a8c3cf6
to
e447d42
Sep 27, 2016
durka
force-pushed the
durka:discriminant_value
branch
from
e447d42
to
a84b550
Sep 27, 2016
This comment has been minimized.
This comment has been minimized.
|
I think it's ready, just waiting for tests. |
This comment has been minimized.
This comment has been minimized.
|
@durka OK, just give a ping once it's ready for bors and i'll send it along. |
This comment has been minimized.
This comment has been minimized.
|
Tests and tidy pass locally. |
This comment has been minimized.
This comment has been minimized.
|
Huzzah! @bors: r=nagisa |
This comment has been minimized.
This comment has been minimized.
|
@bors? you there? |
This comment has been minimized.
This comment has been minimized.
|
@bors: r+ |
This comment has been minimized.
This comment has been minimized.
|
@bors r=nagisa |
aturon
closed this
Sep 28, 2016
aturon
reopened this
Sep 28, 2016
This comment has been minimized.
This comment has been minimized.
|
@bors: r=nagisa |
This comment has been minimized.
This comment has been minimized.
|
Should I try reopening as a new PR? |
durka
closed this
Sep 29, 2016
durka
referenced this pull request
Sep 29, 2016
Merged
add wrapper for discriminant_value, take 2 #36823
This comment has been minimized.
This comment has been minimized.
|
Moved to #36823. |
durka commentedJul 12, 2016
•
edited
add wrapper for discriminant_value intrinsic
Wraps the
discriminant_valueintrinsic under the namestd::mem::discriminant. In order to avoid prematurely leaking information about the implementation of enums, the return value is an opaque type, generic over the enum type, which implementsCopy,Clone,PartialEq,Eq,Hash, andDebug(notably notPartialOrd). There is currently no way to get the value out excepting printing the debug representation.The wrapper is safe and can be stabilized soon as per discussion in #24263.
r? @brson