Auto merge of #153579 - JonathanBrouwer:rollup-DFWynbC, r=JonathanBrouwer

Rollup of 6 pull requests

Successful merges:

 - rust-lang/rust#152535 (std: use `OnceLock` for Xous environment variables)
 - rust-lang/rust#152646 (Update `UnsafeUnpin` impls involving extern types.)
 - rust-lang/rust#153559 (Inline and simplify some code for saving incremental data to disk)
 - rust-lang/rust#151900 (num: Separate public API from internal implementations)
 - rust-lang/rust#153520 (.mailmap: fix broken line with multiple emails)
 - rust-lang/rust#153573 (rustdoc-json: fix incorrect documentation for VariantKind::Struct)

Failed merges:

 - rust-lang/rust#153509 (Cleanup unused diagnostic emission methods - part 2)
This commit is contained in:
bors
2026-03-09 00:40:10 +00:00
63 changed files with 385 additions and 360 deletions
+2 -1
View File
@@ -83,7 +83,8 @@ Ben Sago <ogham@users.noreply.github.com> <ogham@bsago.me>
Ben Striegel <ben.striegel@gmail.com>
Benjamin Jackman <ben@jackman.biz>
Benoît Cortier <benoit.cortier@fried-world.eu>
binarycat <binarycat@envs.net> lolbinarycat <dogedoge61+github@gmail.com> <dogedoge61@gmail.com>
binarycat <binarycat@envs.net> lolbinarycat <dogedoge61+github@gmail.com>
binarycat <binarycat@envs.net> lolbinarycat <dogedoge61@gmail.com>
Bheesham Persaud <bheesham123@hotmail.com> Bheesham Persaud <bheesham.persaud@live.ca>
bjorn3 <17426603+bjorn3@users.noreply.github.com> <bjorn3@users.noreply.github.com>
bjorn3 <17426603+bjorn3@users.noreply.github.com> <bjorn3_gh@protonmail.com>
+24 -11
View File
@@ -8,7 +8,7 @@
};
use rustc_middle::ty::TyCtxt;
use rustc_serialize::Encodable as RustcEncodable;
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
use rustc_serialize::opaque::FileEncoder;
use rustc_session::Session;
use tracing::debug;
@@ -60,13 +60,30 @@ pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) {
// We execute this after `incr_comp_persist_dep_graph` for the serial compiler
// to catch any potential query execution writing to the dep graph.
sess.time("incr_comp_persist_result_cache", || {
// Drop the memory map so that we can remove the file and write to it.
if let Some(odc) = &tcx.query_system.on_disk_cache {
odc.drop_serialized_data(tcx);
}
// The on-disk cache struct is always present in incremental mode,
// even if there was no previous session.
let on_disk_cache = tcx.query_system.on_disk_cache.as_ref().unwrap();
file_format::save_in(sess, query_cache_path, "query cache", |e| {
encode_query_cache(tcx, e)
// For every green dep node that has a disk-cached value from the
// previous session, make sure the value is loaded into the memory
// cache, so that it will be serialized as part of this session.
//
// This reads data from the previous session, so it needs to happen
// before dropping the mmap.
//
// FIXME(Zalathar): This step is intended to be cheap, but still does
// quite a lot of work, especially in builds with few or no changes.
// Can we be smarter about how we identify values that need promotion?
// Can we promote values without decoding them into the memory cache?
tcx.dep_graph.exec_cache_promotions(tcx);
// Drop the memory map so that we can remove the file and write to it.
on_disk_cache.close_serialized_data_mmap();
file_format::save_in(sess, query_cache_path, "query cache", |encoder| {
tcx.sess.time("incr_comp_serialize_result_cache", || {
on_disk_cache.serialize(tcx, encoder)
})
});
});
},
@@ -132,10 +149,6 @@ fn encode_work_product_index(
serialized_products.encode(encoder)
}
fn encode_query_cache(tcx: TyCtxt<'_>, encoder: FileEncoder) -> FileEncodeResult {
tcx.sess.time("incr_comp_serialize_result_cache", || tcx.serialize_query_result_cache(encoder))
}
/// Builds the dependency graph.
///
/// This function creates the *staging dep-graph*. When the dep-graph is modified by a query
@@ -202,20 +202,9 @@ pub fn new_empty() -> Self {
}
}
/// Execute all cache promotions and release the serialized backing Mmap.
///
/// Cache promotions require invoking queries, which needs to read the serialized data.
/// In order to serialize the new on-disk cache, the former on-disk cache file needs to be
/// deleted, hence we won't be able to refer to its memmapped data.
pub fn drop_serialized_data(&self, tcx: TyCtxt<'_>) {
// Load everything into memory so we can write it out to the on-disk
// cache. The vast majority of cacheable query results should already
// be in memory, so this should be a cheap operation.
// Do this *before* we clone 'latest_foreign_def_path_hashes', since
// loading existing queries may cause us to create new DepNodes, which
// may in turn end up invoking `store_foreign_def_id_hash`
tcx.dep_graph.exec_cache_promotions(tcx);
/// Release the serialized backing `Mmap`.
pub fn close_serialized_data_mmap(&self) {
// Obtain a write lock, and replace the mmap with None to drop it.
*self.serialized_data.write() = None;
}
-5
View File
@@ -38,7 +38,6 @@
use rustc_hir::limit::Limit;
use rustc_hir::{self as hir, CRATE_HIR_ID, HirId, Node, TraitCandidate, find_attr};
use rustc_index::IndexVec;
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
use rustc_session::Session;
use rustc_session::config::CrateType;
use rustc_session::cstore::{CrateStoreDyn, Untracked};
@@ -1495,10 +1494,6 @@ pub fn with_stable_hashing_context<R>(
f(StableHashingContext::new(self.sess, &self.untracked))
}
pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult {
self.query_system.on_disk_cache.as_ref().map_or(Ok(0), |c| c.serialize(self, encoder))
}
#[inline]
pub fn local_crate_exports_generics(self) -> bool {
// compiler-builtins has some special treatment in codegen, which can result in confusing
+1 -1
View File
@@ -1,6 +1,6 @@
use crate::fmt::{Debug, Display, Formatter, LowerExp, Result, UpperExp};
use crate::mem::MaybeUninit;
use crate::num::{flt2dec, fmt as numfmt};
use crate::num::imp::{flt2dec, fmt as numfmt};
#[doc(hidden)]
trait GeneralFormat: PartialOrd {
+1 -1
View File
@@ -6,7 +6,7 @@
use crate::char::EscapeDebugExtArgs;
use crate::hint::assert_unchecked;
use crate::marker::{PhantomData, PointeeSized};
use crate::num::fmt as numfmt;
use crate::num::imp::fmt as numfmt;
use crate::ops::Deref;
use crate::ptr::NonNull;
use crate::{iter, mem, result, str};
+1 -1
View File
@@ -2,7 +2,7 @@
use crate::fmt::NumBuffer;
use crate::mem::MaybeUninit;
use crate::num::fmt as numfmt;
use crate::num::imp::fmt as numfmt;
use crate::{fmt, str};
/// Formatting of integers with a non-decimal radix.
+8 -8
View File
@@ -46,8 +46,8 @@
/// marker_impls! {
/// MarkerTrait for
/// u8, i8,
/// {T: ?Sized} *const T,
/// {T: ?Sized} *mut T,
/// {T: PointeeSized} *const T,
/// {T: PointeeSized} *mut T,
/// {T: MarkerTrait} PhantomData<T>,
/// u32,
/// }
@@ -931,15 +931,15 @@ impl<T: PointeeSized> !Freeze for UnsafeCell<T> {}
pub unsafe auto trait UnsafeUnpin {}
#[unstable(feature = "unsafe_unpin", issue = "125735")]
impl<T: ?Sized> !UnsafeUnpin for UnsafePinned<T> {}
impl<T: PointeeSized> !UnsafeUnpin for UnsafePinned<T> {}
marker_impls! {
#[unstable(feature = "unsafe_unpin", issue = "125735")]
unsafe UnsafeUnpin for
{T: ?Sized} PhantomData<T>,
{T: ?Sized} *const T,
{T: ?Sized} *mut T,
{T: ?Sized} &T,
{T: ?Sized} &mut T,
{T: PointeeSized} PhantomData<T>,
{T: PointeeSized} *const T,
{T: PointeeSized} *mut T,
{T: PointeeSized} &T,
{T: PointeeSized} &mut T,
}
/// Types that do not require any pinning guarantees.
+1 -1
View File
@@ -14,7 +14,7 @@
use crate::convert::FloatToInt;
use crate::num::FpCategory;
#[cfg(not(test))]
use crate::num::libm;
use crate::num::imp::libm;
use crate::panic::const_assert;
use crate::{intrinsics, mem};
+1 -1
View File
@@ -1692,7 +1692,7 @@ pub const fn algebraic_rem(self, rhs: f32) -> f32 {
#[unstable(feature = "core_float_math", issue = "137578")]
pub mod math {
use crate::intrinsics;
use crate::num::libm;
use crate::num::imp::libm;
/// Experimental version of `floor` in `core`. See [`f32::floor`] for details.
///
+1 -1
View File
@@ -1690,7 +1690,7 @@ pub const fn algebraic_rem(self, rhs: f64) -> f64 {
/// They will be stabilized as inherent methods._
pub mod math {
use crate::intrinsics;
use crate::num::libm;
use crate::num::imp::libm;
/// Experimental version of `floor` in `core`. See [`f64::floor`] for details.
///
+133
View File
@@ -0,0 +1,133 @@
//! User-facing API for float parsing.
use crate::error::Error;
use crate::fmt;
use crate::num::imp::dec2flt;
use crate::str::FromStr;
macro_rules! from_str_float_impl {
($t:ty) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for $t {
type Err = ParseFloatError;
/// Converts a string in base 10 to a float.
/// Accepts an optional decimal exponent.
///
/// This function accepts strings such as
///
/// * '3.14'
/// * '-3.14'
/// * '2.5E10', or equivalently, '2.5e10'
/// * '2.5E-10'
/// * '5.'
/// * '.5', or, equivalently, '0.5'
/// * '7'
/// * '007'
/// * 'inf', '-inf', '+infinity', 'NaN'
///
/// Note that alphabetical characters are not case-sensitive.
///
/// Leading and trailing whitespace represent an error.
///
/// # Grammar
///
/// All strings that adhere to the following [EBNF] grammar when
/// lowercased will result in an [`Ok`] being returned:
///
/// ```txt
/// Float ::= Sign? ( 'inf' | 'infinity' | 'nan' | Number )
/// Number ::= ( Digit+ |
/// Digit+ '.' Digit* |
/// Digit* '.' Digit+ ) Exp?
/// Exp ::= 'e' Sign? Digit+
/// Sign ::= [+-]
/// Digit ::= [0-9]
/// ```
///
/// [EBNF]: https://www.w3.org/TR/REC-xml/#sec-notation
///
/// # Arguments
///
/// * src - A string
///
/// # Return value
///
/// `Err(ParseFloatError)` if the string did not represent a valid
/// number. Otherwise, `Ok(n)` where `n` is the closest
/// representable floating-point number to the number represented
/// by `src` (following the same rules for rounding as for the
/// results of primitive operations).
// We add the `#[inline(never)]` attribute, since its content will
// be filled with that of `dec2flt`, which has #[inline(always)].
// Since `dec2flt` is generic, a normal inline attribute on this function
// with `dec2flt` having no attributes results in heavily repeated
// generation of `dec2flt`, despite the fact only a maximum of 2
// possible instances can ever exist. Adding #[inline(never)] avoids this.
#[inline(never)]
fn from_str(src: &str) -> Result<Self, ParseFloatError> {
dec2flt::dec2flt(src)
}
}
};
}
#[cfg(target_has_reliable_f16)]
from_str_float_impl!(f16);
from_str_float_impl!(f32);
from_str_float_impl!(f64);
// FIXME(f16): A fallback is used when the backend+target does not support f16 well, in order
// to avoid ICEs.
#[cfg(not(target_has_reliable_f16))]
#[expect(ineffective_unstable_trait_impl, reason = "stable trait on unstable type")]
#[unstable(feature = "f16", issue = "116909")]
impl FromStr for f16 {
type Err = ParseFloatError;
#[inline]
fn from_str(_src: &str) -> Result<Self, ParseFloatError> {
unimplemented!("requires target_has_reliable_f16")
}
}
/// An error which can be returned when parsing a float.
///
/// This error is used as the error type for the [`FromStr`] implementation
/// for [`f32`] and [`f64`].
///
/// # Example
///
/// ```
/// use std::str::FromStr;
///
/// if let Err(e) = f64::from_str("a.12") {
/// println!("Failed conversion to f64: {e}");
/// }
/// ```
#[derive(Debug, Clone, PartialEq, Eq)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct ParseFloatError {
pub(super) kind: FloatErrorKind,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) enum FloatErrorKind {
Empty,
Invalid,
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for ParseFloatError {}
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Display for ParseFloatError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.kind {
FloatErrorKind::Empty => "cannot parse float from empty string",
FloatErrorKind::Invalid => "invalid float literal",
}
.fmt(f)
}
}
@@ -251,7 +251,7 @@ pub fn mul_pow2(&mut self, bits: usize) -> &mut $name {
/// Multiplies itself by `5^e` and returns its own mutable reference.
pub fn mul_pow5(&mut self, mut e: usize) -> &mut $name {
use crate::num::bignum::SMALL_POW5;
use crate::num::imp::bignum::SMALL_POW5;
// There are exactly n trailing zeros on 2^n, and the only relevant digit sizes
// are consecutive powers of two, so this is well suited index for the table.
@@ -281,7 +281,7 @@ pub fn mul_pow5(&mut self, mut e: usize) -> &mut $name {
pub fn mul_digits<'a>(&'a mut self, other: &[$ty]) -> &'a mut $name {
// the internal routine. works best when aa.len() <= bb.len().
fn mul_inner(ret: &mut [$ty; $n], aa: &[$ty], bb: &[$ty]) -> usize {
use crate::num::bignum::FullOps;
use crate::num::imp::bignum::FullOps;
let mut retsz = 0;
for (i, &a) in aa.iter().enumerate() {
@@ -320,7 +320,7 @@ pub fn mul_digits<'a>(&'a mut self, other: &[$ty]) -> &'a mut $name {
/// Divides itself by a digit-sized `other` and returns its own
/// mutable reference *and* the remainder.
pub fn div_rem_small(&mut self, other: $ty) -> (&mut $name, $ty) {
use crate::num::bignum::FullOps;
use crate::num::imp::bignum::FullOps;
assert!(other > 0);
@@ -1,7 +1,9 @@
//! Representation of a float as the significant digits and exponent.
use crate::num::dec2flt::float::RawFloat;
use crate::num::dec2flt::fpu::set_precision;
use dec2flt::float::RawFloat;
use dec2flt::fpu::set_precision;
use crate::num::imp::dec2flt;
const INT_POW10: [u64; 16] = [
1,
@@ -9,7 +9,9 @@
//! algorithm can be found in "ParseNumberF64 by Simple Decimal Conversion",
//! available online: <https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html>.
use crate::num::dec2flt::common::{ByteSlice, is_8digits};
use dec2flt::common::{ByteSlice, is_8digits};
use crate::num::imp::dec2flt;
/// A decimal floating-point number, represented as a sequence of decimal digits.
#[derive(Clone, Debug, PartialEq)]
@@ -1,10 +1,10 @@
//! Implementation of the Eisel-Lemire algorithm.
use crate::num::dec2flt::common::BiasedFp;
use crate::num::dec2flt::float::RawFloat;
use crate::num::dec2flt::table::{
LARGEST_POWER_OF_FIVE, POWER_OF_FIVE_128, SMALLEST_POWER_OF_FIVE,
};
use dec2flt::common::BiasedFp;
use dec2flt::float::RawFloat;
use dec2flt::table::{LARGEST_POWER_OF_FIVE, POWER_OF_FIVE_128, SMALLEST_POWER_OF_FIVE};
use crate::num::imp::dec2flt;
/// Compute w * 10^q using an extended-precision float representation.
///
@@ -87,14 +87,14 @@
issue = "none"
)]
use self::common::BiasedFp;
use self::float::RawFloat;
use self::lemire::compute_float;
use self::parse::{parse_inf_nan, parse_number};
use self::slow::parse_long_mantissa;
use crate::error::Error;
use crate::fmt;
use crate::str::FromStr;
use common::BiasedFp;
use float::RawFloat;
use lemire::compute_float;
use parse::{parse_inf_nan, parse_number};
use slow::parse_long_mantissa;
use crate::num::ParseFloatError;
use crate::num::float_parse::FloatErrorKind;
mod common;
pub mod decimal;
@@ -107,131 +107,6 @@
pub mod lemire;
pub mod parse;
macro_rules! from_str_float_impl {
($t:ty) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for $t {
type Err = ParseFloatError;
/// Converts a string in base 10 to a float.
/// Accepts an optional decimal exponent.
///
/// This function accepts strings such as
///
/// * '3.14'
/// * '-3.14'
/// * '2.5E10', or equivalently, '2.5e10'
/// * '2.5E-10'
/// * '5.'
/// * '.5', or, equivalently, '0.5'
/// * '7'
/// * '007'
/// * 'inf', '-inf', '+infinity', 'NaN'
///
/// Note that alphabetical characters are not case-sensitive.
///
/// Leading and trailing whitespace represent an error.
///
/// # Grammar
///
/// All strings that adhere to the following [EBNF] grammar when
/// lowercased will result in an [`Ok`] being returned:
///
/// ```txt
/// Float ::= Sign? ( 'inf' | 'infinity' | 'nan' | Number )
/// Number ::= ( Digit+ |
/// Digit+ '.' Digit* |
/// Digit* '.' Digit+ ) Exp?
/// Exp ::= 'e' Sign? Digit+
/// Sign ::= [+-]
/// Digit ::= [0-9]
/// ```
///
/// [EBNF]: https://www.w3.org/TR/REC-xml/#sec-notation
///
/// # Arguments
///
/// * src - A string
///
/// # Return value
///
/// `Err(ParseFloatError)` if the string did not represent a valid
/// number. Otherwise, `Ok(n)` where `n` is the closest
/// representable floating-point number to the number represented
/// by `src` (following the same rules for rounding as for the
/// results of primitive operations).
// We add the `#[inline(never)]` attribute, since its content will
// be filled with that of `dec2flt`, which has #[inline(always)].
// Since `dec2flt` is generic, a normal inline attribute on this function
// with `dec2flt` having no attributes results in heavily repeated
// generation of `dec2flt`, despite the fact only a maximum of 2
// possible instances can ever exist. Adding #[inline(never)] avoids this.
#[inline(never)]
fn from_str(src: &str) -> Result<Self, ParseFloatError> {
dec2flt(src)
}
}
};
}
#[cfg(target_has_reliable_f16)]
from_str_float_impl!(f16);
from_str_float_impl!(f32);
from_str_float_impl!(f64);
// FIXME(f16): A fallback is used when the backend+target does not support f16 well, in order
// to avoid ICEs.
#[cfg(not(target_has_reliable_f16))]
impl FromStr for f16 {
type Err = ParseFloatError;
#[inline]
fn from_str(_src: &str) -> Result<Self, ParseFloatError> {
unimplemented!("requires target_has_reliable_f16")
}
}
/// An error which can be returned when parsing a float.
///
/// This error is used as the error type for the [`FromStr`] implementation
/// for [`f32`] and [`f64`].
///
/// # Example
///
/// ```
/// use std::str::FromStr;
///
/// if let Err(e) = f64::from_str("a.12") {
/// println!("Failed conversion to f64: {e}");
/// }
/// ```
#[derive(Debug, Clone, PartialEq, Eq)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct ParseFloatError {
kind: FloatErrorKind,
}
#[derive(Debug, Clone, PartialEq, Eq)]
enum FloatErrorKind {
Empty,
Invalid,
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Error for ParseFloatError {}
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Display for ParseFloatError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.kind {
FloatErrorKind::Empty => "cannot parse float from empty string",
FloatErrorKind::Invalid => "invalid float literal",
}
.fmt(f)
}
}
#[inline]
pub(super) fn pfe_empty() -> ParseFloatError {
ParseFloatError { kind: FloatErrorKind::Empty }
@@ -1,8 +1,10 @@
//! Functions to parse floating-point numbers.
use crate::num::dec2flt::common::{ByteSlice, is_8digits};
use crate::num::dec2flt::decimal::Decimal;
use crate::num::dec2flt::float::RawFloat;
use dec2flt::common::{ByteSlice, is_8digits};
use dec2flt::decimal::Decimal;
use dec2flt::float::RawFloat;
use crate::num::imp::dec2flt;
const MIN_19DIGIT_INT: u64 = 100_0000_0000_0000_0000;
@@ -1,8 +1,10 @@
//! Slow, fallback algorithm for cases the Eisel-Lemire algorithm cannot round.
use crate::num::dec2flt::common::BiasedFp;
use crate::num::dec2flt::decimal_seq::{DecimalSeq, parse_decimal_seq};
use crate::num::dec2flt::float::RawFloat;
use dec2flt::common::BiasedFp;
use dec2flt::decimal_seq::{DecimalSeq, parse_decimal_seq};
use dec2flt::float::RawFloat;
use crate::num::imp::dec2flt;
/// Parse the significant digits and biased, binary exponent of a float.
///
@@ -1,7 +1,7 @@
//! Decodes a floating-point value into individual parts and error ranges.
use crate::num::FpCategory;
use crate::num::dec2flt::float::RawFloat;
use crate::num::imp::dec2flt::float::RawFloat;
/// Decoded unsigned finite value, such that:
///
@@ -4,11 +4,13 @@
//! [^1]: Burger, R. G. and Dybvig, R. K. 1996. Printing floating-point numbers
//! quickly and accurately. SIGPLAN Not. 31, 5 (May. 1996), 108-116.
use flt2dec::estimator::estimate_scaling_factor;
use flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
use crate::cmp::Ordering;
use crate::mem::MaybeUninit;
use crate::num::bignum::{Big32x40 as Big, Digit32 as Digit};
use crate::num::flt2dec::estimator::estimate_scaling_factor;
use crate::num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
use crate::num::imp::bignum::{Big32x40 as Big, Digit32 as Digit};
use crate::num::imp::flt2dec;
static POW10: [Digit; 10] =
[1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000];
@@ -5,9 +5,11 @@
//! [^1]: Florian Loitsch. 2010. Printing floating-point numbers quickly and
//! accurately with integers. SIGPLAN Not. 45, 6 (June 2010), 233-243.
use flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
use crate::mem::MaybeUninit;
use crate::num::diy_float::Fp;
use crate::num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
use crate::num::imp::diy_float::Fp;
use crate::num::imp::flt2dec;
// see the comments in `format_shortest_opt` for the rationale.
#[doc(hidden)]
@@ -455,7 +457,7 @@ pub fn format_shortest<'a>(
d: &Decoded,
buf: &'a mut [MaybeUninit<u8>],
) -> (/*digits*/ &'a [u8], /*exp*/ i16) {
use crate::num::flt2dec::strategy::dragon::format_shortest as fallback;
use flt2dec::strategy::dragon::format_shortest as fallback;
// SAFETY: The borrow checker is not smart enough to let us use `buf`
// in the second branch, so we launder the lifetime here. But we only re-use
// `buf` if `format_shortest_opt` returned `None` so this is okay.
@@ -765,7 +767,7 @@ pub fn format_exact<'a>(
buf: &'a mut [MaybeUninit<u8>],
limit: i16,
) -> (/*digits*/ &'a [u8], /*exp*/ i16) {
use crate::num::flt2dec::strategy::dragon::format_exact as fallback;
use flt2dec::strategy::dragon::format_exact as fallback;
// SAFETY: The borrow checker is not smart enough to let us use `buf`
// in the second branch, so we launder the lifetime here. But we only re-use
// `buf` if `format_exact_opt` returned `None` so this is okay.
@@ -64,7 +64,7 @@
macro_rules! uint_impl {
($U:ident) => {
pub(super) mod $U {
pub(in crate::num) mod $U {
const STAGES: usize = $U::BITS.ilog2() as usize;
#[inline]
const fn prepare(sparse: $U) -> [$U; STAGES] {
@@ -100,7 +100,7 @@ pub(super) mod $U {
}
#[inline(always)]
pub(in super::super) const fn extract_impl(mut x: $U, sparse: $U) -> $U {
pub(in crate::num) const fn extract_impl(mut x: $U, sparse: $U) -> $U {
let masks = prepare(sparse);
x &= sparse;
let mut stage = 0;
@@ -131,7 +131,7 @@ pub(in super::super) const fn extract_impl(mut x: $U, sparse: $U) -> $U {
x
}
#[inline(always)]
pub(in super::super) const fn deposit_impl(mut x: $U, sparse: $U) -> $U {
pub(in crate::num) const fn deposit_impl(mut x: $U, sparse: $U) -> $U {
let masks = prepare(sparse);
let mut stage = STAGES;
while stage > 0 {
@@ -96,7 +96,7 @@ const fn u128_impl(mut val: u128) -> u32 {
macro_rules! define_unsigned_ilog10 {
($($ty:ident => $impl_fn:ident,)*) => {$(
#[inline]
pub(super) const fn $ty(val: NonZero<$ty>) -> u32 {
pub(in crate::num) const fn $ty(val: NonZero<$ty>) -> u32 {
let result = $impl_fn(val.get());
// SAFETY: Integer logarithm is monotonic non-decreasing, so the computed `result` cannot
@@ -117,7 +117,7 @@ pub(super) const fn $ty(val: NonZero<$ty>) -> u32 {
}
#[inline]
pub(super) const fn usize(val: NonZero<usize>) -> u32 {
pub(in crate::num) const fn usize(val: NonZero<usize>) -> u32 {
#[cfg(target_pointer_width = "16")]
let impl_fn = u16;
@@ -136,7 +136,7 @@ macro_rules! define_signed_ilog10 {
($($ty:ident => $impl_fn:ident,)*) => {$(
// 0 < val <= $ty::MAX
#[inline]
pub(super) const fn $ty(val: $ty) -> Option<u32> {
pub(in crate::num) const fn $ty(val: $ty) -> Option<u32> {
if val > 0 {
let result = $impl_fn(val.cast_unsigned());
@@ -166,6 +166,6 @@ pub(super) const fn $ty(val: $ty) -> Option<u32> {
/// on every single primitive type.
#[cold]
#[track_caller]
pub(super) const fn panic_for_nonpositive_argument() -> ! {
pub(in crate::num) const fn panic_for_nonpositive_argument() -> ! {
panic!("argument of integer logarithm must be positive")
}
@@ -37,7 +37,7 @@
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub(super) const fn u8(n: u8) -> u8 {
pub(in crate::num) const fn u8(n: u8) -> u8 {
U8_ISQRT_WITH_REMAINDER[n as usize].0
}
@@ -58,7 +58,7 @@ macro_rules! signed_fn {
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub(super) const unsafe fn $SignedT(n: $SignedT) -> $SignedT {
pub(in crate::num) const unsafe fn $SignedT(n: $SignedT) -> $SignedT {
debug_assert!(n >= 0, "Negative input inside `isqrt`.");
$UnsignedT(n as $UnsignedT) as $SignedT
}
@@ -83,7 +83,7 @@ macro_rules! unsigned_fn {
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub(super) const fn $UnsignedT(mut n: $UnsignedT) -> $UnsignedT {
pub(in crate::num) const fn $UnsignedT(mut n: $UnsignedT) -> $UnsignedT {
if n <= <$HalfBitsT>::MAX as $UnsignedT {
$HalfBitsT(n as $HalfBitsT) as $UnsignedT
} else {
@@ -311,6 +311,6 @@ const fn u128_stages(n: u128) -> u128 {
/// on every single primitive type.
#[cold]
#[track_caller]
pub(super) const fn panic_for_negative_argument() -> ! {
pub(in crate::num) const fn panic_for_negative_argument() -> ! {
panic!("argument of integer square root cannot be negative")
}
+18
View File
@@ -0,0 +1,18 @@
//! Numeric routines, separate from API.
// These modules are public only for testing.
#[cfg(not(no_fp_fmt_parse))]
pub mod bignum;
#[cfg(not(no_fp_fmt_parse))]
pub mod dec2flt;
#[cfg(not(no_fp_fmt_parse))]
pub mod diy_float;
#[cfg(not(no_fp_fmt_parse))]
pub mod flt2dec;
pub mod fmt;
pub(crate) mod int_bits;
pub(crate) mod int_log10;
pub(crate) mod int_sqrt;
pub(crate) mod libm;
pub(crate) mod overflow_panic;
@@ -4,48 +4,48 @@
#[cold]
#[track_caller]
pub(super) const fn add() -> ! {
pub(in crate::num) const fn add() -> ! {
panic!("attempt to add with overflow")
}
#[cold]
#[track_caller]
pub(super) const fn sub() -> ! {
pub(in crate::num) const fn sub() -> ! {
panic!("attempt to subtract with overflow")
}
#[cold]
#[track_caller]
pub(super) const fn mul() -> ! {
pub(in crate::num) const fn mul() -> ! {
panic!("attempt to multiply with overflow")
}
#[cold]
#[track_caller]
pub(super) const fn div() -> ! {
pub(in crate::num) const fn div() -> ! {
panic!("attempt to divide with overflow")
}
#[cold]
#[track_caller]
pub(super) const fn rem() -> ! {
pub(in crate::num) const fn rem() -> ! {
panic!("attempt to calculate the remainder with overflow")
}
#[cold]
#[track_caller]
pub(super) const fn neg() -> ! {
pub(in crate::num) const fn neg() -> ! {
panic!("attempt to negate with overflow")
}
#[cold]
#[track_caller]
pub(super) const fn shr() -> ! {
pub(in crate::num) const fn shr() -> ! {
panic!("attempt to shift right with overflow")
}
#[cold]
#[track_caller]
pub(super) const fn shl() -> ! {
pub(in crate::num) const fn shl() -> ! {
panic!("attempt to shift left with overflow")
}
+19 -19
View File
@@ -553,7 +553,7 @@ pub const fn checked_add(self, rhs: Self) -> Option<Self> {
#[track_caller]
pub const fn strict_add(self, rhs: Self) -> Self {
let (a, b) = self.overflowing_add(rhs);
if b { overflow_panic::add() } else { a }
if b { imp::overflow_panic::add() } else { a }
}
/// Unchecked integer addition. Computes `self + rhs`, assuming overflow
@@ -643,7 +643,7 @@ pub const fn checked_add_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
#[track_caller]
pub const fn strict_add_unsigned(self, rhs: $UnsignedT) -> Self {
let (a, b) = self.overflowing_add_unsigned(rhs);
if b { overflow_panic::add() } else { a }
if b { imp::overflow_panic::add() } else { a }
}
/// Checked integer subtraction. Computes `self - rhs`, returning `None` if
@@ -693,7 +693,7 @@ pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
#[track_caller]
pub const fn strict_sub(self, rhs: Self) -> Self {
let (a, b) = self.overflowing_sub(rhs);
if b { overflow_panic::sub() } else { a }
if b { imp::overflow_panic::sub() } else { a }
}
/// Unchecked integer subtraction. Computes `self - rhs`, assuming overflow
@@ -783,7 +783,7 @@ pub const fn checked_sub_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
#[track_caller]
pub const fn strict_sub_unsigned(self, rhs: $UnsignedT) -> Self {
let (a, b) = self.overflowing_sub_unsigned(rhs);
if b { overflow_panic::sub() } else { a }
if b { imp::overflow_panic::sub() } else { a }
}
/// Checked integer multiplication. Computes `self * rhs`, returning `None` if
@@ -833,7 +833,7 @@ pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
#[track_caller]
pub const fn strict_mul(self, rhs: Self) -> Self {
let (a, b) = self.overflowing_mul(rhs);
if b { overflow_panic::mul() } else { a }
if b { imp::overflow_panic::mul() } else { a }
}
/// Unchecked integer multiplication. Computes `self * rhs`, assuming overflow
@@ -940,7 +940,7 @@ pub const fn checked_div(self, rhs: Self) -> Option<Self> {
#[track_caller]
pub const fn strict_div(self, rhs: Self) -> Self {
let (a, b) = self.overflowing_div(rhs);
if b { overflow_panic::div() } else { a }
if b { imp::overflow_panic::div() } else { a }
}
/// Checked Euclidean division. Computes `self.div_euclid(rhs)`,
@@ -1007,7 +1007,7 @@ pub const fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
#[track_caller]
pub const fn strict_div_euclid(self, rhs: Self) -> Self {
let (a, b) = self.overflowing_div_euclid(rhs);
if b { overflow_panic::div() } else { a }
if b { imp::overflow_panic::div() } else { a }
}
/// Checked integer division without remainder. Computes `self / rhs`,
@@ -1179,7 +1179,7 @@ pub const fn checked_rem(self, rhs: Self) -> Option<Self> {
#[track_caller]
pub const fn strict_rem(self, rhs: Self) -> Self {
let (a, b) = self.overflowing_rem(rhs);
if b { overflow_panic::rem() } else { a }
if b { imp::overflow_panic::rem() } else { a }
}
/// Checked Euclidean remainder. Computes `self.rem_euclid(rhs)`, returning `None`
@@ -1245,7 +1245,7 @@ pub const fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
#[track_caller]
pub const fn strict_rem_euclid(self, rhs: Self) -> Self {
let (a, b) = self.overflowing_rem_euclid(rhs);
if b { overflow_panic::rem() } else { a }
if b { imp::overflow_panic::rem() } else { a }
}
/// Checked negation. Computes `-self`, returning `None` if `self == MIN`.
@@ -1323,7 +1323,7 @@ pub const fn checked_neg(self) -> Option<Self> {
#[track_caller]
pub const fn strict_neg(self) -> Self {
let (a, b) = self.overflowing_neg();
if b { overflow_panic::neg() } else { a }
if b { imp::overflow_panic::neg() } else { a }
}
/// Checked shift left. Computes `self << rhs`, returning `None` if `rhs` is larger
@@ -1379,7 +1379,7 @@ pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
#[track_caller]
pub const fn strict_shl(self, rhs: u32) -> Self {
let (a, b) = self.overflowing_shl(rhs);
if b { overflow_panic::shl() } else { a }
if b { imp::overflow_panic::shl() } else { a }
}
/// Unchecked shift left. Computes `self << rhs`, assuming that
@@ -1558,7 +1558,7 @@ pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
#[track_caller]
pub const fn strict_shr(self, rhs: u32) -> Self {
let (a, b) = self.overflowing_shr(rhs);
if b { overflow_panic::shr() } else { a }
if b { imp::overflow_panic::shr() } else { a }
}
/// Unchecked shift right. Computes `self >> rhs`, assuming that
@@ -1847,7 +1847,7 @@ pub const fn checked_isqrt(self) -> Option<Self> {
} else {
// SAFETY: Input is nonnegative in this `else` branch.
let result = unsafe {
crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT
imp::int_sqrt::$ActualT(self as $ActualT) as $SelfT
};
// Inform the optimizer what the range of outputs is. If
@@ -1864,7 +1864,7 @@ pub const fn checked_isqrt(self) -> Option<Self> {
unsafe {
// SAFETY: `<$ActualT>::MAX` is nonnegative.
const MAX_RESULT: $SelfT = unsafe {
crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT
imp::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT
};
crate::hint::assert_unchecked(result >= 0);
@@ -3142,7 +3142,7 @@ pub const fn pow(self, mut exp: u32) -> Self {
pub const fn isqrt(self) -> Self {
match self.checked_isqrt() {
Some(sqrt) => sqrt,
None => crate::num::int_sqrt::panic_for_negative_argument(),
None => imp::int_sqrt::panic_for_negative_argument(),
}
}
@@ -3448,7 +3448,7 @@ pub const fn ilog(self, base: Self) -> u32 {
if let Some(log) = self.checked_ilog(base) {
log
} else {
int_log10::panic_for_nonpositive_argument()
imp::int_log10::panic_for_nonpositive_argument()
}
}
@@ -3473,7 +3473,7 @@ pub const fn ilog2(self) -> u32 {
if let Some(log) = self.checked_ilog2() {
log
} else {
int_log10::panic_for_nonpositive_argument()
imp::int_log10::panic_for_nonpositive_argument()
}
}
@@ -3498,7 +3498,7 @@ pub const fn ilog10(self) -> u32 {
if let Some(log) = self.checked_ilog10() {
log
} else {
int_log10::panic_for_nonpositive_argument()
imp::int_log10::panic_for_nonpositive_argument()
}
}
@@ -3570,7 +3570,7 @@ pub const fn checked_ilog2(self) -> Option<u32> {
without modifying the original"]
#[inline]
pub const fn checked_ilog10(self) -> Option<u32> {
int_log10::$ActualT(self as $ActualT)
imp::int_log10::$ActualT(self as $ActualT)
}
/// Computes the absolute value of `self`.
+13 -18
View File
@@ -27,16 +27,14 @@ macro_rules! sign_dependent_expr {
};
}
// All these modules are technically private and only exposed for coretests:
#[cfg(not(no_fp_fmt_parse))]
pub mod bignum;
#[cfg(not(no_fp_fmt_parse))]
pub mod dec2flt;
#[cfg(not(no_fp_fmt_parse))]
pub mod diy_float;
#[cfg(not(no_fp_fmt_parse))]
pub mod flt2dec;
pub mod fmt;
// These modules are public only for testing.
#[doc(hidden)]
#[unstable(
feature = "num_internals",
reason = "internal routines only exposed for testing",
issue = "none"
)]
pub mod imp;
#[macro_use]
mod int_macros; // import int_impl!
@@ -44,12 +42,9 @@ macro_rules! sign_dependent_expr {
mod uint_macros; // import uint_impl!
mod error;
mod int_bits;
mod int_log10;
mod int_sqrt;
pub(crate) mod libm;
#[cfg(not(no_fp_fmt_parse))]
mod float_parse;
mod nonzero;
mod overflow_panic;
mod saturating;
mod wrapping;
@@ -57,15 +52,15 @@ macro_rules! sign_dependent_expr {
#[doc(hidden)]
pub mod niche_types;
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(not(no_fp_fmt_parse))]
pub use dec2flt::ParseFloatError;
#[stable(feature = "int_error_matching", since = "1.55.0")]
pub use error::IntErrorKind;
#[stable(feature = "rust1", since = "1.0.0")]
pub use error::ParseIntError;
#[stable(feature = "try_from", since = "1.34.0")]
pub use error::TryFromIntError;
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(not(no_fp_fmt_parse))]
pub use float_parse::ParseFloatError;
#[stable(feature = "generic_nonzero", since = "1.79.0")]
pub use nonzero::NonZero;
#[unstable(
+2 -1
View File
@@ -5,6 +5,7 @@
use crate::cmp::Ordering;
use crate::hash::{Hash, Hasher};
use crate::marker::{Destruct, Freeze, StructuralPartialEq};
use crate::num::imp;
use crate::ops::{BitOr, BitOrAssign, Div, DivAssign, Neg, Rem, RemAssign};
use crate::panic::{RefUnwindSafe, UnwindSafe};
use crate::str::FromStr;
@@ -1817,7 +1818,7 @@ pub const fn ilog2(self) -> u32 {
without modifying the original"]
#[inline]
pub const fn ilog10(self) -> u32 {
super::int_log10::$Int(self)
imp::int_log10::$Int(self)
}
/// Calculates the midpoint (average) between `self` and `rhs`.
+15 -15
View File
@@ -574,7 +574,7 @@ pub const fn swap_bytes(self) -> Self {
without modifying the original"]
#[inline]
pub const fn extract_bits(self, mask: Self) -> Self {
crate::num::int_bits::$ActualT::extract_impl(self as $ActualT, mask as $ActualT) as $SelfT
imp::int_bits::$ActualT::extract_impl(self as $ActualT, mask as $ActualT) as $SelfT
}
/// Returns an integer with the least significant bits of `self`
@@ -591,7 +591,7 @@ pub const fn extract_bits(self, mask: Self) -> Self {
without modifying the original"]
#[inline]
pub const fn deposit_bits(self, mask: Self) -> Self {
crate::num::int_bits::$ActualT::deposit_impl(self as $ActualT, mask as $ActualT) as $SelfT
imp::int_bits::$ActualT::deposit_impl(self as $ActualT, mask as $ActualT) as $SelfT
}
/// Reverses the order of bits in the integer. The least significant bit becomes the most significant bit,
@@ -802,7 +802,7 @@ pub const fn checked_add(self, rhs: Self) -> Option<Self> {
#[track_caller]
pub const fn strict_add(self, rhs: Self) -> Self {
let (a, b) = self.overflowing_add(rhs);
if b { overflow_panic::add() } else { a }
if b { imp::overflow_panic::add() } else { a }
}
/// Unchecked integer addition. Computes `self + rhs`, assuming overflow
@@ -897,7 +897,7 @@ pub const fn checked_add_signed(self, rhs: $SignedT) -> Option<Self> {
#[track_caller]
pub const fn strict_add_signed(self, rhs: $SignedT) -> Self {
let (a, b) = self.overflowing_add_signed(rhs);
if b { overflow_panic::add() } else { a }
if b { imp::overflow_panic::add() } else { a }
}
/// Checked integer subtraction. Computes `self - rhs`, returning
@@ -956,7 +956,7 @@ pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
#[track_caller]
pub const fn strict_sub(self, rhs: Self) -> Self {
let (a, b) = self.overflowing_sub(rhs);
if b { overflow_panic::sub() } else { a }
if b { imp::overflow_panic::sub() } else { a }
}
/// Unchecked integer subtraction. Computes `self - rhs`, assuming overflow
@@ -1081,7 +1081,7 @@ pub const fn checked_sub_signed(self, rhs: $SignedT) -> Option<Self> {
#[track_caller]
pub const fn strict_sub_signed(self, rhs: $SignedT) -> Self {
let (a, b) = self.overflowing_sub_signed(rhs);
if b { overflow_panic::sub() } else { a }
if b { imp::overflow_panic::sub() } else { a }
}
#[doc = concat!(
@@ -1190,7 +1190,7 @@ pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
#[track_caller]
pub const fn strict_mul(self, rhs: Self) -> Self {
let (a, b) = self.overflowing_mul(rhs);
if b { overflow_panic::mul() } else { a }
if b { imp::overflow_panic::mul() } else { a }
}
/// Unchecked integer multiplication. Computes `self * rhs`, assuming overflow
@@ -1615,7 +1615,7 @@ pub const fn ilog(self, base: Self) -> u32 {
if let Some(log) = self.checked_ilog(base) {
log
} else {
int_log10::panic_for_nonpositive_argument()
imp::int_log10::panic_for_nonpositive_argument()
}
}
@@ -1640,7 +1640,7 @@ pub const fn ilog2(self) -> u32 {
if let Some(log) = self.checked_ilog2() {
log
} else {
int_log10::panic_for_nonpositive_argument()
imp::int_log10::panic_for_nonpositive_argument()
}
}
@@ -1665,7 +1665,7 @@ pub const fn ilog10(self) -> u32 {
if let Some(log) = self.checked_ilog10() {
log
} else {
int_log10::panic_for_nonpositive_argument()
imp::int_log10::panic_for_nonpositive_argument()
}
}
@@ -1827,7 +1827,7 @@ pub const fn checked_neg(self) -> Option<Self> {
#[track_caller]
pub const fn strict_neg(self) -> Self {
let (a, b) = self.overflowing_neg();
if b { overflow_panic::neg() } else { a }
if b { imp::overflow_panic::neg() } else { a }
}
/// Checked shift left. Computes `self << rhs`, returning `None`
@@ -1883,7 +1883,7 @@ pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
#[track_caller]
pub const fn strict_shl(self, rhs: u32) -> Self {
let (a, b) = self.overflowing_shl(rhs);
if b { overflow_panic::shl() } else { a }
if b { imp::overflow_panic::shl() } else { a }
}
/// Unchecked shift left. Computes `self << rhs`, assuming that
@@ -2068,7 +2068,7 @@ pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
#[track_caller]
pub const fn strict_shr(self, rhs: u32) -> Self {
let (a, b) = self.overflowing_shr(rhs);
if b { overflow_panic::shr() } else { a }
if b { imp::overflow_panic::shr() } else { a }
}
/// Unchecked shift right. Computes `self >> rhs`, assuming that
@@ -3541,7 +3541,7 @@ pub const fn pow(self, mut exp: u32) -> Self {
without modifying the original"]
#[inline]
pub const fn isqrt(self) -> Self {
let result = crate::num::int_sqrt::$ActualT(self as $ActualT) as $SelfT;
let result = imp::int_sqrt::$ActualT(self as $ActualT) as $SelfT;
// Inform the optimizer what the range of outputs is. If testing
// `core` crashes with no panic message and a `num::int_sqrt::u*`
@@ -3554,7 +3554,7 @@ pub const fn isqrt(self) -> Self {
// integers is bounded by `[0, <$ActualT>::MAX]`, sqrt(n) will be
// bounded by `[sqrt(0), sqrt(<$ActualT>::MAX)]`.
unsafe {
const MAX_RESULT: $SelfT = crate::num::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT;
const MAX_RESULT: $SelfT = imp::int_sqrt::$ActualT(<$ActualT>::MAX) as $SelfT;
crate::hint::assert_unchecked(result <= MAX_RESULT);
}
+1 -1
View File
@@ -3,7 +3,7 @@ mod strategy {
mod grisu;
}
use core::num::flt2dec::{DecodableFloat, Decoded, FullDecoded, MAX_SIG_DIGITS, decode};
use core::num::imp::flt2dec::{DecodableFloat, Decoded, FullDecoded, MAX_SIG_DIGITS, decode};
use std::io::Write;
use test::{Bencher, black_box};
@@ -1,4 +1,4 @@
use core::num::flt2dec::strategy::dragon::*;
use core::num::imp::flt2dec::strategy::dragon::*;
use std::mem::MaybeUninit;
use super::super::*;
@@ -1,4 +1,4 @@
use core::num::flt2dec::strategy::grisu::*;
use core::num::imp::flt2dec::strategy::grisu::*;
use std::mem::MaybeUninit;
use super::super::*;
+2 -2
View File
@@ -1,5 +1,5 @@
use core::num::bignum::Big32x40;
use core::num::bignum::tests::Big8x3 as Big;
use core::num::imp::bignum::Big32x40;
use core::num::imp::bignum::tests::Big8x3 as Big;
#[test]
#[should_panic]
@@ -1,4 +1,4 @@
use core::num::dec2flt::decimal::Decimal;
use core::num::imp::dec2flt::decimal::Decimal;
type FPath<F> = ((i64, u64, bool, bool), Option<F>);
@@ -1,4 +1,4 @@
use core::num::dec2flt::decimal_seq::{DecimalSeq, parse_decimal_seq};
use core::num::imp::dec2flt::decimal_seq::{DecimalSeq, parse_decimal_seq};
#[test]
fn test_trim() {
+1 -1
View File
@@ -1,4 +1,4 @@
use core::num::dec2flt::float::RawFloat;
use core::num::imp::dec2flt::float::RawFloat;
use crate::num::{ldexp_f32, ldexp_f64};
@@ -1,5 +1,7 @@
use core::num::dec2flt::float::RawFloat;
use core::num::dec2flt::lemire::compute_float;
use core::num::imp::dec2flt;
use dec2flt::float::RawFloat;
use dec2flt::lemire::compute_float;
#[cfg(target_has_reliable_f16)]
fn compute_float16(q: i64, w: u64) -> (i32, u64) {
+5 -3
View File
@@ -1,6 +1,8 @@
use core::num::dec2flt::decimal::Decimal;
use core::num::dec2flt::parse::parse_number;
use core::num::dec2flt::{dec2flt, pfe_invalid};
use core::num::imp::dec2flt;
use dec2flt::decimal::Decimal;
use dec2flt::parse::parse_number;
use dec2flt::{dec2flt, pfe_invalid};
fn new_dec(e: i64, m: u64) -> Decimal {
Decimal { exponent: e, mantissa: m, negative: false, many_digits: false }
@@ -1,4 +1,4 @@
use core::num::flt2dec::estimator::*;
use core::num::imp::flt2dec::estimator::*;
use crate::num::ldexp_f64;
+4 -10
View File
@@ -1,11 +1,13 @@
use core::num::flt2dec::{
use core::num::imp::flt2dec::{
DecodableFloat, Decoded, FullDecoded, MAX_SIG_DIGITS, Sign, decode, round_up, to_exact_exp_str,
to_exact_fixed_str, to_shortest_exp_str, to_shortest_str,
};
use core::num::fmt::{Formatted, Part};
use core::num::imp::fmt::{Formatted, Part};
use std::mem::MaybeUninit;
use std::{fmt, str};
use Sign::{Minus, MinusPlus};
use crate::num::{ldexp_f32, ldexp_f64};
mod estimator;
@@ -562,8 +564,6 @@ pub fn to_shortest_str_test<F>(mut f_: F)
where
F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
{
use core::num::flt2dec::Sign::*;
fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize) -> String
where
T: DecodableFloat,
@@ -672,8 +672,6 @@ pub fn to_shortest_exp_str_test<F>(mut f_: F)
where
F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>]) -> (&'a [u8], i16),
{
use core::num::flt2dec::Sign::*;
fn to_string<T, F>(f: &mut F, v: T, sign: Sign, exp_bounds: (i16, i16), upper: bool) -> String
where
T: DecodableFloat,
@@ -789,8 +787,6 @@ pub fn to_exact_exp_str_test<F>(mut f_: F)
where
F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
{
use core::num::flt2dec::Sign::*;
fn to_string<T, F>(f: &mut F, v: T, sign: Sign, ndigits: usize, upper: bool) -> String
where
T: DecodableFloat,
@@ -1065,8 +1061,6 @@ pub fn to_exact_fixed_str_test<F>(mut f_: F)
where
F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
{
use core::num::flt2dec::Sign::*;
fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize) -> String
where
T: DecodableFloat,
+10 -9
View File
@@ -1,10 +1,11 @@
#![cfg(not(target_arch = "wasm32"))]
use core::num::flt2dec::strategy::grisu::{format_exact_opt, format_shortest_opt};
use core::num::flt2dec::{DecodableFloat, Decoded, FullDecoded, MAX_SIG_DIGITS, decode};
use core::num::imp::flt2dec;
use std::mem::MaybeUninit;
use std::str;
use flt2dec::strategy::grisu::{format_exact_opt, format_shortest_opt};
use flt2dec::{DecodableFloat, Decoded, FullDecoded, MAX_SIG_DIGITS, decode};
use rand::distr::{Distribution, Uniform};
pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
@@ -159,7 +160,7 @@ pub fn f32_exhaustive_equivalence_test<F, G>(f: F, g: G, k: usize)
#[test]
fn shortest_random_equivalence_test() {
use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
use flt2dec::strategy::dragon::format_shortest as fallback;
// Miri is too slow
let n = if cfg!(miri) { 10 } else { 10_000 };
@@ -174,7 +175,7 @@ fn shortest_random_equivalence_test() {
#[cfg(target_has_reliable_f16)]
fn shortest_f16_exhaustive_equivalence_test() {
// see the f32 version
use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
use flt2dec::strategy::dragon::format_shortest as fallback;
f16_exhaustive_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS);
}
@@ -188,7 +189,7 @@ fn shortest_f32_exhaustive_equivalence_test() {
// with `--nocapture` (and plenty of time and appropriate rustc flags), this should print:
// `done, ignored=17643158 passed=2121451881 failed=0`.
use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
use flt2dec::strategy::dragon::format_shortest as fallback;
f32_exhaustive_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS);
}
@@ -197,14 +198,14 @@ fn shortest_f32_exhaustive_equivalence_test() {
fn shortest_f64_hard_random_equivalence_test() {
// this again probably has to use appropriate rustc flags.
use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
use flt2dec::strategy::dragon::format_shortest as fallback;
f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 100_000_000);
}
#[test]
#[cfg(target_has_reliable_f16)]
fn exact_f16_random_equivalence_test() {
use core::num::flt2dec::strategy::dragon::format_exact as fallback;
use flt2dec::strategy::dragon::format_exact as fallback;
// Miri is too slow
let n = if cfg!(miri) { 3 } else { 1_000 };
@@ -220,7 +221,7 @@ fn exact_f16_random_equivalence_test() {
#[test]
fn exact_f32_random_equivalence_test() {
use core::num::flt2dec::strategy::dragon::format_exact as fallback;
use flt2dec::strategy::dragon::format_exact as fallback;
// Miri is too slow
let n = if cfg!(miri) { 3 } else { 1_000 };
@@ -236,7 +237,7 @@ fn exact_f32_random_equivalence_test() {
#[test]
fn exact_f64_random_equivalence_test() {
use core::num::flt2dec::strategy::dragon::format_exact as fallback;
use flt2dec::strategy::dragon::format_exact as fallback;
// Miri is too slow
let n = if cfg!(miri) { 2 } else { 1_000 };
@@ -1,5 +1,5 @@
use core::num::bignum::Big32x40 as Big;
use core::num::flt2dec::strategy::dragon::*;
use core::num::imp::bignum::Big32x40 as Big;
use core::num::imp::flt2dec::strategy::dragon::*;
use super::super::*;
@@ -1,4 +1,4 @@
use core::num::flt2dec::strategy::grisu::*;
use core::num::imp::flt2dec::strategy::grisu::*;
use super::super::*;
+8 -15
View File
@@ -2,21 +2,19 @@
use crate::collections::HashMap;
use crate::ffi::{OsStr, OsString};
use crate::io;
use crate::sync::atomic::{Atomic, AtomicUsize, Ordering};
use crate::sync::{Mutex, Once};
use crate::sync::{Mutex, OnceLock};
use crate::sys::pal::params;
static ENV: Atomic<usize> = AtomicUsize::new(0);
static ENV_INIT: Once = Once::new();
type EnvStore = Mutex<HashMap<OsString, OsString>>;
static ENV: OnceLock<EnvStore> = OnceLock::new();
fn get_env_store() -> &'static EnvStore {
ENV_INIT.call_once(|| {
let env_store = EnvStore::default();
ENV.get_or_init(|| {
let mut env_store = HashMap::new();
if let Some(params) = params::get() {
for param in params {
if let Ok(envs) = params::EnvironmentBlock::try_from(&param) {
let mut env_store = env_store.lock().unwrap();
for env in envs {
env_store.insert(env.key.into(), env.value.into());
}
@@ -24,17 +22,12 @@ fn get_env_store() -> &'static EnvStore {
}
}
}
ENV.store(Box::into_raw(Box::new(env_store)) as _, Ordering::Relaxed)
});
unsafe { &*core::ptr::with_exposed_provenance::<EnvStore>(ENV.load(Ordering::Relaxed)) }
Mutex::new(env_store)
})
}
pub fn env() -> Env {
let clone_to_vec = |map: &HashMap<OsString, OsString>| -> Vec<_> {
map.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
};
let env = clone_to_vec(&*get_env_store().lock().unwrap());
let env = get_env_store().lock().unwrap().iter().map(|(k, v)| (k.clone(), v.clone())).collect();
Env::new(env)
}
+3 -3
View File
@@ -856,10 +856,10 @@ pub enum VariantKind {
/// }
/// ```
Struct {
/// The list of variants in the enum.
/// All of the corresponding [`Item`]s are of kind [`ItemEnum::Variant`].
/// The list of named fields in the variant.
/// All of the corresponding [`Item`]s are of kind [`ItemEnum::StructField`].
fields: Vec<Id>,
/// Whether any variants have been removed from the result, due to being private or hidden.
/// Whether any fields have been removed from the result, due to being private or hidden.
has_stripped_fields: bool,
},
}
+1 -1
View File
@@ -21,7 +21,7 @@ pub unsafe fn add(a: u8, b: u8) -> u8 {
// CHECK: i8 noundef{{( zeroext)?}} %a, i8 noundef{{( zeroext)?}} %b
// CHECK: add i8 %b, %a
// DEBUG: icmp ult i8 [[zero:[^,]+]], %a
// DEBUG: call core::num::overflow_panic::add
// DEBUG: call core::num::imp::overflow_panic::add
// DEBUG: unreachable
// NOCHECKS-NOT: unreachable
// NOCHECKS: ret i8 %0
@@ -11,18 +11,18 @@
let mut _7: isize;
let mut _9: &mut std::fmt::Formatter<'_>;
let mut _10: &T;
let mut _11: core::num::flt2dec::Sign;
let mut _11: core::num::imp::flt2dec::Sign;
let mut _12: u32;
let mut _13: u32;
let mut _14: usize;
let mut _15: bool;
let mut _16: &mut std::fmt::Formatter<'_>;
let mut _17: &T;
let mut _18: core::num::flt2dec::Sign;
let mut _18: core::num::imp::flt2dec::Sign;
let mut _19: bool;
scope 1 {
debug force_sign => _4;
let _5: core::num::flt2dec::Sign;
let _5: core::num::imp::flt2dec::Sign;
scope 2 {
debug sign => _5;
scope 3 {
@@ -56,14 +56,14 @@
}
bb1: {
- _5 = core::num::flt2dec::Sign::MinusPlus;
+ _5 = const core::num::flt2dec::Sign::MinusPlus;
- _5 = core::num::imp::flt2dec::Sign::MinusPlus;
+ _5 = const core::num::imp::flt2dec::Sign::MinusPlus;
goto -> bb3;
}
bb2: {
- _5 = core::num::flt2dec::Sign::Minus;
+ _5 = const core::num::flt2dec::Sign::Minus;
- _5 = core::num::imp::flt2dec::Sign::Minus;
+ _5 = const core::num::imp::flt2dec::Sign::Minus;
goto -> bb3;
}
@@ -11,18 +11,18 @@
let mut _7: isize;
let mut _9: &mut std::fmt::Formatter<'_>;
let mut _10: &T;
let mut _11: core::num::flt2dec::Sign;
let mut _11: core::num::imp::flt2dec::Sign;
let mut _12: u32;
let mut _13: u32;
let mut _14: usize;
let mut _15: bool;
let mut _16: &mut std::fmt::Formatter<'_>;
let mut _17: &T;
let mut _18: core::num::flt2dec::Sign;
let mut _18: core::num::imp::flt2dec::Sign;
let mut _19: bool;
scope 1 {
debug force_sign => _4;
let _5: core::num::flt2dec::Sign;
let _5: core::num::imp::flt2dec::Sign;
scope 2 {
debug sign => _5;
scope 3 {
@@ -56,14 +56,14 @@
}
bb1: {
- _5 = core::num::flt2dec::Sign::MinusPlus;
+ _5 = const core::num::flt2dec::Sign::MinusPlus;
- _5 = core::num::imp::flt2dec::Sign::MinusPlus;
+ _5 = const core::num::imp::flt2dec::Sign::MinusPlus;
goto -> bb3;
}
bb2: {
- _5 = core::num::flt2dec::Sign::Minus;
+ _5 = const core::num::flt2dec::Sign::Minus;
- _5 = core::num::imp::flt2dec::Sign::Minus;
+ _5 = const core::num::imp::flt2dec::Sign::Minus;
goto -> bb3;
}
@@ -11,18 +11,18 @@
let mut _7: isize;
let mut _9: &mut std::fmt::Formatter<'_>;
let mut _10: &T;
let mut _11: core::num::flt2dec::Sign;
let mut _11: core::num::imp::flt2dec::Sign;
let mut _12: u32;
let mut _13: u32;
let mut _14: usize;
let mut _15: bool;
let mut _16: &mut std::fmt::Formatter<'_>;
let mut _17: &T;
let mut _18: core::num::flt2dec::Sign;
let mut _18: core::num::imp::flt2dec::Sign;
let mut _19: bool;
scope 1 {
debug force_sign => _4;
let _5: core::num::flt2dec::Sign;
let _5: core::num::imp::flt2dec::Sign;
scope 2 {
debug sign => _5;
scope 3 {
@@ -56,14 +56,14 @@
}
bb1: {
- _5 = core::num::flt2dec::Sign::MinusPlus;
+ _5 = const core::num::flt2dec::Sign::MinusPlus;
- _5 = core::num::imp::flt2dec::Sign::MinusPlus;
+ _5 = const core::num::imp::flt2dec::Sign::MinusPlus;
goto -> bb3;
}
bb2: {
- _5 = core::num::flt2dec::Sign::Minus;
+ _5 = const core::num::flt2dec::Sign::Minus;
- _5 = core::num::imp::flt2dec::Sign::Minus;
+ _5 = const core::num::imp::flt2dec::Sign::Minus;
goto -> bb3;
}
@@ -11,18 +11,18 @@
let mut _7: isize;
let mut _9: &mut std::fmt::Formatter<'_>;
let mut _10: &T;
let mut _11: core::num::flt2dec::Sign;
let mut _11: core::num::imp::flt2dec::Sign;
let mut _12: u32;
let mut _13: u32;
let mut _14: usize;
let mut _15: bool;
let mut _16: &mut std::fmt::Formatter<'_>;
let mut _17: &T;
let mut _18: core::num::flt2dec::Sign;
let mut _18: core::num::imp::flt2dec::Sign;
let mut _19: bool;
scope 1 {
debug force_sign => _4;
let _5: core::num::flt2dec::Sign;
let _5: core::num::imp::flt2dec::Sign;
scope 2 {
debug sign => _5;
scope 3 {
@@ -56,14 +56,14 @@
}
bb1: {
- _5 = core::num::flt2dec::Sign::MinusPlus;
+ _5 = const core::num::flt2dec::Sign::MinusPlus;
- _5 = core::num::imp::flt2dec::Sign::MinusPlus;
+ _5 = const core::num::imp::flt2dec::Sign::MinusPlus;
goto -> bb3;
}
bb2: {
- _5 = core::num::flt2dec::Sign::Minus;
+ _5 = const core::num::flt2dec::Sign::Minus;
- _5 = core::num::imp::flt2dec::Sign::Minus;
+ _5 = const core::num::imp::flt2dec::Sign::Minus;
goto -> bb3;
}
+2 -1
View File
@@ -3,10 +3,11 @@
// EMIT_MIR_FOR_EACH_BIT_WIDTH
#![feature(flt2dec)]
#![feature(num_internals)]
extern crate core;
use core::num::flt2dec;
use core::num::imp::flt2dec;
use std::fmt::{Formatter, Result};
// EMIT_MIR funky_arms.float_to_exponential_common.GVN.diff
+1 -1
View File
@@ -1075,7 +1075,7 @@ gets adapted for the changes, if necessary.
"""
cc = ["@rust-lang/miri", "@RalfJung", "@oli-obk", "@lcnr"]
[mentions."library/core/src/num/{dec2flt,flt2dec}"]
[mentions."library/core/src/num/imp/{dec2flt,flt2dec}"]
message = "Some changes occurred in float parsing"
cc = ["@tgross35"]