Skip to content

calculate Arguments::estimated_capacity() at compile-time - #162052

Draft
joboet wants to merge 2 commits into
rust-lang:mainfrom
joboet:fmt_const_estimated_capacity
Draft

joboet wants to merge 2 commits into
rust-lang:mainfrom
joboet:fmt_const_estimated_capacity

Conversation

@joboet

@joboet joboet commented Aug 31, 2026

Copy link
Copy Markdown
Member

Arguments::estimated_capacity() iterates over the entire formatting template to calculate its estimate, but there's nothing in the heuristic that couldn't be computed at compile-time. Thus, let's try just that. This has the unfortunate side-effect of making Arguments bigger – but there might be ways of reducing the impact of that.

Draft until I've had a chance to look at the performance of this.

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Aug 31, 2026
@joboet

joboet commented Aug 31, 2026

Copy link
Copy Markdown
Member Author

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Aug 31, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Aug 31, 2026
calculate `Arguments::estimated_capacity()` at compile-time
@rust-log-analyzer

This comment has been minimized.

@rust-bors

rust-bors Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 6976f97 (6976f97b830ebc168504a5b24b3267315de2b7e5)
Base parent: be4b6a9 (be4b6a99a3c605d27786c7d48772fec5bd2df76c)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (6976f97): comparison URL.

Overall result: ❌✅ regressions and improvements - please read:

Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf.

Next, please: If you can, justify the regressions found in this try perf run in writing along with @rustbot label: +perf-regression-triaged. If not, fix the regressions and do another perf run. Neutral or positive results will clear the label automatically.

@bors rollup=never rustc-perf
@rustbot label: -S-waiting-on-perf +perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
0.6% [0.3%, 1.3%] 18
Regressions ❌
(secondary)
4.4% [0.1%, 36.5%] 23
Improvements ✅
(primary)
-0.9% [-5.8%, -0.2%] 9
Improvements ✅
(secondary)
-0.6% [-0.8%, -0.5%] 2
All ❌✅ (primary) 0.1% [-5.8%, 1.3%] 27

Max RSS (memory usage)

Results (primary 1.3%, secondary 4.2%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
1.3% [1.3%, 1.3%] 1
Regressions ❌
(secondary)
6.6% [4.4%, 8.8%] 2
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-0.5% [-0.5%, -0.5%] 1
All ❌✅ (primary) 1.3% [1.3%, 1.3%] 1

Cycles

Results (primary -4.4%, secondary 15.2%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
18.0% [3.2%, 36.7%] 6
Improvements ✅
(primary)
-4.4% [-6.3%, -2.5%] 2
Improvements ✅
(secondary)
-1.8% [-1.8%, -1.8%] 1
All ❌✅ (primary) -4.4% [-6.3%, -2.5%] 2

Binary size

Results (primary 1.1%, secondary 1.0%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
1.2% [0.1%, 5.7%] 79
Regressions ❌
(secondary)
1.0% [0.0%, 4.9%] 97
Improvements ✅
(primary)
-0.2% [-0.4%, -0.0%] 5
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 1.1% [-0.4%, 5.7%] 84

Bootstrap: 474.007s -> 478.148s (0.87%)
Artifact size: 307.41 MiB -> 403.42 MiB (31.23%)

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels Aug 31, 2026
@joboet

joboet commented Sep 1, 2026

Copy link
Copy Markdown
Member Author

I had an idea...
@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Sep 1, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Sep 1, 2026
calculate `Arguments::estimated_capacity()` at compile-time
@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
---- [ui] tests/ui/unpretty/flattened-format-args.rs stdout ----
Saved the actual stdout to `/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/unpretty/flattened-format-args/flattened-format-args.stdout`
diff of stdout:

14                 super let args = [format_argument::new_display(args.0)];
15                 unsafe {
16                     format_arguments::new(b"\x08a 123 b \xc0\x05 xyz\n\x00",
-                         &args)
+                         &args, 26usize)
18                 }
19             });
20     };


