Skip to content

Implement int_format_into feature #142098

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 8, 2025
Merged

Conversation

GuillaumeGomez
Copy link
Member

@GuillaumeGomez GuillaumeGomez commented Jun 5, 2025

I took over #138338 with @madhav-madhusoodanan's approval.

Since #136264, a lot of changes happened so I made use of them to reduce the number of changes.

ACP approval: rust-lang/libs-team#546 (comment)

Associated Issue

r? @hanna-kruppe

@rustbot
Copy link
Collaborator

rustbot commented Jun 5, 2025

Failed to set assignee to hanna-kruppe: invalid assignee

Note: Only org members with at least the repository "read" role, users with write permissions, or people who have commented on the PR may be assigned.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jun 5, 2025
assert_eq!(ret, value);

let mut buffer = NumBuffer::<$int>::new();
assert_eq!(value.format_into(&mut buffer), s.as_str());
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since format_into is not part of a trait, I needed to switch from a function to a macro to avoid the generics limitations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could write and implement a trait right here, in the test - right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could indeed, but would be better than the current code?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Less churn; other than that I don't have strong feelings.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If someone else agrees with you I'll make the change (lazyness++ 😆).

@GuillaumeGomez
Copy link
Member Author

r? @Amanieu

@rust-log-analyzer

This comment has been minimized.

@GuillaumeGomez GuillaumeGomez force-pushed the int_format_into branch 2 times, most recently from d11cb44 to 70ab4e0 Compare June 6, 2025 09:44
@rust-log-analyzer

This comment has been minimized.

@GuillaumeGomez GuillaumeGomez changed the title Int format into Implement int_format_into feature Jun 6, 2025
@GuillaumeGomez
Copy link
Member Author

Applied suggestions and opened another PR for the number of digits of u128 computation to not add even more changes to this PR.

@bors
Copy link
Collaborator

bors commented Jun 7, 2025

☔ The latest upstream changes (presumably #142133) made this pull request unmergeable. Please resolve the merge conflicts.

@GuillaumeGomez
Copy link
Member Author

Fixed merge conflict.

@GuillaumeGomez
Copy link
Member Author

Maybe you want to take a look at this one too @tgross35 ? :)

@GuillaumeGomez
Copy link
Member Author

Safety annotation needs to be right on the unsafe block, not on the start of the expression. Well, noted.

@rust-log-analyzer

This comment has been minimized.

@GuillaumeGomez GuillaumeGomez force-pushed the int_format_into branch 3 times, most recently from a8b169e to 9e76d15 Compare July 1, 2025 09:44
@GuillaumeGomez
Copy link
Member Author

@Amanieu I went to the end of the usage of get_unchecked everywhere in #143277 and basically, there is absolutely no difference, the compiler is already optimizing all the code correctly.

@hanna-kruppe
Copy link
Contributor

Note that there were some recent PRs removing unsafe code from int Display impls that didn’t make a difference (#135265, #136594).

@GuillaumeGomez
Copy link
Member Author

GuillaumeGomez commented Jul 1, 2025

Yeah I will just revert the get_unchecked calls I added here as well. No point in keeping them.

@GuillaumeGomez
Copy link
Member Author

And done.

/// Initializes internal buffer.
#[unstable(feature = "int_format_into", issue = "138215")]
pub const fn new() -> Self {
// FIXME: Once const generics feature is working, use `T::BUF_SIZE` instead of 40.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a const { assert!(T::BUF_SIZE <= 40) } here.

/// Returns the length of the buffer.
#[unstable(feature = "int_format_into", issue = "138215")]
pub const fn len(&self) -> usize {
self.buf.len()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe return T::BUF_SIZE here for forward-compatiblity.

@@ -248,6 +253,13 @@ macro_rules! impl_Display {
issue = "none"
)]
pub fn _fmt<'a>(self, buf: &'a mut [MaybeUninit::<u8>]) -> &'a str {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be an unsafe function because it makes assumptions on the size of buf.

n /= 10;

if n == 0 {
break;
}
}
}
cur
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be curr? How does this even compile?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that's because of optimize_for_size. I'm surprised it's not tested in CI.

@@ -336,20 +421,25 @@ macro_rules! impl_Display {
unsafe {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsafe is not needed here since get_unchecked is not used.

@@ -598,12 +688,20 @@ impl u128 {
issue = "none"
)]
pub fn _fmt<'a>(self, buf: &'a mut [MaybeUninit<u8>]) -> &'a str {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, this needs to be unsafe because it assumes the slice size. Or _fmt_inner should be made safe.

tautschnig pushed a commit to model-checking/verify-rust-std that referenced this pull request Jul 3, 2025
…n-128-integers, r=tgross35

Use a distinct `ToString` implementation for `u128` and `i128`

Part of rust-lang#135543.

Follow-up of rust-lang#136264.

When working on rust-lang#142098, I realized that `i128` and `u128` could also benefit from a distinct `ToString` implementation so here it.

The last commit is just me realizing that I forgot to add the format tests for `usize` and `isize`.

Here is the bench comparison:

| bench name | last nightly | with this PR | diff |
|-|-|-|-|
| bench_i128 | 29.25 ns/iter (+/- 0.66) | 17.52 ns/iter (+/- 0.7) | -40.1% |
| bench_u128 | 34.06 ns/iter (+/- 0.21) | 16.1 ns/iter (+/- 0.6) | -52.7% |

I used this code to test:

```rust
#![feature(test)]

extern crate test;

use test::{Bencher, black_box};

#[inline(always)]
fn convert_to_string<T: ToString>(n: T) -> String {
    n.to_string()
}

macro_rules! decl_benches {
    ($($name:ident: $ty:ident,)+) => {
        $(
	    #[bench]
            fn $name(c: &mut Bencher) {
                c.iter(|| convert_to_string(black_box({ let nb: $ty = 20; nb })));
            }
	)+
    }
}

decl_benches! {
    bench_u128: u128,
    bench_i128: i128,
}
```
@GuillaumeGomez
Copy link
Member Author

Applied suggestions.

@Amanieu
Copy link
Member

Amanieu commented Jul 7, 2025

@bors r+

@bors
Copy link
Collaborator

bors commented Jul 7, 2025

📌 Commit 9943c19 has been approved by Amanieu

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 7, 2025
bors added a commit that referenced this pull request Jul 8, 2025
Rollup of 7 pull requests

Successful merges:

 - #142098 (Implement `int_format_into` feature)
 - #143567 (Point to correct argument in Func Call when Self type fails trait bound)
 - #143570 (consider nested cases for duplicate RPITIT)
 - #143571 (remove `has_nested` from builtin candidates)
 - #143586 (Fix wrong cache event query key)
 - #143589 (const-block-as-pattern: do not refer to no-longer-existing nightly feature)
 - #143608 (Fix in std::String docs)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit d41f046 into rust-lang:master Jul 8, 2025
11 checks passed
@rustbot rustbot added this to the 1.90.0 milestone Jul 8, 2025
rust-timer added a commit that referenced this pull request Jul 8, 2025
Rollup merge of #142098 - GuillaumeGomez:int_format_into, r=Amanieu

Implement `int_format_into` feature

I took over #138338 with `@madhav-madhusoodanan's` approval.

Since #136264, a lot of changes happened so I made use of them to reduce the number of changes.

ACP approval: rust-lang/libs-team#546 (comment)

## Associated Issue
- #138215

r? `@hanna-kruppe`
@GuillaumeGomez GuillaumeGomez deleted the int_format_into branch July 8, 2025 09:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants