Major zig language update just landed: removal of destination type from all cast builtins

Thanks to to @mlugg for implementing this accepted proposal.

He also took the time to write a corresponding upgrade guide in the wiki: Using Cast Result Type Inference

In short summary:

-return @intCast(u32, foo);
+return @intCast(foo);

This prevents bugs from occurring from changing the type in one place (the return type in this example), but not the other. If you need the previous semantics, you can get them with @as:

-return @intCast(u32, foo);
+return @as(u32, @intCast(foo));

For anyone who hasn’t checked out the material in the wiki who is wondering how this works, (and for my own understanding) – tldr…

From the wiki:

All of these builtins used to take two parameters; now, they only take one (the value to cast). The type to cast to is inferred based on the expression’s result type .

 // old version, y will be deduced as u8
const y = @intCast(u8, x);

// new version, y will be declared and the cast will be deduced
const y: u8 = @intCast(x);

This is only one application - there are a number of built-ins that are effected by this change. There is also some important stuff about pointer casting rules. It’s enough of a difference that I suggest you check it out - it’s worth reading.

At first glance I thought “this doesn’t line-up with the ‘always be explicit’ nature of Zig.” I mean, the old way showed you explicitly right there at the use site what the result type would be. But after reading the full explanation and seeing how it can eliminate bugs related to updating result types in various places, I totally get it. And as the wiki article says, now these built-ins serve more like markers in the code to signal “hey, a cast is allowed and gonna happen here.”

Yeah, I think the main intent is to just remove a degree of freedom that is uncessary and can even cause issues with activities like aggressive refactoring. It took me a minute to think it through, but if it’s well implemented, then I really like it actually.

I like this change.

I am however curious about how this will affect nested casts.

@intCast(@floatCast(x) * y));

I assume x will be cast to the type of y? And what about

@intCast(@floatCast(x) * @floatCast(y));

right now arithmetical expressions are not handled at all so it will just tell you that it needs a target type

Love this change, really excited for it! Casting of numeric types was always one of my biggest issues with Zig. It was so much typing and made the code in my opinion really hard to read.

Does anyone know when this will fully be implemented? I wonder if it makes more sense to update my Zig now or in a few days.

1 Like

It has already landed in master branch, will be part of the upcoming 0.11.0 release, and is already available in the master branch builds on the download page.