mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-15 12:39:31 +03:00
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:
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,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 {
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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};
|
||||
|
||||
|
||||
@@ -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.
|
||||
///
|
||||
|
||||
@@ -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.
|
||||
///
|
||||
|
||||
@@ -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);
|
||||
|
||||
+4
-2
@@ -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,
|
||||
+3
-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
-1
@@ -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:
|
||||
///
|
||||
+5
-3
@@ -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];
|
||||
+6
-4
@@ -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")
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
@@ -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
@@ -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(
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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::*;
|
||||
|
||||
@@ -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,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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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::*;
|
||||
|
||||
|
||||
Vendored
+8
-15
@@ -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(¶m) {
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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"]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user