mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
parent
42db468dcb
commit
51b1083d66
3 changed files with 42 additions and 20 deletions
23
src/Sema.zig
23
src/Sema.zig
|
|
@ -10343,6 +10343,9 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||||
}
|
}
|
||||||
if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, special.body, operand);
|
if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, special.body, operand);
|
||||||
if (special.is_inline) child_block.inline_case_capture = operand;
|
if (special.is_inline) child_block.inline_case_capture = operand;
|
||||||
|
if (empty_enum) {
|
||||||
|
return Air.Inst.Ref.void_value;
|
||||||
|
}
|
||||||
return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges);
|
return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30479,23 +30482,23 @@ pub fn typeHasOnePossibleValue(
|
||||||
if (enum_obj.tag_ty.hasRuntimeBits()) {
|
if (enum_obj.tag_ty.hasRuntimeBits()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (enum_obj.fields.count() == 1) {
|
switch (enum_obj.fields.count()) {
|
||||||
if (enum_obj.values.count() == 0) {
|
0 => return Value.initTag(.unreachable_value),
|
||||||
|
1 => if (enum_obj.values.count() == 0) {
|
||||||
return Value.zero; // auto-numbered
|
return Value.zero; // auto-numbered
|
||||||
} else {
|
} else {
|
||||||
return enum_obj.values.keys()[0];
|
return enum_obj.values.keys()[0];
|
||||||
}
|
},
|
||||||
} else {
|
else => return null,
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.enum_simple => {
|
.enum_simple => {
|
||||||
const resolved_ty = try sema.resolveTypeFields(block, src, ty);
|
const resolved_ty = try sema.resolveTypeFields(block, src, ty);
|
||||||
const enum_simple = resolved_ty.castTag(.enum_simple).?.data;
|
const enum_simple = resolved_ty.castTag(.enum_simple).?.data;
|
||||||
if (enum_simple.fields.count() == 1) {
|
switch (enum_simple.fields.count()) {
|
||||||
return Value.zero;
|
0 => return Value.initTag(.unreachable_value),
|
||||||
} else {
|
1 => return Value.zero,
|
||||||
return null;
|
else => return null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.enum_nonexhaustive => {
|
.enum_nonexhaustive => {
|
||||||
|
|
@ -30512,7 +30515,7 @@ pub fn typeHasOnePossibleValue(
|
||||||
const tag_val = (try sema.typeHasOnePossibleValue(block, src, union_obj.tag_ty)) orelse
|
const tag_val = (try sema.typeHasOnePossibleValue(block, src, union_obj.tag_ty)) orelse
|
||||||
return null;
|
return null;
|
||||||
const fields = union_obj.fields.values();
|
const fields = union_obj.fields.values();
|
||||||
if (fields.len == 0) return Value.initTag(.empty_struct_value);
|
if (fields.len == 0) return Value.initTag(.unreachable_value);
|
||||||
const only_field = fields[0];
|
const only_field = fields[0];
|
||||||
if (only_field.ty.eql(resolved_ty, sema.mod)) {
|
if (only_field.ty.eql(resolved_ty, sema.mod)) {
|
||||||
const msg = try Module.ErrorMsg.create(
|
const msg = try Module.ErrorMsg.create(
|
||||||
|
|
|
||||||
21
src/type.zig
21
src/type.zig
|
|
@ -5015,22 +5015,22 @@ pub const Type = extern union {
|
||||||
if (enum_full.tag_ty.hasRuntimeBits()) {
|
if (enum_full.tag_ty.hasRuntimeBits()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (enum_full.fields.count() == 1) {
|
switch (enum_full.fields.count()) {
|
||||||
if (enum_full.values.count() == 0) {
|
0 => return Value.initTag(.unreachable_value),
|
||||||
return Value.zero;
|
1 => if (enum_full.values.count() == 0) {
|
||||||
|
return Value.zero; // auto-numbered
|
||||||
} else {
|
} else {
|
||||||
return enum_full.values.keys()[0];
|
return enum_full.values.keys()[0];
|
||||||
}
|
},
|
||||||
} else {
|
else => return null,
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.enum_simple => {
|
.enum_simple => {
|
||||||
const enum_simple = ty.castTag(.enum_simple).?.data;
|
const enum_simple = ty.castTag(.enum_simple).?.data;
|
||||||
if (enum_simple.fields.count() == 1) {
|
switch (enum_simple.fields.count()) {
|
||||||
return Value.zero;
|
0 => return Value.initTag(.unreachable_value),
|
||||||
} else {
|
1 => return Value.zero,
|
||||||
return null;
|
else => return null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.enum_nonexhaustive => {
|
.enum_nonexhaustive => {
|
||||||
|
|
@ -5044,6 +5044,7 @@ pub const Type = extern union {
|
||||||
.@"union", .union_safety_tagged, .union_tagged => {
|
.@"union", .union_safety_tagged, .union_tagged => {
|
||||||
const union_obj = ty.cast(Payload.Union).?.data;
|
const union_obj = ty.cast(Payload.Union).?.data;
|
||||||
const tag_val = union_obj.tag_ty.onePossibleValue() orelse return null;
|
const tag_val = union_obj.tag_ty.onePossibleValue() orelse return null;
|
||||||
|
if (union_obj.fields.count() == 0) return Value.initTag(.unreachable_value);
|
||||||
const only_field = union_obj.fields.values()[0];
|
const only_field = union_obj.fields.values()[0];
|
||||||
const val_val = only_field.ty.onePossibleValue() orelse return null;
|
const val_val = only_field.ty.onePossibleValue() orelse return null;
|
||||||
_ = tag_val;
|
_ = tag_val;
|
||||||
|
|
|
||||||
|
|
@ -48,3 +48,21 @@ test "empty extern union" {
|
||||||
try expect(@sizeOf(U) == 0);
|
try expect(@sizeOf(U) == 0);
|
||||||
try expect(@alignOf(U) == 1);
|
try expect(@alignOf(U) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "empty union passed as argument" {
|
||||||
|
const U = union(enum) {
|
||||||
|
fn f(u: @This()) void {
|
||||||
|
switch (u) {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
U.f(@as(U, undefined));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "empty enum passed as argument" {
|
||||||
|
const E = enum {
|
||||||
|
fn f(e: @This()) void {
|
||||||
|
switch (e) {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
E.f(@as(E, undefined));
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue