Open
Description
The following talks about Debug::fmt
, but is likely true of a lot more methods applied to arrays.
Take the following code:
fn main() {
let a = [1, 2, 3];
let b = [1, 2, 3, 4];
let c = [1, 2, 3, 4, 5];
let d = [1, 2, 3, 4, 5, 6];
println!("{:?}", a);
println!("{:?}", b);
println!("{:?}", c);
println!("{:?}", d);
}
Compiled with --release, you end up with 4 different functions for core::array::<impl core::fmt::Debug for [T; N]>::fmt
(BTW, shouldn't they each have their N replaced by the actual number?). To add insult to injury, each of these have their loops unrolled, so the longer the array, the larger the function, up to 59 (!).
Almost ironically, building with -C opt-level=1
generates 4 functions that create a slice and a separate, common, fmt
function for it.
This is one of these cases where you'd probably want a #[inline(never)]
at the call site in core::array::<impl core::fmt::Debug for [T; N]>::fmt
if that were possible.
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
cuviper commentedon Oct 9, 2020
We could insert a shim
#[inline(never)]
function to call the sliceDebug::fmt
.For other traits, I'd worry about hurting bounds-checking and vectorization if we add artificial barriers.
scottmcm commentedon Oct 11, 2020
Given that these things are already implemented by calling the slice versions, I don't know that there's actually anything array-specific here. This is just the inliner doing what it's told to do. The same thing will plausibly happen with
impl AsRef<Path>
methods with outlined bodies too in-O3
.Given that
-O1
is doing the right thing here, I suspect-Os
is too, which is the particularly-important part IMHO.Even for debug it's not obvious to me that
inline(never)
is desirable here. I could easily imagine someone expecting monomorphization of something like<[u32; 4]>::debug
because there's no other way to stringify such an array instd
.Note that neither the array nor slice implementations of
Debug
are currently even marked#[inline]
:rust/library/core/src/array/mod.rs
Lines 184 to 189 in 9a8ca69
rust/library/core/src/fmt/mod.rs
Lines 2166 to 2171 in 9a8ca69
so this is all LLVM's inlining heuristic deciding that this is a good bet with no extra encouragement.
Were you seeing a regression here? I suppose that this could have changed last summer when we started using const generics for them, or if one of the LLVM upgrades changed the inlining heuristics...
mint
equivalents imgui-rs/imgui-rs#536