Commit 447ca4e3ff

mlugg <mlugg@mlugg.co.uk>
2023-06-22 23:40:13
translate-c: update to new cast builtin syntax
1 parent 283d650
Changed files (2)
src
src/translate_c/ast.zig
@@ -115,15 +115,10 @@ pub const Node = extern union {
 
         /// @import("std").zig.c_builtins.<name>
         import_c_builtin,
-        log2_int_type,
-        /// @import("std").math.Log2Int(operand)
-        std_math_Log2Int,
-        /// @intCast(lhs, rhs)
+        /// @intCast(operand)
         int_cast,
         /// @import("std").zig.c_translation.promoteIntLiteral(value, type, base)
         helpers_promoteIntLiteral,
-        /// @import("std").meta.alignment(value)
-        std_meta_alignment,
         /// @import("std").zig.c_translation.signedRemainder(lhs, rhs)
         signed_remainder,
         /// @divTrunc(lhs, rhs)
@@ -132,23 +127,23 @@ pub const Node = extern union {
         int_from_bool,
         /// @as(lhs, rhs)
         as,
-        /// @truncate(lhs, rhs)
+        /// @truncate(operand)
         truncate,
-        /// @bitCast(lhs, rhs)
+        /// @bitCast(operand)
         bit_cast,
-        /// @floatCast(lhs, rhs)
+        /// @floatCast(operand)
         float_cast,
-        /// @intFromFloat(lhs, rhs)
+        /// @intFromFloat(operand)
         int_from_float,
-        /// @floatFromInt(lhs, rhs)
+        /// @floatFromInt(operand)
         float_from_int,
-        /// @ptrFromInt(lhs, rhs)
+        /// @ptrFromInt(operand)
         ptr_from_int,
         /// @intFromPtr(operand)
         int_from_ptr,
-        /// @alignCast(lhs, rhs)
+        /// @alignCast(operand)
         align_cast,
-        /// @ptrCast(lhs, rhs)
+        /// @ptrCast(operand)
         ptr_cast,
         /// @divExact(lhs, rhs)
         div_exact,
@@ -254,7 +249,6 @@ pub const Node = extern union {
                 .@"comptime",
                 .@"defer",
                 .asm_simple,
-                .std_math_Log2Int,
                 .negate,
                 .negate_wrap,
                 .bit_not,
@@ -270,12 +264,20 @@ pub const Node = extern union {
                 .switch_else,
                 .block_single,
                 .helpers_sizeof,
-                .std_meta_alignment,
                 .int_from_bool,
                 .sizeof,
                 .alignof,
                 .typeof,
                 .typeinfo,
+                .align_cast,
+                .truncate,
+                .bit_cast,
+                .float_cast,
+                .int_from_float,
+                .float_from_int,
+                .ptr_from_int,
+                .ptr_cast,
+                .int_cast,
                 => Payload.UnOp,
 
                 .add,
@@ -314,24 +316,15 @@ pub const Node = extern union {
                 .bit_xor_assign,
                 .div_trunc,
                 .signed_remainder,
-                .int_cast,
                 .as,
-                .truncate,
-                .bit_cast,
-                .float_cast,
-                .int_from_float,
-                .float_from_int,
-                .ptr_from_int,
                 .array_cat,
                 .ellipsis3,
                 .assign,
-                .align_cast,
                 .array_access,
                 .std_mem_zeroinit,
                 .helpers_flexible_array_type,
                 .helpers_shuffle_vector_index,
                 .vector,
-                .ptr_cast,
                 .div_exact,
                 .offset_of,
                 .helpers_cast,
@@ -367,7 +360,6 @@ pub const Node = extern union {
                 .c_pointer, .single_pointer => Payload.Pointer,
                 .array_type, .null_sentinel_array_type => Payload.Array,
                 .arg_redecl, .alias, .fail_decl => Payload.ArgRedecl,
-                .log2_int_type => Payload.Log2IntType,
                 .var_simple, .pub_var_simple, .static_local_var, .mut_str => Payload.SimpleVarDecl,
                 .enum_constant => Payload.EnumConstant,
                 .array_filler => Payload.ArrayFiller,
@@ -644,11 +636,6 @@ pub const Payload = struct {
         },
     };
 
-    pub const Log2IntType = struct {
-        base: Payload,
-        data: std.math.Log2Int(u64),
-    };
-
     pub const SimpleVarDecl = struct {
         base: Payload,
         data: struct {
@@ -885,11 +872,6 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
             try c.buf.append('\n');
             return @as(NodeIndex, 0); // error: integer value 0 cannot be coerced to type 'std.mem.Allocator.Error!u32'
         },
-        .std_math_Log2Int => {
-            const payload = node.castTag(.std_math_Log2Int).?.data;
-            const import_node = try renderStdImport(c, &.{ "math", "Log2Int" });
-            return renderCall(c, import_node, &.{payload});
-        },
         .helpers_cast => {
             const payload = node.castTag(.helpers_cast).?.data;
             const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "cast" });
@@ -900,11 +882,6 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
             const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "promoteIntLiteral" });
             return renderCall(c, import_node, &.{ payload.type, payload.value, payload.base });
         },
-        .std_meta_alignment => {
-            const payload = node.castTag(.std_meta_alignment).?.data;
-            const import_node = try renderStdImport(c, &.{ "meta", "alignment" });
-            return renderCall(c, import_node, &.{payload});
-        },
         .helpers_sizeof => {
             const payload = node.castTag(.helpers_sizeof).?.data;
             const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "sizeof" });
@@ -1081,14 +1058,6 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
                 .data = undefined,
             });
         },
