diff --git a/Cargo.lock b/Cargo.lock index 4422709c32fe..d6d79add053b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1081,7 +1081,7 @@ checksum = "031d29b6d1ea84f63436e45fb6f3c1a3d62dc1650018c53fa7165e108d35d88f" dependencies = [ "cssparser-macros", "dtoa-short", - "itoa", + "itoa 0.4.999", "matches", "phf", "proc-macro2", @@ -2388,7 +2388,7 @@ checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" dependencies = [ "bytes 1.1.0", "fnv", - "itoa", + "itoa 0.4.999", ] [[package]] @@ -2460,7 +2460,7 @@ dependencies = [ "http", "http-body", "httparse", - "itoa", + "itoa 0.4.999", "log", "pin-project", "socket2", @@ -2601,9 +2601,16 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.8" +version = "0.4.999" +dependencies = [ + "itoa 1.0.2", +] + +[[package]] +name = "itoa" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" [[package]] name = "jobserver" @@ -4608,7 +4615,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527" dependencies = [ "indexmap", - "itoa", + "itoa 0.4.999", "ryu", "serde", ] @@ -4631,7 +4638,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" dependencies = [ "dtoa", - "itoa", + "itoa 0.4.999", "serde", "url", ] @@ -4878,7 +4885,7 @@ dependencies = [ "gecko-profiler", "indexmap", "itertools 0.8.2", - "itoa", + "itoa 0.4.999", "lazy_static", "log", "malloc_size_of", diff --git a/Cargo.toml b/Cargo.toml index 5fef4d0c0409..de7ee7ac7cc1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -90,6 +90,9 @@ vcpkg = { path = "build/rust/vcpkg" } # Helper crate for integration in the gecko build system. mozbuild = { path = "build/rust/mozbuild" } +# Patch itoa 0.4 to 1.0. +itoa = { path = "build/rust/itoa" } + # Patch autocfg to hide rustc output. Workaround for https://github.com/cuviper/autocfg/issues/30 autocfg = { path = "third_party/rust/autocfg" } diff --git a/build/rust/itoa/Cargo.toml b/build/rust/itoa/Cargo.toml new file mode 100644 index 000000000000..d14cba7e8294 --- /dev/null +++ b/build/rust/itoa/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "itoa" +version = "0.4.999" +edition = "2018" +license = "MIT OR Apache-2.0" + +[lib] +path = "lib.rs" + +[dependencies] +itoa = "1.0" diff --git a/build/rust/itoa/lib.rs b/build/rust/itoa/lib.rs new file mode 100644 index 000000000000..6072efcdae6d --- /dev/null +++ b/build/rust/itoa/lib.rs @@ -0,0 +1,21 @@ +pub use itoa::*; +use std::{io, fmt}; + +// APIs that were in itoa 0.4 but aren't in 1.0. + +#[inline] +pub fn write(mut wr: W, value: V) -> io::Result { + let mut buf = Buffer::new(); + let s = buf.format(value); + match wr.write_all(s.as_bytes()) { + Ok(()) => Ok(s.len()), + Err(e) => Err(e), + } +} + +/// Write integer to an `fmt::Write`. +#[inline] +pub fn fmt(mut wr: W, value: V) -> fmt::Result { + let mut buf = Buffer::new(); + wr.write_str(buf.format(value)) +} diff --git a/third_party/rust/itoa/.cargo-checksum.json b/third_party/rust/itoa/.cargo-checksum.json index 39fe2678524f..3422ca4a1164 100644 --- a/third_party/rust/itoa/.cargo-checksum.json +++ b/third_party/rust/itoa/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"46f2cf3006d59c73bed95c276f43ddab1a9a9fa177ea0142777b7471c753f558","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"5eac563c0123003363f4706f36927cf4d3b118965e35b51bc515343ce6a711ae","benches/bench.rs":"fc009678431563bfb1b51698fb5b83f5309a3cdab90dc7365800f4e32bc287be","src/lib.rs":"a7b37eab3872193cf666c1d7d4db8d7e82c6dc6d8121fc762b5f69ddb4df3b01","src/udiv128.rs":"1c9c374680162e12c734d369d1494ee8c91e11eb4b05500e96e6303155bdc623","tests/test.rs":"c9b124462b75078e2407e0239222edd7859c3112d65a114742dbb8c47dafc07c"},"package":"b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"} \ No newline at end of file +{"files":{"Cargo.toml":"3c81fd59c059ee454f7812e8a9e90078880a4c101964ac4ce63537cec7d36c1e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"8e9d4e6ac0c740793958bf57c3dbd62827340cf77a282633c388aff70a7c1a22","benches/bench.rs":"636f3093bd461210ad3063289d455f90669c4a1be3273bcd30898de39f02c641","src/lib.rs":"f3b4bd0934f41b8f8a8828a22a9f5ad2af1ac1e7b632743ec2de46fbb4cb0b59","src/udiv128.rs":"16394f767854452756372d74f8025f7329fd8b61a676d81edf489681a6332ee9","tests/test.rs":"f7404fc5f7cd1bdaf74a3b64a70d5b30586241ddc1ce2c82bd1b564999fcce0e"},"package":"112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"} \ No newline at end of file diff --git a/third_party/rust/itoa/Cargo.toml b/third_party/rust/itoa/Cargo.toml index 02b43829ce38..51506e7a1504 100644 --- a/third_party/rust/itoa/Cargo.toml +++ b/third_party/rust/itoa/Cargo.toml @@ -10,20 +10,21 @@ # See Cargo.toml.orig for the original contents. [package] +edition = "2018" +rust-version = "1.36" name = "itoa" -version = "0.4.8" +version = "1.0.2" authors = ["David Tolnay "] -exclude = ["performance.png"] -description = "Fast functions for printing integer primitives to an io::Write" +exclude = [ + "performance.png", + "chart/**", +] +description = "Fast integer primitive to string conversion" documentation = "https://docs.rs/itoa" readme = "README.md" categories = ["value-formatting"] license = "MIT OR Apache-2.0" repository = "https://github.com/dtolnay/itoa" + [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] - -[features] -default = ["std"] -i128 = [] -std = [] diff --git a/third_party/rust/itoa/README.md b/third_party/rust/itoa/README.md index cff3bb327997..6e241e1c370f 100644 --- a/third_party/rust/itoa/README.md +++ b/third_party/rust/itoa/README.md @@ -6,24 +6,33 @@ itoa [docs.rs](https://docs.rs/itoa) [build status](https://github.com/dtolnay/itoa/actions?query=branch%3Amaster) -This crate provides fast functions for printing integer primitives to an -[`io::Write`] or a [`fmt::Write`]. The implementation comes straight from -[libcore] but avoids the performance penalty of going through -[`fmt::Formatter`]. +This crate provides a fast conversion of integer primitives to decimal strings. +The implementation comes straight from [libcore] but avoids the performance +penalty of going through [`core::fmt::Formatter`]. -See also [`dtoa`] for printing floating point primitives. +See also [`ryu`] for printing floating point primitives. -*Version requirement: rustc 1.0+* +*Version requirement: rustc 1.36+* -[`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html -[`fmt::Write`]: https://doc.rust-lang.org/core/fmt/trait.Write.html [libcore]: https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L201-L254 -[`fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html -[`dtoa`]: https://github.com/dtolnay/dtoa +[`core::fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html +[`ryu`]: https://github.com/dtolnay/ryu ```toml [dependencies] -itoa = "0.4" +itoa = "1.0" +``` + +
+ +## Example + +```rust +fn main() { + let mut buffer = itoa::Buffer::new(); + let printed = buffer.format(128u64); + assert_eq!(printed, "128"); +} ```
@@ -34,52 +43,6 @@ itoa = "0.4"
-## Examples - -```rust -use std::{fmt, io}; - -fn demo_itoa_write() -> io::Result<()> { - // Write to a vector or other io::Write. - let mut buf = Vec::new(); - itoa::write(&mut buf, 128u64)?; - println!("{:?}", buf); - - // Write to a stack buffer. - let mut bytes = [0u8; 20]; - let n = itoa::write(&mut bytes[..], 128u64)?; - println!("{:?}", &bytes[..n]); - - Ok(()) -} - -fn demo_itoa_fmt() -> fmt::Result { - // Write to a string. - let mut s = String::new(); - itoa::fmt(&mut s, 128u64)?; - println!("{}", s); - - Ok(()) -} -``` - -The function signatures are: - -```rust -fn write(writer: W, value: V) -> io::Result; - -fn fmt(writer: W, value: V) -> fmt::Result; -``` - -where `itoa::Integer` is implemented for i8, u8, i16, u16, i32, u32, i64, u64, -i128, u128, isize and usize. 128-bit integer support requires rustc 1.26+ and -the `i128` feature of this crate enabled. - -The `write` function is only available when the `std` feature is enabled -(default is enabled). The return value gives the number of bytes written. - -
- #### License diff --git a/third_party/rust/itoa/benches/bench.rs b/third_party/rust/itoa/benches/bench.rs index a9ed517cfd90..acd2a0c1e84e 100644 --- a/third_party/rust/itoa/benches/bench.rs +++ b/third_party/rust/itoa/benches/bench.rs @@ -1,66 +1,40 @@ -#![cfg_attr(feature = "cargo-clippy", allow(cast_lossless))] #![feature(test)] #![allow(non_snake_case)] +#![allow(clippy::cast_lossless)] -extern crate itoa; extern crate test; macro_rules! benches { - ( - $( - $(#[$attr:meta])* - $name:ident($value:expr) - ),* - ) => { - mod bench_itoa_write { + ($($name:ident($value:expr))*) => { + mod bench_itoa_format { use test::{Bencher, black_box}; + $( - $(#[$attr])* #[bench] fn $name(b: &mut Bencher) { - use itoa; - - let mut buf = Vec::with_capacity(40); + let mut buffer = itoa::Buffer::new(); b.iter(|| { - buf.clear(); - itoa::write(&mut buf, black_box($value)).unwrap() - }); - } - )* - } - - mod bench_itoa_fmt { - use test::{Bencher, black_box}; - $( - $(#[$attr])* - #[bench] - fn $name(b: &mut Bencher) { - use itoa; - - let mut buf = String::with_capacity(40); - - b.iter(|| { - buf.clear(); - itoa::fmt(&mut buf, black_box($value)).unwrap() + let printed = buffer.format(black_box($value)); + black_box(printed); }); } )* } mod bench_std_fmt { + use std::io::Write; use test::{Bencher, black_box}; + $( - $(#[$attr])* #[bench] fn $name(b: &mut Bencher) { - use std::io::Write; - let mut buf = Vec::with_capacity(40); b.iter(|| { buf.clear(); - write!(&mut buf, "{}", black_box($value)).unwrap() + write!(&mut buf, "{}", black_box($value)).unwrap(); + black_box(&buf); }); } )* @@ -69,15 +43,13 @@ macro_rules! benches { } benches! { - bench_u64_0(0u64), - bench_u64_half(::max_value() as u64), - bench_u64_max(::max_value()), + bench_u64_0(0u64) + bench_u64_half(u32::max_value() as u64) + bench_u64_max(u64::max_value()) - bench_i16_0(0i16), - bench_i16_min(::min_value()), + bench_i16_0(0i16) + bench_i16_min(i16::min_value()) - #[cfg(feature = "i128")] - bench_u128_0(0u128), - #[cfg(feature = "i128")] - bench_u128_max(::max_value()) + bench_u128_0(0u128) + bench_u128_max(u128::max_value()) } diff --git a/third_party/rust/itoa/src/lib.rs b/third_party/rust/itoa/src/lib.rs index 8d4582e023bf..86604aa2af4e 100644 --- a/third_party/rust/itoa/src/lib.rs +++ b/third_party/rust/itoa/src/lib.rs @@ -6,98 +6,46 @@ //! //!
//! -//! This crate provides fast functions for printing integer primitives to an -//! [`io::Write`] or a [`fmt::Write`]. The implementation comes straight from -//! [libcore] but avoids the performance penalty of going through -//! [`fmt::Formatter`]. +//! This crate provides a fast conversion of integer primitives to decimal +//! strings. The implementation comes straight from [libcore] but avoids the +//! performance penalty of going through [`core::fmt::Formatter`]. //! -//! See also [`dtoa`] for printing floating point primitives. +//! See also [`ryu`] for printing floating point primitives. //! -//! [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html -//! [`fmt::Write`]: https://doc.rust-lang.org/core/fmt/trait.Write.html //! [libcore]: https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L201-L254 -//! [`fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html -//! [`dtoa`]: https://github.com/dtolnay/dtoa +//! [`core::fmt::Formatter`]: https://doc.rust-lang.org/std/fmt/struct.Formatter.html +//! [`ryu`]: https://github.com/dtolnay/ryu //! -//!
+//! # Example +//! +//! ``` +//! fn main() { +//! let mut buffer = itoa::Buffer::new(); +//! let printed = buffer.format(128u64); +//! assert_eq!(printed, "128"); +//! } +//! ``` //! //! # Performance (lower is better) //! //! ![performance](https://raw.githubusercontent.com/dtolnay/itoa/master/performance.png) -//! -//!
-//! -//! # Examples -//! -//! ```edition2018 -//! use std::{fmt, io}; -//! -//! fn demo_itoa_write() -> io::Result<()> { -//! // Write to a vector or other io::Write. -//! let mut buf = Vec::new(); -//! itoa::write(&mut buf, 128u64)?; -//! println!("{:?}", buf); -//! -//! // Write to a stack buffer. -//! let mut bytes = [0u8; 20]; -//! let n = itoa::write(&mut bytes[..], 128u64)?; -//! println!("{:?}", &bytes[..n]); -//! -//! Ok(()) -//! } -//! -//! fn demo_itoa_fmt() -> fmt::Result { -//! // Write to a string. -//! let mut s = String::new(); -//! itoa::fmt(&mut s, 128u64)?; -//! println!("{}", s); -//! -//! Ok(()) -//! } -//! ``` -#![doc(html_root_url = "https://docs.rs/itoa/0.4.8")] -#![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] -#![cfg_attr( - feature = "cargo-clippy", - allow( - expl_impl_clone_on_copy, - missing_errors_doc, - must_use_candidate, - transmute_ptr_to_ptr - ) +#![doc(html_root_url = "https://docs.rs/itoa/1.0.2")] +#![no_std] +#![allow( + clippy::cast_lossless, + clippy::cast_possible_truncation, + clippy::must_use_candidate, + clippy::unreadable_literal )] -#[cfg(feature = "i128")] mod udiv128; -#[cfg(feature = "std")] -use std::{fmt, io, mem, ptr, slice, str}; +use core::mem::{self, MaybeUninit}; +use core::{ptr, slice, str}; -#[cfg(not(feature = "std"))] -use core::{fmt, mem, ptr, slice, str}; - -/// Write integer to an `io::Write`. -#[cfg(feature = "std")] -#[inline] -pub fn write(mut wr: W, value: V) -> io::Result { - let mut buf = Buffer::new(); - let s = buf.format(value); - match wr.write_all(s.as_bytes()) { - Ok(()) => Ok(s.len()), - Err(e) => Err(e), - } -} - -/// Write integer to an `fmt::Write`. -#[inline] -pub fn fmt(mut wr: W, value: V) -> fmt::Result { - let mut buf = Buffer::new(); - wr.write_str(buf.format(value)) -} - -/// A safe API for formatting integers to text. +/// A correctly sized stack allocation for the formatted integer to be written +/// into. /// /// # Example /// @@ -106,9 +54,8 @@ pub fn fmt(mut wr: W, value: V) -> fmt::Result { /// let printed = buffer.format(1234); /// assert_eq!(printed, "1234"); /// ``` -#[derive(Copy)] pub struct Buffer { - bytes: [u8; I128_MAX_LEN], + bytes: [MaybeUninit; I128_MAX_LEN], } impl Default for Buffer { @@ -129,39 +76,35 @@ impl Buffer { /// This is a cheap operation; you don't need to worry about reusing buffers /// for efficiency. #[inline] - #[allow(deprecated)] pub fn new() -> Buffer { - Buffer { - bytes: unsafe { mem::uninitialized() }, - } + let bytes = [MaybeUninit::::uninit(); I128_MAX_LEN]; + Buffer { bytes } } - /// Print an integer into this buffer and return a reference to its string representation - /// within the buffer. + /// Print an integer into this buffer and return a reference to its string + /// representation within the buffer. pub fn format(&mut self, i: I) -> &str { - i.write(self) + i.write(unsafe { + &mut *(&mut self.bytes as *mut [MaybeUninit; I128_MAX_LEN] + as *mut ::Buffer) + }) } } +/// An integer that can be written into an [`itoa::Buffer`][Buffer]. +/// +/// This trait is sealed and cannot be implemented for types outside of itoa. +pub trait Integer: private::Sealed {} + // Seal to prevent downstream implementations of the Integer trait. mod private { - pub trait Sealed {} + pub trait Sealed: Copy { + type Buffer: 'static; + fn write(self, buf: &mut Self::Buffer) -> &str; + } } -/// An integer that can be formatted by `itoa::write` and `itoa::fmt`. -/// -/// This trait is sealed and cannot be implemented for types outside of itoa. -pub trait Integer: private::Sealed { - // Not public API. - #[doc(hidden)] - fn write(self, buf: &mut Buffer) -> &str; -} - -trait IntegerPrivate { - fn write_to(self, buf: &mut B) -> &[u8]; -} - -const DEC_DIGITS_LUT: &'static [u8] = b"\ +const DEC_DIGITS_LUT: &[u8] = b"\ 0001020304050607080910111213141516171819\ 2021222324252627282930313233343536373839\ 4041424344454647484950515253545556575859\ @@ -170,34 +113,16 @@ const DEC_DIGITS_LUT: &'static [u8] = b"\ // Adaptation of the original implementation at // https://github.com/rust-lang/rust/blob/b8214dc6c6fc20d0a660fb5700dca9ebf51ebe89/src/libcore/fmt/num.rs#L188-L266 -macro_rules! impl_IntegerCommon { - ($max_len:expr, $t:ident) => { - impl Integer for $t { - #[inline] - fn write(self, buf: &mut Buffer) -> &str { - unsafe { - debug_assert!($max_len <= I128_MAX_LEN); - let buf = mem::transmute::<&mut [u8; I128_MAX_LEN], &mut [u8; $max_len]>( - &mut buf.bytes, - ); - let bytes = self.write_to(buf); - str::from_utf8_unchecked(bytes) - } - } - } - - impl private::Sealed for $t {} - }; -} - macro_rules! impl_Integer { ($($max_len:expr => $t:ident),* as $conv_fn:ident) => {$( - impl_IntegerCommon!($max_len, $t); + impl Integer for $t {} + + impl private::Sealed for $t { + type Buffer = [MaybeUninit; $max_len]; - impl IntegerPrivate<[u8; $max_len]> for $t { #[allow(unused_comparisons)] #[inline] - fn write_to(self, buf: &mut [u8; $max_len]) -> &[u8] { + fn write(self, buf: &mut [MaybeUninit; $max_len]) -> &str { let is_nonnegative = self >= 0; let mut n = if is_nonnegative { self as $conv_fn @@ -206,7 +131,7 @@ macro_rules! impl_Integer { (!(self as $conv_fn)).wrapping_add(1) }; let mut curr = buf.len() as isize; - let buf_ptr = buf.as_mut_ptr(); + let buf_ptr = buf.as_mut_ptr() as *mut u8; let lut_ptr = DEC_DIGITS_LUT.as_ptr(); unsafe { @@ -253,7 +178,8 @@ macro_rules! impl_Integer { } let len = buf.len() - curr as usize; - unsafe { slice::from_raw_parts(buf_ptr.offset(curr), len) } + let bytes = unsafe { slice::from_raw_parts(buf_ptr.offset(curr), len) }; + unsafe { str::from_utf8_unchecked(bytes) } } } )*}; @@ -288,15 +214,16 @@ impl_Integer!(I32_MAX_LEN => isize, U32_MAX_LEN => usize as u32); #[cfg(target_pointer_width = "64")] impl_Integer!(I64_MAX_LEN => isize, U64_MAX_LEN => usize as u64); -#[cfg(all(feature = "i128"))] macro_rules! impl_Integer128 { ($($max_len:expr => $t:ident),*) => {$( - impl_IntegerCommon!($max_len, $t); + impl Integer for $t {} + + impl private::Sealed for $t { + type Buffer = [MaybeUninit; $max_len]; - impl IntegerPrivate<[u8; $max_len]> for $t { #[allow(unused_comparisons)] #[inline] - fn write_to(self, buf: &mut [u8; $max_len]) -> &[u8] { + fn write(self, buf: &mut [MaybeUninit; $max_len]) -> &str { let is_nonnegative = self >= 0; let n = if is_nonnegative { self as u128 @@ -305,13 +232,13 @@ macro_rules! impl_Integer128 { (!(self as u128)).wrapping_add(1) }; let mut curr = buf.len() as isize; - let buf_ptr = buf.as_mut_ptr(); + let buf_ptr = buf.as_mut_ptr() as *mut u8; unsafe { // Divide by 10^19 which is the highest power less than 2^64. let (n, rem) = udiv128::udivmod_1e19(n); - let buf1 = buf_ptr.offset(curr - U64_MAX_LEN as isize) as *mut [u8; U64_MAX_LEN]; - curr -= rem.write_to(&mut *buf1).len() as isize; + let buf1 = buf_ptr.offset(curr - U64_MAX_LEN as isize) as *mut [MaybeUninit; U64_MAX_LEN]; + curr -= rem.write(&mut *buf1).len() as isize; if n != 0 { // Memset the base10 leading zeros of rem. @@ -321,8 +248,8 @@ macro_rules! impl_Integer128 { // Divide by 10^19 again. let (n, rem) = udiv128::udivmod_1e19(n); - let buf2 = buf_ptr.offset(curr - U64_MAX_LEN as isize) as *mut [u8; U64_MAX_LEN]; - curr -= rem.write_to(&mut *buf2).len() as isize; + let buf2 = buf_ptr.offset(curr - U64_MAX_LEN as isize) as *mut [MaybeUninit; U64_MAX_LEN]; + curr -= rem.write(&mut *buf2).len() as isize; if n != 0 { // Memset the leading zeros. @@ -343,16 +270,15 @@ macro_rules! impl_Integer128 { } let len = buf.len() - curr as usize; - slice::from_raw_parts(buf_ptr.offset(curr), len) + let bytes = slice::from_raw_parts(buf_ptr.offset(curr), len); + str::from_utf8_unchecked(bytes) } } } )*}; } -#[cfg(all(feature = "i128"))] const U128_MAX_LEN: usize = 39; const I128_MAX_LEN: usize = 40; -#[cfg(all(feature = "i128"))] impl_Integer128!(I128_MAX_LEN => i128, U128_MAX_LEN => u128); diff --git a/third_party/rust/itoa/src/udiv128.rs b/third_party/rust/itoa/src/udiv128.rs index 617c1c17cdfe..df53eb526d4f 100644 --- a/third_party/rust/itoa/src/udiv128.rs +++ b/third_party/rust/itoa/src/udiv128.rs @@ -12,7 +12,7 @@ fn u128_mulhi(x: u128, y: u128) -> u128 { let high1 = m >> 64; let m_lo = m as u64; - let high2 = x_hi as u128 * y_lo as u128 + m_lo as u128 >> 64; + let high2 = (x_hi as u128 * y_lo as u128 + m_lo as u128) >> 64; x_hi as u128 * y_hi as u128 + high1 + high2 } @@ -32,9 +32,7 @@ pub fn udivmod_1e19(n: u128) -> (u128, u64) { let quot = if n < 1 << 83 { ((n >> 19) as u64 / (d >> 19)) as u128 } else { - let factor = - (8507059173023461586_u64 as u128) << 64 | 10779635027931437427 as u128; - u128_mulhi(n, factor) >> 62 + u128_mulhi(n, 156927543384667019095894735580191660403) >> 62 }; let rem = (n - quot * d as u128) as u64; diff --git a/third_party/rust/itoa/tests/test.rs b/third_party/rust/itoa/tests/test.rs index 53558689daa6..1d7e8cb60055 100644 --- a/third_party/rust/itoa/tests/test.rs +++ b/third_party/rust/itoa/tests/test.rs @@ -1,28 +1,13 @@ -#![cfg_attr(feature = "cargo-clippy", allow(cast_lossless, string_lit_as_bytes))] #![allow(non_snake_case)] - -extern crate itoa; +#![allow(clippy::cast_lossless)] macro_rules! test { - ( + ($($name:ident($value:expr, $expected:expr))*) => { $( - $(#[$attr:meta])* - $name:ident($value:expr, $expected:expr) - ),* - ) => { - $( - $(#[$attr])* #[test] fn $name() { - #[cfg(feature = "std")] - { - let mut buf = [b'\0'; 40]; - let len = itoa::write(&mut buf[..], $value).unwrap(); - assert_eq!(&buf[0..len], $expected.as_bytes()); - } - - let mut s = String::new(); - itoa::fmt(&mut s, $value).unwrap(); + let mut buffer = itoa::Buffer::new(); + let s = buffer.format($value); assert_eq!(s, $expected); } )* @@ -30,18 +15,15 @@ macro_rules! test { } test! { - test_u64_0(0u64, "0"), - test_u64_half(::max_value() as u64, "4294967295"), - test_u64_max(::max_value(), "18446744073709551615"), - test_i64_min(::min_value(), "-9223372036854775808"), + test_u64_0(0u64, "0") + test_u64_half(u32::max_value() as u64, "4294967295") + test_u64_max(u64::max_value(), "18446744073709551615") + test_i64_min(i64::min_value(), "-9223372036854775808") - test_i16_0(0i16, "0"), - test_i16_min(::min_value(), "-32768"), + test_i16_0(0i16, "0") + test_i16_min(i16::min_value(), "-32768") - #[cfg(feature = "i128")] - test_u128_0(0u128, "0"), - #[cfg(feature = "i128")] - test_u128_max(::max_value(), "340282366920938463463374607431768211455"), - #[cfg(feature = "i128")] - test_i128_min(::min_value(), "-170141183460469231731687303715884105728") + test_u128_0(0u128, "0") + test_u128_max(u128::max_value(), "340282366920938463463374607431768211455") + test_i128_min(i128::min_value(), "-170141183460469231731687303715884105728") }