diff options
| author | Veikka Tuominen <git@vexu.eu> | 2022-08-22 11:13:01 +0300 |
|---|---|---|
| committer | Veikka Tuominen <git@vexu.eu> | 2022-08-22 14:31:58 +0300 |
| commit | 5404dcdfd844e4b9f47dc49a1f43f0e1075a563f (patch) | |
| tree | 06ee8b53580c6b5a31face3950520553a5d5a750 | |
| parent | 560baf67ce77de41da3d03183300cdf1b6d90567 (diff) | |
| download | zig-5404dcdfd844e4b9f47dc49a1f43f0e1075a563f.tar.gz zig-5404dcdfd844e4b9f47dc49a1f43f0e1075a563f.zip | |
Sema: fix fieldCallBind on tuples and anon structs
Closes #12573
| -rw-r--r-- | src/Sema.zig | 30 | ||||
| -rw-r--r-- | test/cases/compile_errors/bogus_method_call_on_slice.zig | 8 |
2 files changed, 31 insertions, 7 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 42d5e96d3d..4f558ccae4 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -21394,14 +21394,30 @@ fn fieldCallBind( switch (concrete_ty.zigTypeTag()) { .Struct => { const struct_ty = try sema.resolveTypeFields(block, src, concrete_ty); - const struct_obj = struct_ty.castTag(.@"struct").?.data; - - const field_index_usize = struct_obj.fields.getIndex(field_name) orelse - break :find_field; - const field_index = @intCast(u32, field_index_usize); - const field = struct_obj.fields.values()[field_index]; + if (struct_ty.castTag(.@"struct")) |struct_obj| { + const field_index_usize = struct_obj.data.fields.getIndex(field_name) orelse + break :find_field; + const field_index = @intCast(u32, field_index_usize); + const field = struct_obj.data.fields.values()[field_index]; - return finishFieldCallBind(sema, block, src, ptr_ty, field.ty, field_index, object_ptr); + return finishFieldCallBind(sema, block, src, ptr_ty, field.ty, field_index, object_ptr); + } else if (struct_ty.isTuple()) { + if (mem.eql(u8, field_name, "len")) { + return sema.addIntUnsigned(Type.usize, struct_ty.structFieldCount()); + } + if (std.fmt.parseUnsigned(u32, field_name, 10)) |field_index| { + if (field_index >= struct_ty.structFieldCount()) break :find_field; + return finishFieldCallBind(sema, block, src, ptr_ty, struct_ty.structFieldType(field_index), field_index, object_ptr); + } else |_| {} + } else { + const max = struct_ty.structFieldCount(); + var i: u32 = 0; + while (i < max) : (i += 1) { + if (mem.eql(u8, struct_ty.structFieldName(i), field_name)) { + return finishFieldCallBind(sema, block, src, ptr_ty, struct_ty.structFieldType(i), i, object_ptr); + } + } + } }, .Union => { const union_ty = try sema.resolveTypeFields(block, src, concrete_ty); diff --git a/test/cases/compile_errors/bogus_method_call_on_slice.zig b/test/cases/compile_errors/bogus_method_call_on_slice.zig index b5cb5e472a..ed18f43f48 100644 --- a/test/cases/compile_errors/bogus_method_call_on_slice.zig +++ b/test/cases/compile_errors/bogus_method_call_on_slice.zig @@ -3,9 +3,17 @@ fn f(m: []const u8) void { m.copy(u8, self[0..], m); } export fn entry() usize { return @sizeOf(@TypeOf(&f)); } +pub export fn entry1() void { + .{}.bar(); +} +pub export fn entry2() void { + .{ .foo = 1 }.bar(); +} // error // backend=stage2 // target=native // +// :7:8: error: no field or member function named 'bar' in '@TypeOf(.{})' +// :10:18: error: no field or member function named 'bar' in 'struct{comptime foo: comptime_int = 1}' // :3:6: error: no field or member function named 'copy' in '[]const u8' |
