mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
stage2: compile error for duplicate switch value on sparse
This commit is contained in:
parent
cec766f73c
commit
e8143f6cbe
13
BRANCH_TODO
13
BRANCH_TODO
@ -36,16 +36,3 @@ Performance optimizations to look into:
|
||||
* look into not emitting redundant dbg stmts to TZIR
|
||||
* make decl references in ZIR be u32 indexes to the Decl dependencies array hash map
|
||||
instead of duplicating *Decl entries in zir.Code.
|
||||
|
||||
|
||||
for (inst.positionals.items) |item| {
|
||||
const resolved = try sema.resolveInst(item);
|
||||
const casted = try sema.coerce(block, operand.ty, resolved);
|
||||
const val = try sema.resolveConstValue(block, item_src, casted);
|
||||
|
||||
if (try seen_values.fetchPut(val, item.src)) |prev| {
|
||||
return sema.mod.fail(&block.base, item.src, "duplicate switch value", .{});
|
||||
// TODO notes "previous value here" prev.value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
17
src/Sema.zig
17
src/Sema.zig
@ -62,8 +62,6 @@ const LazySrcLoc = Module.LazySrcLoc;
|
||||
const RangeSet = @import("RangeSet.zig");
|
||||
const AstGen = @import("AstGen.zig");
|
||||
|
||||
const ValueSrcMap = std.HashMap(Value, LazySrcLoc, Value.hash, Value.eql, std.hash_map.DefaultMaxLoadPercentage);
|
||||
|
||||
pub fn root(sema: *Sema, root_block: *Scope.Block) !zir.Inst.Index {
|
||||
const inst_data = sema.code.instructions.items(.data)[0].pl_node;
|
||||
const extra = sema.code.extraData(zir.Inst.Block, inst_data.payload_index);
|
||||
@ -2557,7 +2555,7 @@ fn analyzeSwitch(
|
||||
|
||||
var extra_index: usize = special.end;
|
||||
{
|
||||
var scalar_i: usize = 0;
|
||||
var scalar_i: u32 = 0;
|
||||
while (scalar_i < scalar_cases_len) : (scalar_i += 1) {
|
||||
const item_ref = @intToEnum(zir.Inst.Ref, sema.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
@ -2571,11 +2569,12 @@ fn analyzeSwitch(
|
||||
&seen_values,
|
||||
item_ref,
|
||||
src_node_offset,
|
||||
.{ .scalar = scalar_i },
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
var multi_i: usize = 0;
|
||||
var multi_i: u32 = 0;
|
||||
while (multi_i < multi_cases_len) : (multi_i += 1) {
|
||||
const items_len = sema.code.extra[extra_index];
|
||||
extra_index += 1;
|
||||
@ -2586,12 +2585,13 @@ fn analyzeSwitch(
|
||||
const items = sema.code.refSlice(extra_index, items_len);
|
||||
extra_index += items_len + body_len;
|
||||
|
||||
for (items) |item_ref| {
|
||||
for (items) |item_ref, item_i| {
|
||||
try sema.validateSwitchItemSparse(
|
||||
block,
|
||||
&seen_values,
|
||||
item_ref,
|
||||
src_node_offset,
|
||||
.{ .multi = .{ .prong = multi_i, .item = @intCast(u32, item_i) } },
|
||||
);
|
||||
}
|
||||
|
||||
@ -2981,14 +2981,19 @@ fn validateSwitchItemBool(
|
||||
}
|
||||
}
|
||||
|
||||
const ValueSrcMap = std.HashMap(Value, AstGen.SwitchProngSrc, Value.hash, Value.eql, std.hash_map.DefaultMaxLoadPercentage);
|
||||
|
||||
fn validateSwitchItemSparse(
|
||||
sema: *Sema,
|
||||
block: *Scope.Block,
|
||||
seen_values: *ValueSrcMap,
|
||||
item_ref: zir.Inst.Ref,
|
||||
src_node_offset: i32,
|
||||
switch_prong_src: AstGen.SwitchProngSrc,
|
||||
) InnerError!void {
|
||||
@panic("TODO");
|
||||
const item_val = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none);
|
||||
const entry = (try seen_values.fetchPut(item_val, switch_prong_src)) orelse return;
|
||||
return sema.validateSwitchDupe(block, entry.value, switch_prong_src, src_node_offset);
|
||||
}
|
||||
|
||||
fn validateSwitchNoRange(
|
||||
|
||||
@ -359,6 +359,22 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
, &.{
|
||||
":6:9: error: duplicate switch value",
|
||||
});
|
||||
|
||||
// Sparse (no range capable) switch expression has duplicate case value.
|
||||
case.addError(
|
||||
\\export fn main() c_int {
|
||||
\\ const A: type = i32;
|
||||
\\ const b: c_int = switch (A) {
|
||||
\\ i32 => 1,
|
||||
\\ bool => 2,
|
||||
\\ f64, i32 => 3,
|
||||
\\ else => 4,
|
||||
\\ };
|
||||
\\}
|
||||
, &.{
|
||||
":6:14: error: duplicate switch value",
|
||||
":4:9: note: previous value here",
|
||||
});
|
||||
}
|
||||
//{
|
||||
// var case = ctx.exeFromCompiledC("optionals", .{});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user