The actual stdout differed from the expected stdout
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args unpretty/flattened-format-args.rs`

error: 1 errors occurred comparing output.
status: exit status: 0
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/unpretty/flattened-format-args.rs" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/unpretty/flattened-format-args" "-Znext-solver=coherence" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers" "--edition=2015" "-Zunpretty=hir" "-Zflatten-format-args=yes"
--- stdout -------------------------------
extern crate std;
#[attr = PreludeImport]
use ::std::prelude::rust_2015::*;
//@ compile-flags: -Zunpretty=hir -Zflatten-format-args=yes
//@ check-pass
//@ edition: 2015

fn main() {
    let x = 1;
    // Should flatten to println!("a 123 b {x} xyz\n"):
    {
        ::std::io::_print({
                super let args = (&x,);
                super let args = [format_argument::new_display(args.0)];
                unsafe {
                    format_arguments::new(b"\x08a 123 b \xc0\x05 xyz\n\x00",
                        &args, 26usize)
                }
            });
    };
}
------------------------------------------
stderr: none

---- [ui] tests/ui/unpretty/flattened-format-args.rs stdout end ----
---- [ui] tests/ui/unpretty/exhaustive.rs#hir stdout ----
Saved the actual stdout to `/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/unpretty/exhaustive.hir/exhaustive.hir.stdout`
diff of stdout:

390         {
391             super let args = (&expr,);
392             super let args = [format_argument::new_display(args.0)];
-             unsafe { format_arguments::new(b"\xc0\x00", &args) }
+             unsafe { format_arguments::new(b"\xc0\x00", &args, 0usize) }
394         };
395     }
396 }


The actual stdout differed from the expected stdout
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args unpretty/exhaustive.rs`

error in revision `hir`: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/unpretty/exhaustive.rs" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--cfg" "hir" "--check-cfg" "cfg(test,FALSE,expanded,hir)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui/unpretty/exhaustive.hir" "-Znext-solver=coherence" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/aarch64-unknown-linux-gnu/native/rust-test-helpers" "--edition=2024" "-Zunpretty=hir"
--- stdout -------------------------------
//@ revisions: expanded hir
//@[expanded]compile-flags: -Zunpretty=expanded
//@[expanded]check-pass
//@[hir]compile-flags: -Zunpretty=hir
//@[hir]check-fail
//@ edition:2024

// Note: the HIR revision includes a `.stderr` file because there are some
// errors that only occur once we get past the AST.

#![allow(incomplete_features)]
#![attr = Feature([auto_traits#0, builtin_syntax#0, const_trait_impl#0,
coroutines#0, decl_macro#0, deref_patterns#0, explicit_tail_calls#0,
gen_blocks#0, more_qualified_paths#0, never_patterns#0, pattern_types#0,
pattern_type_macro#0, prelude_import#0, specialization#0, trace_macros#0,
trait_alias#0, try_blocks#0, try_blocks_heterogeneous#0, yeet_expr#0])]
extern crate std;
#[attr = PreludeImport]
use std::prelude::rust_2024::*;

mod prelude {
    use std::prelude::rust_2024::*;

---

    /// outer single-line doc comment
    /**
     * outer multi-line doc comment
     */
    #[doc = "outer doc attribute"]
    #[doc = "macro"]
    #[allow()]
    #[attr = Repr {reprs: [ReprC]}]
    struct Struct;
}

mod expressions {
    /// ExprKind::Array
    fn expr_array() {
        [];
        [true];
        [true];
        [true, true];
        ["long........................................................................"];
        ["long............................................................",
                true];
    }

