diff --git a/src/ir.cpp b/src/ir.cpp index 34f3ef26a7..110778fb9a 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -5910,10 +5910,18 @@ static IrInstSrc *ir_gen_array_access(IrBuilderSrc *irb, Scope *scope, AstNode * if (array_ref_instruction == irb->codegen->invalid_inst_src) return array_ref_instruction; + // Create an usize-typed result location to hold the subscript value, this + // makes it possible for the compiler to infer the subscript expression type + // if needed + IrInstSrc *usize_type_inst = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); + ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, usize_type_inst, no_result_loc()); + AstNode *subscript_node = node->data.array_access_expr.subscript; - IrInstSrc *subscript_instruction = ir_gen_node(irb, subscript_node, scope); - if (subscript_instruction == irb->codegen->invalid_inst_src) - return subscript_instruction; + IrInstSrc *subscript_value = ir_gen_node_extra(irb, subscript_node, scope, LValNone, &result_loc_cast->base); + if (subscript_value == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; + + IrInstSrc *subscript_instruction = ir_build_implicit_cast(irb, scope, subscript_node, subscript_value, result_loc_cast); IrInstSrc *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction, subscript_instruction, true, PtrLenSingle, nullptr); diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 2b74d8fc77..717793baaa 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -3610,11 +3610,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { cases.add("array access of non array", \\export fn f() void { \\ var bad : bool = undefined; - \\ bad[bad] = bad[bad]; + \\ bad[0] = bad[0]; \\} \\export fn g() void { \\ var bad : bool = undefined; - \\ _ = bad[bad]; + \\ _ = bad[0]; \\} , &[_][]const u8{ "tmp.zig:3:8: error: array access of non-array type 'bool'", diff --git a/test/stage1/behavior/array.zig b/test/stage1/behavior/array.zig index 7ac1e8197d..da56864cc9 100644 --- a/test/stage1/behavior/array.zig +++ b/test/stage1/behavior/array.zig @@ -1,6 +1,8 @@ const std = @import("std"); -const expect = std.testing.expect; +const testing = std.testing; const mem = std.mem; +const expect = testing.expect; +const expectEqual = testing.expectEqual; test "arrays" { var array: [5]u32 = undefined; @@ -360,3 +362,17 @@ test "access the null element of a null terminated array" { S.doTheTest(); comptime S.doTheTest(); } + +test "type deduction for array subscript expression" { + const S = struct { + fn doTheTest() void { + var array = [_]u8{ 0x55, 0xAA }; + var v0 = true; + expectEqual(@as(u8, 0xAA), array[if (v0) 1 else 0]); + var v1 = false; + expectEqual(@as(u8, 0x55), array[if (v1) 1 else 0]); + } + }; + S.doTheTest(); + comptime S.doTheTest(); +}