| author | |
| committer | |
| log | 0ef2e2520af59a42014399282ddea983fa526449 |
| tree | b186116f3064299d58a81cacb2f68ae492d26d65 |
| parent | 7d0a74456b0f239e6cc8532143badeb6781bd47d |
struct and union are kept in stage1 because struct/unionFieldCount are returning zero6 files changed, 57 insertions(+), 87 deletions(-)
src/Module.zig+3-1| ... | @@ -876,10 +876,12 @@ pub const EnumSimple = struct { | ... | @@ -876,10 +876,12 @@ pub const EnumSimple = struct { |
| 876 | /// The Decl that corresponds to the enum itself. | 876 | /// The Decl that corresponds to the enum itself. |
| 877 | owner_decl: *Decl, | 877 | owner_decl: *Decl, |
| 878 | /// Set of field names in declaration order. | 878 | /// Set of field names in declaration order. |
| 879 | fields: std.StringArrayHashMapUnmanaged(void), | 879 | fields: NameMap, |
| 880 | /// Offset from `owner_decl`, points to the enum decl AST node. | 880 | /// Offset from `owner_decl`, points to the enum decl AST node. |
| 881 | node_offset: i32, | 881 | node_offset: i32, |
| 882 | 882 | ||
| 883 | pub const NameMap = EnumFull.NameMap; | ||
| 884 | |||
| 883 | pub fn srcLoc(self: EnumSimple) SrcLoc { | 885 | pub fn srcLoc(self: EnumSimple) SrcLoc { |
| 884 | return .{ | 886 | return .{ |
| 885 | .file_scope = self.owner_decl.getFileScope(), | 887 | .file_scope = self.owner_decl.getFileScope(), |
src/Sema.zig+14-3| ... | @@ -6413,10 +6413,21 @@ fn validateSwitchNoRange( | ... | @@ -6413,10 +6413,21 @@ fn validateSwitchNoRange( |
| 6413 | fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 6413 | fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 6414 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 6414 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 6415 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 6415 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 6416 | _ = extra; | 6416 | const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 6417 | const src = inst_data.src(); | 6417 | const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 6418 | const container_type = try sema.resolveType(block, lhs_src, extra.lhs); | ||
| 6419 | const field_name = try sema.resolveConstString(block, rhs_src, extra.rhs); | ||
| 6418 | 6420 | ||
| 6419 | return sema.fail(block, src, "TODO implement zirHasField", .{}); | 6421 | const has_field = switch (container_type.zigTypeTag()) { |
| 6422 | .Struct => container_type.structFields().contains(field_name), | ||
| 6423 | .Union => container_type.unionFields().contains(field_name), | ||
| 6424 | .Enum => container_type.enumFields().contains(field_name), | ||
| 6425 | else => return sema.fail(block, lhs_src, "expected struct, enum, or union, found '{}'", .{container_type}), | ||
| 6426 | }; | ||
| 6427 | if (has_field) { | ||
| 6428 | return Air.Inst.Ref.bool_true; | ||
| 6429 | } | ||
| 6430 | return Air.Inst.Ref.bool_false; | ||
| 6420 | } | 6431 | } |
| 6421 | 6432 | ||
| 6422 | fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 6433 | fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
src/type.zig+12-60| ... | @@ -3252,14 +3252,11 @@ pub const Type = extern union { | ... | @@ -3252,14 +3252,11 @@ pub const Type = extern union { |
| 3252 | }; | 3252 | }; |
| 3253 | } | 3253 | } |
| 3254 | 3254 | ||
| 3255 | pub fn enumFieldCount(ty: Type) usize { | 3255 | pub fn enumFields(ty: Type) Module.EnumFull.NameMap { |
| 3256 | switch (ty.tag()) { | 3256 | return switch (ty.tag()) { |
| 3257 | .enum_full, .enum_nonexhaustive => { | 3257 | .enum_full, .enum_nonexhaustive => ty.cast(Payload.EnumFull).?.data.fields, |
| 3258 | const enum_full = ty.cast(Payload.EnumFull).?.data; | 3258 | .enum_simple => ty.castTag(.enum_simple).?.data.fields, |
| 3259 | return enum_full.fields.count(); | 3259 | .enum_numbered => ty.castTag(.enum_numbered).?.data.fields, |
| 3260 | }, | ||
| 3261 | .enum_simple => return ty.castTag(.enum_simple).?.data.fields.count(), | ||
| 3262 | .enum_numbered => return ty.castTag(.enum_numbered).?.data.fields.count(), | ||
| 3263 | .atomic_order, | 3260 | .atomic_order, |
| 3264 | .atomic_rmw_op, | 3261 | .atomic_rmw_op, |
| 3265 | .calling_convention, | 3262 | .calling_convention, |
| ... | @@ -3270,65 +3267,20 @@ pub const Type = extern union { | ... | @@ -3270,65 +3267,20 @@ pub const Type = extern union { |
| 3270 | .export_options, | 3267 | .export_options, |
| 3271 | .extern_options, | 3268 | .extern_options, |
| 3272 | => @panic("TODO resolve std.builtin types"), | 3269 | => @panic("TODO resolve std.builtin types"), |
| 3273 | |||
| 3274 | else => unreachable, | 3270 | else => unreachable, |
| 3275 | } | 3271 | }; |
| 3272 | } | ||
| 3273 | |||
| 3274 | pub fn enumFieldCount(ty: Type) usize { | ||
| 3275 | return ty.enumFields().count(); | ||
| 3276 | } | 3276 | } |
| 3277 | 3277 | ||
| 3278 | pub fn enumFieldName(ty: Type, field_index: usize) []const u8 { | 3278 | pub fn enumFieldName(ty: Type, field_index: usize) []const u8 { |
| 3279 | switch (ty.tag()) { | 3279 | return ty.enumFields().keys()[field_index]; |
| 3280 | .enum_full, .enum_nonexhaustive => { | ||
| 3281 | const enum_full = ty.cast(Payload.EnumFull).?.data; | ||
| 3282 | return enum_full.fields.keys()[field_index]; | ||
| 3283 | }, | ||
| 3284 | .enum_simple => { | ||
| 3285 | const enum_simple = ty.castTag(.enum_simple).?.data; | ||
| 3286 | return enum_simple.fields.keys()[field_index]; | ||
| 3287 | }, | ||
| 3288 | .enum_numbered => { | ||
| 3289 | const enum_numbered = ty.castTag(.enum_numbered).?.data; | ||
| 3290 | return enum_numbered.fields.keys()[field_index]; | ||
| 3291 | }, | ||
| 3292 | .atomic_order, | ||
| 3293 | .atomic_rmw_op, | ||
| 3294 | .calling_convention, | ||
| 3295 | .address_space, | ||
| 3296 | .float_mode, | ||
| 3297 | .reduce_op, | ||
| 3298 | .call_options, | ||
| 3299 | .export_options, | ||
| 3300 | .extern_options, | ||
| 3301 | => @panic("TODO resolve std.builtin types"), | ||
| 3302 | else => unreachable, | ||
| 3303 | } | ||
| 3304 | } | 3280 | } |
| 3305 | 3281 | ||
| 3306 | pub fn enumFieldIndex(ty: Type, field_name: []const u8) ?usize { | 3282 | pub fn enumFieldIndex(ty: Type, field_name: []const u8) ?usize { |
| 3307 | switch (ty.tag()) { | 3283 | return ty.enumFields().getIndex(field_name); |
| 3308 | .enum_full, .enum_nonexhaustive => { | ||
| 3309 | const enum_full = ty.cast(Payload.EnumFull).?.data; | ||
| 3310 | return enum_full.fields.getIndex(field_name); | ||
| 3311 | }, | ||
| 3312 | .enum_simple => { | ||
| 3313 | const enum_simple = ty.castTag(.enum_simple).?.data; | ||
| 3314 | return enum_simple.fields.getIndex(field_name); | ||
| 3315 | }, | ||
| 3316 | .enum_numbered => { | ||
| 3317 | const enum_numbered = ty.castTag(.enum_numbered).?.data; | ||
| 3318 | return enum_numbered.fields.getIndex(field_name); | ||
| 3319 | }, | ||
| 3320 | .atomic_order, | ||
| 3321 | .atomic_rmw_op, | ||
| 3322 | .calling_convention, | ||
| 3323 | .address_space, | ||
| 3324 | .float_mode, | ||
| 3325 | .reduce_op, | ||
| 3326 | .call_options, | ||
| 3327 | .export_options, | ||
| 3328 | .extern_options, | ||
| 3329 | => @panic("TODO resolve std.builtin types"), | ||
| 3330 | else => unreachable, | ||
| 3331 | } | ||
| 3332 | } | 3284 | } |
| 3333 | 3285 | ||
| 3334 | /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or | 3286 | /// Asserts `ty` is an enum. `enum_tag` can either be `enum_field_index` or |
test/behavior.zig+2-1| ... | @@ -35,6 +35,7 @@ test { | ... | @@ -35,6 +35,7 @@ test { |
| 35 | _ = @import("behavior/for.zig"); | 35 | _ = @import("behavior/for.zig"); |
| 36 | _ = @import("behavior/generics.zig"); | 36 | _ = @import("behavior/generics.zig"); |
| 37 | _ = @import("behavior/hasdecl.zig"); | 37 | _ = @import("behavior/hasdecl.zig"); |
| 38 | _ = @import("behavior/hasfield.zig"); | ||
| 38 | _ = @import("behavior/if.zig"); | 39 | _ = @import("behavior/if.zig"); |
| 39 | _ = @import("behavior/math.zig"); | 40 | _ = @import("behavior/math.zig"); |
| 40 | _ = @import("behavior/maximum_minimum.zig"); | 41 | _ = @import("behavior/maximum_minimum.zig"); |
| ... | @@ -127,7 +128,7 @@ test { | ... | @@ -127,7 +128,7 @@ test { |
| 127 | _ = @import("behavior/fn_in_struct_in_comptime.zig"); | 128 | _ = @import("behavior/fn_in_struct_in_comptime.zig"); |
| 128 | _ = @import("behavior/for_stage1.zig"); | 129 | _ = @import("behavior/for_stage1.zig"); |
| 129 | _ = @import("behavior/generics_stage1.zig"); | 130 | _ = @import("behavior/generics_stage1.zig"); |
| 130 | _ = @import("behavior/hasfield.zig"); | 131 | _ = @import("behavior/hasfield_stage1.zig"); |
| 131 | _ = @import("behavior/if_stage1.zig"); | 132 | _ = @import("behavior/if_stage1.zig"); |
| 132 | _ = @import("behavior/import.zig"); | 133 | _ = @import("behavior/import.zig"); |
| 133 | _ = @import("behavior/incomplete_struct_param_tld.zig"); | 134 | _ = @import("behavior/incomplete_struct_param_tld.zig"); |
test/behavior/hasfield.zig-22| ... | @@ -2,28 +2,6 @@ const expect = @import("std").testing.expect; | ... | @@ -2,28 +2,6 @@ const expect = @import("std").testing.expect; |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | 3 | ||
| 4 | test "@hasField" { | 4 | test "@hasField" { |
| 5 | const struc = struct { | ||
| 6 | a: i32, | ||
| 7 | b: []u8, | ||
| 8 | |||
| 9 | pub const nope = 1; | ||
| 10 | }; | ||
| 11 | try expect(@hasField(struc, "a") == true); | ||
| 12 | try expect(@hasField(struc, "b") == true); | ||
| 13 | try expect(@hasField(struc, "non-existant") == false); | ||
| 14 | try expect(@hasField(struc, "nope") == false); | ||
| 15 | |||
| 16 | const unin = union { | ||
| 17 | a: u64, | ||
| 18 | b: []u16, | ||
| 19 | |||
| 20 | pub const nope = 1; | ||
| 21 | }; | ||
| 22 | try expect(@hasField(unin, "a") == true); | ||
| 23 | try expect(@hasField(unin, "b") == true); | ||
| 24 | try expect(@hasField(unin, "non-existant") == false); | ||
| 25 | try expect(@hasField(unin, "nope") == false); | ||
| 26 | |||
| 27 | const enm = enum { | 5 | const enm = enum { |
| 28 | a, | 6 | a, |
| 29 | b, | 7 | b, |
test/behavior/hasfield_stage1.zig created+26| ... | @@ -0,0 +1,26 @@ | ||
| 1 | const expect = @import("std").testing.expect; | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | |||
| 4 | test "@hasField" { | ||
| 5 | const struc = struct { | ||
| 6 | a: i32, | ||
| 7 | b: []const u8, | ||
| 8 | |||
| 9 | pub const nope = 1; | ||
| 10 | }; | ||
| 11 | try expect(@hasField(struc, "a") == true); | ||
| 12 | try expect(@hasField(struc, "b") == true); | ||
| 13 | try expect(@hasField(struc, "non-existant") == false); | ||
| 14 | try expect(@hasField(struc, "nope") == false); | ||
| 15 | |||
| 16 | const unin = union { | ||
| 17 | a: u64, | ||
| 18 | b: []const u16, | ||
| 19 | |||
| 20 | pub const nope = 1; | ||
| 21 | }; | ||
| 22 | try expect(@hasField(unin, "a") == true); | ||
| 23 | try expect(@hasField(unin, "b") == true); | ||
| 24 | try expect(@hasField(unin, "non-existant") == false); | ||
| 25 | try expect(@hasField(unin, "nope") == false); | ||
| 26 | } | ||