Uh oh!
There was an error while loading. Please reload this page.
Implement Debug helpers via Cell - #159302
Conversation
rustbot
commented
Jul 14, 2026
|
Details; ModuleID = 'repro.95a4099cea1845-cgu.0'
source_filename = "repro.95a4099cea1845-cgu.0"targetdatalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"targettriple = "arm64-apple-macosx11.0.0"@alloc_fe2ddbdc622a788f5416063d1e8d8ad4 = privateunnamed_addrconstant [3 x i8] c" { ", align1@alloc_94b00be069aafad82a2c6df764237b82 = privateunnamed_addrconstant [2 x i8] c", ", align1@alloc_556e4180596b5b612bb6ed6c0cbb55e1 = privateunnamed_addrconstant [2 x i8] c": ", align1@alloc_3690db001d3db01550bdb6f3f450de28 = privateunnamed_addrconstant [3 x i8] c" {\0A", align1@alloc_f7ac0c356c6ac6fcd03badb685e09ca2 = privateunnamed_addrconstant [2 x i8] c",\0A", align1@alloc_bf0ef947d182249ea2203578272460c5 = privateunnamed_addrconstant [5 x i8] c"Point", align1@alloc_37f62a15fae368a2423b3a16c75adcc9 = privateunnamed_addrconstant [1 x i8] c"x", align1@alloc_cd51bc84b49b21a3fdb2800731f25c21 = privateunnamed_addrconstant [1 x i8] c"y", align1; <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#0}>; Function Attrs: uwtabledefinealign8ptr@_RINvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB6_11DebugStruct10field_withNCNvXCs36UsywoTqr_5reproNtB1f_5PointNtB8_5Debug3fmt0EB1f_(ptralign8%self, ptr%name.0, i64%name.1, ptralign4%value_fmt) unnamed_addr #0 {
start:
%_8 = alloca [32 x i8], align8%op = alloca [32 x i8], align8%_4 = alloca [1 x i8], align1%0 = getelementptrinboundsi8, ptr%self, i648%1 = loadi8, ptr%0, align8%self1 = truncnuwi8%1toi1storeptr%self, ptr%op, align8%2 = getelementptrinboundsi8, ptr%op, i648storeptr%name.0, ptr%2, align8%3 = getelementptrinboundsi8, ptr%2, i648storei64%name.1, ptr%3, align8%4 = getelementptrinboundsi8, ptr%op, i6424storeptr%value_fmt, ptr%4, align8%_7 = zexti1%self1toi64%5 = truncnuwi64%_7toi1bri1%5, label%bb3, label%bb4
bb3: ; preds = %startstorei81, ptr%_4, align1brlabel%bb1
bb4: ; preds = %startcallvoid@llvm.memcpy.p0.p0.i64(ptralign8%_8, ptralign8%op, i6432, i1false)
; call <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#0}>::{closure#0}%6 = callzeroexti1@_RNCINvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB8_11DebugStruct10field_withNCNvXCs36UsywoTqr_5reproNtB1h_5PointNtBa_5Debug3fmt0E0B1h_(ptralign8%_8) #4%7 = zexti1%6toi8storei8%7, ptr%_4, align1brlabel%bb1
bb1: ; preds = %bb3, %bb4%8 = getelementptrinboundsi8, ptr%self, i648%9 = loadi8, ptr%_4, align1%10 = truncnuwi8%9toi1%11 = zexti1%10toi8storei8%11, ptr%8, align8%12 = getelementptrinboundsi8, ptr%self, i649storei81, ptr%12, align1retptr%self
bb2: ; No predecessors!unreachable
}
; <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#1}>; Function Attrs: uwtabledefinealign8ptr@_RINvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB6_11DebugStruct10field_withNCNvXCs36UsywoTqr_5reproNtB1f_5PointNtB8_5Debug3fmts_0EB1f_(ptralign8%self, ptr%name.0, i64%name.1, ptralign4%value_fmt) unnamed_addr #0 {
start:
%_8 = alloca [32 x i8], align8%op = alloca [32 x i8], align8%_4 = alloca [1 x i8], align1%0 = getelementptrinboundsi8, ptr%self, i648%1 = loadi8, ptr%0, align8%self1 = truncnuwi8%1toi1storeptr%self, ptr%op, align8%2 = getelementptrinboundsi8, ptr%op, i648storeptr%name.0, ptr%2, align8%3 = getelementptrinboundsi8, ptr%2, i648storei64%name.1, ptr%3, align8%4 = getelementptrinboundsi8, ptr%op, i6424storeptr%value_fmt, ptr%4, align8%_7 = zexti1%self1toi64%5 = truncnuwi64%_7toi1bri1%5, label%bb3, label%bb4
bb3: ; preds = %startstorei81, ptr%_4, align1brlabel%bb1
bb4: ; preds = %startcallvoid@llvm.memcpy.p0.p0.i64(ptralign8%_8, ptralign8%op, i6432, i1false)
; call <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#1}>::{closure#0}%6 = callzeroexti1@_RNCINvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB8_11DebugStruct10field_withNCNvXCs36UsywoTqr_5reproNtB1h_5PointNtBa_5Debug3fmts_0E0B1h_(ptralign8%_8) #4%7 = zexti1%6toi8storei8%7, ptr%_4, align1brlabel%bb1
bb1: ; preds = %bb3, %bb4%8 = getelementptrinboundsi8, ptr%self, i648%9 = loadi8, ptr%_4, align1%10 = truncnuwi8%9toi1%11 = zexti1%10toi8storei8%11, ptr%8, align8%12 = getelementptrinboundsi8, ptr%self, i649storei81, ptr%12, align1retptr%self
bb2: ; No predecessors!unreachable
}
; <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#0}>::{closure#0}; Function Attrs: inlinehint uwtabledefinezeroexti1@_RNCINvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB8_11DebugStruct10field_withNCNvXCs36UsywoTqr_5reproNtB1h_5PointNtBa_5Debug3fmt0E0B1h_(ptralign8%_1) unnamed_addr #1personalityptr@rust_eh_personality {
start:
%0 = alloca [16 x i8], align8%_50 = alloca [1 x i8], align1%prefix = alloca [16 x i8], align8%writer = alloca [24 x i8], align8%state = alloca [1 x i8], align1%slot = alloca [24 x i8], align8%_0 = alloca [1 x i8], align1storei81, ptr%_50, align1%self = loadptr, ptr%_1, align8%_51 = loadptr, ptr%self, align8%1 = getelementptrinboundsi8, ptr%_51, i6416%_53 = loadi32, ptr%1, align8%_52 = andi32%_53, 8388608%2 = icmpeqi32%_52, 0bri1%2, label%bb11, label%bb1
bb11: ; preds = %start%_40 = loadptr, ptr%_1, align8%3 = getelementptrinboundsi8, ptr%_40, i649%4 = loadi8, ptr%3, align1%_24 = truncnuwi8%4toi1bri1%_24, label%bb12, label%bb13
bb1: ; preds = %start%_34 = loadptr, ptr%_1, align8%5 = getelementptrinboundsi8, ptr%_34, i649%6 = loadi8, ptr%5, align1%_3 = truncnuwi8%6toi1bri1%_3, label%bb5, label%bb2
bb13: ; preds = %bb11storeptr@alloc_fe2ddbdc622a788f5416063d1e8d8ad4, ptr%prefix, align8, !captures!4%7 = getelementptrinboundsi8, ptr%prefix, i648storei643, ptr%7, align8brlabel%bb14
bb12: ; preds = %bb11storeptr@alloc_94b00be069aafad82a2c6df764237b82, ptr%prefix, align8, !captures!4%8 = getelementptrinboundsi8, ptr%prefix, i648storei642, ptr%8, align8brlabel%bb14
bb14: ; preds = %bb12, %bb13%_41 = loadptr, ptr%_1, align8%_42 = loadptr, ptr%_41, align8%9 = loadptr, ptr%prefix, align8%10 = getelementptrinboundsi8, ptr%prefix, i648%11 = loadi64, ptr%10, align8; invoke <core::fmt::Formatter>::write_str%self1 = invokezeroexti1@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptralign8%_42, ptr%9, i64%11)
tolabel%bb15unwindlabel%cleanup
bb24: ; preds = %cleanup%12 = loadi8, ptr%_50, align1%13 = truncnuwi8%12toi1bri1%13, label%bb23, label%bb22
cleanup: ; preds = %bb32, %bb30, %bb28, %bb6, %bb5, %bb2, %bb38, %bb36, %bb34, %bb14%14 = landingpad { ptr, i32 }
cleanup
%15 = extractvalue { ptr, i32 } %14, 0%16 = extractvalue { ptr, i32 } %14, 1storeptr%15, ptr%0, align8%17 = getelementptrinboundsi8, ptr%0, i648storei32%16, ptr%17, align8brlabel%bb24
bb15: ; preds = %bb14%_66 = zexti1%self1toi64%18 = truncnuwi64%_66toi1bri1%18, label%bb33, label%bb34
bb33: ; preds = %bb15storei81, ptr%_0, align1brlabel%bb20
bb34: ; preds = %bb15%_43 = loadptr, ptr%_1, align8%_44 = loadptr, ptr%_43, align8%19 = getelementptrinboundsi8, ptr%_1, i648%_45.0 = loadptr, ptr%19, align8%20 = getelementptrinboundsi8, ptr%19, i648%_45.1 = loadi64, ptr%20, align8; invoke <core::fmt::Formatter>::write_str%self2 = invokezeroexti1@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptralign8%_44, ptr%_45.0, i64%_45.1)
tolabel%bb16unwindlabel%cleanup
bb16: ; preds = %bb34%_69 = zexti1%self2toi64%21 = truncnuwi64%_69toi1bri1%21, label%bb35, label%bb36
bb35: ; preds = %bb16storei81, ptr%_0, align1brlabel%bb20
bb36: ; preds = %bb16%_46 = loadptr, ptr%_1, align8%_47 = loadptr, ptr%_46, align8; invoke <core::fmt::Formatter>::write_str%self3 = invokezeroexti1@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptralign8%_47, ptr@alloc_556e4180596b5b612bb6ed6c0cbb55e1, i642)
tolabel%bb17unwindlabel%cleanup
bb17: ; preds = %bb36%_72 = zexti1%self3toi64%22 = truncnuwi64%_72toi1bri1%22, label%bb37, label%bb38
bb37: ; preds = %bb17storei81, ptr%_0, align1brlabel%bb20
bb38: ; preds = %bb17storei80, ptr%_50, align1%23 = getelementptrinboundsi8, ptr%_1, i6424%_31 = loadptr, ptr%23, align8%_48 = loadptr, ptr%_1, align8%_49 = loadptr, ptr%_48, align8; invoke <repro::Point as core::fmt::Debug>::fmt::{closure#0}%24 = invokezeroexti1@_RNCNvXCs36UsywoTqr_5reproNtB4_5PointNtNtCs2xrpM2fV95l_4core3fmt5Debug3fmt0B4_(ptralign4%_31, ptralign8%_49)
tolabel%bb18unwindlabel%cleanup
bb18: ; preds = %bb38%25 = zexti1%24toi8storei8%25, ptr%_0, align1brlabel%bb19
bb19: ; preds = %bb10, %bb18brlabel%bb21
bb20: ; preds = %bb33, %bb35, %bb37brlabel%bb40
bb40: ; preds = %bb39, %bb25, %bb20brlabel%bb21
bb2: ; preds = %bb1%_35 = loadptr, ptr%_1, align8%_36 = loadptr, ptr%_35, align8; invoke <core::fmt::Formatter>::write_str%self4 = invokezeroexti1@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptralign8%_36, ptr@alloc_3690db001d3db01550bdb6f3f450de28, i643)
tolabel%bb3unwindlabel%cleanup
bb5: ; preds = %bb26, %bb1storeptrnull, ptr%slot, align8storei81, ptr%state, align1%_37 = loadptr, ptr%_1, align8%_38 = loadptr, ptr%_37, align8; invoke <core::fmt::builders::PadAdapter>::wrapinvokevoid@_RNvMs_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB4_10PadAdapter4wrap(ptrsret([24 x i8]) align8%writer, ptralign8%_38, ptralign8%slot, ptr%state)
tolabel%bb6unwindlabel%cleanup
bb3: ; preds = %bb2%_54 = zexti1%self4toi64%26 = truncnuwi64%_54toi1bri1%26, label%bb25, label%bb26
bb25: ; preds = %bb3storei81, ptr%_0, align1brlabel%bb40
bb26: ; preds = %bb3brlabel%bb5
bb6: ; preds = %bb5%27 = getelementptrinboundsi8, ptr%_1, i648%_39.0 = loadptr, ptr%27, align8%28 = getelementptrinboundsi8, ptr%27, i648%_39.1 = loadi64, ptr%28, align8; invoke <core::fmt::Formatter>::write_str%self5 = invokezeroexti1@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptralign8%writer, ptr%_39.0, i64%_39.1)
tolabel%bb7unwindlabel%cleanup
bb7: ; preds = %bb6%_57 = zexti1%self5toi64%29 = truncnuwi64%_57toi1bri1%29, label%bb27, label%bb28
bb27: ; preds = %bb7storei81, ptr%_0, align1brlabel%bb39
bb28: ; preds = %bb7; invoke <core::fmt::Formatter>::write_str%self6 = invokezeroexti1@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptralign8%writer, ptr@alloc_556e4180596b5b612bb6ed6c0cbb55e1, i642)
tolabel%bb8unwindlabel%cleanup
bb8: ; preds = %bb28%_60 = zexti1%self6toi64%30 = truncnuwi64%_60toi1bri1%30, label%bb29, label%bb30
bb29: ; preds = %bb8storei81, ptr%_0, align1brlabel%bb39
bb30: ; preds = %bb8storei80, ptr%_50, align1%31 = getelementptrinboundsi8, ptr%_1, i6424%_18 = loadptr, ptr%31, align8; invoke <repro::Point as core::fmt::Debug>::fmt::{closure#0}%self7 = invokezeroexti1@_RNCNvXCs36UsywoTqr_5reproNtB4_5PointNtNtCs2xrpM2fV95l_4core3fmt5Debug3fmt0B4_(ptralign4%_18, ptralign8%writer)
tolabel%bb9unwindlabel%cleanup
bb9: ; preds = %bb30%_63 = zexti1%self7toi64%32 = truncnuwi64%_63toi1bri1%32, label%bb31, label%bb32
bb31: ; preds = %bb9storei81, ptr%_0, align1brlabel%bb21
bb32: ; preds = %bb9; invoke <core::fmt::Formatter>::write_str%33 = invokezeroexti1@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptralign8%writer, ptr@alloc_f7ac0c356c6ac6fcd03badb685e09ca2, i642)
tolabel%bb10unwindlabel%cleanup
bb10: ; preds = %bb32%34 = zexti1%33toi8storei8%34, ptr%_0, align1brlabel%bb19
bb21: ; preds = %bb40, %bb31, %bb19%35 = loadi8, ptr%_0, align1%36 = truncnuwi8%35toi1reti1%36
bb39: ; preds = %bb27, %bb29brlabel%bb40
bb4: ; No predecessors!unreachable
bb22: ; preds = %bb23, %bb24%37 = loadptr, ptr%0, align8%38 = getelementptrinboundsi8, ptr%0, i648%39 = loadi32, ptr%38, align8%40 = insertvalue { ptr, i32 } poison, ptr%37, 0%41 = insertvalue { ptr, i32 } %40, i32%39, 1resume { ptr, i32 } %41
bb23: ; preds = %bb24brlabel%bb22
}
; <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#1}>::{closure#0}; Function Attrs: inlinehint uwtabledefinezeroexti1@_RNCINvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB8_11DebugStruct10field_withNCNvXCs36UsywoTqr_5reproNtB1h_5PointNtBa_5Debug3fmts_0E0B1h_(ptralign8%_1) unnamed_addr #1personalityptr@rust_eh_personality {
start:
%0 = alloca [16 x i8], align8%_50 = alloca [1 x i8], align1%prefix = alloca [16 x i8], align8%writer = alloca [24 x i8], align8%state = alloca [1 x i8], align1%slot = alloca [24 x i8], align8%_0 = alloca [1 x i8], align1storei81, ptr%_50, align1%self = loadptr, ptr%_1, align8%_51 = loadptr, ptr%self, align8%1 = getelementptrinboundsi8, ptr%_51, i6416%_53 = loadi32, ptr%1, align8%_52 = andi32%_53, 8388608%2 = icmpeqi32%_52, 0bri1%2, label%bb11, label%bb1
bb11: ; preds = %start%_40 = loadptr, ptr%_1, align8%3 = getelementptrinboundsi8, ptr%_40, i649%4 = loadi8, ptr%3, align1%_24 = truncnuwi8%4toi1bri1%_24, label%bb12, label%bb13
bb1: ; preds = %start%_34 = loadptr, ptr%_1, align8%5 = getelementptrinboundsi8, ptr%_34, i649%6 = loadi8, ptr%5, align1%_3 = truncnuwi8%6toi1bri1%_3, label%bb5, label%bb2
bb13: ; preds = %bb11storeptr@alloc_fe2ddbdc622a788f5416063d1e8d8ad4, ptr%prefix, align8, !captures!4%7 = getelementptrinboundsi8, ptr%prefix, i648storei643, ptr%7, align8brlabel%bb14
bb12: ; preds = %bb11storeptr@alloc_94b00be069aafad82a2c6df764237b82, ptr%prefix, align8, !captures!4%8 = getelementptrinboundsi8, ptr%prefix, i648storei642, ptr%8, align8brlabel%bb14
bb14: ; preds = %bb12, %bb13%_41 = loadptr, ptr%_1, align8%_42 = loadptr, ptr%_41, align8%9 = loadptr, ptr%prefix, align8%10 = getelementptrinboundsi8, ptr%prefix, i648%11 = loadi64, ptr%10, align8; invoke <core::fmt::Formatter>::write_str%self1 = invokezeroexti1@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptralign8%_42, ptr%9, i64%11)
tolabel%bb15unwindlabel%cleanup
bb24: ; preds = %cleanup%12 = loadi8, ptr%_50, align1%13 = truncnuwi8%12toi1bri1%13, label%bb23, label%bb22
cleanup: ; preds = %bb32, %bb30, %bb28, %bb6, %bb5, %bb2, %bb38, %bb36, %bb34, %bb14%14 = landingpad { ptr, i32 }
cleanup
%15 = extractvalue { ptr, i32 } %14, 0%16 = extractvalue { ptr, i32 } %14, 1storeptr%15, ptr%0, align8%17 = getelementptrinboundsi8, ptr%0, i648storei32%16, ptr%17, align8brlabel%bb24
bb15: ; preds = %bb14%_66 = zexti1%self1toi64%18 = truncnuwi64%_66toi1bri1%18, label%bb33, label%bb34
bb33: ; preds = %bb15storei81, ptr%_0, align1brlabel%bb20
bb34: ; preds = %bb15%_43 = loadptr, ptr%_1, align8%_44 = loadptr, ptr%_43, align8%19 = getelementptrinboundsi8, ptr%_1, i648%_45.0 = loadptr, ptr%19, align8%20 = getelementptrinboundsi8, ptr%19, i648%_45.1 = loadi64, ptr%20, align8; invoke <core::fmt::Formatter>::write_str%self2 = invokezeroexti1@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptralign8%_44, ptr%_45.0, i64%_45.1)
tolabel%bb16unwindlabel%cleanup
bb16: ; preds = %bb34%_69 = zexti1%self2toi64%21 = truncnuwi64%_69toi1bri1%21, label%bb35, label%bb36
bb35: ; preds = %bb16storei81, ptr%_0, align1brlabel%bb20
bb36: ; preds = %bb16%_46 = loadptr, ptr%_1, align8%_47 = loadptr, ptr%_46, align8; invoke <core::fmt::Formatter>::write_str%self3 = invokezeroexti1@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptralign8%_47, ptr@alloc_556e4180596b5b612bb6ed6c0cbb55e1, i642)
tolabel%bb17unwindlabel%cleanup
bb17: ; preds = %bb36%_72 = zexti1%self3toi64%22 = truncnuwi64%_72toi1bri1%22, label%bb37, label%bb38
bb37: ; preds = %bb17storei81, ptr%_0, align1brlabel%bb20
bb38: ; preds = %bb17storei80, ptr%_50, align1%23 = getelementptrinboundsi8, ptr%_1, i6424%_31 = loadptr, ptr%23, align8%_48 = loadptr, ptr%_1, align8%_49 = loadptr, ptr%_48, align8; invoke <repro::Point as core::fmt::Debug>::fmt::{closure#1}%24 = invokezeroexti1@_RNCNvXCs36UsywoTqr_5reproNtB4_5PointNtNtCs2xrpM2fV95l_4core3fmt5Debug3fmts_0B4_(ptralign4%_31, ptralign8%_49)
tolabel%bb18unwindlabel%cleanup
bb18: ; preds = %bb38%25 = zexti1%24toi8storei8%25, ptr%_0, align1brlabel%bb19
bb19: ; preds = %bb10, %bb18brlabel%bb21
bb20: ; preds = %bb33, %bb35, %bb37brlabel%bb40
bb40: ; preds = %bb39, %bb25, %bb20brlabel%bb21
bb2: ; preds = %bb1%_35 = loadptr, ptr%_1, align8%_36 = loadptr, ptr%_35, align8; invoke <core::fmt::Formatter>::write_str%self4 = invokezeroexti1@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptralign8%_36, ptr@alloc_3690db001d3db01550bdb6f3f450de28, i643)
tolabel%bb3unwindlabel%cleanup
bb5: ; preds = %bb26, %bb1storeptrnull, ptr%slot, align8storei81, ptr%state, align1%_37 = loadptr, ptr%_1, align8%_38 = loadptr, ptr%_37, align8; invoke <core::fmt::builders::PadAdapter>::wrapinvokevoid@_RNvMs_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB4_10PadAdapter4wrap(ptrsret([24 x i8]) align8%writer, ptralign8%_38, ptralign8%slot, ptr%state)
tolabel%bb6unwindlabel%cleanup
bb3: ; preds = %bb2%_54 = zexti1%self4toi64%26 = truncnuwi64%_54toi1bri1%26, label%bb25, label%bb26
bb25: ; preds = %bb3storei81, ptr%_0, align1brlabel%bb40
bb26: ; preds = %bb3brlabel%bb5
bb6: ; preds = %bb5%27 = getelementptrinboundsi8, ptr%_1, i648%_39.0 = loadptr, ptr%27, align8%28 = getelementptrinboundsi8, ptr%27, i648%_39.1 = loadi64, ptr%28, align8; invoke <core::fmt::Formatter>::write_str%self5 = invokezeroexti1@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptralign8%writer, ptr%_39.0, i64%_39.1)
tolabel%bb7unwindlabel%cleanup
bb7: ; preds = %bb6%_57 = zexti1%self5toi64%29 = truncnuwi64%_57toi1bri1%29, label%bb27, label%bb28
bb27: ; preds = %bb7storei81, ptr%_0, align1brlabel%bb39
bb28: ; preds = %bb7; invoke <core::fmt::Formatter>::write_str%self6 = invokezeroexti1@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptralign8%writer, ptr@alloc_556e4180596b5b612bb6ed6c0cbb55e1, i642)
tolabel%bb8unwindlabel%cleanup
bb8: ; preds = %bb28%_60 = zexti1%self6toi64%30 = truncnuwi64%_60toi1bri1%30, label%bb29, label%bb30
bb29: ; preds = %bb8storei81, ptr%_0, align1brlabel%bb39
bb30: ; preds = %bb8storei80, ptr%_50, align1%31 = getelementptrinboundsi8, ptr%_1, i6424%_18 = loadptr, ptr%31, align8; invoke <repro::Point as core::fmt::Debug>::fmt::{closure#1}%self7 = invokezeroexti1@_RNCNvXCs36UsywoTqr_5reproNtB4_5PointNtNtCs2xrpM2fV95l_4core3fmt5Debug3fmts_0B4_(ptralign4%_18, ptralign8%writer)
tolabel%bb9unwindlabel%cleanup
bb9: ; preds = %bb30%_63 = zexti1%self7toi64%32 = truncnuwi64%_63toi1bri1%32, label%bb31, label%bb32
bb31: ; preds = %bb9storei81, ptr%_0, align1brlabel%bb21
bb32: ; preds = %bb9; invoke <core::fmt::Formatter>::write_str%33 = invokezeroexti1@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptralign8%writer, ptr@alloc_f7ac0c356c6ac6fcd03badb685e09ca2, i642)
tolabel%bb10unwindlabel%cleanup
bb10: ; preds = %bb32%34 = zexti1%33toi8storei8%34, ptr%_0, align1brlabel%bb19
bb21: ; preds = %bb40, %bb31, %bb19%35 = loadi8, ptr%_0, align1%36 = truncnuwi8%35toi1reti1%36
bb39: ; preds = %bb27, %bb29brlabel%bb40
bb4: ; No predecessors!unreachable
bb22: ; preds = %bb23, %bb24%37 = loadptr, ptr%0, align8%38 = getelementptrinboundsi8, ptr%0, i648%39 = loadi32, ptr%38, align8%40 = insertvalue { ptr, i32 } poison, ptr%37, 0%41 = insertvalue { ptr, i32 } %40, i32%39, 1resume { ptr, i32 } %41
bb23: ; preds = %bb24brlabel%bb22
}
; <repro::Point as core::fmt::Debug>::fmt::{closure#0}; Function Attrs: inlinehint uwtabledefineinternalzeroexti1@_RNCNvXCs36UsywoTqr_5reproNtB4_5PointNtNtCs2xrpM2fV95l_4core3fmt5Debug3fmt0B4_(ptralign4%_1, ptralign8%f) unnamed_addr #1 {
start:
; call <u32 as core::fmt::Debug>::fmt%_0 = callzeroexti1@_RNvXsW_NtNtCs2xrpM2fV95l_4core3fmt3nummNtB7_5Debug3fmtCs36UsywoTqr_5repro(ptralign4%_1, ptralign8%f) #4reti1%_0
}
; <repro::Point as core::fmt::Debug>::fmt::{closure#1}; Function Attrs: inlinehint uwtabledefineinternalzeroexti1@_RNCNvXCs36UsywoTqr_5reproNtB4_5PointNtNtCs2xrpM2fV95l_4core3fmt5Debug3fmts_0B4_(ptralign4%_1, ptralign8%f) unnamed_addr #1 {
start:
%_3 = getelementptrinboundsi8, ptr%_1, i644; call <u32 as core::fmt::Debug>::fmt%_0 = callzeroexti1@_RNvXsW_NtNtCs2xrpM2fV95l_4core3fmt3nummNtB7_5Debug3fmtCs36UsywoTqr_5repro(ptralign4%_3, ptralign8%f) #4reti1%_0
}
; <repro::Point as core::fmt::Debug>::fmt; Function Attrs: uwtabledefinezeroexti1@_RNvXCs36UsywoTqr_5reproNtB2_5PointNtNtCs2xrpM2fV95l_4core3fmt5Debug3fmt(ptralign4%self, ptralign8%f) unnamed_addr #0 {
start:
%_6 = alloca [16 x i8], align8; call <core::fmt::Formatter>::debug_structcallvoid@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter12debug_struct(ptrsret([16 x i8]) align8%_6, ptralign8%f, ptr@alloc_bf0ef947d182249ea2203578272460c5, i645)
; call <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#0}>%_4 = callalign8ptr@_RINvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB6_11DebugStruct10field_withNCNvXCs36UsywoTqr_5reproNtB1f_5PointNtB8_5Debug3fmt0EB1f_(ptralign8%_6, ptr@alloc_37f62a15fae368a2423b3a16c75adcc9, i641, ptralign4%self)
; call <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#1}>%_3 = callalign8ptr@_RINvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB6_11DebugStruct10field_withNCNvXCs36UsywoTqr_5reproNtB1f_5PointNtB8_5Debug3fmts_0EB1f_(ptralign8%_4, ptr@alloc_cd51bc84b49b21a3fdb2800731f25c21, i641, ptralign4%self)
; call <core::fmt::builders::DebugStruct>::finish%_0 = callzeroexti1@_RNvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB5_11DebugStruct6finish(ptralign8%_3)
reti1%_0
}
; <u32 as core::fmt::Debug>::fmt; Function Attrs: inlinehint uwtabledefineinternalzeroexti1@_RNvXsW_NtNtCs2xrpM2fV95l_4core3fmt3nummNtB7_5Debug3fmtCs36UsywoTqr_5repro(ptralign4%self, ptralign8%f) unnamed_addr #1 {
start:
%_0 = alloca [1 x i8], align1%0 = getelementptrinboundsi8, ptr%f, i6416%_4 = loadi32, ptr%0, align8%_3 = andi32%_4, 33554432%1 = icmpeqi32%_3, 0bri1%1, label%bb2, label%bb1
bb2: ; preds = %start%2 = getelementptrinboundsi8, ptr%f, i6416%_6 = loadi32, ptr%2, align8%_5 = andi32%_6, 67108864%3 = icmpeqi32%_5, 0bri1%3, label%bb4, label%bb3
bb1: ; preds = %start; call <u32 as core::fmt::LowerHex>::fmt%4 = callzeroexti1@_RNvXsu_NtNtCs2xrpM2fV95l_4core3fmt3nummNtB7_8LowerHex3fmt(ptralign4%self, ptralign8%f)
%5 = zexti1%4toi8storei8%5, ptr%_0, align1brlabel%bb6
bb4: ; preds = %bb2; call <u32 as core::fmt::Display>::fmt%6 = callzeroexti1@_RNvXs8_NtNtNtCs2xrpM2fV95l_4core3fmt3num3impmNtB9_7Display3fmt(ptralign4%self, ptralign8%f)
%7 = zexti1%6toi8storei8%7, ptr%_0, align1brlabel%bb5
bb3: ; preds = %bb2; call <u32 as core::fmt::UpperHex>::fmt%8 = callzeroexti1@_RNvXsw_NtNtCs2xrpM2fV95l_4core3fmt3nummNtB7_8UpperHex3fmt(ptralign4%self, ptralign8%f)
%9 = zexti1%8toi8storei8%9, ptr%_0, align1brlabel%bb5
bb5: ; preds = %bb3, %bb4brlabel%bb6
bb6: ; preds = %bb1, %bb5%10 = loadi8, ptr%_0, align1%11 = truncnuwi8%10toi1reti1%11
}
; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)declarevoid@llvm.memcpy.p0.p0.i64(ptrnoaliaswriteonly captures(none), ptrnoaliasreadonly captures(none), i64, i1 immarg) #2; Function Attrs: nounwind uwtabledeclarei32@rust_eh_personality(i32, i32, i64, ptr, ptr) unnamed_addr #3; <core::fmt::Formatter>::write_str; Function Attrs: uwtabledeclarezeroexti1@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter9write_str(ptralign8, ptr, i64) unnamed_addr #0; <core::fmt::builders::PadAdapter>::wrap; Function Attrs: uwtabledeclarevoid@_RNvMs_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB4_10PadAdapter4wrap(ptrsret([24 x i8]) align8, ptralign8, ptralign8, ptr) unnamed_addr #0; <core::fmt::Formatter>::debug_struct; Function Attrs: uwtabledeclarevoid@_RNvMsa_NtCs2xrpM2fV95l_4core3fmtNtB5_9Formatter12debug_struct(ptrsret([16 x i8]) align8, ptralign8, ptr, i64) unnamed_addr #0; <core::fmt::builders::DebugStruct>::finish; Function Attrs: uwtabledeclarezeroexti1@_RNvMs1_NtNtCs2xrpM2fV95l_4core3fmt8buildersNtB5_11DebugStruct6finish(ptralign8) unnamed_addr #0; <u32 as core::fmt::Display>::fmt; Function Attrs: uwtabledeclarezeroexti1@_RNvXs8_NtNtNtCs2xrpM2fV95l_4core3fmt3num3impmNtB9_7Display3fmt(ptralign4, ptralign8) unnamed_addr #0; <u32 as core::fmt::UpperHex>::fmt; Function Attrs: uwtabledeclarezeroexti1@_RNvXsw_NtNtCs2xrpM2fV95l_4core3fmt3nummNtB7_8UpperHex3fmt(ptralign4, ptralign8) unnamed_addr #0; <u32 as core::fmt::LowerHex>::fmt; Function Attrs: uwtabledeclarezeroexti1@_RNvXsu_NtNtCs2xrpM2fV95l_4core3fmt3nummNtB7_8LowerHex3fmt(ptralign4, ptralign8) unnamed_addr #0attributes #0 = { uwtable"frame-pointer"="non-leaf""probe-stack"="inline-asm""target-cpu"="apple-m1" }
attributes #1 = { inlinehintuwtable"frame-pointer"="non-leaf""probe-stack"="inline-asm""target-cpu"="apple-m1" }
attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
attributes #3 = { nounwinduwtable"frame-pointer"="non-leaf""probe-stack"="inline-asm""target-cpu"="apple-m1" }
attributes #4 = { inlinehint }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
!0 = !{i328, !"PIC Level", i322}
!1 = !{i327, !"uwtable", i322}
!2 = !{i327, !"frame-pointer", i321}
!3 = !{!"rustc version 1.99.0-nightly (77cf889bc 2026-07-12)"}
!4 = !{!"address", !"read_provenance"}
Details; ModuleID = 'repro.ada4be50ab0d3186-cgu.0'
source_filename = "repro.ada4be50ab0d3186-cgu.0"targetdatalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"targettriple = "arm64-apple-macosx11.0.0"@vtable.0 = privateunnamed_addrconstant <{ [24 x i8], ptr }> <{ [24 x i8] c"\00\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00", ptr@_RNvXs1_NtNtCs1Jl4pBjAano_4core3fmt8buildersINtB5_9DebugOnceNCNvXCseUiCQVDuJCY_5reproNtB10_5PointNtB7_5Debug3fmt0EB1w_3fmtB10_ }>, align8@vtable.1 = privateunnamed_addrconstant <{ [24 x i8], ptr }> <{ [24 x i8] c"\00\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00", ptr@_RNvXs1_NtNtCs1Jl4pBjAano_4core3fmt8buildersINtB5_9DebugOnceNCNvXCseUiCQVDuJCY_5reproNtB10_5PointNtB7_5Debug3fmts_0EB1w_3fmtB10_ }>, align8@alloc_bf0ef947d182249ea2203578272460c5 = privateunnamed_addrconstant [5 x i8] c"Point", align1@alloc_37f62a15fae368a2423b3a16c75adcc9 = privateunnamed_addrconstant [1 x i8] c"x", align1@alloc_cd51bc84b49b21a3fdb2800731f25c21 = privateunnamed_addrconstant [1 x i8] c"y", align1@alloc_67658ef8123446d70a96e7dbc7651d58 = privateunnamed_addrconstant [40 x i8] c"formatting closure called more than once", align1@alloc_703b1d677d4c28a67f1910a45c16864b = privateunnamed_addrconstant [33 x i8] c"library/core/src/fmt/builders.rs\00", align1@alloc_7fd203ad775cd664e43a5c0ae4634671 = privateunnamed_addrconstant <{ ptr, [16 x i8] }> <{ ptr@alloc_703b1d677d4c28a67f1910a45c16864b, [16 x i8] c" \00\00\00\00\00\00\00H\00\00\00\15\00\00\00" }>, align8; <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#0}>; Function Attrs: uwtabledefinealign8ptr@_RINvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB6_11DebugStruct10field_withNCNvXCseUiCQVDuJCY_5reproNtB1f_5PointNtB8_5Debug3fmt0EB1f_(ptralign8%self, ptr%name.0, i64%name.1, ptralign4%value_fmt) unnamed_addr #0personalityptr@rust_eh_personality {
start:
%0 = alloca [16 x i8], align8%_6 = alloca [8 x i8], align8storeptr%value_fmt, ptr%_6, align8; invoke <core::fmt::builders::DebugStruct>::field%_0 = invokealign8ptr@_RNvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB5_11DebugStruct5field(ptralign8%self, ptr%name.0, i64%name.1, ptr%_6, ptralign8@vtable.0)
tolabel%bb1unwindlabel%cleanup
bb3: ; preds = %cleanup%1 = loadptr, ptr%0, align8%2 = getelementptrinboundsi8, ptr%0, i648%3 = loadi32, ptr%2, align8%4 = insertvalue { ptr, i32 } poison, ptr%1, 0%5 = insertvalue { ptr, i32 } %4, i32%3, 1resume { ptr, i32 } %5
cleanup: ; preds = %start%6 = landingpad { ptr, i32 }
cleanup
%7 = extractvalue { ptr, i32 } %6, 0%8 = extractvalue { ptr, i32 } %6, 1storeptr%7, ptr%0, align8%9 = getelementptrinboundsi8, ptr%0, i648storei32%8, ptr%9, align8brlabel%bb3
bb1: ; preds = %startretptr%_0
}
; <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#1}>; Function Attrs: uwtabledefinealign8ptr@_RINvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB6_11DebugStruct10field_withNCNvXCseUiCQVDuJCY_5reproNtB1f_5PointNtB8_5Debug3fmts_0EB1f_(ptralign8%self, ptr%name.0, i64%name.1, ptralign4%value_fmt) unnamed_addr #0personalityptr@rust_eh_personality {
start:
%0 = alloca [16 x i8], align8%_6 = alloca [8 x i8], align8storeptr%value_fmt, ptr%_6, align8; invoke <core::fmt::builders::DebugStruct>::field%_0 = invokealign8ptr@_RNvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB5_11DebugStruct5field(ptralign8%self, ptr%name.0, i64%name.1, ptr%_6, ptralign8@vtable.1)
tolabel%bb1unwindlabel%cleanup
bb3: ; preds = %cleanup%1 = loadptr, ptr%0, align8%2 = getelementptrinboundsi8, ptr%0, i648%3 = loadi32, ptr%2, align8%4 = insertvalue { ptr, i32 } poison, ptr%1, 0%5 = insertvalue { ptr, i32 } %4, i32%3, 1resume { ptr, i32 } %5
cleanup: ; preds = %start%6 = landingpad { ptr, i32 }
cleanup
%7 = extractvalue { ptr, i32 } %6, 0%8 = extractvalue { ptr, i32 } %6, 1storeptr%7, ptr%0, align8%9 = getelementptrinboundsi8, ptr%0, i648storei32%8, ptr%9, align8brlabel%bb3
bb1: ; preds = %startretptr%_0
}
; <repro::Point as core::fmt::Debug>::fmt::{closure#0}; Function Attrs: inlinehint uwtabledefineinternalzeroexti1@_RNCNvXCseUiCQVDuJCY_5reproNtB4_5PointNtNtCs1Jl4pBjAano_4core3fmt5Debug3fmt0B4_(ptralign4%_1, ptralign8%f) unnamed_addr #1 {
start:
; call <u32 as core::fmt::Debug>::fmt%_0 = callzeroexti1@_RNvXsW_NtNtCs1Jl4pBjAano_4core3fmt3nummNtB7_5Debug3fmtCseUiCQVDuJCY_5repro(ptralign4%_1, ptralign8%f) #4reti1%_0
}
; <repro::Point as core::fmt::Debug>::fmt::{closure#1}; Function Attrs: inlinehint uwtabledefineinternalzeroexti1@_RNCNvXCseUiCQVDuJCY_5reproNtB4_5PointNtNtCs1Jl4pBjAano_4core3fmt5Debug3fmts_0B4_(ptralign4%_1, ptralign8%f) unnamed_addr #1 {
start:
%_3 = getelementptrinboundsi8, ptr%_1, i644; call <u32 as core::fmt::Debug>::fmt%_0 = callzeroexti1@_RNvXsW_NtNtCs1Jl4pBjAano_4core3fmt3nummNtB7_5Debug3fmtCseUiCQVDuJCY_5repro(ptralign4%_3, ptralign8%f) #4reti1%_0
}
; <repro::Point as core::fmt::Debug>::fmt; Function Attrs: uwtabledefinezeroexti1@_RNvXCseUiCQVDuJCY_5reproNtB2_5PointNtNtCs1Jl4pBjAano_4core3fmt5Debug3fmt(ptralign4%self, ptralign8%f) unnamed_addr #0 {
start:
%_6 = alloca [16 x i8], align8; call <core::fmt::Formatter>::debug_structcallvoid@_RNvMsa_NtCs1Jl4pBjAano_4core3fmtNtB5_9Formatter12debug_struct(ptrsret([16 x i8]) align8%_6, ptralign8%f, ptr@alloc_bf0ef947d182249ea2203578272460c5, i645)
; call <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#0}>%_4 = callalign8ptr@_RINvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB6_11DebugStruct10field_withNCNvXCseUiCQVDuJCY_5reproNtB1f_5PointNtB8_5Debug3fmt0EB1f_(ptralign8%_6, ptr@alloc_37f62a15fae368a2423b3a16c75adcc9, i641, ptralign4%self)
; call <core::fmt::builders::DebugStruct>::field_with::<<repro::Point as core::fmt::Debug>::fmt::{closure#1}>%_3 = callalign8ptr@_RINvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB6_11DebugStruct10field_withNCNvXCseUiCQVDuJCY_5reproNtB1f_5PointNtB8_5Debug3fmts_0EB1f_(ptralign8%_4, ptr@alloc_cd51bc84b49b21a3fdb2800731f25c21, i641, ptralign4%self)
; call <core::fmt::builders::DebugStruct>::finish%_0 = callzeroexti1@_RNvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB5_11DebugStruct6finish(ptralign8%_3)
reti1%_0
}
; <core::fmt::builders::DebugOnce<<repro::Point as core::fmt::Debug>::fmt::{closure#0}> as core::fmt::Debug>::fmt; Function Attrs: uwtabledefinezeroexti1@_RNvXs1_NtNtCs1Jl4pBjAano_4core3fmt8buildersINtB5_9DebugOnceNCNvXCseUiCQVDuJCY_5reproNtB10_5PointNtB7_5Debug3fmt0EB1w_3fmtB10_(ptralign8%self, ptralign8%f) unnamed_addr #0 {
start:
%_3 = alloca [8 x i8], align8%0 = loadptr, ptr%self, align8storeptr%0, ptr%_3, align8storeptrnull, ptr%self, align8%1 = loadptr, ptr%_3, align8%2 = ptrtointptr%1toi64%3 = icmpeqi64%2, 0%_5 = selecti1%3, i640, i641%4 = truncnuwi64%_5toi1bri1%4, label%bb3, label%bb2
bb3: ; preds = %start%value_fmt = loadptr, ptr%_3, align8; call <repro::Point as core::fmt::Debug>::fmt::{closure#0}%_0 = callzeroexti1@_RNCNvXCseUiCQVDuJCY_5reproNtB4_5PointNtNtCs1Jl4pBjAano_4core3fmt5Debug3fmt0B4_(ptralign4%value_fmt, ptralign8%f) #4reti1%_0
bb2: ; preds = %start; call core::panicking::panic_fmtcallvoid@_RNvNtCs1Jl4pBjAano_4core9panicking9panic_fmt(ptr@alloc_67658ef8123446d70a96e7dbc7651d58, ptrinttoptr (i6481toptr), ptralign8@alloc_7fd203ad775cd664e43a5c0ae4634671) #5unreachable
bb1: ; No predecessors!unreachable
}
; <core::fmt::builders::DebugOnce<<repro::Point as core::fmt::Debug>::fmt::{closure#1}> as core::fmt::Debug>::fmt; Function Attrs: uwtabledefinezeroexti1@_RNvXs1_NtNtCs1Jl4pBjAano_4core3fmt8buildersINtB5_9DebugOnceNCNvXCseUiCQVDuJCY_5reproNtB10_5PointNtB7_5Debug3fmts_0EB1w_3fmtB10_(ptralign8%self, ptralign8%f) unnamed_addr #0 {
start:
%_3 = alloca [8 x i8], align8%0 = loadptr, ptr%self, align8storeptr%0, ptr%_3, align8storeptrnull, ptr%self, align8%1 = loadptr, ptr%_3, align8%2 = ptrtointptr%1toi64%3 = icmpeqi64%2, 0%_5 = selecti1%3, i640, i641%4 = truncnuwi64%_5toi1bri1%4, label%bb3, label%bb2
bb3: ; preds = %start%value_fmt = loadptr, ptr%_3, align8; call <repro::Point as core::fmt::Debug>::fmt::{closure#1}%_0 = callzeroexti1@_RNCNvXCseUiCQVDuJCY_5reproNtB4_5PointNtNtCs1Jl4pBjAano_4core3fmt5Debug3fmts_0B4_(ptralign4%value_fmt, ptralign8%f) #4reti1%_0
bb2: ; preds = %start; call core::panicking::panic_fmtcallvoid@_RNvNtCs1Jl4pBjAano_4core9panicking9panic_fmt(ptr@alloc_67658ef8123446d70a96e7dbc7651d58, ptrinttoptr (i6481toptr), ptralign8@alloc_7fd203ad775cd664e43a5c0ae4634671) #5unreachable
bb1: ; No predecessors!unreachable
}
; <u32 as core::fmt::Debug>::fmt; Function Attrs: inlinehint uwtabledefineinternalzeroexti1@_RNvXsW_NtNtCs1Jl4pBjAano_4core3fmt3nummNtB7_5Debug3fmtCseUiCQVDuJCY_5repro(ptralign4%self, ptralign8%f) unnamed_addr #1 {
start:
%_0 = alloca [1 x i8], align1%0 = getelementptrinboundsi8, ptr%f, i6416%_4 = loadi32, ptr%0, align8%_3 = andi32%_4, 33554432%1 = icmpeqi32%_3, 0bri1%1, label%bb2, label%bb1
bb2: ; preds = %start%2 = getelementptrinboundsi8, ptr%f, i6416%_6 = loadi32, ptr%2, align8%_5 = andi32%_6, 67108864%3 = icmpeqi32%_5, 0bri1%3, label%bb4, label%bb3
bb1: ; preds = %start; call <u32 as core::fmt::LowerHex>::fmt%4 = callzeroexti1@_RNvXsu_NtNtCs1Jl4pBjAano_4core3fmt3nummNtB7_8LowerHex3fmt(ptralign4%self, ptralign8%f)
%5 = zexti1%4toi8storei8%5, ptr%_0, align1brlabel%bb6
bb4: ; preds = %bb2; call <u32 as core::fmt::Display>::fmt%6 = callzeroexti1@_RNvXs8_NtNtNtCs1Jl4pBjAano_4core3fmt3num3impmNtB9_7Display3fmt(ptralign4%self, ptralign8%f)
%7 = zexti1%6toi8storei8%7, ptr%_0, align1brlabel%bb5
bb3: ; preds = %bb2; call <u32 as core::fmt::UpperHex>::fmt%8 = callzeroexti1@_RNvXsw_NtNtCs1Jl4pBjAano_4core3fmt3nummNtB7_8UpperHex3fmt(ptralign4%self, ptralign8%f)
%9 = zexti1%8toi8storei8%9, ptr%_0, align1brlabel%bb5
bb5: ; preds = %bb3, %bb4brlabel%bb6
bb6: ; preds = %bb1, %bb5%10 = loadi8, ptr%_0, align1%11 = truncnuwi8%10toi1reti1%11
}
; Function Attrs: nounwind uwtabledeclarei32@rust_eh_personality(i32, i32, i64, ptr, ptr) unnamed_addr #2; <core::fmt::builders::DebugStruct>::field; Function Attrs: uwtabledeclarealign8ptr@_RNvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB5_11DebugStruct5field(ptralign8, ptr, i64, ptr, ptralign8) unnamed_addr #0; <core::fmt::Formatter>::debug_struct; Function Attrs: uwtabledeclarevoid@_RNvMsa_NtCs1Jl4pBjAano_4core3fmtNtB5_9Formatter12debug_struct(ptrsret([16 x i8]) align8, ptralign8, ptr, i64) unnamed_addr #0; <core::fmt::builders::DebugStruct>::finish; Function Attrs: uwtabledeclarezeroexti1@_RNvMs2_NtNtCs1Jl4pBjAano_4core3fmt8buildersNtB5_11DebugStruct6finish(ptralign8) unnamed_addr #0; core::panicking::panic_fmt; Function Attrs: cold noinline noreturn uwtabledeclarevoid@_RNvNtCs1Jl4pBjAano_4core9panicking9panic_fmt(ptr, ptr, ptralign8) unnamed_addr #3; <u32 as core::fmt::Display>::fmt; Function Attrs: uwtabledeclarezeroexti1@_RNvXs8_NtNtNtCs1Jl4pBjAano_4core3fmt3num3impmNtB9_7Display3fmt(ptralign4, ptralign8) unnamed_addr #0; <u32 as core::fmt::UpperHex>::fmt; Function Attrs: uwtabledeclarezeroexti1@_RNvXsw_NtNtCs1Jl4pBjAano_4core3fmt3nummNtB7_8UpperHex3fmt(ptralign4, ptralign8) unnamed_addr #0; <u32 as core::fmt::LowerHex>::fmt; Function Attrs: uwtabledeclarezeroexti1@_RNvXsu_NtNtCs1Jl4pBjAano_4core3fmt3nummNtB7_8LowerHex3fmt(ptralign4, ptralign8) unnamed_addr #0attributes #0 = { uwtable"frame-pointer"="non-leaf""probe-stack"="inline-asm""target-cpu"="apple-m1" }
attributes #1 = { inlinehintuwtable"frame-pointer"="non-leaf""probe-stack"="inline-asm""target-cpu"="apple-m1" }
attributes #2 = { nounwinduwtable"frame-pointer"="non-leaf""probe-stack"="inline-asm""target-cpu"="apple-m1" }
attributes #3 = { cold noinlinenoreturnuwtable"frame-pointer"="non-leaf""probe-stack"="inline-asm""target-cpu"="apple-m1" }
attributes #4 = { inlinehint }
attributes #5 = { noinlinenoreturn }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
!0 = !{i328, !"PIC Level", i322}
!1 = !{i327, !"uwtable", i322}
!2 = !{i327, !"frame-pointer", i321}
!3 = !{!"rustc version 1.99.0-dev"} |
Debug helpers that take closures with &mut dyn FnMutr? me (happy to hand this back to @tgross35 if that’s preferred) @bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Implement `Debug` helpers that take closures with `&mut dyn FnMut`
Oh thats fine @hanna-kruppe I just didn't know if you were in the rotation (I've only ever directly requested from 2 other people total in the past 🤣) |
Uh oh!
There was an error while loading. Please reload this page.
This comment has been minimized.
This comment has been minimized.
rust-timer
commented
Jul 14, 2026
Finished benchmarking commit (d43d144): comparison URL. Overall result: ❌✅ regressions and improvements - no action neededBenchmarking means the PR may be perf-sensitive. Consider adding rollup=never if this change is not fit for rolling up. @rustbot label: -S-waiting-on-perf -perf-regression Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
Max RSS (memory usage)Results (secondary 3.0%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (secondary -2.7%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeResults (primary -0.2%, secondary 0.3%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Bootstrap: 491.202s -> 491.87s (0.14%) |
jmillikin
commented
Jul 15, 2026
optional: As discussed in the other thread, since the pre-existing structDebugOnce<F>(Cell<Option<F>>);impl<F> fmt::DebugforDebugOnce<F>whereF:FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,{fnfmt(&self,f:&mut fmt::Formatter<'_>) -> fmt::Result{ifletSome(x) = self.0.replace(None){return(x)(f);}Ok(())}}// ...pubfnfield_with<F>(&mutself,name:&str,value_fmt:F) -> &mutSelfwhereF:FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,{self.field(name,&DebugOnce(Cell::new(Some(value_fmt))))} |
tgross35
commented
Jul 15, 2026
No need, all yours :) |
connortsui20
commented
Jul 15, 2026
@jmillikin could you help me understand why using this |
hanna-kruppe
commented
Jul 15, 2026
I wrote a bigger test program to compare the growth as number of
The "per field" column is just the extra lines of 6 vs 3 fields and 9 vs 6 fields divided by 3. Not sure why it's not an integer. Don't read too much into it. I also skimmed the LLVM IR generated for
I guess @jmillikin's approach side-steps the third problem by not involving closure trait objects. |
There was a problem hiding this comment.
By my measurements above, this PR does improve things significantly. But DebugStruct::field_with vs field still seems to be a ca 10x difference in LLVM IR per call site despite that improvement. I'd like to take the improvements anyway and try to squeeze out more gains in a follow up PR, but it looks like there's a runtime performance regression right now. So if you're up for it, I'd suggest trying the approach described by @jmillikin.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
rustbot
commented
Jul 15, 2026
Reminder, once the PR becomes ready for a review, use |
Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
8dd6849 to
b727274Comparerust-timer
commented
Jul 15, 2026
Finished benchmarking commit (fcf8e93): comparison URL. Overall result: ❌ regressions - no action neededBenchmarking means the PR may be perf-sensitive. Consider adding rollup=never if this change is not fit for rolling up. @rustbot label: -S-waiting-on-perf -perf-regression Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
Max RSS (memory usage)Results (primary 1.0%, secondary 4.6%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (primary 1.8%, secondary 0.1%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis perf run didn't have relevant results for this metric. Bootstrap: 487.651s -> 489.459s (0.37%) |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Is there any way we could reasonably cover this in a codegen test?
There was a problem hiding this comment.
I've asked myself that on other changes to reduce monomorphization, and I never came up with a satisfying answer. Matching against the structure of calling some shared monomorphic function is the closest thing, but that's not really reasonable because it's either way too unspecific or way too sensitive to details like function names.
There was a problem hiding this comment.
It would probably be a good idea to add a benchmark using these functions to https://github.com/rust-lang/rustc-perf/tree/2e1f10b49224c069b9fdca7fe8d1e78790e8c62b/collector, assuming the differences here make it to optimized binary size.
There was a problem hiding this comment.
I don’t think this is worth it in the grand scheme of things. We shouldn’t have an API that’s an unavoidable code size footgun to use at all, but also, this one API isn’t likely to be a sufficiently interesting benchmark for the purpose of rustc-perf, compared to everything else we could be measuring with the limited benchmarking budget. If this API eventually makes its way into a popular application/library, we may measure it that way in a more realistic setting.
Also, yeah, it doesn’t necessarily show up in optimized binary size. The examples we’ve had so far get handled well by function merging so they act mostly like a single field_with call. It’s likely possible to write a microbenchmark that doesn’t have so much obviously identical code, but the real risk is death by a thousand cuts across a large code base, which is hard to model in an artificial benchmark.
hanna-kruppe
commented
Jul 16, 2026
I repeated the previous experiment with the
That's better but honestly still not great. Although a lot of the difference is due to debug info related overhead (the
And a lot of the remaining IR is the aforementioned (1) |
hanna-kruppe
commented
Jul 16, 2026
As another point of comparison, I extended my test with a variant that uses
|
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| match self.0.take() { | ||
| Some(value_fmt) => value_fmt(f), | ||
| None => panic!("formatting closure called more than once"), |
There was a problem hiding this comment.
Are we sure that the panic is optimized out? If not, this should probably return Ok? Even if by some chance this branch were reached, probably better not to panic anyways.
hanna-kruppe
commented
Jul 16, 2026
On the one hand, this PR in its current state is a good contribution that I'd be happy to merge: it significantly reduces the cost of On the other hand, I don't feel this fully fixes #149745. So @connortsui20 I would propose merging this PR minus the "Fixes #149745" bit. And then someone will need to do further work in another PR to fully close that issue. If you're up for it, I can sketch the ideas I have and you try them out. If not, I might try my hand at that myself, after having thought a bunch about it, but I can't promise when I'll get around to it. Does that sound okay to you? |
connortsui20
commented
Jul 16, 2026
@hanna-kruppe that sounds good! Though I will admit that it is probably better if you or someone else takes over as I am not super familiar with LLVM and codegen in general. I have updated the PR description. |
connortsui20
commented
Jul 16, 2026
Also, I think we are at the point where the review comments are not something I can actively fix without a lot of help, feel free to commit directly to this PR! |
hanna-kruppe
commented
Jul 16, 2026
I’ll take the musings about further improvements to the issue, then. Thanks for your work on this! @bors r+ rollup |
…hanna-kruppe Implement `Debug` helpers via `Cell` Related to rust-lang#149745, but does not fix it (yet). Following @jmillikin's [suggestion](rust-lang#159302 (comment)), the builder logic now lives in the pre-existing non-generic methods taking `&dyn fmt::Debug` (where it used to exist), and each `*_with` method wraps its closure in a private `DebugOnce` struct that implements `Debug` by calling the closure, so the body is compiled once. Just for context: A `dyn FnOnce` [can't be called behind a reference](rust-lang#149745 (comment)), hence the `Cell<Option<..>>` stuff in `DebugOnce`. ###### repro.rs ```rust #![feature(debug_closure_helpers)] #![crate_type = "lib"] use core::fmt; pub struct Point { pub x: u32, pub y: u32, } impl fmt::Debug for Point { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Point") .field_with("x", |f| self.x.fmt(f)) .field_with("y", |f| self.y.fmt(f)) .finish() } } ``` ```bash rustc +nightly --edition=2024 --emit=llvm-ir -Copt-level=0 -o before.ll repro.rs rustc +stage1 --edition=2024 --emit=llvm-ir -Copt-level=0 -o after.ll repro.rs ``` On the repro above, I saw the LLVM IR drop from 739 to 268 lines (an earlier version of this PR using `&mut dyn FnMut` measured 372). Since the stable `&dyn fmt::Debug` methods no longer go through any closure indirection, this should also avoid the potential runtime regression in the `derive(Debug)` microbenchmark. This was the only remaining [blocker](rust-lang#117729 (comment)) for stabilizing `debug_closure_helpers`, so it should unblock rust-lang#146099.
Rollup of 10 pull requests Successful merges: - #156977 (interpret: properly check for inhabitedness of nested references) - #159365 (fix: point at method call chain when a return-position `impl Trait` assoc type diverges) - #159402 (Clarify safety requirements for SIMD shl/shr and masked load/store) - #159410 (rustdoc: remove old `--emit` types) - #159302 (Implement `Debug` helpers via `Cell`) - #159386 (add a fallback for `fmuladdf*`) - #159391 (Update tests for LLVM 23) - #159400 (Update books) - #159401 (Gate `tests/debuginfo/function-call.rs` on min GDB 15.1) - #159404 ([aarch64][win] Pass oversized c-variadic args indirectly on Arm64EC)
…hanna-kruppe Implement `Debug` helpers via `Cell` Related to rust-lang#149745, but does not fix it (yet). Following @jmillikin's [suggestion](rust-lang#159302 (comment)), the builder logic now lives in the pre-existing non-generic methods taking `&dyn fmt::Debug` (where it used to exist), and each `*_with` method wraps its closure in a private `DebugOnce` struct that implements `Debug` by calling the closure, so the body is compiled once. Just for context: A `dyn FnOnce` [can't be called behind a reference](rust-lang#149745 (comment)), hence the `Cell<Option<..>>` stuff in `DebugOnce`. ###### repro.rs ```rust #![feature(debug_closure_helpers)] #![crate_type = "lib"] use core::fmt; pub struct Point { pub x: u32, pub y: u32, } impl fmt::Debug for Point { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Point") .field_with("x", |f| self.x.fmt(f)) .field_with("y", |f| self.y.fmt(f)) .finish() } } ``` ```bash rustc +nightly --edition=2024 --emit=llvm-ir -Copt-level=0 -o before.ll repro.rs rustc +stage1 --edition=2024 --emit=llvm-ir -Copt-level=0 -o after.ll repro.rs ``` On the repro above, I saw the LLVM IR drop from 739 to 268 lines (an earlier version of this PR using `&mut dyn FnMut` measured 372). Since the stable `&dyn fmt::Debug` methods no longer go through any closure indirection, this should also avoid the potential runtime regression in the `derive(Debug)` microbenchmark. This was the only remaining [blocker](rust-lang#117729 (comment)) for stabilizing `debug_closure_helpers`, so it should unblock rust-lang#146099.
…uwer Rollup of 10 pull requests Successful merges: - #159365 (fix: point at method call chain when a return-position `impl Trait` assoc type diverges) - #159402 (Clarify safety requirements for SIMD shl/shr and masked load/store) - #159410 (rustdoc: remove old `--emit` types) - #159302 (Implement `Debug` helpers via `Cell`) - #159386 (add a fallback for `fmuladdf*`) - #159391 (Update tests for LLVM 23) - #159400 (Update books) - #159401 (Gate `tests/debuginfo/function-call.rs` on min GDB 15.1) - #159404 ([aarch64][win] Pass oversized c-variadic args indirectly on Arm64EC) - #159405 (Manually implement Clone for GrowableBitSet)
…hanna-kruppe Implement `Debug` helpers via `Cell` Related to rust-lang#149745, but does not fix it (yet). Following @jmillikin's [suggestion](rust-lang#159302 (comment)), the builder logic now lives in the pre-existing non-generic methods taking `&dyn fmt::Debug` (where it used to exist), and each `*_with` method wraps its closure in a private `DebugOnce` struct that implements `Debug` by calling the closure, so the body is compiled once. Just for context: A `dyn FnOnce` [can't be called behind a reference](rust-lang#149745 (comment)), hence the `Cell<Option<..>>` stuff in `DebugOnce`. ###### repro.rs ```rust #![feature(debug_closure_helpers)] #![crate_type = "lib"] use core::fmt; pub struct Point { pub x: u32, pub y: u32, } impl fmt::Debug for Point { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Point") .field_with("x", |f| self.x.fmt(f)) .field_with("y", |f| self.y.fmt(f)) .finish() } } ``` ```bash rustc +nightly --edition=2024 --emit=llvm-ir -Copt-level=0 -o before.ll repro.rs rustc +stage1 --edition=2024 --emit=llvm-ir -Copt-level=0 -o after.ll repro.rs ``` On the repro above, I saw the LLVM IR drop from 739 to 268 lines (an earlier version of this PR using `&mut dyn FnMut` measured 372). Since the stable `&dyn fmt::Debug` methods no longer go through any closure indirection, this should also avoid the potential runtime regression in the `derive(Debug)` microbenchmark. This was the only remaining [blocker](rust-lang#117729 (comment)) for stabilizing `debug_closure_helpers`, so it should unblock rust-lang#146099.
…uwer Rollup of 16 pull requests Successful merges: - #150732 (Convert `-Ctarget-cpu` into a target-modifier for AVR, AMDGCN and NVPTX ) - #159301 (Update Enzyme to handle LLVM23) - #159365 (fix: point at method call chain when a return-position `impl Trait` assoc type diverges) - #159402 (Clarify safety requirements for SIMD shl/shr and masked load/store) - #159410 (rustdoc: remove old `--emit` types) - #158398 (Comment about empty run_passes, fixup of #158040) - #158843 (Fix ICE in `write_interface` when the interface file can't be written) - #159302 (Implement `Debug` helpers via `Cell`) - #159332 (Honor field-level lint attributes in non_snake_case) - #159386 (add a fallback for `fmuladdf*`) - #159391 (Update tests for LLVM 23) - #159400 (Update books) - #159401 (Gate `tests/debuginfo/function-call.rs` on min GDB 15.1) - #159404 ([aarch64][win] Pass oversized c-variadic args indirectly on Arm64EC) - #159405 (Manually implement Clone for GrowableBitSet) - #159415 (rustdoc: rename the doc parts metadata params)
…uwer Rollup of 17 pull requests Successful merges: - #159301 (Update Enzyme to handle LLVM23) - #159365 (fix: point at method call chain when a return-position `impl Trait` assoc type diverges) - #159402 (Clarify safety requirements for SIMD shl/shr and masked load/store) - #159408 (rustc_data_structures: Expand documentation for rustc jobserver APIs) - #159410 (rustdoc: remove old `--emit` types) - #158398 (Comment about empty run_passes, fixup of #158040) - #158843 (Fix ICE in `write_interface` when the interface file can't be written) - #159302 (Implement `Debug` helpers via `Cell`) - #159332 (Honor field-level lint attributes in non_snake_case) - #159340 (Rename `errors.rs` file to `diagnostics.rs` (14/N)) - #159386 (add a fallback for `fmuladdf*`) - #159391 (Update tests for LLVM 23) - #159400 (Update books) - #159401 (Gate `tests/debuginfo/function-call.rs` on min GDB 15.1) - #159404 ([aarch64][win] Pass oversized c-variadic args indirectly on Arm64EC) - #159405 (Manually implement Clone for GrowableBitSet) - #159415 (rustdoc: rename the doc parts metadata params)
Uh oh!
There was an error while loading. Please reload this page.
Rollup merge of #159302 - connortsui20:dyn-debug-helpers, r=hanna-kruppe Implement `Debug` helpers via `Cell` Related to #149745, but does not fix it (yet). Following @jmillikin's [suggestion](#159302 (comment)), the builder logic now lives in the pre-existing non-generic methods taking `&dyn fmt::Debug` (where it used to exist), and each `*_with` method wraps its closure in a private `DebugOnce` struct that implements `Debug` by calling the closure, so the body is compiled once. Just for context: A `dyn FnOnce` [can't be called behind a reference](#149745 (comment)), hence the `Cell<Option<..>>` stuff in `DebugOnce`. ###### repro.rs ```rust #![feature(debug_closure_helpers)] #![crate_type = "lib"] use core::fmt; pub struct Point { pub x: u32, pub y: u32, } impl fmt::Debug for Point { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Point") .field_with("x", |f| self.x.fmt(f)) .field_with("y", |f| self.y.fmt(f)) .finish() } } ``` ```bash rustc +nightly --edition=2024 --emit=llvm-ir -Copt-level=0 -o before.ll repro.rs rustc +stage1 --edition=2024 --emit=llvm-ir -Copt-level=0 -o after.ll repro.rs ``` On the repro above, I saw the LLVM IR drop from 739 to 268 lines (an earlier version of this PR using `&mut dyn FnMut` measured 372). Since the stable `&dyn fmt::Debug` methods no longer go through any closure indirection, this should also avoid the potential runtime regression in the `derive(Debug)` microbenchmark. This was the only remaining [blocker](#117729 (comment)) for stabilizing `debug_closure_helpers`, so it should unblock #146099.
…uwer Rollup of 17 pull requests Successful merges: - rust-lang/rust#159301 (Update Enzyme to handle LLVM23) - rust-lang/rust#159365 (fix: point at method call chain when a return-position `impl Trait` assoc type diverges) - rust-lang/rust#159402 (Clarify safety requirements for SIMD shl/shr and masked load/store) - rust-lang/rust#159408 (rustc_data_structures: Expand documentation for rustc jobserver APIs) - rust-lang/rust#159410 (rustdoc: remove old `--emit` types) - rust-lang/rust#158398 (Comment about empty run_passes, fixup of rust-lang/rust#158040) - rust-lang/rust#158843 (Fix ICE in `write_interface` when the interface file can't be written) - rust-lang/rust#159302 (Implement `Debug` helpers via `Cell`) - rust-lang/rust#159332 (Honor field-level lint attributes in non_snake_case) - rust-lang/rust#159340 (Rename `errors.rs` file to `diagnostics.rs` (14/N)) - rust-lang/rust#159386 (add a fallback for `fmuladdf*`) - rust-lang/rust#159391 (Update tests for LLVM 23) - rust-lang/rust#159400 (Update books) - rust-lang/rust#159401 (Gate `tests/debuginfo/function-call.rs` on min GDB 15.1) - rust-lang/rust#159404 ([aarch64][win] Pass oversized c-variadic args indirectly on Arm64EC) - rust-lang/rust#159405 (Manually implement Clone for GrowableBitSet) - rust-lang/rust#159415 (rustdoc: rename the doc parts metadata params)
View all comments
Related to #149745, but does not fix it (yet).
Following @jmillikin's suggestion, the builder logic now lives in the pre-existing non-generic methods taking
&dyn fmt::Debug(where it used to exist), and each*_withmethod wraps its closure in a privateDebugOncestruct that implementsDebugby calling the closure, so the body is compiled once.Just for context: A
dyn FnOncecan't be called behind a reference, hence theCell<Option<..>>stuff inDebugOnce.repro.rs
On the repro above, I saw the LLVM IR drop from 739 to 268 lines (an earlier version of this PR using
&mut dyn FnMutmeasured 372). Since the stable&dyn fmt::Debugmethods no longer go through any closure indirection, this should also avoid the potential runtime regression in thederive(Debug)microbenchmark.This was the only remaining blocker for stabilizing
debug_closure_helpers, so it should unblock #146099.