-        .log2_int_type => {
-            const payload = node.castTag(.log2_int_type).?.data;
-            return c.addNode(.{
-                .tag = .identifier,
-                .main_token = try c.addTokenFmt(.identifier, "u{d}", .{payload}),
-                .data = undefined,
-            });
-        },
         .identifier => {
             const payload = node.castTag(.identifier).?.data;
             return c.addNode(.{
@@ -1344,7 +1313,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
         },
         .int_cast => {
             const payload = node.castTag(.int_cast).?.data;
-            return renderBuiltinCall(c, "@intCast", &.{ payload.lhs, payload.rhs });
+            return renderBuiltinCall(c, "@intCast", &.{payload});
         },
         .signed_remainder => {
             const payload = node.castTag(.signed_remainder).?.data;
@@ -1365,27 +1334,27 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
         },
         .truncate => {
             const payload = node.castTag(.truncate).?.data;
-            return renderBuiltinCall(c, "@truncate", &.{ payload.lhs, payload.rhs });
+            return renderBuiltinCall(c, "@truncate", &.{payload});
         },
         .bit_cast => {
             const payload = node.castTag(.bit_cast).?.data;
-            return renderBuiltinCall(c, "@bitCast", &.{ payload.lhs, payload.rhs });
+            return renderBuiltinCall(c, "@bitCast", &.{payload});
         },
         .float_cast => {
             const payload = node.castTag(.float_cast).?.data;
-            return renderBuiltinCall(c, "@floatCast", &.{ payload.lhs, payload.rhs });
+            return renderBuiltinCall(c, "@floatCast", &.{payload});
         },
         .int_from_float => {
             const payload = node.castTag(.int_from_float).?.data;
-            return renderBuiltinCall(c, "@intFromFloat", &.{ payload.lhs, payload.rhs });
+            return renderBuiltinCall(c, "@intFromFloat", &.{payload});
         },
         .float_from_int => {
             const payload = node.castTag(.float_from_int).?.data;
-            return renderBuiltinCall(c, "@floatFromInt", &.{ payload.lhs, payload.rhs });
+            return renderBuiltinCall(c, "@floatFromInt", &.{payload});
         },
         .ptr_from_int => {
             const payload = node.castTag(.ptr_from_int).?.data;
-            return renderBuiltinCall(c, "@ptrFromInt", &.{ payload.lhs, payload.rhs });
+            return renderBuiltinCall(c, "@ptrFromInt", &.{payload});
         },
         .int_from_ptr => {
             const payload = node.castTag(.int_from_ptr).?.data;
@@ -1393,11 +1362,11 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
         },
         .align_cast => {
             const payload = node.castTag(.align_cast).?.data;
-            return renderBuiltinCall(c, "@alignCast", &.{ payload.lhs, payload.rhs });
+            return renderBuiltinCall(c, "@alignCast", &.{payload});
         },
         .ptr_cast => {
             const payload = node.castTag(.ptr_cast).?.data;
-            return renderBuiltinCall(c, "@ptrCast", &.{ payload.lhs, payload.rhs });
+            return renderBuiltinCall(c, "@ptrCast", &.{payload});
         },
         .div_exact => {
             const payload = node.castTag(.div_exact).?.data;
@@ -2330,14 +2299,11 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
         .float_from_int,
         .ptr_from_int,
         .std_mem_zeroes,
-        .std_math_Log2Int,
-        .log2_int_type,
         .int_from_ptr,
         .sizeof,
         .alignof,
         .typeof,
         .typeinfo,
-        .std_meta_alignment,
         .vector,
         .helpers_sizeof,
         .helpers_cast,
src/translate_c.zig
@@ -1010,17 +1010,23 @@ fn buildFlexibleArrayFn(
     const bit_offset = layout.getFieldOffset(field_index); // this is a target-specific constant based on the struct layout
     const byte_offset = bit_offset / 8;
 
-    const casted_self = try Tag.ptr_cast.create(c.arena, .{
+    const casted_self = try Tag.as.create(c.arena, .{
         .lhs = intermediate_type_ident,
-        .rhs = self_param,
+        .rhs = try Tag.ptr_cast.create(c.arena, self_param),
     });
     const field_offset = try transCreateNodeNumber(c, byte_offset, .int);
     const field_ptr = try Tag.add.create(c.arena, .{ .lhs = casted_self, .rhs = field_offset });
 
-    const alignment = try Tag.alignof.create(c.arena, element_type);
-
-    const ptr_val = try Tag.align_cast.create(c.arena, .{ .lhs = alignment, .rhs = field_ptr });
-    const ptr_cast = try Tag.ptr_cast.create(c.arena, .{ .lhs = return_type_ident, .rhs = ptr_val });
+    const ptr_cast = try Tag.as.create(c.arena, .{
+        .lhs = return_type_ident,
+        .rhs = try Tag.ptr_cast.create(
+            c.arena,
+            try Tag.align_cast.create(
+                c.arena,
+                field_ptr,
+            ),
+        ),
+    });
     const return_stmt = try Tag.@"return".create(c.arena, ptr_cast);
     try block_scope.statements.append(return_stmt);
 
@@ -1579,14 +1585,14 @@ fn transOffsetOfExpr(
 /// pointer arithmetic expressions, where wraparound will ensure we get the correct value.
 /// node -> @bitCast(usize, @intCast(isize, node))
 fn usizeCastForWrappingPtrArithmetic(gpa: mem.Allocator, node: Node) TransError!Node {
-    const intcast_node = try Tag.int_cast.create(gpa, .{
+    const intcast_node = try Tag.as.create(gpa, .{
         .lhs = try Tag.type.create(gpa, "isize"),
-        .rhs = node,
+        .rhs = try Tag.int_cast.create(gpa, node),
     });
 
-    return Tag.bit_cast.create(gpa, .{
+    return Tag.as.create(gpa, .{
         .lhs = try Tag.type.create(gpa, "usize"),
-        .rhs = intcast_node,
+        .rhs = try Tag.bit_cast.create(gpa, intcast_node),
     });
 }
 
@@ -1781,7 +1787,10 @@ fn transBinaryOperator(
         const elem_type = c_pointer.castTag(.c_pointer).?.data.elem_type;
         const sizeof = try Tag.sizeof.create(c.arena, elem_type);
 
-        const bitcast = try Tag.bit_cast.create(c.arena, .{ .lhs = ptrdiff_type, .rhs = infixOpNode });
+        const bitcast = try Tag.as.create(c.arena, .{
+            .lhs = ptrdiff_type,
+            .rhs = try Tag.bit_cast.create(c.arena, infixOpNode),
+        });
 
         return Tag.div_exact.create(c.arena, .{
             .lhs = bitcast,
@@ -2310,7 +2319,7 @@ fn transIntegerLiteral(
     //     unsigned char y = 256;
     // How this gets evaluated is the 256 is an integer, which gets truncated to signed char, then bit-casted
     // to unsigned char, resulting in 0. In order for this to work, we have to emit this zig code:
-    //     var y = @bitCast(u8, @truncate(i8, @as(c_int, 256)));
+    //     var y = @as(u8, @bitCast(@as(i8, @truncate(@as(c_int, 256)))));
     // Ideally in translate-c we could flatten this out to simply:
     //     var y: u8 = 0;
     // But the first step is to be correct, and the next step is to make the output more elegant.
@@ -2501,7 +2510,10 @@ fn transCCast(
             .lt => {
                 // @truncate(SameSignSmallerInt, src_int_expr)
                 const ty_node = try transQualTypeIntWidthOf(c, dst_type, src_type_is_signed);
-                src_int_expr = try Tag.truncate.create(c.arena, .{ .lhs = ty_node, .rhs = src_int_expr });
+                src_int_expr = try Tag.as.create(c.arena, .{
+                    .lhs = ty_node,
+                    .rhs = try Tag.truncate.create(c.arena, src_int_expr),
+                });
             },
             .gt => {
                 // @as(SameSignBiggerInt, src_int_expr)
@@ -2512,36 +2524,57 @@ fn transCCast(
                 // src_int_expr = src_int_expr
             },
         }
-        // @bitCast(dest_type, intermediate_value)
-        return Tag.bit_cast.create(c.arena, .{ .lhs = dst_node, .rhs = src_int_expr });
+        // @as(dest_type, @bitCast(intermediate_value))
+        return Tag.as.create(c.arena, .{
+            .lhs = dst_node,
+            .rhs = try Tag.bit_cast.create(c.arena, src_int_expr),
+        });
     }
     if (cIsVector(src_type) or cIsVector(dst_type)) {
         // C cast where at least 1 operand is a vector requires them to be same size
-        // @bitCast(dest_type, val)
-        return Tag.bit_cast.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
+        // @as(dest_type, @bitCast(val))
+        return Tag.as.create(c.arena, .{
+            .lhs = dst_node,
+            .rhs = try Tag.bit_cast.create(c.arena, expr),
+        });
     }
     if (cIsInteger(dst_type) and qualTypeIsPtr(src_type)) {
         // @intCast(dest_type, @intFromPtr(val))
         const int_from_ptr = try Tag.int_from_ptr.create(c.arena, expr);
-        return Tag.int_cast.create(c.arena, .{ .lhs = dst_node, .rhs = int_from_ptr });
+        return Tag.as.create(c.arena, .{
+            .lhs = dst_node,
+            .rhs = try Tag.int_cast.create(c.arena, int_from_ptr),
+        });
     }
     if (cIsInteger(src_type) and qualTypeIsPtr(dst_type)) {
-        // @ptrFromInt(dest_type, val)
-        return Tag.ptr_from_int.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
+        // @as(dest_type, @ptrFromInt(val))
+        return Tag.as.create(c.arena, .{
+            .lhs = dst_node,
+            .rhs = try Tag.ptr_from_int.create(c.arena, expr),
+        });
     }
     if (cIsFloating(src_type) and cIsFloating(dst_type)) {
-        // @floatCast(dest_type, val)
-        return Tag.float_cast.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
+        // @as(dest_type, @floatCast(val))
+        return Tag.as.create(c.arena, .{
+            .lhs = dst_node,
+            .rhs = try Tag.float_cast.create(c.arena, expr),
+        });
     }
     if (cIsFloating(src_type) and !cIsFloating(dst_type)) {
-        // @intFromFloat(dest_type, val)
-        return Tag.int_from_float.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
+        // @as(dest_type, @intFromFloat(val))
+        return Tag.as.create(c.arena, .{
+            .lhs = dst_node,
+            .rhs = try Tag.int_from_float.create(c.arena, expr),
+        });
     }
     if (!cIsFloating(src_type) and cIsFloating(dst_type)) {
         var rhs = expr;
         if (qualTypeIsBoolean(src_type)) rhs = try Tag.int_from_bool.create(c.arena, expr);
-        // @floatFromInt(dest_type, val)
-        return Tag.float_from_int.create(c.arena, .{ .lhs = dst_node, .rhs = rhs });
+        // @as(dest_type, @floatFromInt(val))
+        return Tag.as.create(c.arena, .{
+            .lhs = dst_node,
+            .rhs = try Tag.float_from_int.create(c.arena, rhs),
+        });
     }
     if (qualTypeIsBoolean(src_type) and !qualTypeIsBoolean(dst_type)) {
         // @intFromBool returns a u1
@@ -3487,9 +3520,9 @@ fn transSignedArrayAccess(
 
     const then_value = try Tag.add.create(c.arena, .{
         .lhs = container_node,
-        .rhs = try Tag.int_cast.create(c.arena, .{
+        .rhs = try Tag.as.create(c.arena, .{
             .lhs = try Tag.type.create(c.arena, "usize"),
-            .rhs = tmp_ref,
+            .rhs = try Tag.int_cast.create(c.arena, tmp_ref),
         }),
     });
 
@@ -3499,17 +3532,17 @@ fn transSignedArrayAccess(
     });
 
     const minuend = container_node;
-    const signed_size = try Tag.int_cast.create(c.arena, .{
+    const signed_size = try Tag.as.create(c.arena, .{
         .lhs = try Tag.type.create(c.arena, "isize"),
-        .rhs = tmp_ref,
+        .rhs = try Tag.int_cast.create(c.arena, tmp_ref),
     });
     const to_cast = try Tag.add_wrap.create(c.arena, .{
         .lhs = signed_size,
         .rhs = try Tag.negate.create(c.arena, Tag.one_literal.init()),
     });
-    const bitcast_node = try Tag.bit_cast.create(c.arena, .{
+    const bitcast_node = try Tag.as.create(c.arena, .{
         .lhs = try Tag.type.create(c.arena, "usize"),
-        .rhs = to_cast,
+        .rhs = try Tag.bit_cast.create(c.arena, to_cast),
     });
     const subtrahend = try Tag.bit_not.create(c.arena, bitcast_node);
     const difference = try Tag.sub.create(c.arena, .{
@@ -3566,7 +3599,13 @@ fn transArrayAccess(c: *Context, scope: *Scope, stmt: *const clang.ArraySubscrip
     const rhs = if (is_longlong or is_signed) blk: {
         // check if long long first so that signed long long doesn't just become unsigned long long
         const typeid_node = if (is_longlong) try Tag.type.create(c.arena, "usize") else try transQualTypeIntWidthOf(c, subscr_qt, false);
-        break :blk try Tag.int_cast.create(c.arena, .{ .lhs = typeid_node, .rhs = try transExpr(c, scope, subscr_expr, .used) });
+        break :blk try Tag.as.create(c.arena, .{
+            .lhs = typeid_node,
+            .rhs = try Tag.int_cast.create(
+                c.arena,
+                try transExpr(c, scope, subscr_expr, .used),
+            ),
+        });
     } else try transExpr(c, scope, subscr_expr, .used);
 
     const node = try Tag.array_access.create(c.arena, .{
@@ -3968,8 +4007,7 @@ fn transCreateCompoundAssign(
         }
 
         if (is_shift) {
-            const cast_to_type = try qualTypeToLog2IntRef(c, scope, rhs_qt, loc);
-            rhs_node = try Tag.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node });
+            rhs_node = try Tag.int_cast.create(c.arena, rhs_node);
         } else if (requires_int_cast) {
             rhs_node = try transCCast(c, scope, loc, lhs_qt, rhs_qt, rhs_node);
         }
@@ -4008,8 +4046,7 @@ fn transCreateCompoundAssign(
         try block_scope.statements.append(assign);
     } else {
         if (is_shift) {
-            const cast_to_type = try qualTypeToLog2IntRef(c, &block_scope.base, rhs_qt, loc);
-            rhs_node = try Tag.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node });
+            rhs_node = try Tag.int_cast.create(c.arena, rhs_node);
         } else if (requires_int_cast) {
             rhs_node = try transCCast(c, &block_scope.base, loc, lhs_qt, rhs_qt, rhs_node);
         }
@@ -4029,7 +4066,10 @@ fn transCreateCompoundAssign(
 // Casting away const or volatile requires us to use @ptrFromInt
 fn removeCVQualifiers(c: *Context, dst_type_node: Node, expr: Node) Error!Node {
     const int_from_ptr = try Tag.int_from_ptr.create(c.arena, expr);
-    return Tag.ptr_from_int.create(c.arena, .{ .lhs = dst_type_node, .rhs = int_from_ptr });
+    return Tag.as.create(c.arena, .{
+        .lhs = dst_type_node,
+        .rhs = try Tag.ptr_from_int.create(c.arena, int_from_ptr),
+    });
 }
 
 fn transCPtrCast(
@@ -4062,11 +4102,12 @@ fn transCPtrCast(
             // For opaque types a ptrCast is enough
             expr
         else blk: {
-            const alignof = try Tag.std_meta_alignment.create(c.arena, dst_type_node);
-            const align_cast = try Tag.align_cast.create(c.arena, .{ .lhs = alignof, .rhs = expr });
-            break :blk align_cast;
+            break :blk try Tag.align_cast.create(c.arena, expr);
         };
-        return Tag.ptr_cast.create(c.arena, .{ .lhs = dst_type_node, .rhs = rhs });
+        return Tag.as.create(c.arena, .{
+            .lhs = dst_type_node,
+            .rhs = try Tag.ptr_cast.create(c.arena, rhs),
+        });
     }
 }
 
@@ -4337,19 +4378,6 @@ fn qualTypeIntBitWidth(c: *Context, qt: clang.QualType) !u32 {
     }
 }
 
-fn qualTypeToLog2IntRef(c: *Context, scope: *Scope, qt: clang.QualType, source_loc: clang.SourceLocation) !Node {
-    const int_bit_width = try qualTypeIntBitWidth(c, qt);
-
-    if (int_bit_width != 0) {
-        // we can perform the log2 now.
-        const cast_bit_width = math.log2_int(u64, int_bit_width);
-        return Tag.log2_int_type.create(c.arena, cast_bit_width);
-    }
-
-    const zig_type = try transQualType(c, scope, qt, source_loc);
-    return Tag.std_math_Log2Int.create(c.arena, zig_type);
-}
-
 fn qualTypeChildIsFnProto(qt: clang.QualType) bool {
     const ty = qualTypeCanon(qt);
 
@@ -4731,14 +4759,12 @@ fn transCreateNodeShiftOp(
 
     const lhs_expr = stmt.getLHS();
     const rhs_expr = stmt.getRHS();
-    const rhs_location = rhs_expr.getBeginLoc();
     // lhs >> @as(u5, rh)
 
     const lhs = try transExpr(c, scope, lhs_expr, .used);
 
-    const rhs_type = try qualTypeToLog2IntRef(c, scope, stmt.getType(), rhs_location);
     const rhs = try transExprCoercing(c, scope, rhs_expr, .used);
-    const rhs_casted = try Tag.int_cast.create(c.arena, .{ .lhs = rhs_type, .rhs = rhs });
+    const rhs_casted = try Tag.int_cast.create(c.arena, rhs);
 
     return transCreateNodeInfixOp(c, op, lhs, rhs_casted, used);
 }
@@ -6513,9 +6539,9 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node)
             },
             .LBracket => {
                 const index_val = try macroIntFromBool(c, try parseCExpr(c, m, scope));
-                const index = try Tag.int_cast.create(c.arena, .{
+                const index = try Tag.as.create(c.arena, .{
                     .lhs = try Tag.type.create(c.arena, "usize"),
-                    .rhs = index_val,
+                    .rhs = try Tag.int_cast.create(c.arena, index_val),
                 });
                 node = try Tag.array_access.create(c.arena, .{ .lhs = node, .rhs = index });
                 try m.skip(c, .RBracket);