    /// ExprKind::ConstBlock
    fn expr_const_block() {
---
                };
    }

    /// ExprKind::Call
    fn expr_call() {
        let f;
        f();
        f::<u8>();
        f::<1>();
        f::<'static, u8, 1>();
        f(true);
        f(true);
        ()();
    }

    /// ExprKind::MethodCall
    fn expr_method_call() {
        let x;
        x.f();
        x.f::<u8>();
        x.collect::<Vec<_>>();
    }

    /// ExprKind::Tup
    fn expr_tup() { (); (true,); (true, false); (true, false); }

    /// ExprKind::Binary
    fn expr_binary() {
        let (a, b, c, d, x, y);
        true || false;
        true || false && false;
        a < 1 && 2 < b && c > 3 && 4 > d;
        a & b & !c;
        a + b * c - d + -1 * -2 - -3;
        x = !y;
    }

    /// ExprKind::Unary
    fn expr_unary() { let expr; *expr; !expr; -expr; }

    /// ExprKind::Lit
    fn expr_lit() { 'x'; 1000i8; 1.00000000000000000000001; }

    /// ExprKind::Cast
    fn expr_cast() { let expr; expr as T; expr as T<u8>; }

    /// ExprKind::Type
    fn expr_type() { let expr; type_ascribe!(expr, T); }

    /// ExprKind::Let
    fn expr_let() {
        let b;
        if let Some(a) = b { }
        if let _ = true && false { }
        if let _ = (true && false) { }
    }

    /// ExprKind::If
    fn expr_if() {
        if true { }
        if !true { }
        if let true = true { } else { }
        if true { } else if false { }
        if true { } else if false { } else { }
        if true { return; } else if false { 0 } else { 0 }
    }

    /// ExprKind::While
    fn expr_while() {
        loop { if false { } else { break; } }
        'a: loop { if false { } else { break; } }
        loop { if let true = true { } else { break; } }
    }

    /// ExprKind::ForLoop
    fn expr_for_loop() {
        let x;
        {
            let _t =
                match into_iter(x) {
                    mut iter =>
                        loop {
                            match next(&mut iter) {
                                None {} => break,
                                Some {  0: _ } => { }
                            }
                        },
                };
            _t
        };
        {
            let _t =
                match into_iter(x) {
                    mut iter =>
                        'a: loop {
                            match next(&mut iter) {
                                None {} => break,
                                Some {  0: _ } => { }
                            }
                        },
                };
            _t
        }
    }

    /// ExprKind::Loop
    fn expr_loop() { loop { } 'a: loop { } }

    /// ExprKind::Match
    fn expr_match() {
        let value;
        match value { }
        match value { ok => 1, }
        match value { ok => 1, err => 0, }
    }

    /// ExprKind::Closure
    fn expr_closure() {
        let value;
        || { };
        |x| { };
        |x: u8| { };
        || ();
        move || value;
        || |mut _task_context: ResumeTy| { { let _t = value; _t } };
        move || |mut _task_context: ResumeTy| { { let _t = value; _t } };
        || value; //[hir]~ ERROR closures cannot be static
        move || value; //[hir]~ ERROR closures cannot be static
        || |mut _task_context: ResumeTy| { { let _t = value; _t } };
        move || |mut _task_context: ResumeTy| { { let _t = value; _t } };
        || -> u8 { value };
        1 + (|| { });
    }

    /// ExprKind::Block
    fn expr_block() {
        { }
---
        { }
    }

    /// ExprKind::Gen
    fn expr_gen() {
        |mut _task_context: ResumeTy| { };
        move |mut _task_context: ResumeTy| { };
        || { };
        move || { };
        |mut _task_context: ResumeTy| { };
        move |mut _task_context: ResumeTy| { };
    }

    /// ExprKind::Await
    fn expr_await() {
        let fut;
        {
            fut; //[hir]~ ERROR `await` is only allowed
            (/*ERROR*/)
        };
    }

    /// ExprKind::TryBlock
    fn expr_try_block() {
        { from_output(()) }
        { return; from_output(()) }
        type_ascribe!({ from_output(()) }, Option<_>);
        type_ascribe!({
                from_output(match branch(None) {
                        Break {  0: residual } => #[allow(unreachable_code)]
                            break from_residual(residual),
                        Continue {  0: val } => #[allow(unreachable_code)]
                            val,
                    })
            }, Option<String>)
    }

    /// ExprKind::Assign
    fn expr_assign() { let expr; expr = true; }

    /// ExprKind::AssignOp
    fn expr_assign_op() { let expr; expr += true; }

    /// ExprKind::Field
    fn expr_field() { let expr; expr.field; expr.0; }

    /// ExprKind::Index
    fn expr_index() { let expr; expr[true]; }

    /// ExprKind::Range
    fn expr_range() {
        let (lo, hi);
        RangeFull {  };
        RangeTo { end: hi };
        RangeFrom { start: lo };
        Range { start: lo, end: hi };
        Range { start: lo, end: hi };
        RangeToInclusive { end: hi };
        range_inclusive_new(lo, hi);
        range_inclusive_new(-2, -1);
    }

    /// ExprKind::Underscore
    fn expr_underscore() {
        (/*ERROR*/); //[hir]~ ERROR in expressions, `_` can only
    }

    /// ExprKind::Path
    fn expr_path() {
        let x;
        crate::expressions::expr_path;
        crate::expressions::expr_path::<'static>;
        <T as Default>::default;
        <T as ::core::default::Default>::default;
        x; //[hir]~ ERROR parenthesized type parameters
        x::<T, T>; //[hir]~ ERROR parenthesized type parameters
        crate::expressions::expr_path;
        //[hir]~^ ERROR parenthesized type parameters
        //[hir]~| ERROR parenthesized type parameters
        core::marker::PhantomData;
        //[hir]~^ ERROR parenthesized type parameters
        //[hir]~| ERROR parenthesized type parameters
    }

    /// ExprKind::AddrOf
    fn expr_addr_of() {
        let expr;
        &expr;
        &mut expr;
        &raw const expr;
        &raw mut expr;
    }

    /// ExprKind::Break
    fn expr_break() { 'a: { break; break 'a; break true; break 'a true; } }

    /// ExprKind::Continue
    fn expr_continue() { 'a: { continue; continue 'a; } }

    /// ExprKind::Ret
    fn expr_ret() { return; return true; }


---




        //[hir]~ ERROR `yield` can only be used





---


        // ...

        //[hir]~ ERROR invalid ABI





---




        //[hir]~ ERROR `..` patterns are not allowed here





---




        //[hir]~ ERROR parenthesized type parameters


        //[hir]~ ERROR `impl Trait` is not allowed
        //[hir]~ ERROR `impl Trait` is not allowed
        //[hir]~ ERROR `impl Trait` is not allowed
        //[hir]~ ERROR `impl Trait` is not allowed
        //[hir]~ ERROR `impl Trait` is not allowed
        //[hir]~ ERROR `impl Trait` is not allowed









        const { offset_of!(T, field) };
    }
    /// ExprKind::MacCall
    fn expr_mac_call() { "..."; "..."; "..."; }
    /// ExprKind::Struct
    fn expr_struct() {
        struct Struct {
        }
        let (x, base);
        Struct {  };
        <Struct as ToOwned>::Owned {  };
        Struct { .. };
        Struct { ..base };
        Struct { x };
        Struct { x, ..base };
        Struct { x: true };
        Struct { x: true, .. };
        Struct { x: true, ..base };
        Struct { 0: true, ..base };
    }
    /// ExprKind::Repeat
    fn expr_repeat() { [(); 0]; }
    /// ExprKind::Paren
    fn expr_paren() { let expr; expr; }
    /// ExprKind::Try
    fn expr_try() {
        let expr;
        match branch(expr) {
            Break {  0: residual } => #[allow(unreachable_code)]
                return from_residual(residual),
            Continue {  0: val } => #[allow(unreachable_code)]
                val,
        };
    }
    /// ExprKind::Yield
    fn expr_yield() { yield (); yield true; }
    /// ExprKind::Yeet
    fn expr_yeet() { return from_yeet(()); return from_yeet(0); }
    /// ExprKind::Become
    fn expr_become() { become true; }
    /// ExprKind::IncludedBytes
    fn expr_include_bytes() {
        b"data for include_bytes in ../expanded-exhaustive.rs\n";
    }
    /// ExprKind::FormatArgs
    fn expr_format_args() {
        let expr;
        format_arguments::from_str("");
        {
            super let args = (&expr,);
            super let args = [format_argument::new_display(args.0)];
            unsafe { format_arguments::new(b"\xc0\x00", &args, 0usize) }
        };
    }
}
mod items {
    /// ItemKind::ExternCrate
    mod item_extern_crate {
        extern crate core;
        extern crate self as unpretty;
        extern crate core as _;
    }
    /// ItemKind::Use
    mod item_use {
        use ::{};
        use crate::expressions;
        use crate::items::item_use;
        use core::*;
    }
    /// ItemKind::Static
    mod item_static {
        static A: () = { };
        static mut B: () = { };
    }
    /// ItemKind::Const
    mod item_const {
        const A: () = { };
        trait TraitItems {
            const
            B:
            ();
            const
            C:
---
    mod item_fn {
        const unsafe extern "C" fn f() { }
        async unsafe extern "C" fn g()
            ->
                /*impl Trait*/ |mut _task_context: ResumeTy|
            { { let _t = { }; _t } }
        fn h<'a, T>() where T: 'a { }
        trait TraitItems {
            unsafe extern "C" fn f();
        }
        impl TraitItems for _ {
            unsafe extern "C" fn f() { }
        }
    }
---
            Tuple(),
            Struct {
                },
        }
        enum Generic<'a, T> where T: 'a {
            Tuple(T),
            Struct {
                    t: T,
                },
        }
    }
---
    /// ItemKind::TraitAlias
    mod item_trait_alias {
        trait Trait<T> = Sized where for<'a> T: 'a;
    }
    /// ItemKind::Impl
    mod item_impl {
        impl () { }
        impl <T> () { }
        impl Default for () { }
        impl <T> const Default for () { }
    }
    /// ItemKind::MacCall
    mod item_mac_call { }
    /// ItemKind::MacroDef
    mod item_macro_def {
        macro_rules! mac { () => {...}; }
        macro stringify { () => {} }
    }
    /// ItemKind::Delegation
    /** FIXME: todo */
    mod item_delegation { }
    /// ItemKind::DelegationMac
    /** FIXME: todo */
    mod item_delegation_mac { }
}
mod patterns {
    /// PatKind::Missing
    fn pat_missing() { let _: for fn(u32, T, &'_ str); }
    /// PatKind::Wild
    fn pat_wild() { let _; }
    /// PatKind::Ident
    fn pat_ident() {
        let x;
        let ref x;
        let mut x;
        let ref mut x;
        let ref mut x@_;
    }
    /// PatKind::Struct
    fn pat_struct() {
        let T {};
        let T::<T> {};
        let T::<'static> {};
        let T {  x };
        let T {  x: _x };
        let T { .. };
        let T {  x, .. };
        let T {  x: _x, .. };
        let T {  0: _x, .. };
        let <T as ToOwned>::Owned {};
    }
    /// PatKind::TupleStruct
    fn pat_tuple_struct() {
        struct Tuple();
        let Tuple();
        let Tuple::<T>();
        let Tuple::<'static>();
        let Tuple(x);
        let Tuple(..);
        let Tuple(x, ..);
    }
    /// PatKind::Or
    fn pat_or() { let true | false; let true; let true | false; }
    /// PatKind::Path
    fn pat_path() {
        let core::marker::PhantomData;
        let core::marker::PhantomData::<T>;
        let core::marker::PhantomData::<'static>;
        let <T as Trait>::CONST;
    }
    /// PatKind::Tuple
    fn pat_tuple() { let (); let (true,); let (true, false); }
    /// PatKind::Deref
    fn pat_deref() { let deref!(pat); }
    /// PatKind::Ref
    fn pat_ref() { let &pat; let &mut pat; }
    /// PatKind::Expr
    fn pat_expr() { let 1000i8; let -""; }
    /// PatKind::Range
    fn pat_range() { let ..1; let 0...; let 0..1; let 0...1; let -2...-1; }
    /// PatKind::Slice
    fn pat_slice() { let []; let [true]; let [true]; let [true, false]; }
    /// PatKind::Rest
    fn pat_rest() { let _; }
    /// PatKind::Never
    fn pat_never() { let !; let Some(!); }
    /// PatKind::Paren
    fn pat_paren() { let pat; }
    /// PatKind::MacCall
    fn pat_mac_call() { let ""; let ""; let ""; }
}
mod statements {
    /// StmtKind::Let
    fn stmt_let() {
        let _;
---
        struct Struct {
        }
        struct Unit;
    }
    /// StmtKind::Expr
    fn stmt_expr() { () }
    /// StmtKind::Semi
    fn stmt_semi() { 1 + 1; }
    /// StmtKind::Empty
    fn stmt_empty() { }
    /// StmtKind::MacCall
    fn stmt_mac_call() { "..."; "..."; "..."; }
}
mod types {
    /// TyKind::Slice
    fn ty_slice() { let _: [T]; }
    /// TyKind::Array
    fn ty_array() { let _: [T; 0]; }
    /// TyKind::Ptr
    fn ty_ptr() { let _: *const T; let _: *mut T; }
    /// TyKind::Ref
    fn ty_ref() {
        let _: &T;
        let _: &mut T;
        let _: &'static T;
        let _: &'static mut [T];
        let _: &T<T<T<T<T>>>>;
        let _: &T<T<T<T<T>>>>;
    }
    /// TyKind::BareFn
    fn ty_bare_fn() {
        let _: fn();
        let _: fn() -> ();
        let _: fn(T);
        let _: fn(t: T);
        let _: fn();
        let _: for<'a> fn();
    }
    /// TyKind::Never
    fn ty_never() { let _: !; }
    /// TyKind::Tup
    fn ty_tup() { let _: (); let _: (T,); let _: (T, T); }
    /// TyKind::Path
    fn ty_path() {
        let _: T;
        let _: T<'static>;
        let _: T<T>;
        let _: T<T>;
        let _: T;
        let _: <T as ToOwned>::Owned;
    }
    /// TyKind::TraitObject
    fn ty_trait_object() {
        let _: dyn Send;
        let _: dyn Send + 'static;
        let _: dyn Send + 'static;
        let _: dyn for<'a> Send;
    }
    /// TyKind::ImplTrait
    const fn ty_impl_trait() {
        let _: (/*ERROR*/);
        let _: (/*ERROR*/);
        let _: (/*ERROR*/);
        let _: (/*ERROR*/);
        let _: (/*ERROR*/);
        let _: (/*ERROR*/);
    }
    /// TyKind::Paren
    fn ty_paren() { let _: T; }
    /// TyKind::Typeof
    /** unused for now */
    fn ty_typeof() { }
    /// TyKind::Infer
    fn ty_infer() { let _: _; }
    /// TyKind::ImplicitSelf
    /** there is no syntax for this */
    fn ty_implicit_self() { }
    /// TyKind::MacCall
    fn ty_mac_call() {
        macro_rules! ty { ($ty:ty) => { $ty } }
        let _: T;
        let _: T;
        let _: T;
    }
    /// TyKind::CVarArgs
    /** FIXME: todo */
    fn ty_c_var_args() { }
    /// TyKind::Pat
    fn ty_pat() { let _: u32 is 1..=RangeMax; }
}
mod visibilities {
    /// VisibilityKind::Public
    mod visibility_public {
        struct Pub;
---
--- stderr -------------------------------
error[E0697]: closures cannot be static
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:209:9
   |
LL |         static || value;            //[hir]~ ERROR closures cannot be static
   |         ^^^^^^^^^

error[E0697]: closures cannot be static
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:210:9
   |
LL |         static move || value;       //[hir]~ ERROR closures cannot be static
   |         ^^^^^^^^^^^^^^

error[E0728]: `await` is only allowed inside `async` functions and blocks
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:239:13
   |
LL |     fn expr_await() {
   |     --------------- this is not `async`
LL |         let fut;
LL |         fut.await;  //[hir]~ ERROR `await` is only allowed
   |             ^^^^^ only allowed inside `async` functions and blocks

error: in expressions, `_` can only be used on the left-hand side of an assignment
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:290:9
   |
LL |         _;      //[hir]~ ERROR in expressions, `_` can only
   |         ^ `_` not allowed here

error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:300:9
   |
LL |         x::();            //[hir]~ ERROR parenthesized type parameters
   |         ^^^^^ only `Fn` traits may use parentheses

error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:301:9
   |
LL |         x::(T, T) -> T;   //[hir]~ ERROR parenthesized type parameters
   |         ^^^^^^^^^^^^^^ only `Fn` traits may use parentheses
   |
help: use angle brackets instead
   |
LL -         x::(T, T) -> T;   //[hir]~ ERROR parenthesized type parameters
LL +         x::<T, T> -> T;   //[hir]~ ERROR parenthesized type parameters
   |

error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:302:9
   |
LL |         crate::() -> ()::expressions::() -> ()::expr_path;
   |         ^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses

error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:302:26
   |
LL |         crate::() -> ()::expressions::() -> ()::expr_path;
   |                          ^^^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses

error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:305:9
   |
LL |         core::()::marker::()::PhantomData;
   |         ^^^^^^^^ only `Fn` traits may use parentheses

error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:305:19
   |
LL |         core::()::marker::()::PhantomData;
   |                   ^^^^^^^^^^ only `Fn` traits may use parentheses

error: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:392:9
   |
LL |         yield;          //[hir]~ ERROR `yield` can only be used
   |         ^^^^^
   |
help: use `#[coroutine]` to make this closure a coroutine
   |
LL |     #[coroutine] fn expr_yield() {
   |     ++++++++++++

error[E0703]: invalid ABI: found `C++`
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:472:23
   |
LL |         unsafe extern "C++" {}  //[hir]~ ERROR invalid ABI
   |                       ^^^^^ invalid ABI
   |
   = note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions

error: `..` patterns are not allowed here
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:674:13
   |
LL |         let ..;     //[hir]~ ERROR `..` patterns are not allowed here
   |             ^^
   |
   = note: only allowed in tuple, tuple struct, and slice patterns

error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:789:16
   |
LL |         let _: T() -> !;    //[hir]~ ERROR parenthesized type parameters
   |                ^^^^^^^^ only `Fn` traits may use parentheses

error[E0562]: `impl Trait` is not allowed in the type of variable bindings
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:803:16
   |
LL |         let _: impl Send;               //[hir]~ ERROR `impl Trait` is not allowed
   |                ^^^^^^^^^
   |
   = note: `impl Trait` is only allowed in arguments and return types of functions and methods
   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0562]: `impl Trait` is not allowed in the type of variable bindings
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:804:16
   |
LL |         let _: impl Send + 'static;     //[hir]~ ERROR `impl Trait` is not allowed
   |                ^^^^^^^^^^^^^^^^^^^
   |
   = note: `impl Trait` is only allowed in arguments and return types of functions and methods
   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0562]: `impl Trait` is not allowed in the type of variable bindings
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:805:16
   |
LL |         let _: impl 'static + Send;     //[hir]~ ERROR `impl Trait` is not allowed
   |                ^^^^^^^^^^^^^^^^^^^
   |
   = note: `impl Trait` is only allowed in arguments and return types of functions and methods
   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0562]: `impl Trait` is not allowed in the type of variable bindings
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:806:16
   |
LL |         let _: impl ?Sized;             //[hir]~ ERROR `impl Trait` is not allowed
   |                ^^^^^^^^^^^
   |
   = note: `impl Trait` is only allowed in arguments and return types of functions and methods
   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0562]: `impl Trait` is not allowed in the type of variable bindings
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:807:16
   |
LL |         let _: impl [const] Clone;       //[hir]~ ERROR `impl Trait` is not allowed
   |                ^^^^^^^^^^^^^^^^^^
   |
   = note: `impl Trait` is only allowed in arguments and return types of functions and methods
   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0562]: `impl Trait` is not allowed in the type of variable bindings
