diff options
| author | David <87927264+Rexicon226@users.noreply.github.com> | 2023-11-16 06:38:16 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-11-16 14:38:16 +0000 |
| commit | 941090d94f6b6c7c5207f06917743e79ff06426f (patch) | |
| tree | 89a9cbd53f32e26b39779f997aecb1ce090ee75d /src/Sema.zig | |
| parent | acf9de376d176d35dcfd245d14939766aeba4638 (diff) | |
| download | zig-941090d94f6b6c7c5207f06917743e79ff06426f.tar.gz zig-941090d94f6b6c7c5207f06917743e79ff06426f.zip | |
Move duplicate field detection for struct init expressions into AstGen
Partially addresses #17916.
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 59 |
1 files changed, 11 insertions, 48 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 2615a5b27d..39fd818d97 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -4690,17 +4690,7 @@ fn validateStructInit( try sema.tupleFieldIndex(block, struct_ty, field_name, field_src) else try sema.structFieldIndex(block, struct_ty, field_name, field_src); - if (found_fields[field_index.*].unwrap()) |other_field_ptr| { - const other_field_ptr_data = sema.code.instructions.items(.data)[@intFromEnum(other_field_ptr)].pl_node; - const other_field_src: LazySrcLoc = .{ .node_offset_initializer = other_field_ptr_data.src_node }; - const msg = msg: { - const msg = try sema.errMsg(block, field_src, "duplicate field", .{}); - errdefer msg.destroy(gpa); - try sema.errNote(block, other_field_src, msg, "other field here", .{}); - break :msg msg; - }; - return sema.failWithOwnedErrorMsg(block, msg); - } + assert(found_fields[field_index.*] == .none); found_fields[field_index.*] = field_ptr.toOptional(); } @@ -19222,18 +19212,7 @@ fn zirStructInit( try sema.tupleFieldIndex(block, resolved_ty, field_name, field_src) else try sema.structFieldIndex(block, resolved_ty, field_name, field_src); - if (field_inits[field_index] != .none) { - const other_field_type = found_fields[field_index]; - const other_field_type_data = zir_datas[@intFromEnum(other_field_type)].pl_node; - const other_field_src: LazySrcLoc = .{ .node_offset_initializer = other_field_type_data.src_node }; - const msg = msg: { - const msg = try sema.errMsg(block, field_src, "duplicate field", .{}); - errdefer msg.destroy(gpa); - try sema.errNote(block, other_field_src, msg, "other field here", .{}); - break :msg msg; - }; - return sema.failWithOwnedErrorMsg(block, msg); - } + assert(field_inits[field_index] == .none); found_fields[field_index] = item.data.field_type; const uncoerced_init = try sema.resolveInst(item.data.init); const field_ty = resolved_ty.structFieldType(field_index, mod); @@ -19533,16 +19512,13 @@ fn structInitAnon( const types = try sema.arena.alloc(InternPool.Index, extra_data.fields_len); const values = try sema.arena.alloc(InternPool.Index, types.len); - - var fields = std.AutoArrayHashMap(InternPool.NullTerminatedString, u32).init(sema.arena); - try fields.ensureUnusedCapacity(types.len); + const names = try sema.arena.alloc(InternPool.NullTerminatedString, types.len); // Find which field forces the expression to be runtime, if any. const opt_runtime_index = rs: { var runtime_index: ?usize = null; var extra_index = extra_end; - for (types, 0..) |*field_ty, i_usize| { - const i: u32 = @intCast(i_usize); + for (types, values, names, 0..) |*field_ty, *field_val, *field_name, i_usize| { const item = switch (kind) { .anon_init => sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index), .typed_init => sema.code.extraData(Zir.Inst.StructInit.Item, extra_index), @@ -19558,29 +19534,16 @@ fn structInitAnon( break :name sema.code.nullTerminatedString(field_type_extra.data.name_start); }, }; - const name_ip = try mod.intern_pool.getOrPutString(gpa, name); - const gop = fields.getOrPutAssumeCapacity(name_ip); - if (gop.found_existing) { - const msg = msg: { - const decl = mod.declPtr(block.src_decl); - const field_src = mod.initSrc(src.node_offset.x, decl, i); - const msg = try sema.errMsg(block, field_src, "duplicate field", .{}); - errdefer msg.destroy(gpa); - const prev_source = mod.initSrc(src.node_offset.x, decl, gop.value_ptr.*); - try sema.errNote(block, prev_source, msg, "other field here", .{}); - break :msg msg; - }; - return sema.failWithOwnedErrorMsg(block, msg); - } - gop.value_ptr.* = i; + const name_ip = try mod.intern_pool.getOrPutString(gpa, name); + field_name.* = name_ip; const init = try sema.resolveInst(item.data.init); field_ty.* = sema.typeOf(init).toIntern(); if (field_ty.toType().zigTypeTag(mod) == .Opaque) { const msg = msg: { const decl = mod.declPtr(block.src_decl); - const field_src = mod.initSrc(src.node_offset.x, decl, i); + const field_src = mod.initSrc(src.node_offset.x, decl, @intCast(i_usize)); const msg = try sema.errMsg(block, field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); errdefer msg.destroy(sema.gpa); @@ -19590,17 +19553,17 @@ fn structInitAnon( return sema.failWithOwnedErrorMsg(block, msg); } if (try sema.resolveValue(init)) |init_val| { - values[i] = try init_val.intern(field_ty.toType(), mod); + field_val.* = try init_val.intern(field_ty.toType(), mod); } else { - values[i] = .none; - runtime_index = i; + field_val.* = .none; + runtime_index = @intCast(i_usize); } } break :rs runtime_index; }; const tuple_ty = try ip.getAnonStructType(gpa, .{ - .names = fields.keys(), + .names = names, .types = types, .values = values, }); |
