Skip to content

[RFC accepted] add wrapper for discriminant_value intrinsic - #34785

Closed
durka wants to merge 1 commit into
rust-lang:masterfrom
durka:discriminant_value
Closed

[RFC accepted] add wrapper for discriminant_value intrinsic#34785
durka wants to merge 1 commit into
rust-lang:masterfrom
durka:discriminant_value

Conversation

@durka

@durkadurka commented Jul 12, 2016

Copy link
Copy Markdown
Contributor

add wrapper for discriminant_value intrinsic

Wraps the discriminant_value intrinsic under the name std::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 implements Copy, Clone, PartialEq, Eq, Hash, and Debug (notably not PartialOrd). 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

@durka

Copy link
Copy Markdown
ContributorAuthor

I just realized the wrapper should be safe. Another commit incoming...

Comment threadsrc/libcore/raw.rs Outdated

@sfacklersfacklerJul 12, 2016

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 in v.

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
.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 in v.

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
.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Er, yeah. Your doc change is what I was thinking of.

@alexcrichton

Copy link
Copy Markdown
Member

I might personally prefer this being located in the std::mem module as opposed to std::raw. We've almost deleted the entire std::raw module and I'd personally like to see it go out all the way!

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!

@durka

durka commented Jul 12, 2016

Copy link
Copy Markdown
ContributorAuthor

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 std::mem as well (though it doesn't have much if anything to do with memory).

@durka
durkaforce-pushed the discriminant_value branch 2 times, most recently from 29e3b0d to 1001205CompareJuly 12, 2016 18:16
@durka

durka commented Jul 12, 2016

Copy link
Copy Markdown
ContributorAuthor

@sfackler's comment was hidden, but I added a note about comparisons.

@durka
durkaforce-pushed the discriminant_value branch 2 times, most recently from eb26969 to 3a88d88CompareJuly 12, 2016 18:17
Comment threadsrc/libcore/mem.rs Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these examples may not compile, the discriminants should be the same here, right? Additionally, shouldn't a shared reference be passed in?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)].
+///
+/// If T is 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
.

@durka
durkaforce-pushed the discriminant_value branch 3 times, most recently from 987979d to c35ec62CompareJuly 12, 2016 18:26
@sfackler

Copy link
Copy Markdown
Member

@alexcrichton I want to stabilize type_name or something like it, so we might want to keep std::raw around for things like that.

@durka

durka commented Jul 12, 2016

Copy link
Copy Markdown
ContributorAuthor

Is it the case that a discriminant can never be larger than u64? (I think there is an RFC to add u128 and whatnot...)

@durka

Copy link
Copy Markdown
ContributorAuthor

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.

@durkadurka changed the title add stable wrapper for discriminant_value intrinsicadd soon-to-be-stable wrapper for discriminant_value intrinsicJul 12, 2016
@alexcrichton

Copy link
Copy Markdown
Member

@sfackler hm that's a good point about type_name, but I figure we can probably figure out a better way to do that than putting it in std::raw

@brsonbrson added the relnotes Marks issues that should be documented in the release notes of the next release. label Jul 12, 2016
@durka
durkaforce-pushed the discriminant_value branch from c35ec62 to 90e4530CompareJuly 13, 2016 02:27
@aturon

Copy link
Copy Markdown
Contributor

I wasn't initially a fan of std::mem for this, but I can sort of see it now. E.g. this is not so different from things like size_of, which are type-generic functions giving repr details. I could see type_name living here eventually, too.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could still call it on a struct, just to check that it doesn't panic.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@durka

durka commented Aug 1, 2016

Copy link
Copy Markdown
ContributorAuthor

RFC posted at rust-lang/rfcs#1696.

@bors

bors commented Aug 26, 2016

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (presumably #35906) made this pull request unmergeable. Please resolve the merge conflicts.

@durka

Copy link
Copy Markdown
ContributorAuthor

Waiting to rebase until the RFC process concludes.

@durkadurka changed the title [WIP] add wrapper for discriminant_value intrinsic[RFC accepted] add wrapper for discriminant_value intrinsicSep 16, 2016
@durka

Copy link
Copy Markdown
ContributorAuthor

Rebased and updated.

I removed the Reflect bound as per the RFC (nobody opined on it during FCP). I'm assuming that trait's FCP will end in deprecation; if not, we could revisit.

I updated the stability section of the documentation to say (again, nobody opined during FCP):

Discriminants can change if enum variants are reordered, if a new variant is addedin the middle, or (in the case of a C-like enum) if explicitly set discriminants are changed. Therefore, relying on the discriminants of enums outside of your crate may be a poor decision. However, discriminants of an identical enum should not change between subsequent compilations with the same compiler.

@aturon

Copy link
Copy Markdown
Contributor

@nagisa Can you take over this review, given that you've already looked at the PR?

Comment threadsrc/libcore/mem.rs Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point.

Comment threadsrc/libcore/mem.rs Outdated

@nagisanagisaSep 27, 2016

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably wants to use a debug builder and output something along the lines of Discriminant(<number>), rather than outputting a plain number.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

Comment threadsrc/libcore/mem.rs Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not derive all these implementations?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'd get nonsense bounds on T.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought I'd included a comment to this effect. I'll add one.

@durka

Copy link
Copy Markdown
ContributorAuthor

I think it's ready, just waiting for tests.

@aturon

Copy link
Copy Markdown
Contributor

@durka OK, just give a ping once it's ready for bors and i'll send it along.

@durka

Copy link
Copy Markdown
ContributorAuthor

Tests and tidy pass locally.

@aturon

Copy link
Copy Markdown
Contributor

Huzzah!

@bors: r=nagisa

@durka

Copy link
Copy Markdown
ContributorAuthor

@bors? you there?

@aturon

Copy link
Copy Markdown
Contributor

@bors: r+

@aturon

Copy link
Copy Markdown
Contributor

@bors r=nagisa

@aturonaturon closed this Sep 28, 2016
@aturonaturon reopened this Sep 28, 2016
@aturon

Copy link
Copy Markdown
Contributor

@bors: r=nagisa

@durka

Copy link
Copy Markdown
ContributorAuthor

Should I try reopening as a new PR?

@durka

Copy link
Copy Markdown
ContributorAuthor

Moved to #36823.

bors added a commit that referenced this pull request Sep 30, 2016
add wrapper for discriminant_value, take 2
[This is #34785 reopened, since @bors apparently gave up on that thread.]
add wrapper for discriminant_value intrinsic
Implementation of [RFC 1696](https://github.com/rust-lang/rfcs/blob/master/text/1696-discriminant.md).
Wraps the `discriminant_value` intrinsic under the name `std::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 implements Copy, Clone, PartialEq, Eq, Hash, and Debug (notably not PartialOrd). 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.
cc @aturon
r? @nagisa
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

relnotesMarks issues that should be documented in the release notes of the next release.T-langRelevant to the language teamT-libs-api[DEPRECATED; DO NOT USE]

Projects

None yet

Development

Successfully merging this pull request may close these issues.

16 participants

@durka@alexcrichton@sfackler@aturon@ollie27@eddyb@SimonSapin@nagisa@petrochenkov@brson@glaebhoerl@nikomatsakis@arielb1@strega-nil@bors@tbu-