Code change:
throw_ub_custom!(fluent::const_eval_copy_nonoverlapping_overlapping); } } <ins> } </ins> <del> for i in 0..num_copies { ptr::copy( src_bytes, dest_bytes.add((size * i).bytes_usize()), // `Size` multiplication size.bytes_usize(), ); </del> <ins> let size_in_bytes = size.bytes_usize(); // For particularly large arrays (where this is perf-sensitive) it's common that // we're writing a single byte repeatedly. So, optimize that case to a memset. if size_in_bytes == 1 && num_copies >= 1 { // SAFETY: `src_bytes` would be read from anyway by copies below (num_copies >= 1). // Since size_in_bytes = 1, then the `init.no_bytes_init()` check above guarantees // that this read at type `u8` is OK -- it must be an initialized byte. let value = *src_bytes; dest_bytes.write_bytes(value, (size * num_copies).bytes_usize()); } else if src_alloc_id == dest_alloc_id { let mut dest_ptr = dest_bytes; for _ in 0..num_copies { ptr::copy(src_bytes, dest_ptr, size_in_bytes); dest_ptr = dest_ptr.add(size_in_bytes); </ins> } } else { <del> for i in 0..num_copies { ptr::copy_nonoverlapping( src_bytes, dest_bytes.add((size * i).bytes_usize()), // `Size` multiplication size.bytes_usize(), ); </del> <ins> let mut dest_ptr = dest_bytes; for _ in 0..num_copies { ptr::copy_nonoverlapping(src_bytes, dest_ptr, size_in_bytes); dest_ptr = dest_ptr.add(size_in_bytes); </ins> } } }

Related discussion:
text: This program takes an inordinate amount of time and memory to compile (it's worse if the array is actually used, but this is a minimal test case): const SIZE: usize = 1 << 30; static SLICE: [u8; SIZE] = [0u8; SIZE]; fn main() {} I was hoping this would be a viable way to get a big chunk of so I don't have to depend on an crate to get a lot of static zeroes, but the effect on compile time makes that impractical. If I run , the big offender is: Although the time (and memory) is reportedly spent checking lints, setting doesn't make any difference. I'm guessing the "lint checking" pass includes some things that need to be checked even if lints are suppressed? If not, it seems like a separate issue is that a lot of work could be saved with cap-lints set (e.g. when compiling dependencies). Here are the top results from , for : So it looks like miri is actually creating the array and folding over it. I know it's not going to find any problems, because I have ECC memory :laughing:. There are already some bugs relating to slow compilation of large arrays, with the most relevant I could find being , . I think this is separate from those cases because: the input in this case is a [0; _] array, whereas the others initialize arrays from sequences of elements those cases seem to refer to superlinear runtime; this issue appears roughly linear in time and space and only becomes noticeable for much larger arrays the bottleneck in this case occurs during lint checking, which I didn't see in any other array performance bugs
Have you seen any improvement after ?
I've wondered before whether we should special-case constants whose bits are all defined and zero. I'll open a discussion in the const-eval zulip channel.
I also ran into this problem. has that discussion happened?
Kind of. We will have special treatment for constants that consist solely of undef bytes (see ). This scheme can likely be extended to support all bytes being zero withour requiring time or space overhead.
I opened for this.
was closed, are there still plans to implement this?
Not right now... there are other more important construction sites in const eval.