Skip to content

impl fmt::Display for u32 compiles to large binary #118940

Description

@StackOverflowExcept1on

My target is wasm32-unknown-unknown but I think it can be applied to any embedded systems. I just want to define panic handler, but formatting core::panic::Location costs amlost 3 KiB in binary. This is because inefficient impl Display for u32. Also see: https://github.com/dtolnay/itoa

[package]
name = "demo"
version = "0.1.0"
edition = "2021"

[lib]
name = "demo"
crate-type = ["cdylib"]

[dependencies]
arrayvec = { version = "0.7.4", default-features = false }

[profile.release]
opt-level = "z"
codegen-units = 1
lto = true
strip = true
#![no_std]
#![feature(panic_info_message)]

#[allow(improper_ctypes)]
extern "C" {
    pub fn sc_panic(msg: &str) -> !;
}

#[panic_handler]
fn panic(panic_info: &core::panic::PanicInfo) -> ! {
    use core::fmt::Write;

    let mut msg = arrayvec::ArrayString::<1024>::new();

    // 2_009 bytes binary:
    /*let _ = write!(&mut msg, "{}", unsafe {
        panic_info.message().unwrap_unchecked()
    });*/

    // 5_076 bytes binary:
    let _ = write!(&mut msg, "{}", unsafe {
        panic_info.location().unwrap_unchecked()
    });
    // ^^^ +3 KiB to print location in format {file}:{line}:{column}???

    // exit from smart contract with msg
    unsafe { sc_panic(&msg) }
}

#[no_mangle]
extern "C" fn entry_point() {
    panic!("msg");
}

This is mostly because this line:

f.pad_integral(is_nonnegative, "", buf_slice)

Could we have something like specialization for more simpler impl Display for $num?

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Dec 14, 2023
  2. added
    I-heavyIssue: Problems and improvements with respect to binary size of generated code.
    on Dec 14, 2023
  3. removed
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Dec 16, 2023
  4. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    T-libsRelevant to the library team, which will review and decide on the PR/issue.
    and removed
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Dec 17, 2023
  5. GKFX commented on Apr 27, 2024

    @GKFX
    Contributor

    At present, both {} and (e.g.) {:06} pass the integer to Argument::new_display, which returns a pointer to Display::fmt unconditionally. new_display doesn't see whether this has extra flags or not so it has no opportunity to return a simplified formatting function. You would have to change format_args to give new_display visibility of the Placeholder struct to allow a specialized formatting function to be returned instead. (Edit: a new_simple_display was tried in #104525 but not merged, with tracking issue #99012.)

  6. added
    C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing such
    on Feb 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-heavyIssue: Problems and improvements with respect to binary size of generated code.T-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions