mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
parent
a40cdad18c
commit
efc98fcbeb
@ -887,12 +887,6 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn checkNonScalarSentinel(expected: anytype, actual: @TypeOf(expected)) void {
|
|
||||||
if (!std.meta.eql(expected, actual)) {
|
|
||||||
panicSentinelMismatch(expected, actual);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn panicSentinelMismatch(expected: anytype, actual: @TypeOf(expected)) noreturn {
|
pub fn panicSentinelMismatch(expected: anytype, actual: @TypeOf(expected)) noreturn {
|
||||||
@branchHint(.cold);
|
@branchHint(.cold);
|
||||||
std.debug.panicExtra(null, @returnAddress(), "sentinel mismatch: expected {any}, found {any}", .{ expected, actual });
|
std.debug.panicExtra(null, @returnAddress(), "sentinel mismatch: expected {any}, found {any}", .{ expected, actual });
|
||||||
|
|||||||
20
src/Sema.zig
20
src/Sema.zig
@ -19741,6 +19741,14 @@ fn checkNullableType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !voi
|
|||||||
return sema.failWithExpectedOptionalType(block, src, ty);
|
return sema.failWithExpectedOptionalType(block, src, ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn checkSentinelType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void {
|
||||||
|
const pt = sema.pt;
|
||||||
|
const zcu = pt.zcu;
|
||||||
|
if (!ty.isSelfComparable(zcu, true)) {
|
||||||
|
return sema.fail(block, src, "non-scalar sentinel type '{}'", .{ty.fmt(pt)});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn zirIsNonNull(
|
fn zirIsNonNull(
|
||||||
sema: *Sema,
|
sema: *Sema,
|
||||||
block: *Block,
|
block: *Block,
|
||||||
@ -20542,6 +20550,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
|||||||
const val = try sema.resolveConstDefinedValue(block, sentinel_src, coerced, .{
|
const val = try sema.resolveConstDefinedValue(block, sentinel_src, coerced, .{
|
||||||
.needed_comptime_reason = "pointer sentinel value must be comptime-known",
|
.needed_comptime_reason = "pointer sentinel value must be comptime-known",
|
||||||
});
|
});
|
||||||
|
try checkSentinelType(sema, block, sentinel_src, elem_ty);
|
||||||
break :blk val.toIntern();
|
break :blk val.toIntern();
|
||||||
} else .none;
|
} else .none;
|
||||||
|
|
||||||
@ -28114,13 +28123,9 @@ fn panicSentinelMismatch(
|
|||||||
.operation = .And,
|
.operation = .And,
|
||||||
} },
|
} },
|
||||||
});
|
});
|
||||||
} else if (sentinel_ty.isSelfComparable(zcu, true))
|
} else ok: {
|
||||||
try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel)
|
assert(sentinel_ty.isSelfComparable(zcu, true));
|
||||||
else {
|
break :ok try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel);
|
||||||
const panic_fn = try pt.getBuiltin("checkNonScalarSentinel");
|
|
||||||
const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel };
|
|
||||||
try sema.callBuiltin(parent_block, src, panic_fn, .auto, &args, .@"safety check");
|
|
||||||
return;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!pt.zcu.comp.formatted_panics) {
|
if (!pt.zcu.comp.formatted_panics) {
|
||||||
@ -33573,6 +33578,7 @@ fn analyzeSlice(
|
|||||||
const sentinel = s: {
|
const sentinel = s: {
|
||||||
if (sentinel_opt != .none) {
|
if (sentinel_opt != .none) {
|
||||||
const casted = try sema.coerce(block, elem_ty, sentinel_opt, sentinel_src);
|
const casted = try sema.coerce(block, elem_ty, sentinel_opt, sentinel_src);
|
||||||
|
try checkSentinelType(sema, block, sentinel_src, elem_ty);
|
||||||
break :s try sema.resolveConstDefinedValue(block, sentinel_src, casted, .{
|
break :s try sema.resolveConstDefinedValue(block, sentinel_src, casted, .{
|
||||||
.needed_comptime_reason = "slice sentinel must be comptime-known",
|
.needed_comptime_reason = "slice sentinel must be comptime-known",
|
||||||
});
|
});
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
export fn foo() void {
|
||||||
|
const S = struct { a: u32 };
|
||||||
|
var arr = [_]S{ .{ .a = 1 }, .{ .a = 2 } };
|
||||||
|
const s = arr[0..1 :.{ .a = 1 }];
|
||||||
|
_ = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
// backend=stage2
|
||||||
|
// target=native
|
||||||
|
//
|
||||||
|
// :4:26: error: non-scalar sentinel type 'tmp.foo.S'
|
||||||
|
// :2:15: note: struct declared here
|
||||||
@ -1,21 +0,0 @@
|
|||||||
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, "sentinel mismatch: expected tmp.main.S{ .a = 1 }, found tmp.main.S{ .a = 2 }")) {
|
|
||||||
std.process.exit(0);
|
|
||||||
}
|
|
||||||
std.process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn main() !void {
|
|
||||||
const S = struct { a: u32 };
|
|
||||||
var arr = [_]S{ .{ .a = 1 }, .{ .a = 2 } };
|
|
||||||
const s = arr[0..1 :.{ .a = 1 }];
|
|
||||||
_ = s;
|
|
||||||
return error.TestFailed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// run
|
|
||||||
// backend=llvm
|
|
||||||
// target=native
|
|
||||||
Loading…
x
Reference in New Issue
Block a user