@@ -3474,44 +3474,13 @@ impl<T> [T] {
34743474 // Ts = size_of::<U> / gcd(size_of::<T>, size_of::<U>)
34753475 //
34763476 // Luckily since all this is constant-evaluated... performance here matters not!
3477- #[ inline]
3478- fn gcd ( a : usize , b : usize ) -> usize {
3479- use crate :: intrinsics;
3480- // iterative stein’s algorithm
3481- // We should still make this `const fn` (and revert to recursive algorithm if we do)
3482- // because relying on llvm to consteval all this is… well, it makes me uncomfortable.
3483-
3484- // SAFETY: `a` and `b` are checked to be non-zero values.
3485- let ( ctz_a, mut ctz_b) = unsafe {
3486- if a == 0 {
3487- return b;
3488- }
3489- if b == 0 {
3490- return a;
3491- }
3492- ( intrinsics:: cttz_nonzero ( a) , intrinsics:: cttz_nonzero ( b) )
3493- } ;
3494- let k = ctz_a. min ( ctz_b) ;
3495- let mut a = a >> ctz_a;
3496- let mut b = b;
3497- loop {
3498- // remove all factors of 2 from b
3499- b >>= ctz_b;
3500- if a > b {
3501- mem:: swap ( & mut a, & mut b) ;
3502- }
3503- b = b - a;
3504- // SAFETY: `b` is checked to be non-zero.
3505- unsafe {
3506- if b == 0 {
3507- break ;
3508- }
3509- ctz_b = intrinsics:: cttz_nonzero ( b) ;
3510- }
3511- }
3512- a << k
3477+ const fn gcd ( a : usize , b : usize ) -> usize {
3478+ if b == 0 { a } else { gcd ( b, a % b) }
35133479 }
3514- let gcd: usize = gcd ( mem:: size_of :: < T > ( ) , mem:: size_of :: < U > ( ) ) ;
3480+
3481+ // Explicitly wrap the function call in a const block so it gets
3482+ // constant-evaluated even in debug mode.
3483+ let gcd: usize = const { gcd ( mem:: size_of :: < T > ( ) , mem:: size_of :: < U > ( ) ) } ;
35153484 let ts: usize = mem:: size_of :: < U > ( ) / gcd;
35163485 let us: usize = mem:: size_of :: < T > ( ) / gcd;
35173486
0 commit comments