##[error]  --> /checkout/tests/ui/unpretty/exhaustive.rs:808:16
   |
LL |         let _: impl for<'a> Send;       //[hir]~ ERROR `impl Trait` is not allowed
   |                ^^^^^^^^^^^^^^^^^
   |
   = note: `impl Trait` is only allowed in arguments and return types of functions and methods
   = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
   = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: aborting due to 20 previous errors

Some errors have detailed explanations: E0214, E0562, E0697, E0703, E0728.
For more information about an error, try `rustc --explain E0214`.

@rust-bors

rust-bors Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 0022abb (0022abbf7156a1442b78f632b74f639d7f5cb467)
Base parent: 7022271 (70222712809cd5cc1718ed8995914a1cbacb6b92)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (0022abb): comparison URL.

Overall result: ❌✅ regressions and improvements - please read:

Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf.

Next, please: If you can, justify the regressions found in this try perf run in writing along with @rustbot label: +perf-regression-triaged. If not, fix the regressions and do another perf run. Neutral or positive results will clear the label automatically.

@bors rollup=never rustc-perf
@rustbot label: -S-waiting-on-perf +perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
0.6% [0.1%, 2.1%] 22
Regressions ❌
(secondary)
4.7% [0.1%, 36.2%] 22
Improvements ✅
(primary)
-0.7% [-5.7%, -0.1%] 14
Improvements ✅
(secondary)
-0.4% [-0.8%, -0.1%] 6
All ❌✅ (primary) 0.1% [-5.7%, 2.1%] 36

