Commit graph

75 commits

Author SHA1 Message Date
David Tolnay
4df1a5561a
Touch up Debug example from PR 92322 2022-01-04 14:28:28 -08:00
Alper Çugun
1773e8318f
Add another implementation example to Debug trait 2021-12-27 12:28:11 +01:00
jam1garner
37c8f254ed Use non-generic inner function for pointer formatting 2021-11-26 13:59:57 -05:00
Matthias Krüger
95750ae439
Rollup merge of #89897 - jkugelman:must-use-core, r=joshtriplett
Add #[must_use] to remaining core functions

I've run out of compelling reasons to group functions together across crates so I'm just going to go module-by-module. This is everything remaining from the `core` crate.

Ignored by clippy for reasons unknown:

```rust
core::alloc::Layout   unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self;
core::any             const fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str;
```

Ignored by clippy because of `mut`:

```rust
str   fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str);
```

<del>
Ignored by clippy presumably because a caller might want `f` called for side effects. That seems like a bad usage of `map` to me.

```rust
core::cell::Ref<'b, T>   fn map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Ref<'b, T>;
core::cell::Ref<'b, T>   fn map_split<U: ?Sized, V: ?Sized, F>(orig: Ref<'b, T>, f: F) -> (Ref<'b, U>, Ref<'b, V>);
```
</del>

Parent issue: #89692

r? ```@joshtriplett```
2021-10-31 09:20:26 +01:00
John Kugelman
68b0d86294 Add #[must_use] to remaining core functions 2021-10-30 18:21:29 -04:00
Pietro Albini
b63ab8005a update cfg(bootstrap) 2021-10-23 21:55:57 -04:00
Yuki Okushi
ca6798ab07
Rollup merge of #86479 - exphp-forks:float-debug-exponential, r=yaahc
Automatic exponential formatting in Debug

