Skip to content
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

Numeric traits inconsistent with integer type system #21069

Closed
sneves opened this issue Jan 13, 2015 · 5 comments · Fixed by #23549
Closed

Numeric traits inconsistent with integer type system #21069

sneves opened this issue Jan 13, 2015 · 5 comments · Fixed by #23549
Assignees
Labels
I-needs-decision Issue: In need of a decision.
Milestone

Comments

@sneves
Copy link
Contributor

sneves commented Jan 13, 2015

From all the integer traits present in std::num, only SignedInt includes Neg. The Neg trait is not implemented by Int and UnsignedInt types because, presumably, it does not make sense to negate unsigned integers. I will not argue whether this is a good policy or not.

However, this makes writing generic code for unsigned types harder than it needs to be. For example, suppose we have the function

fn f(x: u32) -> u32 { -(x >> 31) }

This function works perfectly (albeit with a warning, but it is valid Rust as far as I can tell) when implemented with a concrete unsigned integer type. However, when making the function generic it stops working:

fn f<T: UnsignedInt>(x: T) -> T { -(x >> (size_of::<T>()*8 - 1)) }
// error: cannot apply unary operator `-` to type `T`

Changing this to 0 - <expression> is a simple solution, but one that also does not work very well without pulling other (NumCast, FromPrimitive) traits. Another solution is to pull in the Neg trait directly, but this increases verbosity due to Neg's associated type machinery. All in all, the lack of unsigned negation complicates things.

Now, I accept that you may not want to make unsigned negation common or encouraged behavior. But in that case it also makes no sense to have the - operator available at all for unsigned types; users that really want such semantics can replace it by 0-<expression> in non-generic code.

My overall point is:

  • If u32, usize, etc allow negation, i.e., have the Neg type implemented, so should UnsignedInt;
  • If UnsignedInt is not meant to be negatable, neither should be u32, usize, etc.
@klutzy
Copy link
Contributor

klutzy commented Jan 13, 2015

rust-lang/rfcs#560 proposes: make integers not wrapping but "overflow", and provide separate "wrapping" operations and types. (i.e. Wrapping<u32> provides modular arithmetic on 2^32.)
In this setting, unary negation nearly always overflows so there's a discussion of removing it.

I think Wrapping<T> should provide unary negation.

cc #20795
cc rust-lang/rfcs#369

@Gankra
Copy link
Contributor

Gankra commented Jan 21, 2015

CC @aturon @bjz

@aturon
Copy link
Member

aturon commented Feb 16, 2015

Nominating for 1.0-beta P-backcompat-libs.

@brendanzab
Copy link
Member

Agreed - might make sense to add Neg to unsigned ints for bitwise stuff.

@pnkfelix
Copy link
Member

1.0 beta, P-backcompats-lib, I-needsdecision

@pnkfelix pnkfelix added P-backcompat-libs I-needs-decision Issue: In need of a decision. labels Feb 19, 2015
@pnkfelix pnkfelix added this to the 1.0 beta milestone Feb 19, 2015
aturon added a commit to aturon/rust that referenced this issue Mar 31, 2015
This commit stabilizes the `std::num` module:

* The `Int` and `Float` traits are deprecated in favor of (1) the
  newly-added inherent methods and (2) the generic traits available in
  rust-lang/num.

* The `Zero` and `One` traits are reintroduced in `std::num`, which
  together with various other traits allow you to recover the most
  common forms of generic programming.

* The `FromStrRadix` trait, and associated free function, is deprecated
  in favor of inherent implementations.

* A wide range of methods and constants for both integers and floating
  point numbers are now `#[stable]`, having been adjusted for integer
  guidelines.

* `is_positive` and `is_negative` are renamed to `is_sign_positive` and
  `is_sign_negative`, in order to address rust-lang#22985

* The `Wrapping` type is moved to `std::num` and stabilized;
  `WrappingOps` is deprecated in favor of inherent methods on the
  integer types, and direct implementation of operations on
  `Wrapping<X>` for each concrete integer type `X`.

Closes rust-lang#22985
Closes rust-lang#21069

[breaking-change]
Manishearth added a commit to Manishearth/rust that referenced this issue Mar 31, 2015
This commit stabilizes the `std::num` module:

