mirror of
https://github.com/ziglang/zig.git
synced 2025-12-23 22:53:06 +00:00
commit
9cca6728e5
@ -1164,6 +1164,10 @@ fn fnProtoExpr(
|
|||||||
const tree = astgen.tree;
|
const tree = astgen.tree;
|
||||||
const token_tags = tree.tokens.items(.tag);
|
const token_tags = tree.tokens.items(.tag);
|
||||||
|
|
||||||
|
if (fn_proto.name_token) |some| {
|
||||||
|
return astgen.failTok(some, "function type cannot have a name", .{});
|
||||||
|
}
|
||||||
|
|
||||||
const is_extern = blk: {
|
const is_extern = blk: {
|
||||||
const maybe_extern_token = fn_proto.extern_export_inline_token orelse break :blk false;
|
const maybe_extern_token = fn_proto.extern_export_inline_token orelse break :blk false;
|
||||||
break :blk token_tags[maybe_extern_token] == .keyword_extern;
|
break :blk token_tags[maybe_extern_token] == .keyword_extern;
|
||||||
|
|||||||
53
src/Sema.zig
53
src/Sema.zig
@ -2497,18 +2497,6 @@ fn zirEnumDecl(
|
|||||||
extra_index = try mod.scanNamespace(&enum_obj.namespace, extra_index, decls_len, new_decl);
|
extra_index = try mod.scanNamespace(&enum_obj.namespace, extra_index, decls_len, new_decl);
|
||||||
|
|
||||||
const body = sema.code.extra[extra_index..][0..body_len];
|
const body = sema.code.extra[extra_index..][0..body_len];
|
||||||
if (fields_len == 0) {
|
|
||||||
assert(body.len == 0);
|
|
||||||
if (tag_type_ref != .none) {
|
|
||||||
const ty = try sema.resolveType(block, tag_ty_src, tag_type_ref);
|
|
||||||
if (ty.zigTypeTag() != .Int and ty.zigTypeTag() != .ComptimeInt) {
|
|
||||||
return sema.fail(block, tag_ty_src, "expected integer tag type, found '{}'", .{ty.fmt(sema.mod)});
|
|
||||||
}
|
|
||||||
enum_obj.tag_ty = try ty.copy(new_decl_arena_allocator);
|
|
||||||
enum_obj.tag_ty_inferred = false;
|
|
||||||
}
|
|
||||||
return decl_val;
|
|
||||||
}
|
|
||||||
extra_index += body.len;
|
extra_index += body.len;
|
||||||
|
|
||||||
const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable;
|
const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable;
|
||||||
@ -2566,6 +2554,9 @@ fn zirEnumDecl(
|
|||||||
}
|
}
|
||||||
enum_obj.tag_ty = try ty.copy(decl_arena_allocator);
|
enum_obj.tag_ty = try ty.copy(decl_arena_allocator);
|
||||||
enum_obj.tag_ty_inferred = false;
|
enum_obj.tag_ty_inferred = false;
|
||||||
|
} else if (fields_len == 0) {
|
||||||
|
enum_obj.tag_ty = try Type.Tag.int_unsigned.create(decl_arena_allocator, 0);
|
||||||
|
enum_obj.tag_ty_inferred = true;
|
||||||
} else {
|
} else {
|
||||||
const bits = std.math.log2_int_ceil(usize, fields_len);
|
const bits = std.math.log2_int_ceil(usize, fields_len);
|
||||||
enum_obj.tag_ty = try Type.Tag.int_unsigned.create(decl_arena_allocator, bits);
|
enum_obj.tag_ty = try Type.Tag.int_unsigned.create(decl_arena_allocator, bits);
|
||||||
@ -3788,6 +3779,7 @@ fn validateStructInit(
|
|||||||
if ((is_comptime or block.is_comptime) and
|
if ((is_comptime or block.is_comptime) and
|
||||||
(try sema.resolveDefinedValue(block, init_src, struct_ptr)) != null)
|
(try sema.resolveDefinedValue(block, init_src, struct_ptr)) != null)
|
||||||
{
|
{
|
||||||
|
try sema.resolveStructLayout(block, init_src, struct_ty);
|
||||||
// In this case the only thing we need to do is evaluate the implicit
|
// In this case the only thing we need to do is evaluate the implicit
|
||||||
// store instructions for default field values, and report any missing fields.
|
// store instructions for default field values, and report any missing fields.
|
||||||
// Avoid the cost of the extra machinery for detecting a comptime struct init value.
|
// Avoid the cost of the extra machinery for detecting a comptime struct init value.
|
||||||
@ -3982,6 +3974,7 @@ fn validateStructInit(
|
|||||||
try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store);
|
try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
try sema.resolveStructLayout(block, init_src, struct_ty);
|
||||||
|
|
||||||
// Our task is to insert `store` instructions for all the default field values.
|
// Our task is to insert `store` instructions for all the default field values.
|
||||||
for (found_fields) |field_ptr, i| {
|
for (found_fields) |field_ptr, i| {
|
||||||
@ -9003,6 +8996,9 @@ fn zirSwitchCond(
|
|||||||
.ErrorSet,
|
.ErrorSet,
|
||||||
.Enum,
|
.Enum,
|
||||||
=> {
|
=> {
|
||||||
|
if (operand_ty.isSlice()) {
|
||||||
|
return sema.fail(block, src, "switch on type '{}'", .{operand_ty.fmt(sema.mod)});
|
||||||
|
}
|
||||||
if ((try sema.typeHasOnePossibleValue(block, operand_src, operand_ty))) |opv| {
|
if ((try sema.typeHasOnePossibleValue(block, operand_src, operand_ty))) |opv| {
|
||||||
return sema.addConstant(operand_ty, opv);
|
return sema.addConstant(operand_ty, opv);
|
||||||
}
|
}
|
||||||
@ -15849,6 +15845,7 @@ fn finishStructInit(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_ref) {
|
if (is_ref) {
|
||||||
|
try sema.resolveStructLayout(block, dest_src, struct_ty);
|
||||||
const target = sema.mod.getTarget();
|
const target = sema.mod.getTarget();
|
||||||
const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{
|
const alloc_ty = try Type.ptr(sema.arena, sema.mod, .{
|
||||||
.pointee_type = struct_ty,
|
.pointee_type = struct_ty,
|
||||||
@ -21895,17 +21892,18 @@ fn unionFieldPtr(
|
|||||||
if (union_val.isUndef()) {
|
if (union_val.isUndef()) {
|
||||||
return sema.failWithUseOfUndef(block, src);
|
return sema.failWithUseOfUndef(block, src);
|
||||||
}
|
}
|
||||||
|
const enum_field_index = union_obj.tag_ty.enumFieldIndex(field_name).?;
|
||||||
const tag_and_val = union_val.castTag(.@"union").?.data;
|
const tag_and_val = union_val.castTag(.@"union").?.data;
|
||||||
var field_tag_buf: Value.Payload.U32 = .{
|
var field_tag_buf: Value.Payload.U32 = .{
|
||||||
.base = .{ .tag = .enum_field_index },
|
.base = .{ .tag = .enum_field_index },
|
||||||
.data = field_index,
|
.data = @intCast(u32, enum_field_index),
|
||||||
};
|
};
|
||||||
const field_tag = Value.initPayload(&field_tag_buf.base);
|
const field_tag = Value.initPayload(&field_tag_buf.base);
|
||||||
const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, sema.mod);
|
const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, sema.mod);
|
||||||
if (!tag_matches) {
|
if (!tag_matches) {
|
||||||
const msg = msg: {
|
const msg = msg: {
|
||||||
const active_index = tag_and_val.tag.castTag(.enum_field_index).?.data;
|
const active_index = tag_and_val.tag.castTag(.enum_field_index).?.data;
|
||||||
const active_field_name = union_obj.fields.keys()[active_index];
|
const active_field_name = union_obj.tag_ty.enumFieldName(active_index);
|
||||||
const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });
|
const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });
|
||||||
errdefer msg.destroy(sema.gpa);
|
errdefer msg.destroy(sema.gpa);
|
||||||
try sema.addDeclaredHereNote(msg, union_ty);
|
try sema.addDeclaredHereNote(msg, union_ty);
|
||||||
@ -21930,12 +21928,11 @@ fn unionFieldPtr(
|
|||||||
if (!initializing and union_obj.layout == .Auto and block.wantSafety() and
|
if (!initializing and union_obj.layout == .Auto and block.wantSafety() and
|
||||||
union_ty.unionTagTypeSafety() != null and union_obj.fields.count() > 1)
|
union_ty.unionTagTypeSafety() != null and union_obj.fields.count() > 1)
|
||||||
{
|
{
|
||||||
const enum_ty = union_ty.unionTagTypeHypothetical();
|
|
||||||
const wanted_tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index);
|
const wanted_tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index);
|
||||||
const wanted_tag = try sema.addConstant(enum_ty, wanted_tag_val);
|
const wanted_tag = try sema.addConstant(union_obj.tag_ty, wanted_tag_val);
|
||||||
// TODO would it be better if get_union_tag supported pointers to unions?
|
// TODO would it be better if get_union_tag supported pointers to unions?
|
||||||
const union_val = try block.addTyOp(.load, union_ty, union_ptr);
|
const union_val = try block.addTyOp(.load, union_ty, union_ptr);
|
||||||
const active_tag = try block.addTyOp(.get_union_tag, enum_ty, union_val);
|
const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_val);
|
||||||
const ok = try block.addBinOp(.cmp_eq, active_tag, wanted_tag);
|
const ok = try block.addBinOp(.cmp_eq, active_tag, wanted_tag);
|
||||||
try sema.addSafetyCheck(block, ok, .inactive_union_field);
|
try sema.addSafetyCheck(block, ok, .inactive_union_field);
|
||||||
}
|
}
|
||||||
@ -21966,9 +21963,10 @@ fn unionFieldVal(
|
|||||||
if (union_val.isUndef()) return sema.addConstUndef(field.ty);
|
if (union_val.isUndef()) return sema.addConstUndef(field.ty);
|
||||||
|
|
||||||
const tag_and_val = union_val.castTag(.@"union").?.data;
|
const tag_and_val = union_val.castTag(.@"union").?.data;
|
||||||
|
const enum_field_index = union_obj.tag_ty.enumFieldIndex(field_name).?;
|
||||||
var field_tag_buf: Value.Payload.U32 = .{
|
var field_tag_buf: Value.Payload.U32 = .{
|
||||||
.base = .{ .tag = .enum_field_index },
|
.base = .{ .tag = .enum_field_index },
|
||||||
.data = field_index,
|
.data = @intCast(u32, enum_field_index),
|
||||||
};
|
};
|
||||||
const field_tag = Value.initPayload(&field_tag_buf.base);
|
const field_tag = Value.initPayload(&field_tag_buf.base);
|
||||||
const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, sema.mod);
|
const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty, sema.mod);
|
||||||
@ -21979,7 +21977,7 @@ fn unionFieldVal(
|
|||||||
} else {
|
} else {
|
||||||
const msg = msg: {
|
const msg = msg: {
|
||||||
const active_index = tag_and_val.tag.castTag(.enum_field_index).?.data;
|
const active_index = tag_and_val.tag.castTag(.enum_field_index).?.data;
|
||||||
const active_field_name = union_obj.fields.keys()[active_index];
|
const active_field_name = union_obj.tag_ty.enumFieldName(active_index);
|
||||||
const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });
|
const msg = try sema.errMsg(block, src, "access of union field '{s}' while field '{s}' is active", .{ field_name, active_field_name });
|
||||||
errdefer msg.destroy(sema.gpa);
|
errdefer msg.destroy(sema.gpa);
|
||||||
try sema.addDeclaredHereNote(msg, union_ty);
|
try sema.addDeclaredHereNote(msg, union_ty);
|
||||||
@ -22004,10 +22002,9 @@ fn unionFieldVal(
|
|||||||
if (union_obj.layout == .Auto and block.wantSafety() and
|
if (union_obj.layout == .Auto and block.wantSafety() and
|
||||||
union_ty.unionTagTypeSafety() != null and union_obj.fields.count() > 1)
|
union_ty.unionTagTypeSafety() != null and union_obj.fields.count() > 1)
|
||||||
{
|
{
|
||||||
const enum_ty = union_ty.unionTagTypeHypothetical();
|
|
||||||
const wanted_tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index);
|
const wanted_tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index);
|
||||||
const wanted_tag = try sema.addConstant(enum_ty, wanted_tag_val);
|
const wanted_tag = try sema.addConstant(union_obj.tag_ty, wanted_tag_val);
|
||||||
const active_tag = try block.addTyOp(.get_union_tag, enum_ty, union_byval);
|
const active_tag = try block.addTyOp(.get_union_tag, union_obj.tag_ty, union_byval);
|
||||||
const ok = try block.addBinOp(.cmp_eq, active_tag, wanted_tag);
|
const ok = try block.addBinOp(.cmp_eq, active_tag, wanted_tag);
|
||||||
try sema.addSafetyCheck(block, ok, .inactive_union_field);
|
try sema.addSafetyCheck(block, ok, .inactive_union_field);
|
||||||
}
|
}
|
||||||
@ -22254,8 +22251,7 @@ fn tupleField(
|
|||||||
|
|
||||||
if (try sema.resolveMaybeUndefVal(block, tuple_src, tuple)) |tuple_val| {
|
if (try sema.resolveMaybeUndefVal(block, tuple_src, tuple)) |tuple_val| {
|
||||||
if (tuple_val.isUndef()) return sema.addConstUndef(field_ty);
|
if (tuple_val.isUndef()) return sema.addConstUndef(field_ty);
|
||||||
const field_values = tuple_val.castTag(.aggregate).?.data;
|
return sema.addConstant(field_ty, tuple_val.fieldValue(tuple_ty, field_index));
|
||||||
return sema.addConstant(field_ty, field_values[field_index]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);
|
try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);
|
||||||
@ -28854,10 +28850,11 @@ pub fn typeHasOnePossibleValue(
|
|||||||
|
|
||||||
.tuple, .anon_struct => {
|
.tuple, .anon_struct => {
|
||||||
const tuple = ty.tupleFields();
|
const tuple = ty.tupleFields();
|
||||||
for (tuple.values) |val| {
|
for (tuple.values) |val, i| {
|
||||||
if (val.tag() == .unreachable_value) {
|
const is_comptime = val.tag() != .unreachable_value;
|
||||||
return null; // non-comptime field
|
if (is_comptime) continue;
|
||||||
}
|
if ((try sema.typeHasOnePossibleValue(block, src, tuple.types[i])) != null) continue;
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return Value.initTag(.empty_struct_value);
|
return Value.initTag(.empty_struct_value);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1721,13 +1721,13 @@ const Writer = struct {
|
|||||||
const body = self.code.extra[extra_index..][0..body_len];
|
const body = self.code.extra[extra_index..][0..body_len];
|
||||||
extra_index += body.len;
|
extra_index += body.len;
|
||||||
|
|
||||||
|
const prev_parent_decl_node = self.parent_decl_node;
|
||||||
|
if (src_node) |off| self.parent_decl_node = self.relativeToNodeIndex(off);
|
||||||
|
try self.writeBracedDecl(stream, body);
|
||||||
if (fields_len == 0) {
|
if (fields_len == 0) {
|
||||||
assert(body.len == 0);
|
try stream.writeAll(", {})");
|
||||||
try stream.writeAll("{}, {})");
|
self.parent_decl_node = prev_parent_decl_node;
|
||||||
} else {
|
} else {
|
||||||
const prev_parent_decl_node = self.parent_decl_node;
|
|
||||||
if (src_node) |off| self.parent_decl_node = self.relativeToNodeIndex(off);
|
|
||||||
try self.writeBracedDecl(stream, body);
|
|
||||||
try stream.writeAll(", {\n");
|
try stream.writeAll(", {\n");
|
||||||
|
|
||||||
self.indent += 2;
|
self.indent += 2;
|
||||||
|
|||||||
15
src/type.zig
15
src/type.zig
@ -4979,19 +4979,20 @@ pub const Type = extern union {
|
|||||||
const s = ty.castTag(.@"struct").?.data;
|
const s = ty.castTag(.@"struct").?.data;
|
||||||
assert(s.haveFieldTypes());
|
assert(s.haveFieldTypes());
|
||||||
for (s.fields.values()) |field| {
|
for (s.fields.values()) |field| {
|
||||||
if (field.ty.onePossibleValue() == null) {
|
if (field.is_comptime) continue;
|
||||||
return null;
|
if (field.ty.onePossibleValue() != null) continue;
|
||||||
}
|
return null;
|
||||||
}
|
}
|
||||||
return Value.initTag(.empty_struct_value);
|
return Value.initTag(.empty_struct_value);
|
||||||
},
|
},
|
||||||
|
|
||||||
.tuple, .anon_struct => {
|
.tuple, .anon_struct => {
|
||||||
const tuple = ty.tupleFields();
|
const tuple = ty.tupleFields();
|
||||||
for (tuple.values) |val| {
|
for (tuple.values) |val, i| {
|
||||||
if (val.tag() == .unreachable_value) {
|
const is_comptime = val.tag() != .unreachable_value;
|
||||||
return null; // non-comptime field
|
if (is_comptime) continue;
|
||||||
}
|
if (tuple.types[i].onePossibleValue() != null) continue;
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return Value.initTag(.empty_struct_value);
|
return Value.initTag(.empty_struct_value);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1170,3 +1170,8 @@ test "switch on an extern enum with negative value" {
|
|||||||
Foo.Bar => return,
|
Foo.Bar => return,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "Non-exhaustive enum with nonstandard int size behaves correctly" {
|
||||||
|
const E = enum(u15) { _ };
|
||||||
|
try expect(@sizeOf(E) == @sizeOf(u15));
|
||||||
|
}
|
||||||
|
|||||||
@ -564,3 +564,18 @@ test "nested packed struct field access test" {
|
|||||||
try std.testing.expect(arg.g.h == 6);
|
try std.testing.expect(arg.g.h == 6);
|
||||||
try std.testing.expect(arg.g.i == 8);
|
try std.testing.expect(arg.g.i == 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "runtime init of unnamed packed struct type" {
|
||||||
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||||
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||||
|
|
||||||
|
var z: u8 = 123;
|
||||||
|
try (packed struct {
|
||||||
|
x: u8,
|
||||||
|
pub fn m(s: @This()) !void {
|
||||||
|
try expect(s.x == 123);
|
||||||
|
}
|
||||||
|
}{ .x = z }).m();
|
||||||
|
}
|
||||||
|
|||||||
@ -301,3 +301,30 @@ test "tuple type with void field" {
|
|||||||
const x = T{{}};
|
const x = T{{}};
|
||||||
try expect(@TypeOf(x[0]) == void);
|
try expect(@TypeOf(x[0]) == void);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "zero sized struct in tuple handled correctly" {
|
||||||
|
const State = struct {
|
||||||
|
const Self = @This();
|
||||||
|
data: @Type(.{
|
||||||
|
.Struct = .{
|
||||||
|
.is_tuple = true,
|
||||||
|
.layout = .Auto,
|
||||||
|
.decls = &.{},
|
||||||
|
.fields = &.{.{
|
||||||
|
.name = "0",
|
||||||
|
.field_type = struct {},
|
||||||
|
.default_value = null,
|
||||||
|
.is_comptime = false,
|
||||||
|
.alignment = 0,
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
pub fn do(this: Self) usize {
|
||||||
|
return @sizeOf(@TypeOf(this));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var s: State = undefined;
|
||||||
|
try expect(s.do() == 0);
|
||||||
|
}
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
const Enum = enum(u32) { a, b };
|
||||||
|
const TaggedUnion = union(Enum) {
|
||||||
|
b: []const u8,
|
||||||
|
a: []const u8,
|
||||||
|
};
|
||||||
|
pub export fn entry() void {
|
||||||
|
const result = TaggedUnion{ .b = "b" };
|
||||||
|
_ = result.b;
|
||||||
|
_ = result.a;
|
||||||
|
}
|
||||||
|
pub export fn entry1() void {
|
||||||
|
const result = TaggedUnion{ .b = "b" };
|
||||||
|
_ = &result.b;
|
||||||
|
_ = &result.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
// backend=stage2
|
||||||
|
// target=native
|
||||||
|
//
|
||||||
|
// :9:15: error: access of union field 'a' while field 'b' is active
|
||||||
|
// :2:21: note: union declared here
|
||||||
|
// :14:16: error: access of union field 'a' while field 'b' is active
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
pub export fn entry() void {
|
||||||
|
_ = .{ .a = 0, .a = 1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
// backend=stage2
|
||||||
|
// target=native
|
||||||
|
//
|
||||||
|
// :2:21: error: duplicate field
|
||||||
|
// :2:13: note: other field here
|
||||||
7
test/cases/compile_errors/function_type_named.zig
Normal file
7
test/cases/compile_errors/function_type_named.zig
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
const aFunc = fn someFunc(x: i32) void;
|
||||||
|
|
||||||
|
// error
|
||||||
|
// backend=stage2
|
||||||
|
// target=native
|
||||||
|
//
|
||||||
|
// :1:18: error: function type cannot have a name
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
const MyStruct = struct { x: i32 };
|
||||||
|
|
||||||
|
fn hi(comptime T: type) usize {
|
||||||
|
return @sizeOf(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const value = hi(MyStruct{ .x = 12 });
|
||||||
|
|
||||||
|
// error
|
||||||
|
// backend=stage2
|
||||||
|
// target=native
|
||||||
|
//
|
||||||
|
// :7:33: error: expected type 'type', found 'tmp.MyStruct'
|
||||||
|
// :1:18: note: struct declared here
|
||||||
13
test/cases/compile_errors/switch_on_slice.zig
Normal file
13
test/cases/compile_errors/switch_on_slice.zig
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
pub export fn entry() void {
|
||||||
|
var a: [:0]const u8 = "foo";
|
||||||
|
switch (a) {
|
||||||
|
"--version", "version" => unreachable,
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
// backend=stage2
|
||||||
|
// target=native
|
||||||
|
//
|
||||||
|
// :3:13: error: switch on type '[:0]const u8'
|
||||||
Loading…
x
Reference in New Issue
Block a user