Max RSS (memory usage)

Results (primary 3.7%, secondary 1.3%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
5.1% [1.6%, 12.6%] 4
Regressions ❌
(secondary)
5.2% [3.8%, 9.0%] 8
Improvements ✅
(primary)
-2.0% [-2.0%, -2.0%] 1
Improvements ✅
(secondary)
-4.0% [-7.9%, -2.2%] 6
All ❌✅ (primary) 3.7% [-2.0%, 12.6%] 5

Cycles

Results (primary -7.0%, secondary 7.8%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
15.8% [2.6%, 37.0%] 7
Improvements ✅
(primary)
-7.0% [-7.0%, -7.0%] 1
Improvements ✅
(secondary)
-6.2% [-7.8%, -3.8%] 4
All ❌✅ (primary) -7.0% [-7.0%, -7.0%] 1

Binary size

Results (primary 1.3%, secondary 1.1%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
1.5% [0.2%, 5.7%] 58
Regressions ❌
(secondary)
1.1% [0.0%, 4.9%] 87
Improvements ✅
(primary)
-0.2% [-1.1%, -0.0%] 9
Improvements ✅
(secondary)
-0.1% [-0.1%, -0.1%] 1
All ❌✅ (primary) 1.3% [-1.1%, 5.7%] 67

Bootstrap: 475.539s -> 475.55s (0.00%)
Artifact size: 400.59 MiB -> 403.80 MiB (0.80%)

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Sep 1, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

perf-regression Performance regression. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. 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.

4 participants