Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infer destination type of cast builtins using result type #16163

Merged
merged 7 commits into from
Jun 24, 2023

Conversation

mlugg
Copy link
Member

@mlugg mlugg commented Jun 23, 2023

This PR implements #5909. Affected builtins:

  • @addrSpaceCast
  • @alignCast
  • @bitCast
  • @errSetCast
  • @floatCast
  • @intFromFloat
  • @intCast
  • @enumFromInt
  • @floatFromInt
  • @ptrFromInt
  • @ptrCast
  • @truncate

The language changes here are mostly explained in that issue, but there's one slightly subtle thing: pointer casts. It's common to nest different kinds of pointer cast, e.g. @alignCast(a, @ptrCast(T, ptr)). The problem is, if we naively implemented these casts, such usages would become much more convoluted; e.g. @alignCast(@as(*align(1)T, @ptrCast(T))). The solution @andrewrk and I agreed upon is that chained pointer cast builtins are a special case. Any sequence of the following builtins...

  • @ptrCast
  • @alignCast
  • @addrSpaceCast
  • @constCast
  • @volatileCast

... is special-cased to act as a single operation with a single result type. This allows you to just write e.g. @alignCast(@ptrCast(ptr)); similarly, you can cast every pointer property using @ptrCast(@alignCast(@addrSpaceCast(@constCast(@volatileCast(ptr))))) (please don't though, that's awful). Note that the order of these operations doesn't matter; you can reorder them and will get the same ZIR.

This PR introduces zig fmt fixups for most of the builtins changed. Exceptions include:

  • @alignCast cannot be automatically fixed, as the old usage doesn't mention the pointer type.
  • @addrSpaceCast cannot be automatically fixed for the same reason.
  • @truncate had a slightly odd usage which means its fixup is incorrect for vector operands. This incorrect fix will never cause a silent bug; always a compile error.

@mlugg mlugg requested a review from kristoff-it as a code owner June 23, 2023 18:56
@mlugg mlugg force-pushed the feat/builtins-infer-dest-ty branch from 90d3031 to f48e291 Compare June 23, 2023 19:12
@Snektron
Copy link
Collaborator

