In addition to being nicer, this also allows you to use `sum` and `product` for
iterators yielding custom types aside from the standard integers.
Due to removing the `AdditiveIterator` and `MultiplicativeIterator` trait, this
is a breaking change.
[breaking-change]
These constants are small and can fit even in `u8`, but semantically they have type `usize` because they denote sizes and are almost always used in `usize` context. The change of their type to `u32` during the integer audit led only to the large amount of `as usize` noise (see the second commit, which removes this noise).
This is a minor [breaking-change] to an unstable interface.
r? @aturon
Recent numerics stabilization removed the inherent `min_value` and
`max_value` methods from integer types, assuming that the module-level
constants would suffice. However, that failed to account for the use
case in FFI code when dealing with integer type aliases.
This commit reintroduces the methods as `#[stable]`, since this is
essential functionality for 1.0.
It's unfortunate to freeze these as methods, but when we can provide
inherent associated constants these methods can be deprecated.
r? @sfackler
cc @alexcrichton
Recent numerics stabilization removed the inherent `min_value` and
`max_value` methods from integer types, assuming that the module-level
constants would suffice. However, that failed to account for the use
case in FFI code when dealing with integer type aliases.
This commit reintroduces the methods as `#[stable]`, since this is
essential functionality for 1.0.
It's unfortunate to freeze these as methods, but when we can provide
inherent associated constants these methods can be deprecated.
const_eval : add overflow-checking for {`+`, `-`, `*`, `/`, `<<`, `>>`}.
One tricky detail here: There is some duplication of labor between `rustc::middle::const_eval` and `rustc_trans::trans::consts`. It might be good to explore ways to try to factor out the common structure to the two passes (by abstracting over the particular value-representation used in the compile-time interpreter).
----
Update: Rebased atop #23841Fix#22531Fix#23030Fix#23221Fix#23235
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#22985Closes#21069
[breaking-change]
This allows `Wrapping<T>` to be used in `assert_eq!`, for example.
One of the tests (compile-fail/xc-private-method.rs) fails, but I can hardly imagine it is related to this change. I would also like to add a tests to ensure that `assert_eq!` compiles and keeps working in the future for `Wrapped<T>` values, but there appear to be no tests in libcore. What would be a good place to add such a test?
This permits all coercions to be performed in casts, but adds lints to warn in those cases.
Part of this patch moves cast checking to a later stage of type checking. We acquire obligations to check casts as part of type checking where we previously checked them. Once we have type checked a function or module, then we check any cast obligations which have been acquired. That means we have more type information available to check casts (this was crucial to making coercions work properly in place of some casts), but it means that casts cannot feed input into type inference.
[breaking change]
* Adds two new lints for trivial casts and trivial numeric casts, these are warn by default, but can cause errors if you build with warnings as errors. Previously, trivial numeric casts and casts to trait objects were allowed.
* The unused casts lint has gone.
* Interactions between casting and type inference have changed in subtle ways. Two ways this might manifest are:
- You may need to 'direct' casts more with extra type information, for example, in some cases where `foo as _ as T` succeeded, you may now need to specify the type for `_`
- Casts do not influence inference of integer types. E.g., the following used to type check:
```
let x = 42;
let y = &x as *const u32;
```
Because the cast would inform inference that `x` must have type `u32`. This no longer applies and the compiler will fallback to `i32` for `x` and thus there will be a type error in the cast. The solution is to add more type information:
```
let x: u32 = 42;
let y = &x as *const u32;
```
Unstable items used in a macro expansion will now always trigger
stability warnings, *unless* the unstable items are directly inside a
macro marked with `#[allow_internal_unstable]`. IOW, the compiler warns
unless the span of the unstable item is a subspan of the definition of a
macro marked with that attribute.
E.g.
#[allow_internal_unstable]
macro_rules! foo {
($e: expr) => {{
$e;
unstable(); // no warning
only_called_by_foo!();
}}
}
macro_rules! only_called_by_foo {
() => { unstable() } // warning
}
foo!(unstable()) // warning
The unstable inside `foo` is fine, due to the attribute. But the
`unstable` inside `only_called_by_foo` is not, since that macro doesn't
have the attribute, and the `unstable` passed into `foo` is also not
fine since it isn't contained in the macro itself (that is, even though
it is only used directly in the macro).
In the process this makes the stability tracking much more precise,
e.g. previously `println!("{}", unstable())` got no warning, but now it
does. As such, this is a bug fix that may cause [breaking-change]s.
The attribute is definitely feature gated, since it explicitly allows
side-stepping the feature gating system.
* `core::num`: adjust `UnsignedInt::is_power_of_two`,
`UnsignedInt::next_power_of_two`, `Int::pow`.
In particular for `Int::pow`: (1.) do not panic when `base`
overflows if `acc` never observes the overflowed `base`, and (2.)
if `acc` does observe the overflowed `base`, make sure we only
panic if we would have otherwise (e.g. during a computation of
`base * base`).
* also in `core::num`: avoid underflow during computation of `uint::MAX`.
* `std::num`: adjust tests `uint::test_uint_from_str_overflow`,
`uint::test_uint_to_str_overflow`, `strconv`
* `coretest::num`: adjust `test::test_int_from_str_overflow`.
These return the result of the operation *plus* an overflow/underflow bit.
This can make it easier to write operations where you want to chain
some arithmetic together, but also want to return a flag signalling if
overflow every occurred.
Many of the core rust libraries have places that rely on integer
wrapping behaviour. These places have been altered to use the wrapping_*
methods:
* core:#️⃣:sip - A number of macros
* core::str - The `maximal_suffix` method in `TwoWaySearcher`
* rustc::util::nodemap - Implementation of FnvHash
* rustc_back::sha2 - A number of macros and other places
* rand::isaac - Isaac64Rng, changed to use the Wrapping helper type
Some places had "benign" underflow. This is when underflow or overflow
occurs, but the unspecified value is not used due to other conditions.
* collections::bit::Bitv - underflow when `self.nbits` is zero.
* collections:#️⃣:{map,table} - Underflow when searching an empty
table. Did cause undefined behaviour in this case due to an
out-of-bounds ptr::offset based on the underflowed index. However the
resulting pointers would never be read from.
* syntax::ext::deriving::encodable - Underflow when calculating the
index of the last field in a variant with no fields.
These cases were altered to avoid the underflow, often by moving the
underflowing operation to a place where underflow could not happen.
There was one case that relied on the fact that unsigned arithmetic and
two's complement arithmetic are identical with wrapping semantics. This
was changed to use the wrapping_* methods.
Finally, the calculation of variant discriminants could overflow if the
preceeding discriminant was `U64_MAX`. The logic in `rustc::middle::ty`
for this was altered to avoid the overflow completely, while the
remaining places were changed to use wrapping methods. This is because
`rustc::middle::ty::enum_variants` now throws an error when the
calculated discriminant value overflows a `u64`.
This behaviour can be triggered by the following code:
```
enum Foo {
A = U64_MAX,
B
}
```
This commit also implements the remaining integer operators for
Wrapped<T>.
* count_ones/zeros, trailing_ones/zeros return u32, not usize
* rotate_left/right take u32, not usize
* RADIX, MANTISSA_DIGITS, DIGITS, BITS, BYTES are u32, not usize
Doesn't touch pow because there's another PR for it.
[breaking-change]
Some function signatures have changed, so this is a [breaking-change].
In particular, radixes and numerical values of digits are represented by `u32` now.
Part of #22240