| ... | @@ -715,6 +715,7 @@ fn zirStructDecl( | ... | @@ -715,6 +715,7 @@ fn zirStructDecl( |
| 715 | } else sema.src; | 715 | } else sema.src; |
| 716 | | 716 | |
| 717 | var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa); | 717 | var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa); |
| | 718 | errdefer new_decl_arena.deinit(); |
| 718 | | 719 | |
| 719 | const struct_obj = try new_decl_arena.allocator.create(Module.Struct); | 720 | const struct_obj = try new_decl_arena.allocator.create(Module.Struct); |
| 720 | const struct_ty = try Type.Tag.@"struct".create(&new_decl_arena.allocator, struct_obj); | 721 | const struct_ty = try Type.Tag.@"struct".create(&new_decl_arena.allocator, struct_obj); |
| ... | @@ -779,6 +780,7 @@ fn zirEnumDecl( | ... | @@ -779,6 +780,7 @@ fn zirEnumDecl( |
| 779 | const tracy = trace(@src()); | 780 | const tracy = trace(@src()); |
| 780 | defer tracy.end(); | 781 | defer tracy.end(); |
| 781 | | 782 | |
| | 783 | const mod = sema.mod; |
| 782 | const gpa = sema.gpa; | 784 | const gpa = sema.gpa; |
| 783 | const small = @bitCast(Zir.Inst.EnumDecl.Small, extended.small); | 785 | const small = @bitCast(Zir.Inst.EnumDecl.Small, extended.small); |
| 784 | var extra_index: usize = extended.operand; | 786 | var extra_index: usize = extended.operand; |
| ... | @@ -814,6 +816,7 @@ fn zirEnumDecl( | ... | @@ -814,6 +816,7 @@ fn zirEnumDecl( |
| 814 | } else 0; | 816 | } else 0; |
| 815 | | 817 | |
| 816 | var new_decl_arena = std.heap.ArenaAllocator.init(gpa); | 818 | var new_decl_arena = std.heap.ArenaAllocator.init(gpa); |
| | 819 | errdefer new_decl_arena.deinit(); |
| 817 | | 820 | |
| 818 | const tag_ty = blk: { | 821 | const tag_ty = blk: { |
| 819 | if (tag_type_ref != .none) { | 822 | if (tag_type_ref != .none) { |
| ... | @@ -835,7 +838,7 @@ fn zirEnumDecl( | ... | @@ -835,7 +838,7 @@ fn zirEnumDecl( |
| 835 | const enum_ty = Type.initPayload(&enum_ty_payload.base); | 838 | const enum_ty = Type.initPayload(&enum_ty_payload.base); |
| 836 | const enum_val = try Value.Tag.ty.create(&new_decl_arena.allocator, enum_ty); | 839 | const enum_val = try Value.Tag.ty.create(&new_decl_arena.allocator, enum_ty); |
| 837 | const type_name = try sema.createTypeName(block, small.name_strategy); | 840 | const type_name = try sema.createTypeName(block, small.name_strategy); |
| 838 | const new_decl = try sema.mod.createAnonymousDeclNamed(&block.base, .{ | 841 | const new_decl = try mod.createAnonymousDeclNamed(&block.base, .{ |
| 839 | .ty = Type.initTag(.type), | 842 | .ty = Type.initTag(.type), |
| 840 | .val = enum_val, | 843 | .val = enum_val, |
| 841 | }, type_name); | 844 | }, type_name); |
| ... | @@ -855,7 +858,7 @@ fn zirEnumDecl( | ... | @@ -855,7 +858,7 @@ fn zirEnumDecl( |
| 855 | &enum_obj.namespace, new_decl, new_decl.name, | 858 | &enum_obj.namespace, new_decl, new_decl.name, |
| 856 | }); | 859 | }); |
| 857 | | 860 | |
| 858 | extra_index = try sema.mod.scanNamespace(&enum_obj.namespace, extra_index, decls_len, new_decl); | 861 | extra_index = try mod.scanNamespace(&enum_obj.namespace, extra_index, decls_len, new_decl); |
| 859 | | 862 | |
| 860 | const body = sema.code.extra[extra_index..][0..body_len]; | 863 | const body = sema.code.extra[extra_index..][0..body_len]; |
| 861 | if (fields_len == 0) { | 864 | if (fields_len == 0) { |
| ... | @@ -883,7 +886,7 @@ fn zirEnumDecl( | ... | @@ -883,7 +886,7 @@ fn zirEnumDecl( |
| 883 | // Within the field type, default value, and alignment expressions, the "owner decl" | 886 | // Within the field type, default value, and alignment expressions, the "owner decl" |
| 884 | // should be the enum itself. Thus we need a new Sema. | 887 | // should be the enum itself. Thus we need a new Sema. |
| 885 | var enum_sema: Sema = .{ | 888 | var enum_sema: Sema = .{ |
| 886 | .mod = sema.mod, | 889 | .mod = mod, |
| 887 | .gpa = gpa, | 890 | .gpa = gpa, |
| 888 | .arena = &new_decl_arena.allocator, | 891 | .arena = &new_decl_arena.allocator, |
| 889 | .code = sema.code, | 892 | .code = sema.code, |
| ... | @@ -932,7 +935,18 @@ fn zirEnumDecl( | ... | @@ -932,7 +935,18 @@ fn zirEnumDecl( |
| 932 | const field_name = try new_decl_arena.allocator.dupe(u8, field_name_zir); | 935 | const field_name = try new_decl_arena.allocator.dupe(u8, field_name_zir); |
| 933 | | 936 | |
| 934 | const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name); | 937 | const gop = enum_obj.fields.getOrPutAssumeCapacity(field_name); |
| 935 | assert(!gop.found_existing); | 938 | if (gop.found_existing) { |
| | 939 | const tree = try sema.getAstTree(block); |
| | 940 | const field_src = enumFieldSrcLoc(block.src_decl, tree.*, src.node_offset, field_i); |
| | 941 | const other_tag_src = enumFieldSrcLoc(block.src_decl, tree.*, src.node_offset, gop.index); |
| | 942 | const msg = msg: { |
| | 943 | const msg = try mod.errMsg(&block.base, field_src, "duplicate enum tag", .{}); |
| | 944 | errdefer msg.destroy(gpa); |
| | 945 | try mod.errNote(&block.base, other_tag_src, msg, "other tag here", .{}); |
| | 946 | break :msg msg; |
| | 947 | }; |
| | 948 | return mod.failWithOwnedErrorMsg(&block.base, msg); |
| | 949 | } |
| 936 | | 950 | |
| 937 | if (has_tag_value) { | 951 | if (has_tag_value) { |
| 938 | const tag_val_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); | 952 | const tag_val_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| ... | @@ -981,6 +995,7 @@ fn zirUnionDecl( | ... | @@ -981,6 +995,7 @@ fn zirUnionDecl( |
| 981 | } else 0; | 995 | } else 0; |
| 982 | | 996 | |
| 983 | var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa); | 997 | var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa); |
| | 998 | errdefer new_decl_arena.deinit(); |
| 984 | | 999 | |
| 985 | const union_obj = try new_decl_arena.allocator.create(Module.Union); | 1000 | const union_obj = try new_decl_arena.allocator.create(Module.Union); |
| 986 | const union_ty = try Type.Tag.@"union".create(&new_decl_arena.allocator, union_obj); | 1001 | const union_ty = try Type.Tag.@"union".create(&new_decl_arena.allocator, union_obj); |
| ... | @@ -1046,6 +1061,7 @@ fn zirErrorSetDecl( | ... | @@ -1046,6 +1061,7 @@ fn zirErrorSetDecl( |
| 1046 | const fields = sema.code.extra[extra.end..][0..extra.data.fields_len]; | 1061 | const fields = sema.code.extra[extra.end..][0..extra.data.fields_len]; |
| 1047 | | 1062 | |
| 1048 | var new_decl_arena = std.heap.ArenaAllocator.init(gpa); | 1063 | var new_decl_arena = std.heap.ArenaAllocator.init(gpa); |
| | 1064 | errdefer new_decl_arena.deinit(); |
| 1049 | | 1065 | |
| 1050 | const error_set = try new_decl_arena.allocator.create(Module.ErrorSet); | 1066 | const error_set = try new_decl_arena.allocator.create(Module.ErrorSet); |
| 1051 | const error_set_ty = try Type.Tag.error_set.create(&new_decl_arena.allocator, error_set); | 1067 | const error_set_ty = try Type.Tag.error_set.create(&new_decl_arena.allocator, error_set); |
| ... | @@ -7446,3 +7462,53 @@ fn typeHasOnePossibleValue( | ... | @@ -7446,3 +7462,53 @@ fn typeHasOnePossibleValue( |
| 7446 | .inferred_alloc_mut => unreachable, | 7462 | .inferred_alloc_mut => unreachable, |
| 7447 | }; | 7463 | }; |
| 7448 | } | 7464 | } |
| | 7465 | |
| | 7466 | fn getAstTree(sema: *Sema, block: *Scope.Block) InnerError!*const std.zig.ast.Tree { |
| | 7467 | return block.src_decl.namespace.file_scope.getTree(sema.gpa) catch |err| { |
| | 7468 | log.err("unable to load AST to report compile error: {s}", .{@errorName(err)}); |
| | 7469 | return error.AnalysisFail; |
| | 7470 | }; |
| | 7471 | } |
| | 7472 | |
| | 7473 | fn enumFieldSrcLoc( |
| | 7474 | decl: *Decl, |
| | 7475 | tree: std.zig.ast.Tree, |
| | 7476 | node_offset: i32, |
| | 7477 | field_index: usize, |
| | 7478 | ) LazySrcLoc { |
| | 7479 | @setCold(true); |
| | 7480 | const enum_node = decl.relativeToNodeIndex(node_offset); |
| | 7481 | const node_tags = tree.nodes.items(.tag); |
| | 7482 | var buffer: [2]std.zig.ast.Node.Index = undefined; |
| | 7483 | const container_decl = switch (node_tags[enum_node]) { |
| | 7484 | .container_decl, |
| | 7485 | .container_decl_trailing, |
| | 7486 | => tree.containerDecl(enum_node), |
| | 7487 | |
| | 7488 | .container_decl_two, |
| | 7489 | .container_decl_two_trailing, |
| | 7490 | => tree.containerDeclTwo(&buffer, enum_node), |
| | 7491 | |
| | 7492 | .container_decl_arg, |
| | 7493 | .container_decl_arg_trailing, |
| | 7494 | => tree.containerDeclArg(enum_node), |
| | 7495 | |
| | 7496 | else => unreachable, |
| | 7497 | }; |
| | 7498 | var it_index: usize = 0; |
| | 7499 | for (container_decl.ast.members) |member_node| { |
| | 7500 | switch (node_tags[member_node]) { |
| | 7501 | .container_field_init, |
| | 7502 | .container_field_align, |
| | 7503 | .container_field, |
| | 7504 | => { |
| | 7505 | if (it_index == field_index) { |
| | 7506 | return .{ .node_offset = decl.nodeIndexToRelative(member_node) }; |
| | 7507 | } |
| | 7508 | it_index += 1; |
| | 7509 | }, |
| | 7510 | |
| | 7511 | else => continue, |
| | 7512 | } |
| | 7513 | } else unreachable; |
| | 7514 | } |