Context: See [this comment from the libs team](https://github.com/rust-lang/rfcs/pull/2729#issuecomment-853454204)

---

Makes `"{:?}"` switch to exponential for floats based on magnitude. The libs team suggested exploring this idea in the discussion thread for RFC rust-lang/rfcs#2729. (**note:** this is **not** an implementation of the RFC; it is an implementation of one of the alternatives)

Thresholds chosen were 1e-4 and 1e16.  Justification described [here](https://github.com/rust-lang/rfcs/pull/2729#issuecomment-864482954).

**This will require a crater run.**

---

As mentioned in the commit message of 8731d4dfb4, this behavior will not apply when a precision is supplied, because I wanted to preserve the following existing and useful behavior of `{:.PREC?}` (which recursively applies `{:.PREC}` to floats in a struct):

```rust
assert_eq!(
    format!("{:.2?}", [100.0, 0.000004]),
    "[100.00, 0.00]",
)
```

I looked around and am not sure where there are any tests that actually use this in the test suite, though?

All things considered, I'm surprised that this change did not seem to break even a single existing test in `x.py test --stage 2`.  (even when I tried a smaller threshold of 1e6)
2021-10-20 04:35:10 +09:00
John Kugelman
06e625f7d5 Add #[must_use] to as_type conversions 2021-10-11 13:57:38 -04:00
Manish Goregaokar
4e8c853c9e
Rollup merge of #89502 - FabianWolff:issue-89493, r=joshtriplett
Fix Lower/UpperExp formatting for integers and precision zero

Fixes the integer part of #89493 (I daren't touch the floating-point formatting code). The issue is that the "subtracted" precision essentially behaves like extra trailing zeros, but this is not currently reflected in the code properly.
2021-10-05 12:52:46 -07:00
Fabian Wolff
e3996ffcb6 Fix Lower/UpperExp formatting for integers and precision zero 2021-10-03 23:05:03 +02:00
Cameron Steffen
eec856bfbc Make diangostic item names consistent 2021-10-02 19:38:19 -05:00
Cameron Steffen
f5e4f78eb7 Add private arg to fmt::UnsafeArg 2021-09-30 12:32:05 -05:00
bors
f06f9bbd3a Auto merge of #88999 - Migi:master, r=oli-obk
Make `Duration` respect `width` when formatting using `Debug`

When printing or writing a `std::time::Duration` using `Debug` formatting, it previously completely ignored any specified `width`. This is unlike types like integers and floats, which do pad to `width`, for both `Display` and `Debug`, though not all types consider `width` in their `Debug` output (see e.g. #30164). Curiously, `Duration`'s `Debug` formatting *did* consider `precision`.

This PR makes `Duration` pad to `width` just like integers and floats, so that
```rust
format!("|{:8?}|", Duration::from_millis(1234))
```
returns
```
|1.234s  |
```

Before you ask "who formats `Debug` output?", note that `Duration` doesn't actually implement `Display`, so `Debug` is currently the only way to format `Duration`s. I think that's wrong, and `Duration` should get a `Display` implementation, but in the meantime there's no harm in making the `Debug` formatting respect `width` rather than ignore it.

I chose the default alignment to be left-aligned. The general rule Rust uses is: numeric types are right-aligned by default, non-numeric types left-aligned. It wasn't clear to me whether `Duration` is a numeric type or not. The fact that a formatted `Duration` can end with suffixes of variable length (`"s"`, `"ms"`, `"µs"`, etc.) made me lean towards left-alignment, but it would be trivial to change it.

Fixes issue #88059.
2021-09-24 15:22:26 +00:00
Cameron Steffen
09b37d7433 Use ZST for fmt unsafety
This allows the format_args! macro to keep the pre-expansion code out of
the unsafe block without doing gymnastics with nested `match`
expressions. This reduces codegen.
2021-09-21 10:04:44 -05:00
Michiel De Muynck
77ceb2b5d8 Make Duration's Debug format pad to width
Duration's Debug formatting previously ignored the width parameter.
This commit fixes that.

Fixes issue #88059.
2021-09-16 03:09:31 +02:00
Fabian Wolff
79adda930f Ignore automatically derived impls of Clone and Debug in dead code analysis 2021-09-09 19:49:07 +02:00
Mark Rousskov
b4e7649d6d Bump stage0 compiler to 1.56 2021-09-08 20:51:05 -04:00
klensy
f5f489b945 fix clippy lints 2021-09-01 15:52:29 +03:00
klensy
6c9e708f4b fmt::Formatter::pad: don't call chars().count() more than one time 2021-09-01 15:36:57 +03:00
Cameron Steffen
f4ef07c2a9 Get piece unchecked in write 2021-08-16 16:28:16 +00:00
Cameron Steffen
975bc18481 Make Arguments constructors unsafe 2021-08-16 16:28:16 +00:00
Yuki Okushi
c25b979db6
Rollup merge of #87052 - phlopsi:patch-1, r=jyn514
Optimize fmt::PadAdapter::wrap

After adding the first `write!` usage to my project and printing the result to the console, I noticed, that my binary contains the strings "called `Option::unwrap()` on a `None` value`" and more importantly "C:\Users\Patrick Fischer\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\fmt\builders.rs", with my release build being configured as follows:
```
[profile.release]
panic = "abort"
codegen-units = 1
strip = "symbols" # the important bit
lto = true
```
I am in a no_std environment and my custom panic handler is a simple `loop {}`. I did not expect the above information to be preserved. I heavily suspect the edited function to be the culprit. It contains the only direct use of `Option::unwrap` in the entire file and I tracked the symbols in the assembly to be used from the section `_ZN68_$LT$core..fmt..builders..PadAdapter$u20$as$u20$core..fmt..Write$GT$9write_str17ha1d5e5efe167202aE`.

Aside from me suspecting this function to be the culprit, the replaced code performs the same operation as `Option::insert`, but without the `unreachable_unchecked` optimization `Option::insert` provides. Therefore, it makes sense to me to use the more optimized version, instead.

As I don't change any semantics, I hope a simple pull request suffices.
2021-07-30 16:26:52 +09:00
Mara Bos
b64c4f9560 Add new const_format_args!() macro and use it in panics. 2021-07-28 16:12:25 +02:00
Mara Bos
f827d3e285 Make const panic!("..") work in Rust 2021.
During const eval, this replaces calls to core::panicking::panic_fmt and
std::panicking::being_panic_fmt with a call to a new const fn:
core::panicking::const_panic_fmt. That function uses
fmt::Arguments::as_str() to get the str and calls panic_str with that
instead.

panic!() invocations with formatting arguments are still not accepted,
as the creation of such a fmt::Arguments cannot be done in constant
functions right now.
2021-07-28 16:10:41 +02:00
phlopsi
3e82dca65c Optimize fmt::PadAdapter::wrap 2021-07-11 08:06:29 +02:00
bors
90442458ac Auto merge of #86048 - nbdd0121:no_floating_point, r=Amanieu
core: add unstable no_fp_fmt_parse to disable float formatting code

In some projects (e.g. kernel), floating point is forbidden. They can disable
hardware floating point support and use `+soft-float` to avoid fp instructions
from being generated, but as libcore contains the formatting code for `f32`
and `f64`, some fp intrinsics are depended. One could define stubs for these
intrinsics that just panic [1], but it means that if any formatting functions
are accidentally used, mistake can only be caught during the runtime rather
than during compile-time or link-time, and they consume a lot of space without
LTO.

This patch provides an unstable cfg `no_fp_fmt_parse` to disable these.
A panicking stub is still provided for the `Debug` implementation (unfortunately)
because there are some SIMD types that use `#[derive(Debug)]`.

[1]: https://lkml.org/lkml/2021/4/14/1028
2021-07-04 14:18:57 +00:00
Gary Guo
ec7292ad3c core: add unstable no_fp_fmt_parse to disable float fmt/parse code
In some projects (e.g. kernel), floating point is forbidden. They can disable
hardware floating point support and use `+soft-float` to avoid fp instructions
from being generated, but as libcore contains the formatting code for `f32`
and `f64`, some fp intrinsics are depended. One could define stubs for these
intrinsics that just panic [1], but it means that if any formatting functions
are accidentally used, mistake can only be caught during the runtime rather
than during compile-time or link-time, and they consume a lot of space without
LTO.

This patch provides an unstable cfg `no_fp_fmt_parse` to disable these.
A panicking stub is still provided for the `Debug` implementation (unfortunately)
because there are some SIMD types that use `#[derive(Debug)]`.

[1]: https://lkml.org/lkml/2021/4/14/1028
2021-07-02 22:52:37 +01:00
Jonas Schievink
b3fbfe474b Make fmt::Arguments::as_str unstably const 2021-06-27 03:54:06 +02:00
Aris Merchant
20ea5fedea Change Debug unimplemented message per request 2021-06-22 00:38:31 -07:00
Michael Lamparski
8731d4dfb4 Automatic exponential formatting in Debug
* {:.PREC?} already had legitimately useful behavior (recursive formatting of structs using
  fixed precision for floats) and I suspect that changes to the output there would be unwelcome.

  (besides, precision introduces sinister edge cases where a number can be rounded up to one
  of the thresholds)

  Thus, the new behavior of Debug is, "dynamically switch to exponential, but only if there's
  no precision."

* This could not be implemented in terms of float_to_decimal_common without repeating the branch
  on precision, so 'float_to_general_debug' is a new function.  The name is '_debug' instead of
  '_common' because the considerations in the previous bullet make this logic pretty specific
  to Debug.

* 'float_to_decimal_common' is now only used by Display, so I inlined the min_precision argument
  and renamed the function accordingly.
2021-06-19 20:53:26 -04:00
Aris Merchant
f1f1c9b25b Improve errors for missing Debug and Display impls 2021-06-16 01:13:28 -07:00
Gary Guo
37647d1733 Move flt2dec::{Formatted, Part} to dedicated module
They are used by integer formatting as well and is not exclusive to float.
2021-06-06 02:54:51 +01:00
klensy
7c0db6f0f1 fix pad_integral example 2021-05-23 14:48:16 +03:00
Mark Rousskov
c7c9336469 Avoid zero-length write_str in fmt::write 2021-05-17 09:30:58 -04:00
Mark Rousskov
80ac15f667 Optimize default ToString impl
This avoids a zero-length write_str call, which boils down to a zero-length
memmove and ultimately costs quite a few instructions on some workloads.

This is approximately a 0.33% instruction count win on diesel-check.
2021-05-17 09:29:02 -04:00
Mara Bos
49a5c80a3b
Rollup merge of #84390 - m-ou-se:make-debug-non-exhaustive-without-fields-a-little-bit-less-verbose, r=kennytm
Format `Struct { .. }` on one line even with `{:#?}`.

The result of `debug_struct("A").finish_non_exhaustive()` before this change:
```
A {
    ..
}
```
And after this change:
```
A { .. }
```

If there's any fields, the result stays unchanged:
```
A {
    field: value,
    ..
}
2021-04-21 23:06:21 +02:00
Christiaan Dirkx
fdae75738b Change the Debug impl of Any and UnsafeCell to use finish_non_exhaustive 2021-04-21 14:51:04 +02:00
Christiaan Dirkx
1fb3256fcb Replace all fmt.pad with debug_struct 2021-04-21 14:38:24 +02:00
Mara Bos
82dc73b1ae Format Struct { .. } on one line even with {:#?}. 2021-04-21 13:50:56 +02:00
Jacob Hughes
58218f6c27 Remove T: Debug bound on UnsafeCell Debug impl 2021-03-31 12:11:36 -04:00
Dylan DPC
b2e254318d
Rollup merge of #82917 - cuviper:iter-zip, r=m-ou-se
Add function core::iter::zip

This makes it a little easier to `zip` iterators:

```rust
for (x, y) in zip(xs, ys) {}
// vs.
for (x, y) in xs.into_iter().zip(ys) {}
```

You can `zip(&mut xs, &ys)` for the conventional `iter_mut()` and
`iter()`, respectively. This can also support arbitrary nesting, where
it's easier to see the item layout than with arbitrary `zip` chains:

```rust
for ((x, y), z) in zip(zip(xs, ys), zs) {}
for (x, (y, z)) in zip(xs, zip(ys, zs)) {}
// vs.
for ((x, y), z) in xs.into_iter().zip(ys).zip(xz) {}
for (x, (y, z)) in xs.into_iter().zip((ys.into_iter().zip(xz)) {}
```

It may also format more nicely, especially when the first iterator is a
longer chain of methods -- for example:

```rust
    iter::zip(
        trait_ref.substs.types().skip(1),
        impl_trait_ref.substs.types().skip(1),
    )
    // vs.
    trait_ref
        .substs
        .types()
        .skip(1)
        .zip(impl_trait_ref.substs.types().skip(1))
```

This replaces the tuple-pair `IntoIterator` in #78204.
There is prior art for the utility of this in [`itertools::zip`].

[`itertools::zip`]: https://docs.rs/itertools/0.10.0/itertools/fn.zip.html
2021-03-27 20:37:07 +01:00
bors
aef11409b4 Auto merge of #78618 - workingjubilee:ieee754-fmt, r=m-ou-se
Add IEEE 754 compliant fmt/parse of -0, infinity, NaN

This pull request improves the Rust float formatting/parsing libraries to comply with IEEE 754's formatting expectations around certain special values, namely signed zero, the infinities, and NaN. It also adds IEEE 754 compliance tests that, while less stringent in certain places than many of the existing flt2dec/dec2flt capability tests, are intended to serve as the beginning of a roadmap to future compliance with the standard. Some relevant documentation is also adjusted with clarifying remarks.

This PR follows from discussion in https://github.com/rust-lang/rfcs/issues/1074, and closes #24623.

The most controversial change here is likely to be that -0 is now printed as -0. Allow me to explain: While there appears to be community support for an opt-in toggle of printing floats as if they exist in the naively expected domain of numbers, i.e. not the extended reals (where floats live), IEEE 754-2019 is clear that a float converted to a string should be capable of being transformed into the original floating point bit-pattern when it satisfies certain conditions (namely, when it is an actual numeric value i.e. not a NaN and the original and destination float width are the same). -0 is given special attention here as a value that should have its sign preserved. In addition, the vast majority of other programming languages not only output `-0` but output `-0.0` here.

While IEEE 754 offers a broad leeway in how to handle producing what it calls a "decimal character sequence", it is clear that the operations a language provides should be capable of round tripping, and it is confusing to advertise the f32 and f64 types as binary32 and binary64 yet have the most basic way of producing a string and then reading it back into a floating point number be non-conformant with the standard. Further, existing documentation suggested that e.g. -0 would be printed with -0 regardless of the presence of the `+` fmt character, but it prints "+0" instead if given such (which was what led to the opening of #24623).

There are other parsing and formatting issues for floating point numbers which prevent Rust from complying with the standard, as well as other well-documented challenges on the arithmetic level, but I hope that this can be the beginning of motion towards solving those challenges.
2021-03-27 10:40:16 +00:00
Josh Stone
3b1f5e3462 Use iter::zip in library/ 2021-03-26 09:32:29 -07:00
Ömer Sinan Ağacan
819247f179 Update char::escape_debug_ext to handle different escapes in strings vs. chars
Fixes #83046

The program

    fn main() {
        println!("{:?}", '"');
        println!("{:?}", "'");
    }

would previously print

    '\"'
    "\'"

With this patch it now prints:

    '"'
    "'"
2021-03-26 11:23:51 +03:00
Mara Bos
b1fac3a5e1
Bump debug_non_exhaustive stabilization to 1.53. 2021-03-24 22:54:04 +01:00
Jubilee Young
74db93ed2d Preserve signed zero on roundtrip
This commit removes the previous mechanism of differentiating
between "Debug" and "Display" formattings for the sign of -0 so as
to comply with the IEEE 754 standard's requirements on external
character sequences preserving various attributes of a floating
point representation.

In addition, numerous tests are fixed.
2021-03-22 17:02:09 -07:00
Gus Wynn
b8e498162e
Update library/core/src/fmt/builders.rs
Co-authored-by: Yuki Okushi <huyuumi.dev@gmail.com>
2021-03-12 08:52:26 -08:00
Gus Wynn
73ddfa0eea stabilize debug_non_exhaustive 2021-03-11 15:17:44 -08:00
Steven Fackler
4613b3764c Stabilize Arguments::as_str
Closes #74442
2021-02-14 17:48:51 -05:00
Kogia-sima
ada714d9ce Optimize udiv_1e19() function 2021-01-29 02:27:20 +09:00