aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorDavid <87927264+Rexicon226@users.noreply.github.com>2023-11-16 06:38:16 -0800
committerGitHub <noreply@github.com>2023-11-16 14:38:16 +0000
commit941090d94f6b6c7c5207f06917743e79ff06426f (patch)
tree89a9cbd53f32e26b39779f997aecb1ce090ee75d /src/Sema.zig
parentacf9de376d176d35dcfd245d14939766aeba4638 (diff)
downloadzig-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.zig59
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,
});