* The `Int` and `Float` traits are deprecated in favor of (1) the
  newly-added inherent methods and (2) the generic traits available in
  rust-lang/num.

* The `Zero` and `One` traits are reintroduced in `std::num`, which
  together with various other traits allow you to recover the most
  common forms of generic programming.

* The `FromStrRadix` trait, and associated free function, is deprecated
  in favor of inherent implementations.

* A wide range of methods and constants for both integers and floating
  point numbers are now `#[stable]`, having been adjusted for integer
  guidelines.

* `is_positive` and `is_negative` are renamed to `is_sign_positive` and
  `is_sign_negative`, in order to address rust-lang#22985

* The `Wrapping` type is moved to `std::num` and stabilized;
  `WrappingOps` is deprecated in favor of inherent methods on the
  integer types, and direct implementation of operations on
  `Wrapping<X>` for each concrete integer type `X`.

Closes rust-lang#22985
Closes rust-lang#21069

[breaking-change]

r? @alexcrichton
aturon added a commit to aturon/rust that referenced this issue Mar 31, 2015
This commit stabilizes the `std::num` module:

* The `Int` and `Float` traits are deprecated in favor of (1) the
  newly-added inherent methods and (2) the generic traits available in
  rust-lang/num.

* The `Zero` and `One` traits are reintroduced in `std::num`, which
  together with various other traits allow you to recover the most
  common forms of generic programming.

* The `FromStrRadix` trait, and associated free function, is deprecated
  in favor of inherent implementations.

* A wide range of methods and constants for both integers and floating
  point numbers are now `#[stable]`, having been adjusted for integer
  guidelines.

* `is_positive` and `is_negative` are renamed to `is_sign_positive` and
  `is_sign_negative`, in order to address rust-lang#22985

* The `Wrapping` type is moved to `std::num` and stabilized;
  `WrappingOps` is deprecated in favor of inherent methods on the
  integer types, and direct implementation of operations on
  `Wrapping<X>` for each concrete integer type `X`.

Closes rust-lang#22985
Closes rust-lang#21069

[breaking-change]
bors added a commit that referenced this issue Mar 31, 2015
This commit stabilizes the `std::num` module:

* The `Int` and `Float` traits are deprecated in favor of (1) the
  newly-added inherent methods and (2) the generic traits available in
  rust-lang/num.

* The `Zero` and `One` traits are reintroduced in `std::num`, which
  together with various other traits allow you to recover the most
  common forms of generic programming.

* The `FromStrRadix` trait, and associated free function, is deprecated
  in favor of inherent implementations.

* A wide range of methods and constants for both integers and floating
  point numbers are now `#[stable]`, having been adjusted for integer
  guidelines.

* `is_positive` and `is_negative` are renamed to `is_sign_positive` and
  `is_sign_negative`, in order to address #22985

* The `Wrapping` type is moved to `std::num` and stabilized;
  `WrappingOps` is deprecated in favor of inherent methods on the
  integer types, and direct implementation of operations on
  `Wrapping<X>` for each concrete integer type `X`.

Closes #22985
Closes #21069

[breaking-change]

r? @alexcrichton
alexcrichton added a commit to alexcrichton/rust that referenced this issue Mar 31, 2015
This commit stabilizes the `std::num` module:

* The `Int` and `Float` traits are deprecated in favor of (1) the
  newly-added inherent methods and (2) the generic traits available in
  rust-lang/num.

* The `Zero` and `One` traits are reintroduced in `std::num`, which
  together with various other traits allow you to recover the most
  common forms of generic programming.

* The `FromStrRadix` trait, and associated free function, is deprecated
  in favor of inherent implementations.

* A wide range of methods and constants for both integers and floating
  point numbers are now `#[stable]`, having been adjusted for integer
  guidelines.

* `is_positive` and `is_negative` are renamed to `is_sign_positive` and
  `is_sign_negative`, in order to address rust-lang#22985

* The `Wrapping` type is moved to `std::num` and stabilized;
  `WrappingOps` is deprecated in favor of inherent methods on the
  integer types, and direct implementation of operations on
  `Wrapping<X>` for each concrete integer type `X`.

Closes rust-lang#22985
Closes rust-lang#21069

[breaking-change]

r? @alexcrichton
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I-needs-decision Issue: In need of a decision.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants