makepad/libs/relax/compiler/tests/copy_sizes.rs
Admin ad03c2f488 makepad run / Relax: library stability, attribute shapes, more lints, x64 TLS fix
- stability: unstable std/core/alloc items need their feature (E0658) on every
  path, from a table generated from rustc's library sources (std/gen_stability.py)
- attributes: malformed `inline`/`must_use`/`deprecated`/`link*` (E0539/E0805/
  E0565) and other attribute-shape checks; `main` entry checks
- typeck: ManuallyDrop is a transparent lang-item struct (dyn unsizing through
  it works); invalid assignment targets (E0070/E0067); wide_pointer_comparisons
- consts: generic param order/defaults, const param types, E0572, cycles; NaN
  and non-structural constants in patterns; E0491/E0478 well-formedness
- parser: cfg paren-expr meta, `$t:ty` not a bound, items in impl/trait bodies
- lints: unused_imports from recorded import use; unused_mut through closures,
  non_shorthand_field_patterns, drop_bounds, dyn_drop and more
- codegen: x64 domain-base TLS read no longer skips its block (segfault fixed);
  arm64 constant-size copies of 32 B+ as 16-byte vector pairs
- rustc tests/ui agreement ~93.4%

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 23:20:42 +02:00

50 lines
1.6 KiB
Rust

// constant-size aggregate moves of every size from 1 to 300 bytes (the backends' memcpy
// expansions: scalar tails, 16-byte vector pairs, the overlapping vector tail, the loop above
// 256 bytes) copy exactly their bytes: the bytes after and before the copy stay as they were
use std::hint::black_box;
#[derive(Clone, Copy)]
struct Blob<const N: usize>([u8; N]);
fn fill<const N: usize>(seed: u8) -> Blob<N> {
let mut b = [0u8; N];
for i in 0..N {
b[i] = seed.wrapping_mul(31).wrapping_add(i as u8).wrapping_add(1);
}
Blob(b)
}
#[inline(never)]
fn moved<const N: usize>(src: &Blob<N>) -> Blob<N> {
let t = *src;
let u = t;
black_box(&u);
u
}
fn check<const N: usize>() {
let a: Blob<N> = fill(N as u8);
let b = moved(&a);
assert!(a.0 == b.0, "copy of {} bytes", N);
// a copy into the middle of a buffer leaves its neighbours alone
let mut buf = [0xA5u8; 400];
let at = 17;
unsafe { std::ptr::write(buf.as_mut_ptr().add(at) as *mut Blob<N>, black_box(a)) };
for i in 0..400 {
let want = if i >= at && i < at + N { a.0[i - at] } else { 0xA5 };
assert_eq!(buf[i], want, "size {} byte {}", N, i);
}
}
macro_rules! sizes { ($($n:literal)*) => { $( check::<$n>(); )* } }
#[test]
fn copies_of_every_small_size() {
sizes!(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64);
}
#[test]
fn copies_of_larger_sizes() {
sizes!(65 80 96 100 112 127 128 129 144 160 161 168 192 200 224 240 255 256 257 272 288 300);
}