-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
NonZero lang item. #499
NonZero lang item. #499
Conversation
As part of this we'd introduce a new lang item: | ||
``` | ||
#[lang = "non_zero"] | ||
struct NonZero<T>(T); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if I put a non-pointer, non-integral type in NonZero
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the initial implementation in rust-lang/rust#19536 it doesn't do anything special. It would just act as any other struct there and the optimization wouldn't kick in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That seems like a reasonable approach, but I think we may want to make it an error to use NonZero
for non-supported types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, we could probably actually do that just by limiting the types constructor will accept.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be baked into the compiler, because there is no trait for the types we'd like to fit here. We could possibly write a marker-only trait with unsafe
traits and default traits.
This appears to be just a special case for a more general case of being able to limit the possible values a type can take. For instance, we know Could Rust benefit from being able to limit ranges more than just |
@Thiez Sort of, in the sense that enums of the form
would be optimized. But this doesn't seem like a rather common usage. |
@luqmana Obviously, this is a good thing to have. We discussed this in triage today. Current thinking is that we would like to close this RFC for now. There is already a tracking issue #278 indicating that this is a desirable feature to add to rust at some point after 1.0. It seems that there are enough use cases here that it's worth trying to think through the public-facing interface in more detail. However, it's still worth optimizing common cases like What do you think? |
@nikomatsakis That works for me. As for not exporting the lang item, initially I just placed it in |
Seems like you can shove it in its own module. |
@Manishearth I actually do think it would be a useful feature to have. I have wanted it quite often. |
In accordance with #499 (comment), closing this PR. |
This extends the nullable enum opt to traverse beyond just the first level to find possible fields to use as the discriminant. So now, it'll work through structs, tuples, and fixed sized arrays. This also introduces a new lang item, NonZero, that you can use to wrap raw pointers or integral types to indicate to rustc that the underlying value is known to never be 0/NULL. We then use this in Vec, Rc and Arc to have them also benefit from the nullable enum opt. As per rust-lang/rfcs#499 NonZero is not exposed via the `libstd` facade. ``` x86_64 Linux: T Option<T> (Before) Option<T> (After) ---------------------------------------------------------------------------------- Vec<int> 24 32 24 String 24 32 24 Rc<int> 8 16 8 Arc<int> 8 16 8 [Box<int>, ..2] 16 24 16 (String, uint) 32 40 32 ``` Fixes #19419. Fixes #13194. Fixes #9378. Fixes #7576.
No description provided.