authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-03-03 12:13:13+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-08 18:52:44-04:00
loge2fd289a33bb35cf4b86daa4d80adb7cc0c2c2b0
treeabb7d449b2d8e6d505e4ef4598793e3bbe711b16
parent06d0dac0fb58c2d20036e34f5c1a1bc9c386c189

ir: Create usize result_loc for array subscript expr

Allow the subscript expression to infer the resulting type. Closes #4169

3 files changed, 30 insertions(+), 6 deletions(-)

src/ir.cpp+11-3
...@@ -5910,10 +5910,18 @@ static IrInstSrc *ir_gen_array_access(IrBuilderSrc *irb, Scope *scope, AstNode *...@@ -5910,10 +5910,18 @@ static IrInstSrc *ir_gen_array_access(IrBuilderSrc *irb, Scope *scope, AstNode *
5910 if (array_ref_instruction == irb->codegen->invalid_inst_src)5910 if (array_ref_instruction == irb->codegen->invalid_inst_src)
5911 return array_ref_instruction;5911 return array_ref_instruction;
59125912
5913 // Create an usize-typed result location to hold the subscript value, this
5914 // makes it possible for the compiler to infer the subscript expression type
5915 // if needed
5916 IrInstSrc *usize_type_inst = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize);
5917 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, usize_type_inst, no_result_loc());
5918
5913 AstNode *subscript_node = node->data.array_access_expr.subscript;5919 AstNode *subscript_node = node->data.array_access_expr.subscript;
5914 IrInstSrc *subscript_instruction = ir_gen_node(irb, subscript_node, scope);5920 IrInstSrc *subscript_value = ir_gen_node_extra(irb, subscript_node, scope, LValNone, &result_loc_cast->base);
5915 if (subscript_instruction == irb->codegen->invalid_inst_src)5921 if (subscript_value == irb->codegen->invalid_inst_src)
5916 return subscript_instruction;5922 return irb->codegen->invalid_inst_src;
5923
5924 IrInstSrc *subscript_instruction = ir_build_implicit_cast(irb, scope, subscript_node, subscript_value, result_loc_cast);
59175925
5918 IrInstSrc *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction,5926 IrInstSrc *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction,
5919 subscript_instruction, true, PtrLenSingle, nullptr);5927 subscript_instruction, true, PtrLenSingle, nullptr);
test/compile_errors.zig+2-2
...@@ -3610,11 +3610,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3610,11 +3610,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3610 cases.add("array access of non array",3610 cases.add("array access of non array",
3611 \\export fn f() void {3611 \\export fn f() void {
3612 \\ var bad : bool = undefined;3612 \\ var bad : bool = undefined;
3613 \\ bad[bad] = bad[bad];3613 \\ bad[0] = bad[0];
3614 \\}3614 \\}
3615 \\export fn g() void {3615 \\export fn g() void {
3616 \\ var bad : bool = undefined;3616 \\ var bad : bool = undefined;
3617 \\ _ = bad[bad];3617 \\ _ = bad[0];
3618 \\}3618 \\}
3619 , &[_][]const u8{3619 , &[_][]const u8{
3620 "tmp.zig:3:8: error: array access of non-array type 'bool'",3620 "tmp.zig:3:8: error: array access of non-array type 'bool'",
test/stage1/behavior/array.zig+17-1
...@@ -1,6 +1,8 @@...@@ -1,6 +1,8 @@
1const std = @import("std");1const std = @import("std");
2const expect = std.testing.expect;2const testing = std.testing;
3const mem = std.mem;3const mem = std.mem;
4const expect = testing.expect;
5const expectEqual = testing.expectEqual;
46
5test "arrays" {7test "arrays" {
6 var array: [5]u32 = undefined;8 var array: [5]u32 = undefined;
...@@ -360,3 +362,17 @@ test "access the null element of a null terminated array" {...@@ -360,3 +362,17 @@ test "access the null element of a null terminated array" {
360 S.doTheTest();362 S.doTheTest();
361 comptime S.doTheTest();363 comptime S.doTheTest();
362}364}
365
366test "type deduction for array subscript expression" {
367 const S = struct {
368 fn doTheTest() void {
369 var array = [_]u8{ 0x55, 0xAA };
370 var v0 = true;
371 expectEqual(@as(u8, 0xAA), array[if (v0) 1 else 0]);
372 var v1 = false;
373 expectEqual(@as(u8, 0x55), array[if (v1) 1 else 0]);
374 }
375 };
376 S.doTheTest();
377 comptime S.doTheTest();
378}