Merge pull request #13091 from Vexu/small-proposals
Implement some small proposals
This commit is contained in:
@@ -4064,7 +4064,7 @@ test "labeled break from labeled block expression" {
|
||||
|
||||
{#header_open|Shadowing#}
|
||||
<p>{#link|Identifiers#} are never allowed to "hide" other identifiers by using the same name:</p>
|
||||
{#code_begin|test_err|local shadows declaration#}
|
||||
{#code_begin|test_err|local variable shadows declaration#}
|
||||
const pi = 3.14;
|
||||
|
||||
test "inside test block" {
|
||||
|
||||
@@ -2004,7 +2004,8 @@ fn blockExpr(
|
||||
return labeledBlockExpr(gz, scope, rl, block_node, statements);
|
||||
}
|
||||
|
||||
try blockExprStmts(gz, scope, statements);
|
||||
var sub_gz = gz.makeSubBlock(scope);
|
||||
try blockExprStmts(&sub_gz, &sub_gz.base, statements);
|
||||
return rvalue(gz, rl, .void_value, block_node);
|
||||
}
|
||||
|
||||
@@ -2772,7 +2773,13 @@ fn varDecl(
|
||||
}
|
||||
const ident_name = try astgen.identAsString(name_token);
|
||||
|
||||
try astgen.detectLocalShadowing(scope, ident_name, name_token, ident_name_raw);
|
||||
try astgen.detectLocalShadowing(
|
||||
scope,
|
||||
ident_name,
|
||||
name_token,
|
||||
ident_name_raw,
|
||||
if (token_tags[var_decl.ast.mut_token] == .keyword_const) .@"local constant" else .@"local variable",
|
||||
);
|
||||
|
||||
if (var_decl.ast.init_node == 0) {
|
||||
return astgen.failNode(node, "variables must be initialized", .{});
|
||||
@@ -3502,7 +3509,7 @@ fn fnDecl(
|
||||
|
||||
const param_name = try astgen.identAsString(name_token);
|
||||
if (!is_extern) {
|
||||
try astgen.detectLocalShadowing(params_scope, param_name, name_token, name_bytes);
|
||||
try astgen.detectLocalShadowing(params_scope, param_name, name_token, name_bytes, .@"function parameter");
|
||||
}
|
||||
break :blk param_name;
|
||||
} else if (!is_extern) {
|
||||
@@ -5181,7 +5188,7 @@ fn orelseCatchExpr(
|
||||
}
|
||||
const err_name = try astgen.identAsString(payload);
|
||||
|
||||
try astgen.detectLocalShadowing(scope, err_name, payload, err_str);
|
||||
try astgen.detectLocalShadowing(scope, err_name, payload, err_str, .@"capture");
|
||||
|
||||
err_val_scope = .{
|
||||
.parent = &else_scope.base,
|
||||
@@ -5480,7 +5487,7 @@ fn ifExpr(
|
||||
const token_name_str = tree.tokenSlice(token_name_index);
|
||||
if (mem.eql(u8, "_", token_name_str))
|
||||
break :s &then_scope.base;
|
||||
try astgen.detectLocalShadowing(&then_scope.base, ident_name, token_name_index, token_name_str);
|
||||
try astgen.detectLocalShadowing(&then_scope.base, ident_name, token_name_index, token_name_str, .@"capture");
|
||||
payload_val_scope = .{
|
||||
.parent = &then_scope.base,
|
||||
.gen_zir = &then_scope,
|
||||
@@ -5505,7 +5512,7 @@ fn ifExpr(
|
||||
break :s &then_scope.base;
|
||||
const payload_inst = try then_scope.addUnNode(tag, cond.inst, if_full.ast.then_expr);
|
||||
const ident_name = try astgen.identAsString(ident_token);
|
||||
try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes);
|
||||
try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .@"capture");
|
||||
payload_val_scope = .{
|
||||
.parent = &then_scope.base,
|
||||
.gen_zir = &then_scope,
|
||||
@@ -5551,7 +5558,7 @@ fn ifExpr(
|
||||
const error_token_str = tree.tokenSlice(error_token);
|
||||
if (mem.eql(u8, "_", error_token_str))
|
||||
break :s &else_scope.base;
|
||||
try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token, error_token_str);
|
||||
try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token, error_token_str, .@"capture");
|
||||
payload_val_scope = .{
|
||||
.parent = &else_scope.base,
|
||||
.gen_zir = &else_scope,
|
||||
@@ -5816,7 +5823,7 @@ fn whileExpr(
|
||||
break :s &then_scope.base;
|
||||
const payload_name_loc = payload_token + @boolToInt(payload_is_ref);
|
||||
const ident_name = try astgen.identAsString(payload_name_loc);
|
||||
try astgen.detectLocalShadowing(&then_scope.base, ident_name, payload_name_loc, ident_bytes);
|
||||
try astgen.detectLocalShadowing(&then_scope.base, ident_name, payload_name_loc, ident_bytes, .@"capture");
|
||||
payload_val_scope = .{
|
||||
.parent = &then_scope.base,
|
||||
.gen_zir = &then_scope,
|
||||
@@ -5843,7 +5850,7 @@ fn whileExpr(
|
||||
const ident_bytes = tree.tokenSlice(ident_token);
|
||||
if (mem.eql(u8, "_", ident_bytes))
|
||||
break :s &then_scope.base;
|
||||
try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes);
|
||||
try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .@"capture");
|
||||
payload_val_scope = .{
|
||||
.parent = &then_scope.base,
|
||||
.gen_zir = &then_scope,
|
||||
@@ -5919,7 +5926,7 @@ fn whileExpr(
|
||||
const ident_bytes = tree.tokenSlice(error_token);
|
||||
if (mem.eql(u8, ident_bytes, "_"))
|
||||
break :s &else_scope.base;
|
||||
try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token, ident_bytes);
|
||||
try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token, ident_bytes, .@"capture");
|
||||
payload_val_scope = .{
|
||||
.parent = &else_scope.base,
|
||||
.gen_zir = &else_scope,
|
||||
@@ -6092,7 +6099,7 @@ fn forExpr(
|
||||
.lhs = array_ptr,
|
||||
.rhs = index,
|
||||
});
|
||||
try astgen.detectLocalShadowing(&then_scope.base, name_str_index, ident, value_name);
|
||||
try astgen.detectLocalShadowing(&then_scope.base, name_str_index, ident, value_name, .@"capture");
|
||||
payload_val_scope = .{
|
||||
.parent = &then_scope.base,
|
||||
.gen_zir = &then_scope,
|
||||
@@ -6118,7 +6125,7 @@ fn forExpr(
|
||||
return astgen.failTok(index_token, "discard of index capture; omit it instead", .{});
|
||||
}
|
||||
const index_name = try astgen.identAsString(index_token);
|
||||
try astgen.detectLocalShadowing(payload_sub_scope, index_name, index_token, token_bytes);
|
||||
try astgen.detectLocalShadowing(payload_sub_scope, index_name, index_token, token_bytes, .@"loop index capture");
|
||||
index_scope = .{
|
||||
.parent = payload_sub_scope,
|
||||
.gen_zir = &then_scope,
|
||||
@@ -6433,7 +6440,7 @@ fn switchExpr(
|
||||
});
|
||||
}
|
||||
const capture_name = try astgen.identAsString(ident);
|
||||
try astgen.detectLocalShadowing(&case_scope.base, capture_name, ident, ident_slice);
|
||||
try astgen.detectLocalShadowing(&case_scope.base, capture_name, ident, ident_slice, .@"capture");
|
||||
capture_val_scope = .{
|
||||
.parent = &case_scope.base,
|
||||
.gen_zir = &case_scope,
|
||||
@@ -6458,7 +6465,7 @@ fn switchExpr(
|
||||
return astgen.failTok(tag_token, "tag capture on non-inline prong", .{});
|
||||
}
|
||||
const tag_name = try astgen.identAsString(tag_token);
|
||||
try astgen.detectLocalShadowing(payload_sub_scope, tag_name, tag_token, tag_slice);
|
||||
try astgen.detectLocalShadowing(payload_sub_scope, tag_name, tag_token, tag_slice, .@"switch tag capture");
|
||||
tag_inst = @intCast(Zir.Inst.Index, astgen.instructions.len);
|
||||
try astgen.instructions.append(gpa, .{
|
||||
.tag = .switch_capture_tag,
|
||||
@@ -11669,6 +11676,7 @@ fn detectLocalShadowing(
|
||||
ident_name: u32,
|
||||
name_token: Ast.TokenIndex,
|
||||
token_bytes: []const u8,
|
||||
id_cat: Scope.IdCat,
|
||||
) !void {
|
||||
const gpa = astgen.gpa;
|
||||
if (token_bytes[0] != '@' and isPrimitive(token_bytes)) {
|
||||
@@ -11682,6 +11690,7 @@ fn detectLocalShadowing(
|
||||
}
|
||||
|
||||
var s = scope;
|
||||
var outer_scope = false;
|
||||
while (true) switch (s.tag) {
|
||||
.local_val => {
|
||||
const local_val = s.cast(Scope.LocalVal).?;
|
||||
@@ -11689,6 +11698,17 @@ fn detectLocalShadowing(
|
||||
const name_slice = mem.span(astgen.nullTerminatedString(ident_name));
|
||||
const name = try gpa.dupe(u8, name_slice);
|
||||
defer gpa.free(name);
|
||||
if (outer_scope) {
|
||||
return astgen.failTokNotes(name_token, "{s} '{s}' shadows {s} from outer scope", .{
|
||||
@tagName(id_cat), name, @tagName(local_val.id_cat),
|
||||
}, &[_]u32{
|
||||
try astgen.errNoteTok(
|
||||
local_val.token_src,
|
||||
"previous declaration here",
|
||||
.{},
|
||||
),
|
||||
});
|
||||
}
|
||||
return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{
|
||||
@tagName(local_val.id_cat), name,
|
||||
}, &[_]u32{
|
||||
@@ -11707,6 +11727,17 @@ fn detectLocalShadowing(
|
||||
const name_slice = mem.span(astgen.nullTerminatedString(ident_name));
|
||||
const name = try gpa.dupe(u8, name_slice);
|
||||
defer gpa.free(name);
|
||||
if (outer_scope) {
|
||||
return astgen.failTokNotes(name_token, "{s} '{s}' shadows {s} from outer scope", .{
|
||||
@tagName(id_cat), name, @tagName(local_ptr.id_cat),
|
||||
}, &[_]u32{
|
||||
try astgen.errNoteTok(
|
||||
local_ptr.token_src,
|
||||
"previous declaration here",
|
||||
.{},
|
||||
),
|
||||
});
|
||||
}
|
||||
return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{
|
||||
@tagName(local_ptr.id_cat), name,
|
||||
}, &[_]u32{
|
||||
@@ -11720,6 +11751,7 @@ fn detectLocalShadowing(
|
||||
s = local_ptr.parent;
|
||||
},
|
||||
.namespace => {
|
||||
outer_scope = true;
|
||||
const ns = s.cast(Scope.Namespace).?;
|
||||
const decl_node = ns.decls.get(ident_name) orelse {
|
||||
s = ns.parent;
|
||||
@@ -11728,13 +11760,16 @@ fn detectLocalShadowing(
|
||||
const name_slice = mem.span(astgen.nullTerminatedString(ident_name));
|
||||
const name = try gpa.dupe(u8, name_slice);
|
||||
defer gpa.free(name);
|
||||
return astgen.failTokNotes(name_token, "local shadows declaration of '{s}'", .{
|
||||
name,
|
||||
return astgen.failTokNotes(name_token, "{s} shadows declaration of '{s}'", .{
|
||||
@tagName(id_cat), name,
|
||||
}, &[_]u32{
|
||||
try astgen.errNoteNode(decl_node, "declared here", .{}),
|
||||
});
|
||||
},
|
||||
.gen_zir => s = s.cast(GenZir).?.parent,
|
||||
.gen_zir => {
|
||||
s = s.cast(GenZir).?.parent;
|
||||
outer_scope = true;
|
||||
},
|
||||
.defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
|
||||
.top => break,
|
||||
};
|
||||
@@ -11844,8 +11879,8 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast.
|
||||
.local_val => {
|
||||
const local_val = s.cast(Scope.LocalVal).?;
|
||||
if (local_val.name == name_str_index) {
|
||||
return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{
|
||||
@tagName(local_val.id_cat), token_bytes,
|
||||
return astgen.failTokNotes(name_token, "declaration '{s}' shadows {s} from outer scope", .{
|
||||
token_bytes, @tagName(local_val.id_cat),
|
||||
}, &[_]u32{
|
||||
try astgen.errNoteTok(
|
||||
local_val.token_src,
|
||||
@@ -11859,8 +11894,8 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast.
|
||||
.local_ptr => {
|
||||
const local_ptr = s.cast(Scope.LocalPtr).?;
|
||||
if (local_ptr.name == name_str_index) {
|
||||
return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{
|
||||
@tagName(local_ptr.id_cat), token_bytes,
|
||||
return astgen.failTokNotes(name_token, "declaration '{s}' shadows {s} from outer scope", .{
|
||||
token_bytes, @tagName(local_ptr.id_cat),
|
||||
}, &[_]u32{
|
||||
try astgen.errNoteTok(
|
||||
local_ptr.token_src,
|
||||
|
||||
27
src/Sema.zig
27
src/Sema.zig
@@ -7622,6 +7622,10 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
|
||||
const src = inst_data.src();
|
||||
const operand = try sema.resolveInst(inst_data.operand);
|
||||
return sema.analyzeErrUnionCode(block, src, operand);
|
||||
}
|
||||
|
||||
fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref {
|
||||
const operand_ty = sema.typeOf(operand);
|
||||
if (operand_ty.zigTypeTag() != .ErrorUnion) {
|
||||
return sema.fail(block, src, "expected error union type, found '{}'", .{
|
||||
@@ -9998,6 +10002,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges);
|
||||
}
|
||||
|
||||
const backend_supports_is_named_enum = sema.mod.comp.bin_file.options.use_llvm;
|
||||
|
||||
if (scalar_cases_len + multi_cases_len == 0 and !special.is_inline) {
|
||||
if (empty_enum) {
|
||||
return Air.Inst.Ref.void_value;
|
||||
@@ -10008,6 +10014,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
if (err_set and try sema.maybeErrorUnwrap(block, special.body, operand)) {
|
||||
return Air.Inst.Ref.unreachable_value;
|
||||
}
|
||||
if (backend_supports_is_named_enum and block.wantSafety() and operand_ty.zigTypeTag() == .Enum and
|
||||
(!operand_ty.isNonexhaustiveEnum() or union_originally))
|
||||
{
|
||||
const ok = try block.addUnOp(.is_named_enum_value, operand);
|
||||
try sema.addSafetyCheck(block, ok, .corrupt_switch);
|
||||
}
|
||||
return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges);
|
||||
}
|
||||
|
||||
@@ -10465,6 +10477,13 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
case_block.wip_capture_scope = wip_captures.scope;
|
||||
case_block.inline_case_capture = .none;
|
||||
|
||||
if (backend_supports_is_named_enum and special.body.len != 0 and block.wantSafety() and
|
||||
operand_ty.zigTypeTag() == .Enum and (!operand_ty.isNonexhaustiveEnum() or union_originally))
|
||||
{
|
||||
const ok = try case_block.addUnOp(.is_named_enum_value, operand);
|
||||
try sema.addSafetyCheck(&case_block, ok, .corrupt_switch);
|
||||
}
|
||||
|
||||
const analyze_body = if (union_originally and !special.is_inline)
|
||||
for (seen_enum_fields) |seen_field, index| {
|
||||
if (seen_field != null) continue;
|
||||
@@ -14114,6 +14133,14 @@ fn analyzeCmp(
|
||||
// numeric types.
|
||||
return sema.cmpNumeric(block, src, lhs, rhs, op, lhs_src, rhs_src);
|
||||
}
|
||||
if (is_equality_cmp and lhs_ty.zigTypeTag() == .ErrorUnion and rhs_ty.zigTypeTag() == .ErrorSet) {
|
||||
const casted_lhs = try sema.analyzeErrUnionCode(block, lhs_src, lhs);
|
||||
return sema.cmpSelf(block, src, casted_lhs, rhs, op, lhs_src, rhs_src);
|
||||
}
|
||||
if (is_equality_cmp and lhs_ty.zigTypeTag() == .ErrorSet and rhs_ty.zigTypeTag() == .ErrorUnion) {
|
||||
const casted_rhs = try sema.analyzeErrUnionCode(block, rhs_src, rhs);
|
||||
return sema.cmpSelf(block, src, lhs, casted_rhs, op, lhs_src, rhs_src);
|
||||
}
|
||||
const instructions = &[_]Air.Inst.Ref{ lhs, rhs };
|
||||
const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } });
|
||||
if (!resolved_type.isSelfComparable(is_equality_cmp)) {
|
||||
|
||||
@@ -809,3 +809,24 @@ test "alignment of wrapping an error union payload" {
|
||||
};
|
||||
try expect((S.foo() catch unreachable).x == 1234);
|
||||
}
|
||||
|
||||
test "compare error union and error set" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
|
||||
var a: anyerror = error.Foo;
|
||||
var b: anyerror!u32 = error.Bar;
|
||||
|
||||
try expect(a != b);
|
||||
try expect(b != a);
|
||||
|
||||
b = error.Foo;
|
||||
|
||||
try expect(a == b);
|
||||
try expect(b == a);
|
||||
|
||||
b = 2;
|
||||
|
||||
try expect(a != b);
|
||||
try expect(b != a);
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
export fn entry() void {
|
||||
var number_or_error: anyerror!i32 = error.SomethingAwful;
|
||||
_ = number_or_error == error.SomethingAwful;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:25: error: operator == not allowed for type 'anyerror!i32'
|
||||
@@ -16,7 +16,7 @@ fn bar(a: usize) void {
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:15: error: redeclaration of function parameter 'a'
|
||||
// :3:15: error: declaration 'a' shadows function parameter from outer scope
|
||||
// :1:8: note: previous declaration here
|
||||
// :9:19: error: redeclaration of function parameter 'a'
|
||||
// :9:19: error: declaration 'a' shadows function parameter from outer scope
|
||||
// :6:8: note: previous declaration here
|
||||
|
||||
@@ -8,5 +8,5 @@ fn foo() void {}
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:9: error: local shadows declaration of 'foo'
|
||||
// :2:9: error: local variable shadows declaration of 'foo'
|
||||
// :5:1: note: declared here
|
||||
|
||||
@@ -7,5 +7,5 @@ export fn entry() void { f(1); }
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:11: error: redeclaration of function parameter 'a'
|
||||
// :2:11: error: local constant 'a' shadows function parameter from outer scope
|
||||
// :1:6: note: previous declaration here
|
||||
|
||||
@@ -10,5 +10,5 @@ export fn entry() void {
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :5:9: error: local shadows declaration of 'Bar'
|
||||
// :5:9: error: local variable shadows declaration of 'Bar'
|
||||
// :2:1: note: declared here
|
||||
|
||||
@@ -8,5 +8,5 @@ export fn entry() void {
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:6: error: local shadows declaration of 'Foo'
|
||||
// :2:6: error: function parameter shadows declaration of 'Foo'
|
||||
// :1:1: note: declared here
|
||||
|
||||
@@ -10,5 +10,5 @@ fn foo() void {
|
||||
//
|
||||
// :3:1: error: redeclaration of 'entry'
|
||||
// :2:1: note: other declaration here
|
||||
// :6:9: error: local shadows declaration of 'foo'
|
||||
// :6:9: error: local variable shadows declaration of 'foo'
|
||||
// :5:1: note: declared here
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "switch on corrupt value")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
const E = enum(u32) {
|
||||
one = 1,
|
||||
two = 2,
|
||||
};
|
||||
pub fn main() !void {
|
||||
var a: E = undefined;
|
||||
@ptrCast(*u32, &a).* = 255;
|
||||
switch (a) {
|
||||
.one => @panic("one"),
|
||||
else => @panic("else"),
|
||||
}
|
||||
}
|
||||
// run
|
||||
// backend=llvm
|
||||
// target=native
|
||||
@@ -0,0 +1,29 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "switch on corrupt value")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
const E = enum(u16) {
|
||||
one = 1,
|
||||
two = 2,
|
||||
_,
|
||||
};
|
||||
const U = union(E) {
|
||||
one: u16,
|
||||
two: u16,
|
||||
};
|
||||
pub fn main() !void {
|
||||
var a: U = undefined;
|
||||
@ptrCast(*align(@alignOf(U)) u32, &a).* = 0xFFFF_FFFF;
|
||||
switch (a) {
|
||||
.one => @panic("one"),
|
||||
else => @panic("else"),
|
||||
}
|
||||
}
|
||||
// run
|
||||
// backend=llvm
|
||||
// target=native
|
||||
23
test/cases/safety/switch else on corrupt enum value.zig
Normal file
23
test/cases/safety/switch else on corrupt enum value.zig
Normal file
@@ -0,0 +1,23 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
|
||||
_ = stack_trace;
|
||||
if (std.mem.eql(u8, message, "switch on corrupt value")) {
|
||||
std.process.exit(0);
|
||||
}
|
||||
std.process.exit(1);
|
||||
}
|
||||
const E = enum(u32) {
|
||||
one = 1,
|
||||
two = 2,
|
||||
};
|
||||
pub fn main() !void {
|
||||
var a: E = undefined;
|
||||
@ptrCast(*u32, &a).* = 255;
|
||||
switch (a) {
|
||||
else => @panic("else"),
|
||||
}
|
||||
}
|
||||
// run
|
||||
// backend=llvm
|
||||
// target=native
|
||||
@@ -5,5 +5,5 @@ pub fn main() void {
|
||||
|
||||
// error
|
||||
//
|
||||
// :3:9: error: local shadows declaration of 'testing'
|
||||
// :3:9: error: local variable shadows declaration of 'testing'
|
||||
// :1:1: note: declared here
|
||||
|
||||
@@ -6,5 +6,5 @@ pub fn main() void {
|
||||
|
||||
// error
|
||||
//
|
||||
// :3:19: error: redeclaration of local variable 'i'
|
||||
// :3:19: error: loop index capture 'i' shadows local variable from outer scope
|
||||
// :2:9: note: previous declaration here
|
||||
|
||||
@@ -6,5 +6,5 @@ pub fn main() void {
|
||||
|
||||
// error
|
||||
//
|
||||
// :3:16: error: redeclaration of local variable 'i'
|
||||
// :3:16: error: capture 'i' shadows local variable from outer scope
|
||||
// :2:9: note: previous declaration here
|
||||
|
||||
@@ -6,5 +6,5 @@ pub fn main() void {
|
||||
|
||||
// error
|
||||
//
|
||||
// :3:18: error: redeclaration of local variable 'i'
|
||||
// :3:18: error: capture 'i' shadows local variable from outer scope
|
||||
// :2:9: note: previous declaration here
|
||||
|
||||
@@ -9,5 +9,5 @@ pub fn main() void {
|
||||
|
||||
// error
|
||||
//
|
||||
// :5:13: error: redeclaration of local variable 'i'
|
||||
// :5:13: error: capture 'i' shadows local variable from outer scope
|
||||
// :2:9: note: previous declaration here
|
||||
|
||||
@@ -5,5 +5,5 @@ pub fn main() void {
|
||||
|
||||
// error
|
||||
//
|
||||
// :3:16: error: redeclaration of local variable 'i'
|
||||
// :3:16: error: capture 'i' shadows local variable from outer scope
|
||||
// :2:9: note: previous declaration here
|
||||
|
||||
@@ -5,5 +5,5 @@ pub fn main() void {
|
||||
|
||||
// error
|
||||
//
|
||||
// :3:16: error: redeclaration of local variable 'i'
|
||||
// :3:16: error: capture 'i' shadows local variable from outer scope
|
||||
// :2:9: note: previous declaration here
|
||||
|
||||
@@ -5,5 +5,5 @@ pub fn main() void {
|
||||
|
||||
// error
|
||||
//
|
||||
// :3:28: error: redeclaration of local variable 'i'
|
||||
// :3:28: error: capture 'i' shadows local variable from outer scope
|
||||
// :2:9: note: previous declaration here
|
||||
|
||||
Reference in New Issue
Block a user