Consider the following code:
byte b = byte.min;
int x = -b;
writeln(x);
Currently (without the -transition=intpromote switch), this prints -128.
With the switch, it prints 128.
This is the fix implemented by the new promotion rules, and it makes sense that the negation of -128 should be an int of 128.
Thus, the compiler complains:
Deprecation: integral promotion not done for -b, use '-transition=intpromote' switch or -cast(int)(b)
But, what about this code?
b = cast(byte)-b;
writeln(b);
This prints -128 with or without the intpromote switch. That is, there is no difference depending on whether you are int-promoting first or not.
However, the compiler still emits the warning without the switch. If you do:
b = cast(byte)-cast(int)b;
It works with and without the switch, but this is busywork the user shouldn't have to do. Obviously casting to int isn't going to make a difference.
This is really going to suck when this code becomes an error and not a deprecation warning.
The compiler should delay printing the deprecation until it knows the expression is not cast to the original type that was promoted or smaller.
This fix should go along with a change to the message that says:
"... or -cast(int)b or cast the result to the original type or smaller"
That's a mouthful, but maybe someone can come up with something better.
Comment #1 by hsteoh — 2018-02-20T23:26:48Z
+1000! Having to write monstrosities like `b = cast(ubyte) -cast(int) b;` is the one thing that ticked me off enough to start a forum discussion about it.
In any case, I've written an infectious wrapper type along the lines suggested by Luis Marques (IIRC) that hides away this insane cast-o-mania, so I could just write `b = -b.np` (np stands for No Promote[1], ie., it just truncates) and it will Just Work(tm) without insanity-inducing nested casts.
[1] np can also stand for "no problem", as in, I don't have to care about squint-inducing casts anymore. :-D
Comment #2 by robert.schadek — 2024-12-13T18:56:46Z