Description
The code generated by #[derive(Debug)]
uses core::fmt::DebugStruct
and its siblings: DebugList
, DebugMap
, DebugSet
, and DebugTuple
. Internally, these types use &dyn fmt::Debug
, and it appears that in Rust userspace apps this defeats LLVM's devirtualization. This causes most or all of the Debug
implementations (including Debug
implementations for types from libcore) to be compiled in.
I ran some tests on a stripped-down libtock-rs that removes all of its #[derive(Debug)]
instances. In these tests, I manually derived Debug using the core::fmt::Debug* types as well as implemented it entirely manually. Here are the resulting sizes of .text (in bytes):
- DebugStruct: 15664
- DebugTuple: 15504
- DebugList: 15584
- DebugSet: 15584
- DebugMap: 16576
- Manual implementation (no Debug*): 504
Based on this test, I think it may be wise to avoid #[derive(Debug)]
in libtock-rs and instead derive Debug manually. I count 12 uses of #[derive(Debug)]
in libtock-rs so this seems reasonable.
Any comments before I make this change?