If this is just going to replace @thing with @as(@thing( everywhere then im not sure that it improves anything.

Sorry to be so pessimistic about this change lol

@ghost
Copy link

ghost commented Jun 23, 2023

The original idea behind the proposal was sound, but browsing through the actual changeset, this feels like a net negative for readability.

Edit: Looks like @Snektron beat me to it 😄

@mlugg
Copy link
Member Author

mlugg commented Jun 23, 2023

These changes are simple auto-formats, which use @as indiscriminately to ensure correctness. In all code I manually migrated, readability was equivalent or improved. Here are a couple of examples:

// old:
const hdr = @ptrCast(
    *const macho.mach_header_64,
    @alignCast(@alignOf(macho.mach_header_64), mapped_mem.ptr),
);
// new:
const hdr: *const macho.mach_header_64 = @ptrCast(@alignCast(mapped_mem.ptr);

// old:
const self = @ptrCast(*Self, @alignCast(@alignOf(Self), ctx));
// new:
const self: *Self = @ptrCast(@alignCast(ctx));

// old:
var test_ptr = @ptrFromInt(*allowzero addrspace(.fs) u64, 0);
// new: (no shorter, but more readable, which is a very common case)
var test_ptr: *allowzero addrspace(.fs) u64 = @ptrFromInt(0);

The vast majority of use cases of @as in the auto-formatted code are redundant; result type inference works pretty well. Any of these builtins in a function parameter, struct or array init, const or var init with a type annotation, etc, will all be able to infer their result type no problem.

@mlugg mlugg force-pushed the feat/builtins-infer-dest-ty branch from f48e291 to 4baf4f3 Compare June 23, 2023 19:34
@Snektron
Copy link
Collaborator

The vast majority of use cases of @as in the auto-formatted code are redundant

Sure. As it stands, though...

@mlugg
Copy link
Member Author

mlugg commented Jun 23, 2023

A language change having an ugly auto-format doesn't really matter; the alternative is there being no auto-fixup and the only migration path being a manual rewrite. Someone could easily go through std (etc) and start manually tweaking these calls to use the new syntax more cleanly; ugly code is temporary, a better language is forever. I personally didn't fancy making the 9000 lines of changes manually - you're welcome to work on cleaning them up if it's going to be an issue for you, but I don't really see how it would be. The language change itself, when correctly applied, results in nicer code, almost across the board.

@mlugg mlugg force-pushed the feat/builtins-infer-dest-ty branch from 4baf4f3 to 9fe695a Compare June 23, 2023 21:11
@MasonRemaley
Copy link
Contributor

This PR solves a major problem in the ZON parser I'm working on.

ZON currently cannot support non-exhaustive enums since ZON literals are untyped but non-exhaustive enums cannot be instantiated without passing destination type to @enumToInt in the case where the value has no tag.

If @intToEnum instead infers the destination type as it does in this PR, this becomes a non-issue.

@mlugg mlugg force-pushed the feat/builtins-infer-dest-ty branch from 9fe695a to 1bc12cb Compare June 23, 2023 22:59
@andrewrk
Copy link
Member

Note that for some reason CI checks don't run if there are any merge conflicts.

@mlugg mlugg force-pushed the feat/builtins-infer-dest-ty branch 7 times, most recently from 9699438 to cb1b3a4 Compare June 24, 2023 16:03
Copy link
Member

@andrewrk andrewrk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! I'm recompiling zig1.wasm right now and will merge shortly.

Most of this migration was performed automatically with `zig fmt`. There
were a few exceptions which I had to manually fix:

* `@alignCast` and `@addrSpaceCast` cannot be automatically rewritten
* `@truncate`'s fixup is incorrect for vectors
* Test cases are not formatted, and their error locations change
CBE was translating to access the `len` field rather than `ptr`.
Air.zig specifies that this operation is valid on a slice.
Needed due to the breaking changes to casting builtins, which are used
by the compiler when building itself.

Note from Andrew: I re-ran update-zig1 on my PC and replaced this
commit.

Signed-off-by: Andrew Kelley <andrew@ziglang.org>
@andrewrk andrewrk force-pushed the feat/builtins-infer-dest-ty branch from cb1b3a4 to 21ac0be Compare June 24, 2023 23:57
@andrewrk andrewrk merged commit 146b79a into ziglang:master Jun 24, 2023
linusg added a commit to linusg/zig-args that referenced this pull request Jun 27, 2023
linusg added a commit to linusg/zig-libgc that referenced this pull request Jun 27, 2023
razcore-rad added a commit to razcore-rad/mach that referenced this pull request Jun 27, 2023
This [Zig PR](ziglang/zig#16163) changes
the way casts work in Zig.

This mach-glfw PR updates the code using the new syntax.

For more details about this change in Zig check out [the official wiki](https://github.com/ziglang/zig/wiki/Using-Cast-Result-Type-Inference).
robbielyman added a commit to robbielyman/seamstress that referenced this pull request Jun 27, 2023
joachimschmidt557 pushed a commit to joachimschmidt557/linenoize that referenced this pull request Jun 27, 2023
* Update renamed builtins

See: ziglang/zig#16046

* Update builtins to infer target type

See: ziglang/zig#16163
joachimschmidt557 pushed a commit to ziglibs/ansi-term that referenced this pull request Jun 27, 2023
* `@enumToInt` => `@intFromEnum`

The `@enumToInt` built-in was just renamed to `@intFromEnum`.

ref: ziglang/zig@a6c8ee5

* `@bitCast` no longer needs the type parameter

`@bitCast` and other casts no longer need
the destination type as an argument.

ref: ziglang/zig#16163
robbielyman added a commit to robbielyman/seamstress that referenced this pull request Jun 27, 2023
* fix: for zig-0.11.0+3859, `@Cast` directives take one argument

follows Zig's merging of [ziglang/zig#16163]

* feat: rework `screen.lua` to incorporate "move"
jiacai2050 added a commit to jiacai2050/simargs that referenced this pull request Jun 28, 2023
ikskuh pushed a commit to ikskuh/zig-args that referenced this pull request Jun 28, 2023
robbielyman added a commit to robbielyman/seamstress that referenced this pull request Jul 3, 2023
* fix: for zig-0.11.0+3859, `@Cast` directives take one argument

follows Zig's merging of [ziglang/zig#16163]

* feat: rework `screen.lua` to incorporate "move"
Spadi0 added a commit to Spadi0/zig-toml that referenced this pull request Jul 3, 2023
The relevant changes are in these two PRs: ziglang/zig#16046 and
ziglang/zig#16163. They change the cast builtins to infer the result
type and change the order of the conversion builtins to `@xFromY`
instead of `@yToX`.
ikskuh pushed a commit to ikskuh/zig-opengl that referenced this pull request Jul 20, 2023
@ifreund ifreund mentioned this pull request Jul 21, 2023
@iacore
Copy link
Contributor

iacore commented Aug 25, 2023

I think in some cases, @alignCast can be somewhat fixed by simple removing the first argument.

I'm updating https://github.com/greenfork/jzignet, and most of the usage there can be automatically fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants