https://ziglang.org/download/0.14.0/release-notes.html
Roc gets a mention in the LLVM Builder API https://ziglang.org/download/0.14.0/release-notes.html#LLVM-Builder-API
Big thanks to the Zig team for this :heart_eyes:
I started looking at zig 0.14.0. Looks like it should mostly be a minor update. Here is the starter list of minor complaints. I think a number of the issues can be fixed on main before even updating to 0.14.0. For example, all of the naming conflicts:
src/base.zig:40:5: error: duplicate union member name 'Int'
Int: Int,
^~~
src/base.zig:48:15: note: duplicate name here
pub const Int = union(enum) {
^~~
src/base.zig:39:21: note: union declared here
pub const Literal = union(enum) {
^~~~~
src/base.zig:41:5: error: duplicate union member name 'Float'
Float: Float,
^~~~~
src/base.zig:62:15: note: duplicate name here
pub const Float = union(enum) {
^~~~~
src/base.zig:39:21: note: union declared here
pub const Literal = union(enum) {
^~~~~
src/types.zig:10:5: error: duplicate union member name 'Int'
Int: Int,
^~~
src/types.zig:17:15: note: duplicate name here
pub const Int = enum {
^~~
src/types.zig:9:23: note: union declared here
pub const Primitive = union(enum) {
^~~~~
src/types.zig:11:5: error: duplicate union member name 'Float'
Float: Float,
^~~~~
src/types.zig:30:15: note: duplicate name here
pub const Float = enum {
^~~~~
src/types.zig:9:23: note: union declared here
pub const Primitive = union(enum) {
^~~~~
src/check/parse/IR.zig:1506:28: error: expected type 'check.parse.IR.NodeStore.TypeAnnoIdx', found 'check.parse.IR.NodeStore.getTypeAnno__struct_27714'
.ret = ret,
^~~
src/check/parse/IR.zig:1503:30: note: struct declared here
const ret = .{ .id = store.extra_data.items[@as(usize, @intCast(node.main_token))] };
~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/check/parse/IR.zig:536:29: note: struct declared here
pub const TypeAnnoIdx = struct { id: u32 };
^~~~~~~~~~~~~~~~~~
src/check/parse/Parser.zig:869:47: error: expected type 'check.parse.IR.NodeStore.Body', found 'check.parse.Parser.parseExprWithBp__struct_29141'
expr = self.store.addExpr(.{ .block = body });
~^~~~~~~~~~~~
src/check/parse/Parser.zig:865:31: note: struct declared here
const body = .{
~^
src/check/parse/IR.zig:1557:22: note: struct declared here
pub const Body = struct {
^~~~~~
src/check/parse/tokenize.zig:810:17: error: switch on type '?check.parse.tokenize.BraceKind'
switch (last) {
^~~~
src/snapshot.zig:9:16: error: root source file struct 'std' has no member named 'rand'
var prng = std.rand.DefaultPrng.init(1234567890);
^~~~
/Users/bren077s/vendor/zig-0.14.0/lib/std/std.zig:1:1: note: struct declared here
pub const ArrayHashMap = array_hash_map.ArrayHashMap;
Also, all deps except for zig-bootstrap (for building the new version of musl llvm) are updated. So I think we technically could update now given nothing actually depends on llvm yet.
zig-afl-kit 0.14.0: https://github.com/kristoff-it/zig-afl-kit/tree/zig-0.14.0
Started a draft PR, but am headed to sleep now. Anyone feel free to push fixes to: https://github.com/roc-lang/roc/pull/7679
I think for the first set of errors we just nesd to lowercase the struct field name
Hey @Andrew Kelley with the zig 0.14.0 update, is this the expected behaviour and resolution?
I think it is from Remove Anonymous Struct Types, Unify Tuples
Initial code:
const ret = .{ .id = store.extra_data.items[@as(usize, @intCast(node.main_token))] };
return .{ .@"fn" = .{
.region = emptyRegion(),
.ret = ret,
.args = .{ .span = .{
.start = node.data.lhs,
.len = node.data.rhs,
} },
} };
Error:
src/check/parse/IR.zig:1506:28: error: expected type 'check.parse.IR.NodeStore.TypeAnnoIdx', found 'check.parse.IR.NodeStore.getTypeAnno__struct_26120'
.ret = ret,
^~~
src/check/parse/IR.zig:1503:30: note: struct declared here
const ret = .{ .id = store.extra_data.items[@as(usize, @intCast(node.main_token))] };
~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/check/parse/IR.zig:536:29: note: struct declared here
pub const TypeAnnoIdx = struct { id: u32 };
Solution 1:
const ret = TypeAnnoIdx{ .id = store.extra_data.items[@as(usize, @intCast(node.main_token))] };
return .{ .@"fn" = .{
.region = emptyRegion(),
.ret = ret,
.args = .{ .span = .{
.start = node.data.lhs,
.len = node.data.rhs,
} },
} };
Solution 2:
return .{ .@"fn" = .{
.region = emptyRegion(),
.ret = .{ .id = store.extra_data.items[@as(usize, @intCast(node.main_token))] },
.args = .{ .span = .{
.start = node.data.lhs,
.len = node.data.rhs,
} },
} };
This feels like a regression in type inference. Though maybe this is expected with what is linked above (I'm not sure though). Feels odd that I can't pull a struct field into a separate constant without adding a type.
Thank you @Brendan Hansknecht for upgrading us. I just updated everything on my system to 14 and it was a smooth experience. :smiley:
It nice having essentially no deps
makes updates easy
Did they get rid of anonymous struct inference?
I've never had a problem with this code before:
check/parse/IR.zig:1223:24: error: expected type 'check.parse.IR.NodeStore.Statement', found 'check.parse.IR.NodeStore.getStatement__struct_11541'
return imp;
^~~
check/parse/IR.zig:1222:30: note: struct declared here
const imp = .{ .import = i };
~^~~~~~~~~~~~~~~
check/parse/IR.zig:1783:27: note: union declared here
pub const Statement = union(enum) {
^~~~~
check/parse/IR.zig:1184:69: note: function return type declared here
pub fn getStatement(store: *NodeStore, statement: StatementIdx) Statement {
I'm not fully sure, but it seems like it. I made a comment about it above. Feels like an accidental bug, but the release notes suggests that they may have made anonymous structs(not defined inline with use) into structural instead of nominal types.
This change reworks how anonymous struct literals and tuples work.
Previously, an untyped anonymous struct literal (e.g.
const x = .{ .a = 123 }
) was given an "anonymous struct type", which is a special kind of struct which coerces using structural equivalence. This mechanism was a holdover from before we used Result Location Semantics as the primary mechanism of type inference. This change changes the language so that the type assigned here is a "normal" struct type. It uses a form of equivalence based on the AST node and the type's structure, much like a reified (@Type) type.Additionally, tuples have been simplified. The distinction between "simple" and "complex" tuple types is eliminated. All tuples, even those explicitly declared using
struct { ... }
syntax, use structural equivalence, and do not undergo staged type resolution. Tuples are very restricted: they cannot have non-auto layouts, cannot have aligned fields, and cannot have default values with the exception of comptime fields. Tuples currently do not have optimized layout, but this can be changed in the future.This change simplifies the language, and fixes some problematic coercions through pointers which led to unintuitive behavior.
solution 2 looks good
So basically if a struct is anonymous and not assigned to a annotated var, it is giving its own type, so either create it at a usage site where it’s obvious what it’s meant to be? Otherwise you need to be explicit?
Last updated: Jul 06 2025 at 12:14 UTC