pub fn usual_arithmetic(
types: &mut Types,
left: TypeId,
right: TypeId,
target: &TargetInfo,
) -> Option<TypeId>Expand description
The usual arithmetic conversions, 6.3.1.8: the one type both operands are converted to.
None when either operand is not an arithmetic type, which is not a failure of this
function but the shape of a diagnostic its caller is about to write.
The floating rules come first and the integer rules only run when neither side is floating,
which is why unsigned long long + float is float and loses precision rather than being
the other way round.
The complexity comes off both operands first and goes back on at the end, which is 6.3.1.8p1
read literally: the rule is written over the corresponding real types and says the result is
complex when either operand was. Doing it that way is also what gives gcc’s answer for the
complex integer types, since _Complex int + long is the integer rule on int and long
with the complexity carried across, and none of the integer rules had to learn the word.
A half of a complex operand is not promoted, which is measured from gcc 16.2.0 rather than
read anywhere: _Complex char + _Complex char is a _Complex char where char + char is an
int. The promotions are written over the integer types and a complex one is not one of
them, so the operand that is not complex is promoted and the half is taken as it stands.
_Complex char + char is therefore a _Complex int, since the char beside it promotes and
the rule then picks the wider of the two.