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 upRFC: Add std::num::NonZeroU32 and friends, deprecate core::nonzero #2307
Conversation
This comment has been minimized.
This comment has been minimized.
|
Not featured in the RFC because I couldn’t find a way to express it more objectively: I think the |
SimonSapin
referenced this pull request
Jan 21, 2018
Closed
Tracking issue for `NonZero`/`Unique`/`Shared` stabilization #27730
This comment has been minimized.
This comment has been minimized.
|
A more general approach would use |
This comment has been minimized.
This comment has been minimized.
|
@eddyb Is this an argument against adding non-zero integer types? I’d like to keep details of a more general feature out of scope for this PR, thanks :) |
This comment has been minimized.
This comment has been minimized.
|
Yes, if const generics were further along, I'd be more against this RFC. As it stands, a mention in alternatives is probably enough. |
This comment has been minimized.
This comment has been minimized.
|
I would argue that
Are non-zero integers actually used in practice to justify stabilizing these types? I have only ever seen |
This comment has been minimized.
This comment has been minimized.
|
I think @stoklund also used the max value in Cranelift, and the Rust compiler itself has a few types for which that's a dummy. So maybe we can defer this until a more general approach can be tried out. |
This comment has been minimized.
This comment has been minimized.
|
Servo has a few types like These could likely just as well have |
This comment has been minimized.
This comment has been minimized.
|
If this is an argument for rejecting this RFC one question is: who’s volunteering for championing the designing and RFC and implementation for that more general feature? |
This comment has been minimized.
This comment has been minimized.
|
Agree that hardcoding the sentinel value to zero seems limiting. Also agree that waiting for const generics seems like a showstopper (and might also end up overengineered). Is there any reason this has to be in core/std? Looking at the example implementation in the RFC, it looks like all of this is using stable features and could easily exist in a third-party crate. If possible, that seems like the way to go. |
This comment has been minimized.
This comment has been minimized.
|
@bstrie The compiler has to be told what the invalid values are - hence |
This comment has been minimized.
This comment has been minimized.
|
@bstrie A wrapper type that maintains invariant in order to help with some algorithm’s correctness can be outside of |
This comment has been minimized.
This comment has been minimized.
|
Ah, I glossed over the non_zero lang item there... figured that this implementation was taking advantage of some of the new enum niche optimizations somehow. Is a new lang item really preferable to stabilizing the Zeroable trait? (I see a lot of dislike for Zeroable in rust-lang/rust#27730, but not much explicit discussion of its downsides.) |
This comment has been minimized.
This comment has been minimized.
|
@bstrie The I’d forgotten to list the stabilizing |
This comment has been minimized.
This comment has been minimized.
Fleshgrinder
commented
Jan 28, 2018
•
|
I am coming from this Reddit where I basically asked for unsigned integer types without zero. I am using the term natural number to refer to ℕ⁺ = {1, 2, …}, hence, excluding zero, which I refer to as whole numbers ℕ⁰ = {0, 1, 2, …}. I see great value in the addition of these types to Rust and have many use cases where they are useful. I do not know how |
This comment has been minimized.
This comment has been minimized.
|
@Fleshgrinder struct BoundedU32<const LOWER_BOUND: u32, const UPPER_BOUND: u32>(/* … */);Then natural integers (up to bit storage capacity) become just a special case that you could define in your crates: type NonZeroU32 = BoundedU32<1, u32::MAX>; |
This comment has been minimized.
This comment has been minimized.
Fleshgrinder
commented
Jan 28, 2018
|
I figured, well, that would definitely be better than having dedicated types due to the flexibility they offer. |
This comment has been minimized.
This comment has been minimized.
matthieu-m
commented
Jan 28, 2018
|
It seems to me that there are two different requests here:
I am not sure that mixing them is the right approach. For example, imagine that I create two types: I would not be able to use a It seems that for the case of enum layout optimization, relying on
The nice thing about functions being that they are easily composed. For example, the implementation for |
This comment has been minimized.
This comment has been minimized.
Fleshgrinder
commented
Jan 28, 2018
|
So I was playing a little with the nightly The situation would be the same with |
This comment has been minimized.
This comment has been minimized.
|
@SimonSapin "Bounded" is the opposite of what you want (unless you make it wrap around, which would be confusing but equivalent in power) i.e. your example would be @matthieu-m Using anything other than a single range per enum requires potentially expensive rewrites when the enum discriminant is ever operated on. We could be tracking multiple ranges and pick a contiguous piece of them for each Even/odd is more interesting problem, pretty similar to taking advantage of pointer alignment. struct InvalidRange {
offset: usize,
size: usize,
range: RangeInclusive<u128>
}
trait HasInvalid {
const fn next_invalid(previous: Option<InvalidRange>) -> Option<InvalidRange>;
} |
This comment has been minimized.
This comment has been minimized.
|
I started it, but this is getting into the details of designing a feature that is not the one proposed in this RFC. Please let’s keep this thread about this proposal. We can discuss the existence of a potential more general feature as an argument for rejecting this RFC, without going into the details of how exactly that other feature works. (Though once again I am not making that argument. We can do both.) If someone does want to follow through discussing these details, please consider making a separate RFC or forum thread. |
This comment has been minimized.
This comment has been minimized.
fstirlitz
commented
Jan 28, 2018
|
The non-orthogonality of this proposal seems somewhat unsatisfying. What if some day someone wishes to have an |
This comment has been minimized.
This comment has been minimized.
|
On Even if we made |
This comment has been minimized.
This comment has been minimized.
fstirlitz
commented
Jan 28, 2018
|
Okay, atomics are a bad example. My point was a little more abstract, though: eliminating genericity may make it harder/impossible to simultaneously forbid zero values and use other features. It may be the case that this genericity is not worth the trouble (I'm not especially aware of all the trade-offs involved), but I think it's at least worth thinking about. |
This comment has been minimized.
This comment has been minimized.
Fleshgrinder
commented
Jan 29, 2018
|
Maybe it would be better to implement the non-zero types as primitives, like I expected them to be, in that case, atomics would work like the work right now with the others. I honestly never thought about an integer without zero and fail to see the use case, however, for real natural numbers it should be quite easy to define such a primitive type. |
This comment has been minimized.
This comment has been minimized.
The main use case is using
Why? I don’t think having
I don’t understand, you explain some more what you mean here? (At the moment we have |
This comment has been minimized.
This comment has been minimized.
Fleshgrinder
commented
Jan 29, 2018
|
Integer: {-∞, …, -2, -1, 0, 1, 2, …, ∞} What I said is that I fail to see the use case for non-zero integers (hence {-∞, …, -2, -1, 1, 2, …, ∞}) but that I see the use case for non-zero unsigned integers (Natural Number; hence {1, 2, …, ∞}). The latter is what applies to identifiers (usually) and is the use case I am coming from. With primitives I meant |
This comment has been minimized.
This comment has been minimized.
|
Ah ok. Yes, the |
This comment has been minimized.
This comment has been minimized.
|
trying again: @rfcbot fcp merge |
This comment has been minimized.
This comment has been minimized.
|
As one of the people who wanted to understand the details of why this couldn't use a generic type, I do agree that this shouldn't block the RFC. I do, however, think we need to address that before stabilization, and during the development process we should either end up with a generic type or with a clear explanation of why a generic type can't work or doesn't work well. Reasonable? |
This comment has been minimized.
This comment has been minimized.
|
@joshtriplett Agreed! I think it should be listed as an unresolved question and hence recorded on the tracking issue. |
This comment has been minimized.
This comment has been minimized.
|
@rfcbot fcp merge |
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Mar 8, 2018
•
|
Team member @aturon has proposed to merge this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
rfcbot
added
proposed-final-comment-period
final-comment-period
and removed
proposed-final-comment-period
labels
Mar 8, 2018
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Mar 8, 2018
|
|
SimonSapin
added a commit
to SimonSapin/rust
that referenced
this pull request
Mar 8, 2018
SimonSapin
added a commit
to SimonSapin/rust
that referenced
this pull request
Mar 17, 2018
This comment has been minimized.
This comment has been minimized.
|
Bikeshed: how about Edit: I also like |
This comment has been minimized.
This comment has been minimized.
|
The fact that “positive” does not include zero in English is something that I’ve learned a couple years ago but it is still subtle in my mind. This is not the case in French, “nombre positif” correctly translates to “non-negative number”. Relying on such a subtle (at least to some parts of the world) aspect of what “positive” means to express the core property of these types doesn’t sound great to me. |
This comment has been minimized.
This comment has been minimized.
|
This is the usual meaning in programming, though. For example,
And overall, |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Mar 18, 2018
|
The final comment period is now complete. |
Centril
referenced this pull request
Mar 18, 2018
Closed
Tracking issue for std::num::NonZero* types #49137
Centril
merged commit b728bf6
into
rust-lang:master
Mar 18, 2018
This comment has been minimized.
This comment has been minimized.
|
Huzzah! This RFC has been accepted. Tracking issue: rust-lang/rust#49137 |
SimonSapin
deleted the
SimonSapin:concrete-nonzero
branch
Mar 18, 2018
This comment has been minimized.
This comment has been minimized.
|
FWIW, even though I'm aware that "positive" technically excludes zero, whenever a non-mathematician says "positive" I don't feel safe assuming that they really meant to exclude zero, because so many people use positive/negative colloquially without thinking about the zero case. Even if I was reading a language spec that used the word "positive", unless there was an explicit mention of zero or non-negative/non-positive very close by (which is the case in all of @scottmcm's links), I'd feel the need to double-check that I hadn't discovered an unintentional underspecification. So I think |
This comment has been minimized.
This comment has been minimized.
|
@Ixrec I agree, but since this RFC is merged further discussion should probably go into the tracking issue: rust-lang/rust#49137 |
SimonSapin commentedJan 21, 2018
•
edited by Centril
Add
std::num::NonZeroU32and eleven other concrete types (one for each primitive integer type) to replace and deprecatecore::nonzero::NonZero<T>. (Non-zero/non-null raw pointers are available throughstd::ptr::NonNull<U>.)Rendered
Tracking issue