And with Rational.val requiring atomic access, we can only flatten it if the underlying HW supports it (in this case, 2 ints fits nicely in 64bits so we're good). Larger .val's can only be flattened if marked as "non-atomic" (the B3n case). And because there's no tearing, handing out the flattened Rational.val[] is safe. Do I have that right?
Correct. If Rational were non-atomic, the values could tear, but the array would still be null/init-safe.
I'd add there is one more thing going on that makes handing out the Rational.val[] as a Rational; the user can't put zeroes in it, because they can't construct the zero. (And they can't put nulls in it, because the array store check will prevent that.)