mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
Merge pull request #11284 from topolarity/compile-errors-indep-files
Add primitive file support for compile error tests
This commit is contained in:
commit
6ef761307c
@ -45,7 +45,7 @@ cd $WORKSPACE
|
||||
|
||||
# Look for non-conforming code formatting.
|
||||
# Formatting errors can be fixed by running `zig fmt` on the files printed here.
|
||||
$ZIG fmt --check .
|
||||
$ZIG fmt --check . --exclude test/compile_errors/
|
||||
|
||||
# Build stage2 standalone so that we can test stage2 against stage2 compiler-rt.
|
||||
$ZIG build -p stage2 -Denable-llvm -Duse-zig-libcxx
|
||||
|
||||
20
src/main.zig
20
src/main.zig
@ -3792,6 +3792,7 @@ pub const usage_fmt =
|
||||
\\ --check List non-conforming files and exit with an error
|
||||
\\ if the list is non-empty
|
||||
\\ --ast-check Run zig ast-check on every file
|
||||
\\ --exclude [file] Exclude file or directory from formatting
|
||||
\\
|
||||
\\
|
||||
;
|
||||
@ -3815,6 +3816,8 @@ pub fn cmdFmt(gpa: Allocator, arena: Allocator, args: []const []const u8) !void
|
||||
var check_ast_flag: bool = false;
|
||||
var input_files = ArrayList([]const u8).init(gpa);
|
||||
defer input_files.deinit();
|
||||
var excluded_files = ArrayList([]const u8).init(gpa);
|
||||
defer excluded_files.deinit();
|
||||
|
||||
{
|
||||
var i: usize = 0;
|
||||
@ -3840,6 +3843,13 @@ pub fn cmdFmt(gpa: Allocator, arena: Allocator, args: []const []const u8) !void
|
||||
check_flag = true;
|
||||
} else if (mem.eql(u8, arg, "--ast-check")) {
|
||||
check_ast_flag = true;
|
||||
} else if (mem.eql(u8, arg, "--exclude")) {
|
||||
if (i + 1 >= args.len) {
|
||||
fatal("expected parameter after --exclude", .{});
|
||||
}
|
||||
i += 1;
|
||||
const next_arg = args[i];
|
||||
try excluded_files.append(next_arg);
|
||||
} else {
|
||||
fatal("unrecognized parameter: '{s}'", .{arg});
|
||||
}
|
||||
@ -3940,6 +3950,16 @@ pub fn cmdFmt(gpa: Allocator, arena: Allocator, args: []const []const u8) !void
|
||||
defer fmt.seen.deinit();
|
||||
defer fmt.out_buffer.deinit();
|
||||
|
||||
// Mark any excluded files/directories as already seen,
|
||||
// so that they are skipped later during actual processing
|
||||
for (excluded_files.items) |file_path| {
|
||||
var dir = try fs.cwd().openDir(file_path, .{});
|
||||
defer dir.close();
|
||||
|
||||
const stat = try dir.stat();
|
||||
try fmt.seen.put(stat.inode, {});
|
||||
}
|
||||
|
||||
for (input_files.items) |file_path| {
|
||||
try fmtPath(&fmt, file_path, check_flag, fs.cwd(), file_path);
|
||||
}
|
||||
|
||||
99
src/test.zig
99
src/test.zig
@ -20,6 +20,7 @@ const assert = std.debug.assert;
|
||||
|
||||
const zig_h = link.File.C.zig_h;
|
||||
|
||||
var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
const hr = "=" ** 80;
|
||||
|
||||
test {
|
||||
@ -594,6 +595,104 @@ pub const TestContext = struct {
|
||||
case.compiles(fixed_src);
|
||||
}
|
||||
|
||||
/// Adds a compile-error test for each file in the provided directory, using the
|
||||
/// selected backend and output mode. If `one_test_case_per_file` is true, a new
|
||||
/// test case is created for each file. Otherwise, a single test case is used for
|
||||
/// all tests.
|
||||
///
|
||||
/// Each file should include a test manifest as a contiguous block of comments at
|
||||
/// the end of the file. The first line should be the test case name, followed by
|
||||
/// a blank line, then one expected errors on each line in the form
|
||||
/// `:line:column: error: message`
|
||||
pub fn addErrorCasesFromDir(
|
||||
ctx: *TestContext,
|
||||
name: []const u8,
|
||||
dir: std.fs.Dir,
|
||||
backend: Backend,
|
||||
output_mode: std.builtin.OutputMode,
|
||||
is_test: bool,
|
||||
one_test_case_per_file: bool,
|
||||
) !void {
|
||||
if (skip_compile_errors) return;
|
||||
|
||||
const gpa = general_purpose_allocator.allocator();
|
||||
var case: ?*Case = null;
|
||||
|
||||
var it = dir.iterate();
|
||||
while (try it.next()) |entry| {
|
||||
if (entry.kind != .File) continue;
|
||||
|
||||
var contents = try dir.readFileAlloc(gpa, entry.name, std.math.maxInt(u32));
|
||||
defer gpa.free(contents);
|
||||
|
||||
// The manifest is the last contiguous block of comments in the file
|
||||
// We scan for the beginning by searching backward for the first non-empty line that does not start with "//"
|
||||
var manifest_start: ?usize = null;
|
||||
var manifest_end: usize = contents.len;
|
||||
if (contents.len > 0) {
|
||||
var cursor: usize = contents.len - 1;
|
||||
while (true) {
|
||||
// Move to beginning of line
|
||||
while (cursor > 0 and contents[cursor - 1] != '\n') cursor -= 1;
|
||||
|
||||
// Check if line is non-empty and does not start with "//"
|
||||
if (cursor + 1 < contents.len and contents[cursor + 1] != '\n' and contents[cursor + 1] != '\r') {
|
||||
if (std.mem.startsWith(u8, contents[cursor..], "//")) {
|
||||
manifest_start = cursor;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else manifest_end = cursor;
|
||||
|
||||
// Move to previous line
|
||||
if (cursor != 0) cursor -= 1 else break;
|
||||
}
|
||||
}
|
||||
|
||||
var errors = std.ArrayList([]const u8).init(gpa);
|
||||
defer errors.deinit();
|
||||
|
||||
if (manifest_start) |start| {
|
||||
// Due to the above processing, we know that this is a contiguous block of comments
|
||||
var manifest_it = std.mem.tokenize(u8, contents[start..manifest_end], "\r\n");
|
||||
|
||||
// First line is the test case name
|
||||
const first_line = manifest_it.next() orelse return error.InvalidFile;
|
||||
const case_name = try std.mem.concat(gpa, u8, &.{ name, ": ", std.mem.trim(u8, first_line[2..], " \t") });
|
||||
|
||||
// If the second line is present, it should be blank
|
||||
if (manifest_it.next()) |second_line| {
|
||||
if (std.mem.trim(u8, second_line[2..], " \t").len != 0) return error.InvalidFile;
|
||||
}
|
||||
|
||||
// All following lines are expected error messages
|
||||
while (manifest_it.next()) |line| try errors.append(try gpa.dupe(u8, std.mem.trim(u8, line[2..], " \t")));
|
||||
|
||||
// The entire file contents is the source, including the manifest
|
||||
const src = try gpa.dupeZ(u8, contents);
|
||||
|
||||
// Create a new test case, if necessary
|
||||
case = if (one_test_case_per_file or case == null) blk: {
|
||||
ctx.cases.append(TestContext.Case{
|
||||
.name = if (one_test_case_per_file) case_name else name,
|
||||
.target = .{},
|
||||
.backend = backend,
|
||||
.updates = std.ArrayList(TestContext.Update).init(ctx.cases.allocator),
|
||||
.is_test = is_test,
|
||||
.output_mode = output_mode,
|
||||
.files = std.ArrayList(TestContext.File).init(ctx.cases.allocator),
|
||||
}) catch @panic("out of memory");
|
||||
break :blk &ctx.cases.items[ctx.cases.items.len - 1];
|
||||
} else case.?;
|
||||
|
||||
// Add our update + expected errors
|
||||
case.?.addError(src, errors.items);
|
||||
} else {
|
||||
return error.InvalidFile; // Manifests are currently mandatory
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn init() TestContext {
|
||||
const allocator = std.heap.page_allocator;
|
||||
return .{ .cases = std.ArrayList(Case).init(allocator) };
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
5
test/compile_errors/stage1/exe/main_missing_name.zig
Normal file
5
test/compile_errors/stage1/exe/main_missing_name.zig
Normal file
@ -0,0 +1,5 @@
|
||||
pub fn (main) void {}
|
||||
|
||||
// main missing name
|
||||
//
|
||||
// tmp.zig:1:5: error: missing function name
|
||||
@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
// missing main fn in executable
|
||||
//
|
||||
// error: root source file has no member called 'main'
|
||||
6
test/compile_errors/stage1/exe/private_main_fn.zig
Normal file
6
test/compile_errors/stage1/exe/private_main_fn.zig
Normal file
@ -0,0 +1,6 @@
|
||||
fn main() void {}
|
||||
|
||||
// private main fn
|
||||
//
|
||||
// error: 'main' is private
|
||||
// tmp.zig:1:1: note: declared here
|
||||
@ -0,0 +1,7 @@
|
||||
pub fn main() !void {
|
||||
@import("std").debug.print("{d} {d} {d} {d} {d}", .{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15});
|
||||
}
|
||||
|
||||
// std.fmt error for unused arguments
|
||||
//
|
||||
// ?:?:?: error: 10 unused arguments in '{d} {d} {d} {d} {d}'
|
||||
@ -0,0 +1,10 @@
|
||||
const Foo = struct {};
|
||||
export fn a() void {
|
||||
const T = [*c]Foo;
|
||||
var t: T = undefined;
|
||||
_ = t;
|
||||
}
|
||||
|
||||
// C pointer pointing to non C ABI compatible type or has align attr
|
||||
//
|
||||
// tmp.zig:3:19: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'
|
||||
@ -0,0 +1,9 @@
|
||||
export fn a() void {
|
||||
var x: *anyopaque = undefined;
|
||||
var y: [*c]anyopaque = x;
|
||||
_ = y;
|
||||
}
|
||||
|
||||
// C pointer to anyopaque
|
||||
//
|
||||
// tmp.zig:3:16: error: C pointers cannot point to opaque types
|
||||
12
test/compile_errors/stage1/obj/Frame_of_generic_function.zig
Normal file
12
test/compile_errors/stage1/obj/Frame_of_generic_function.zig
Normal file
@ -0,0 +1,12 @@
|
||||
export fn entry() void {
|
||||
var frame: @Frame(func) = undefined;
|
||||
_ = frame;
|
||||
}
|
||||
fn func(comptime T: type) void {
|
||||
var x: T = undefined;
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// @Frame() of generic function
|
||||
//
|
||||
// tmp.zig:2:16: error: @Frame() of generic function
|
||||
@ -0,0 +1,14 @@
|
||||
export fn f1(x: u32) u32 {
|
||||
const y = -%x;
|
||||
return -y;
|
||||
}
|
||||
const V = @import("std").meta.Vector;
|
||||
export fn f2(x: V(4, u32)) V(4, u32) {
|
||||
const y = -%x;
|
||||
return -y;
|
||||
}
|
||||
|
||||
// Issue #5586: Make unary minus for unsigned types a compile error
|
||||
//
|
||||
// tmp.zig:3:12: error: negation of type 'u32'
|
||||
// tmp.zig:8:12: error: negation of type 'u32'
|
||||
@ -0,0 +1,8 @@
|
||||
fn foo() void {
|
||||
var sequence = "repeat".*** 10;
|
||||
_ = sequence;
|
||||
}
|
||||
|
||||
// Issue #6823: don't allow .* to be followed by **
|
||||
//
|
||||
// tmp.zig:2:28: error: '.*' cannot be followed by '*'. Are you missing a space?
|
||||
@ -0,0 +1,14 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
pub const io_mode = .evented;
|
||||
pub fn main() !void {
|
||||
if (builtin.os.tag == .windows) {
|
||||
_ = try (std.net.StreamServer.init(.{})).accept();
|
||||
} else {
|
||||
@compileError("Unsupported OS");
|
||||
}
|
||||
}
|
||||
|
||||
// Issue #9165: windows tcp server compilation error
|
||||
//
|
||||
// error: Unsupported OS
|
||||
@ -0,0 +1,9 @@
|
||||
const Foo = error{A};
|
||||
comptime {
|
||||
const z = Foo.Bar;
|
||||
_ = z;
|
||||
}
|
||||
|
||||
// access non-existent member of error set
|
||||
//
|
||||
// tmp.zig:3:18: error: no error named 'Bar' in 'Foo'
|
||||
@ -0,0 +1,19 @@
|
||||
fn outer(y: u32) fn (u32) u32 {
|
||||
const st = struct {
|
||||
fn get(z: u32) u32 {
|
||||
return z + y;
|
||||
}
|
||||
};
|
||||
return st.get;
|
||||
}
|
||||
export fn entry() void {
|
||||
var func = outer(10);
|
||||
var x = func(3);
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// accessing runtime parameter from outer function
|
||||
//
|
||||
// tmp.zig:4:24: error: 'y' not accessible from inner function
|
||||
// tmp.zig:3:28: note: crossed function definition here
|
||||
// tmp.zig:1:10: note: declared here
|
||||
@ -0,0 +1,8 @@
|
||||
comptime {
|
||||
var a: i64 = undefined;
|
||||
a += a;
|
||||
}
|
||||
|
||||
// add assign on undefined value
|
||||
//
|
||||
// tmp.zig:3:5: error: use of undefined value here causes undefined behavior
|
||||
@ -0,0 +1,8 @@
|
||||
comptime {
|
||||
var a: i64 = undefined;
|
||||
_ = a + a;
|
||||
}
|
||||
|
||||
// add on undefined value
|
||||
//
|
||||
// tmp.zig:3:9: error: use of undefined value here causes undefined behavior
|
||||
@ -0,0 +1,10 @@
|
||||
const y = add(65530, 10);
|
||||
fn add(a: u16, b: u16) u16 {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(y)); }
|
||||
|
||||
// add overflow in function evaluation
|
||||
//
|
||||
// tmp.zig:3:14: error: operation caused overflow
|
||||
@ -0,0 +1,8 @@
|
||||
comptime {
|
||||
var a: i64 = undefined;
|
||||
a +%= a;
|
||||
}
|
||||
|
||||
// add wrap assign on undefined value
|
||||
//
|
||||
// tmp.zig:3:5: error: use of undefined value here causes undefined behavior
|
||||
@ -0,0 +1,8 @@
|
||||
comptime {
|
||||
var a: i64 = undefined;
|
||||
_ = a +% a;
|
||||
}
|
||||
|
||||
// add wrap on undefined value
|
||||
//
|
||||
// tmp.zig:3:9: error: use of undefined value here causes undefined behavior
|
||||
10
test/compile_errors/stage1/obj/addition_with_non_numbers.zig
Normal file
10
test/compile_errors/stage1/obj/addition_with_non_numbers.zig
Normal file
@ -0,0 +1,10 @@
|
||||
const Foo = struct {
|
||||
field: i32,
|
||||
};
|
||||
const x = Foo {.field = 1} + Foo {.field = 2};
|
||||
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(x)); }
|
||||
|
||||
// addition with non numbers
|
||||
//
|
||||
// tmp.zig:4:28: error: invalid operands to binary expression: 'Foo' and 'Foo'
|
||||
@ -0,0 +1,8 @@
|
||||
const x = 3;
|
||||
const y = &x;
|
||||
fn foo() *const i32 { return y; }
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(foo)); }
|
||||
|
||||
// address of number literal
|
||||
//
|
||||
// tmp.zig:3:30: error: expected type '*const i32', found '*const comptime_int'
|
||||
@ -0,0 +1,7 @@
|
||||
export fn entry() void {
|
||||
@alignCast(4, @as(u32, 3));
|
||||
}
|
||||
|
||||
// @alignCast expects pointer or slice
|
||||
//
|
||||
// tmp.zig:2:19: error: expected pointer or slice, found 'u32'
|
||||
@ -0,0 +1,8 @@
|
||||
export fn f() void {
|
||||
var s: struct {} align(4) = undefined;
|
||||
_ = s;
|
||||
}
|
||||
|
||||
// aligned variable of zero-bit type
|
||||
//
|
||||
// tmp.zig:2:5: error: variable 's' of zero-bit type 'struct:2:12' has no in-memory representation, it cannot be aligned
|
||||
@ -0,0 +1,12 @@
|
||||
const Number = enum {
|
||||
a,
|
||||
b align(i32),
|
||||
};
|
||||
export fn entry1() void {
|
||||
var x: Number = undefined;
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// alignment of enum field specified
|
||||
//
|
||||
// tmp.zig:3:7: error: expected ',' after field
|
||||
19
test/compile_errors/stage1/obj/ambiguous_decl_reference.zig
Normal file
19
test/compile_errors/stage1/obj/ambiguous_decl_reference.zig
Normal file
@ -0,0 +1,19 @@
|
||||
fn foo() void {}
|
||||
fn bar() void {
|
||||
const S = struct {
|
||||
fn baz() void {
|
||||
foo();
|
||||
}
|
||||
fn foo() void {}
|
||||
};
|
||||
S.baz();
|
||||
}
|
||||
export fn entry() void {
|
||||
bar();
|
||||
}
|
||||
|
||||
// ambiguous decl reference
|
||||
//
|
||||
// tmp.zig:5:13: error: ambiguous reference
|
||||
// tmp.zig:7:9: note: declared here
|
||||
// tmp.zig:1:1: note: also declared here
|
||||
@ -0,0 +1,8 @@
|
||||
comptime {
|
||||
var a: bool = undefined;
|
||||
_ = a and a;
|
||||
}
|
||||
|
||||
// and on undefined value
|
||||
//
|
||||
// tmp.zig:3:9: error: use of undefined value here causes undefined behavior
|
||||
13
test/compile_errors/stage1/obj/array_access_of_non_array.zig
Normal file
13
test/compile_errors/stage1/obj/array_access_of_non_array.zig
Normal file
@ -0,0 +1,13 @@
|
||||
export fn f() void {
|
||||
var bad : bool = undefined;
|
||||
bad[0] = bad[0];
|
||||
}
|
||||
export fn g() void {
|
||||
var bad : bool = undefined;
|
||||
_ = bad[0];
|
||||
}
|
||||
|
||||
// array access of non array
|
||||
//
|
||||
// tmp.zig:3:8: error: array access of non-array type 'bool'
|
||||
// tmp.zig:7:12: error: array access of non-array type 'bool'
|
||||
8
test/compile_errors/stage1/obj/array_access_of_type.zig
Normal file
8
test/compile_errors/stage1/obj/array_access_of_type.zig
Normal file
@ -0,0 +1,8 @@
|
||||
export fn foo() void {
|
||||
var b: u8[40] = undefined;
|
||||
_ = b;
|
||||
}
|
||||
|
||||
// array access of type
|
||||
//
|
||||
// tmp.zig:2:14: error: array access of non-array type 'type'
|
||||
@ -0,0 +1,7 @@
|
||||
export fn f() void {
|
||||
i[i] = i[i];
|
||||
}
|
||||
|
||||
// array access of undeclared identifier
|
||||
//
|
||||
// tmp.zig:2:5: error: use of undeclared identifier 'i'
|
||||
@ -0,0 +1,15 @@
|
||||
export fn f() void {
|
||||
var array = "aoeu";
|
||||
var bad = false;
|
||||
array[bad] = array[bad];
|
||||
}
|
||||
export fn g() void {
|
||||
var array = "aoeu";
|
||||
var bad = false;
|
||||
_ = array[bad];
|
||||
}
|
||||
|
||||
// array access with non integer index
|
||||
//
|
||||
// tmp.zig:4:11: error: expected type 'usize', found 'bool'
|
||||
// tmp.zig:9:15: error: expected type 'usize', found 'bool'
|
||||
@ -0,0 +1,9 @@
|
||||
const src = "aoeu";
|
||||
const derp: usize = 1234;
|
||||
const a = derp ++ "foo";
|
||||
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(a)); }
|
||||
|
||||
// array concatenation with wrong type
|
||||
//
|
||||
// tmp.zig:3:11: error: expected array, found 'usize'
|
||||
@ -0,0 +1,12 @@
|
||||
export fn zig_array(x: [10]u8) void {
|
||||
try std.testing.expect(std.mem.eql(u8, &x, "1234567890"));
|
||||
}
|
||||
const std = @import("std");
|
||||
export fn zig_return_array() [10]u8 {
|
||||
return "1234567890".*;
|
||||
}
|
||||
|
||||
// array in c exported function
|
||||
//
|
||||
// tmp.zig:1:24: error: parameter of type '[10]u8' not allowed in function with calling convention 'C'
|
||||
// tmp.zig:5:30: error: return type '[10]u8' not allowed in function with calling convention 'C'
|
||||
15
test/compile_errors/stage1/obj/asm_at_compile_time.zig
Normal file
15
test/compile_errors/stage1/obj/asm_at_compile_time.zig
Normal file
@ -0,0 +1,15 @@
|
||||
comptime {
|
||||
doSomeAsm();
|
||||
}
|
||||
|
||||
fn doSomeAsm() void {
|
||||
asm volatile (
|
||||
\\.globl aoeu;
|
||||
\\.type aoeu, @function;
|
||||
\\.set aoeu, derp;
|
||||
);
|
||||
}
|
||||
|
||||
// asm at compile time
|
||||
//
|
||||
// tmp.zig:6:5: error: unable to evaluate constant expression
|
||||
@ -0,0 +1,10 @@
|
||||
export fn entry() void {
|
||||
var a = b;
|
||||
_ = a;
|
||||
}
|
||||
fn b() callconv(.Inline) void { }
|
||||
|
||||
// assign inline fn to non-comptime var
|
||||
//
|
||||
// tmp.zig:2:5: error: functions marked inline must be stored in const or comptime var
|
||||
// tmp.zig:5:1: note: declared here
|
||||
@ -0,0 +1,7 @@
|
||||
const a: *u8 = null;
|
||||
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(a)); }
|
||||
|
||||
// assign null to non-optional pointer
|
||||
//
|
||||
// tmp.zig:1:16: error: expected type '*u8', found '@Type(.Null)'
|
||||
@ -0,0 +1,8 @@
|
||||
export fn f() void {
|
||||
var cstr = "Hat";
|
||||
cstr[0] = 'W';
|
||||
}
|
||||
|
||||
// assign through constant pointer
|
||||
//
|
||||
// tmp.zig:3:13: error: cannot assign to constant
|
||||
@ -0,0 +1,8 @@
|
||||
export fn f() void {
|
||||
var cstr: []const u8 = "Hat";
|
||||
cstr[0] = 'W';
|
||||
}
|
||||
|
||||
// assign through constant slice
|
||||
//
|
||||
// tmp.zig:3:13: error: cannot assign to constant
|
||||
11
test/compile_errors/stage1/obj/assign_to_constant_field.zig
Normal file
11
test/compile_errors/stage1/obj/assign_to_constant_field.zig
Normal file
@ -0,0 +1,11 @@
|
||||
const Foo = struct {
|
||||
field: i32,
|
||||
};
|
||||
export fn derp() void {
|
||||
const f = Foo {.field = 1234,};
|
||||
f.field = 0;
|
||||
}
|
||||
|
||||
// assign to constant field
|
||||
//
|
||||
// tmp.zig:6:15: error: cannot assign to constant
|
||||
@ -0,0 +1,8 @@
|
||||
export fn f() void {
|
||||
const a = 3;
|
||||
a = 4;
|
||||
}
|
||||
|
||||
// assign to constant variable
|
||||
//
|
||||
// tmp.zig:3:9: error: cannot assign to constant
|
||||
@ -0,0 +1,7 @@
|
||||
export fn entry() void {
|
||||
'a'.* = 1;
|
||||
}
|
||||
|
||||
// assign to invalid dereference
|
||||
//
|
||||
// tmp.zig:2:8: error: attempt to dereference non-pointer type 'comptime_int'
|
||||
@ -0,0 +1,8 @@
|
||||
export fn foo() void {
|
||||
var vga_mem: u16 = 0xB8000;
|
||||
_ = vga_mem;
|
||||
}
|
||||
|
||||
// assign too big number to u16
|
||||
//
|
||||
// tmp.zig:2:24: error: integer value 753664 cannot be coerced to type 'u16'
|
||||
8
test/compile_errors/stage1/obj/assign_unreachable.zig
Normal file
8
test/compile_errors/stage1/obj/assign_unreachable.zig
Normal file
@ -0,0 +1,8 @@
|
||||
export fn f() void {
|
||||
const a = return;
|
||||
}
|
||||
|
||||
// assign unreachable
|
||||
//
|
||||
// tmp.zig:2:5: error: unreachable code
|
||||
// tmp.zig:2:15: note: control flow is diverted here
|
||||
@ -0,0 +1,19 @@
|
||||
fn maybe(is: bool) ?u8 {
|
||||
if (is) return @as(u8, 10) else return null;
|
||||
}
|
||||
const U = union {
|
||||
Ye: u8,
|
||||
};
|
||||
const S = struct {
|
||||
num: u8,
|
||||
};
|
||||
export fn entry() void {
|
||||
var u = U{ .Ye = maybe(false) };
|
||||
var s = S{ .num = maybe(false) };
|
||||
_ = u;
|
||||
_ = s;
|
||||
}
|
||||
|
||||
// assigning to struct or union fields that are not optionals with a function that returns an optional
|
||||
//
|
||||
// tmp.zig:11:27: error: cannot convert optional to payload type. consider using `.?`, `orelse`, or `if`. expected type 'u8', found '?u8'
|
||||
@ -0,0 +1,11 @@
|
||||
export fn entry() void {
|
||||
_ = async amain();
|
||||
}
|
||||
fn amain() callconv(.Async) void {
|
||||
var x: [@sizeOf(@Frame(amain))]u8 = undefined;
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// async function depends on its own frame
|
||||
//
|
||||
// tmp.zig:4:1: error: cannot resolve '@Frame(amain)': function not fully analyzed yet
|
||||
@ -0,0 +1,15 @@
|
||||
export fn entry() void {
|
||||
_ = async amain();
|
||||
}
|
||||
fn amain() callconv(.Async) void {
|
||||
other();
|
||||
}
|
||||
fn other() void {
|
||||
var x: [@sizeOf(@Frame(amain))]u8 = undefined;
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// async function indirectly depends on its own frame
|
||||
//
|
||||
// tmp.zig:4:1: error: unable to determine async function frame of 'amain'
|
||||
// tmp.zig:5:10: note: analysis of function 'other' depends on the frame
|
||||
@ -0,0 +1,8 @@
|
||||
export fn entry() void {
|
||||
var x: u32 = 0;
|
||||
@atomicStore(u32, &x, 1, .Acquire);
|
||||
}
|
||||
|
||||
// atomic orderings of atomicStore Acquire or AcqRel
|
||||
//
|
||||
// tmp.zig:3:30: error: @atomicStore atomic ordering must not be Acquire or AcqRel
|
||||
@ -0,0 +1,9 @@
|
||||
const AtomicOrder = @import("std").builtin.AtomicOrder;
|
||||
export fn f() void {
|
||||
var x: i32 = 1234;
|
||||
while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {}
|
||||
}
|
||||
|
||||
// atomic orderings of cmpxchg - failure stricter than success
|
||||
//
|
||||
// tmp.zig:4:81: error: failure atomic ordering must be no stricter than success
|
||||
@ -0,0 +1,9 @@
|
||||
const AtomicOrder = @import("std").builtin.AtomicOrder;
|
||||
export fn f() void {
|
||||
var x: i32 = 1234;
|
||||
while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {}
|
||||
}
|
||||
|
||||
// atomic orderings of cmpxchg - success Monotonic or stricter
|
||||
//
|
||||
// tmp.zig:4:58: error: success atomic ordering must be Monotonic or stricter
|
||||
@ -0,0 +1,7 @@
|
||||
export fn entry() void {
|
||||
@fence(.Monotonic);
|
||||
}
|
||||
|
||||
// atomic orderings of fence Acquire or stricter
|
||||
//
|
||||
// tmp.zig:2:12: error: atomic ordering must be Acquire or stricter
|
||||
@ -0,0 +1,8 @@
|
||||
export fn entry() void {
|
||||
var x = false;
|
||||
_ = @atomicRmw(bool, &x, .Add, true, .SeqCst);
|
||||
}
|
||||
|
||||
// atomicrmw with bool op not .Xchg
|
||||
//
|
||||
// tmp.zig:3:30: error: @atomicRmw with bool only allowed with .Xchg
|
||||
@ -0,0 +1,14 @@
|
||||
export fn entry() void {
|
||||
const E = enum(u8) {
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
d,
|
||||
};
|
||||
var x: E = .a;
|
||||
_ = @atomicRmw(E, &x, .Add, .b, .SeqCst);
|
||||
}
|
||||
|
||||
// atomicrmw with enum op not .Xchg
|
||||
//
|
||||
// tmp.zig:9:27: error: @atomicRmw with enum only allowed with .Xchg
|
||||
@ -0,0 +1,8 @@
|
||||
export fn entry() void {
|
||||
var x: f32 = 0;
|
||||
_ = @atomicRmw(f32, &x, .And, 2, .SeqCst);
|
||||
}
|
||||
|
||||
// atomicrmw with float op not .Xchg, .Add or .Sub
|
||||
//
|
||||
// tmp.zig:3:29: error: @atomicRmw with float only allowed with .Xchg, .Add and .Sub
|
||||
@ -0,0 +1,9 @@
|
||||
export fn entry() void {
|
||||
switch (error.Hi) {
|
||||
.Hi => {},
|
||||
}
|
||||
}
|
||||
|
||||
// attempt to cast enum literal to error
|
||||
//
|
||||
// tmp.zig:3:9: error: expected type 'error{Hi}', found '@Type(.EnumLiteral)'
|
||||
@ -0,0 +1,12 @@
|
||||
fn SimpleList(comptime L: usize) type {
|
||||
var T = u8;
|
||||
return struct {
|
||||
array: [L]T,
|
||||
};
|
||||
}
|
||||
|
||||
// attempt to close over comptime variable from outer scope
|
||||
//
|
||||
// tmp.zig:4:19: error: mutable 'T' not accessible from here
|
||||
// tmp.zig:2:9: note: declared mutable here
|
||||
// tmp.zig:3:12: note: crosses namespace boundary here
|
||||
@ -0,0 +1,8 @@
|
||||
const builtin = @import("std").builtin;
|
||||
comptime {
|
||||
_ = @Type(.{ .Float = .{ .bits = 17 } });
|
||||
}
|
||||
|
||||
// attempt to create 17 bit float type
|
||||
//
|
||||
// tmp.zig:3:16: error: 17-bit float unsupported
|
||||
@ -0,0 +1,12 @@
|
||||
fn foo() anyerror!u32 {
|
||||
return 1;
|
||||
}
|
||||
|
||||
export fn entry() void {
|
||||
const x = -foo();
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// attempt to negate a non-integer, non-float or non-vector type
|
||||
//
|
||||
// tmp.zig:6:15: error: negation of type 'anyerror!u32'
|
||||
@ -0,0 +1,15 @@
|
||||
extern fn foo(ptr: fn(*void) callconv(.C) void) void;
|
||||
|
||||
export fn entry() void {
|
||||
foo(bar);
|
||||
}
|
||||
|
||||
fn bar(x: *void) callconv(.C) void { _ = x; }
|
||||
export fn entry2() void {
|
||||
bar(&{});
|
||||
}
|
||||
|
||||
// attempt to use 0 bit type in extern fn
|
||||
//
|
||||
// tmp.zig:1:23: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'
|
||||
// tmp.zig:7:11: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'
|
||||
@ -0,0 +1,10 @@
|
||||
export fn entry(a: bool, b: bool) i32 {
|
||||
if (a && b) {
|
||||
return 1234;
|
||||
}
|
||||
return 5678;
|
||||
}
|
||||
|
||||
// attempted `&&`
|
||||
//
|
||||
// tmp.zig:2:11: error: ambiguous use of '&&'; use 'and' for logical AND, or change whitespace to ' & &' for bitwise AND
|
||||
@ -0,0 +1,11 @@
|
||||
export fn entry(a: bool, b: bool) i32 {
|
||||
if (a || b) {
|
||||
return 1234;
|
||||
}
|
||||
return 5678;
|
||||
}
|
||||
|
||||
// attempted `||` on boolean values
|
||||
//
|
||||
// tmp.zig:2:9: error: expected error set type, found 'bool'
|
||||
// tmp.zig:2:11: note: `||` merges error sets; `or` performs boolean OR
|
||||
@ -0,0 +1,8 @@
|
||||
export fn entry() void {
|
||||
const x: [*]const bool = true;
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// attempted implicit cast from T to [*]const T
|
||||
//
|
||||
// tmp.zig:2:30: error: expected type '[*]const bool', found 'bool'
|
||||
@ -0,0 +1,12 @@
|
||||
export fn entry(byte: u8) void {
|
||||
const w: i32 = 1234;
|
||||
var x: *const i32 = &w;
|
||||
var y: *[1]i32 = x;
|
||||
y[0] += 1;
|
||||
_ = byte;
|
||||
}
|
||||
|
||||
// attempted implicit cast from *const T to *[1]T
|
||||
//
|
||||
// tmp.zig:4:22: error: expected type '*[1]i32', found '*const i32'
|
||||
// tmp.zig:4:22: note: cast discards const qualifier
|
||||
@ -0,0 +1,9 @@
|
||||
export fn entry() void {
|
||||
const u: u32 = 42;
|
||||
const x: []u32 = &u;
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// attempted implicit cast from *const T to []T
|
||||
//
|
||||
// tmp.zig:3:23: error: expected type '[]u32', found '*const u32'
|
||||
@ -0,0 +1,9 @@
|
||||
comptime {
|
||||
const ptr = @intToPtr(*align(1) i32, 0x1);
|
||||
const aligned = @alignCast(4, ptr);
|
||||
_ = aligned;
|
||||
}
|
||||
|
||||
// bad @alignCast at comptime
|
||||
//
|
||||
// tmp.zig:3:35: error: pointer address 0x1 is not aligned to 4 bytes
|
||||
@ -0,0 +1,9 @@
|
||||
export fn a() void {
|
||||
var x: [10]u8 = undefined;
|
||||
var y: []align(16) u8 = &x;
|
||||
_ = y;
|
||||
}
|
||||
|
||||
// bad alignment in implicit cast from array pointer to slice
|
||||
//
|
||||
// tmp.zig:3:30: error: expected type '[]align(16) u8', found '*[10]u8'
|
||||
13
test/compile_errors/stage1/obj/bad_alignment_type.zig
Normal file
13
test/compile_errors/stage1/obj/bad_alignment_type.zig
Normal file
@ -0,0 +1,13 @@
|
||||
export fn entry1() void {
|
||||
var x: []align(true) i32 = undefined;
|
||||
_ = x;
|
||||
}
|
||||
export fn entry2() void {
|
||||
var x: *align(@as(f64, 12.34)) i32 = undefined;
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// bad alignment type
|
||||
//
|
||||
// tmp.zig:2:20: error: expected type 'u29', found 'bool'
|
||||
// tmp.zig:6:19: error: fractional component prevents float value 12.340000 from being casted to type 'u29'
|
||||
@ -0,0 +1,15 @@
|
||||
export fn entry() void {
|
||||
const BlockKind = u32;
|
||||
|
||||
const Block = struct {
|
||||
kind: BlockKind,
|
||||
};
|
||||
|
||||
bogus;
|
||||
|
||||
_ = Block;
|
||||
}
|
||||
|
||||
// bad identifier in function with struct defined inside function which references local const
|
||||
//
|
||||
// tmp.zig:8:5: error: use of undeclared identifier 'bogus'
|
||||
5
test/compile_errors/stage1/obj/bad_import.zig
Normal file
5
test/compile_errors/stage1/obj/bad_import.zig
Normal file
@ -0,0 +1,5 @@
|
||||
const bogus = @import("bogus-does-not-exist.zig",);
|
||||
|
||||
// bad import
|
||||
//
|
||||
// tmp.zig:1:23: error: unable to load '${DIR}bogus-does-not-exist.zig': FileNotFound
|
||||
28
test/compile_errors/stage1/obj/bad_usage_of_call.zig
Normal file
28
test/compile_errors/stage1/obj/bad_usage_of_call.zig
Normal file
@ -0,0 +1,28 @@
|
||||
export fn entry1() void {
|
||||
@call(.{}, foo, {});
|
||||
}
|
||||
export fn entry2() void {
|
||||
comptime @call(.{ .modifier = .never_inline }, foo, .{});
|
||||
}
|
||||
export fn entry3() void {
|
||||
comptime @call(.{ .modifier = .never_tail }, foo, .{});
|
||||
}
|
||||
export fn entry4() void {
|
||||
@call(.{ .modifier = .never_inline }, bar, .{});
|
||||
}
|
||||
export fn entry5(c: bool) void {
|
||||
var baz = if (c) baz1 else baz2;
|
||||
@call(.{ .modifier = .compile_time }, baz, .{});
|
||||
}
|
||||
fn foo() void {}
|
||||
fn bar() callconv(.Inline) void {}
|
||||
fn baz1() void {}
|
||||
fn baz2() void {}
|
||||
|
||||
// bad usage of @call
|
||||
//
|
||||
// tmp.zig:2:21: error: expected tuple or struct, found 'void'
|
||||
// tmp.zig:5:14: error: unable to perform 'never_inline' call at compile-time
|
||||
// tmp.zig:8:14: error: unable to perform 'never_tail' call at compile-time
|
||||
// tmp.zig:11:5: error: no-inline call of inline function
|
||||
// tmp.zig:15:5: error: the specified modifier requires a comptime-known function
|
||||
@ -0,0 +1,8 @@
|
||||
comptime {
|
||||
var a: i64 = undefined;
|
||||
a &= a;
|
||||
}
|
||||
|
||||
// bin and assign on undefined value
|
||||
//
|
||||
// tmp.zig:3:5: error: use of undefined value here causes undefined behavior
|
||||
@ -0,0 +1,8 @@
|
||||
comptime {
|
||||
var a: i64 = undefined;
|
||||
_ = a & a;
|
||||
}
|
||||
|
||||
// bin and on undefined value
|
||||
//
|
||||
// tmp.zig:3:9: error: use of undefined value here causes undefined behavior
|
||||
@ -0,0 +1,8 @@
|
||||
comptime {
|
||||
var a: i64 = undefined;
|
||||
_ = ~a;
|
||||
}
|
||||
|
||||
// bin not on undefined value
|
||||
//
|
||||
// tmp.zig:3:10: error: use of undefined value here causes undefined behavior
|
||||
@ -0,0 +1,8 @@
|
||||
comptime {
|
||||
var a: i64 = undefined;
|
||||
a |= a;
|
||||
}
|
||||
|
||||
// bin or assign on undefined value
|
||||
//
|
||||
// tmp.zig:3:5: error: use of undefined value here causes undefined behavior
|
||||
@ -0,0 +1,8 @@
|
||||
comptime {
|
||||
var a: i64 = undefined;
|
||||
_ = a | a;
|
||||
}
|
||||
|
||||
// bin or on undefined value
|
||||
//
|
||||
// tmp.zig:3:9: error: use of undefined value here causes undefined behavior
|
||||
@ -0,0 +1,8 @@
|
||||
comptime {
|
||||
var a: i64 = undefined;
|
||||
a ^= a;
|
||||
}
|
||||
|
||||
// bin xor assign on undefined value
|
||||
//
|
||||
// tmp.zig:3:5: error: use of undefined value here causes undefined behavior
|
||||
@ -0,0 +1,8 @@
|
||||
comptime {
|
||||
var a: i64 = undefined;
|
||||
_ = a ^ a;
|
||||
}
|
||||
|
||||
// bin xor on undefined value
|
||||
//
|
||||
// tmp.zig:3:9: error: use of undefined value here causes undefined behavior
|
||||
@ -0,0 +1,9 @@
|
||||
const TINY_QUANTUM_SHIFT = 4;
|
||||
const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;
|
||||
var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);
|
||||
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(block_aligned_stuff)); }
|
||||
|
||||
// binary not on number literal
|
||||
//
|
||||
// tmp.zig:3:60: error: unable to perform binary not operation on type 'comptime_int'
|
||||
@ -0,0 +1,8 @@
|
||||
export fn entry(byte: u8) void {
|
||||
var oops = @bitCast(u7, byte);
|
||||
_ = oops;
|
||||
}
|
||||
|
||||
// @bitCast same size but bit count mismatch
|
||||
//
|
||||
// tmp.zig:2:25: error: destination type 'u7' has 7 bits but source type 'u8' has 8 bits
|
||||
8
test/compile_errors/stage1/obj/bitCast_to_enum_type.zig
Normal file
8
test/compile_errors/stage1/obj/bitCast_to_enum_type.zig
Normal file
@ -0,0 +1,8 @@
|
||||
export fn entry() void {
|
||||
const y = @bitCast(enum(u32) { a, b }, @as(u32, 3));
|
||||
_ = y;
|
||||
}
|
||||
|
||||
// bitCast to enum type
|
||||
//
|
||||
// tmp.zig:2:24: error: cannot cast a value of type 'y'
|
||||
@ -0,0 +1,8 @@
|
||||
export fn entry() void {
|
||||
var foo = (@bitCast(u8, @as(f32, 1.0)) == 0xf);
|
||||
_ = foo;
|
||||
}
|
||||
|
||||
// @bitCast with different sizes inside an expression
|
||||
//
|
||||
// tmp.zig:2:25: error: destination type 'u8' has size 1 but source type 'f32' has size 4
|
||||
@ -0,0 +1,8 @@
|
||||
export fn entry() void {
|
||||
const x = &@as(u8, 1) << 10;
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// bit shifting only works on integer types
|
||||
//
|
||||
// tmp.zig:2:16: error: bit shifting operation expected integer type, found '*const u8'
|
||||
6
test/compile_errors/stage1/obj/bogus_compile_var.zig
Normal file
6
test/compile_errors/stage1/obj/bogus_compile_var.zig
Normal file
@ -0,0 +1,6 @@
|
||||
const x = @import("builtin").bogus;
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(x)); }
|
||||
|
||||
// bogus compile var
|
||||
//
|
||||
// tmp.zig:1:29: error: container 'builtin' has no member called 'bogus'
|
||||
@ -0,0 +1,9 @@
|
||||
var self = "aoeu";
|
||||
fn f(m: []const u8) void {
|
||||
m.copy(u8, self[0..], m);
|
||||
}
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(f)); }
|
||||
|
||||
// bogus method call on slice
|
||||
//
|
||||
// tmp.zig:3:6: error: no member named 'copy' in '[]const u8'
|
||||
@ -0,0 +1,8 @@
|
||||
comptime {
|
||||
var a: bool = undefined;
|
||||
_ = !a;
|
||||
}
|
||||
|
||||
// bool not on undefined value
|
||||
//
|
||||
// tmp.zig:3:10: error: use of undefined value here causes undefined behavior
|
||||
@ -0,0 +1,7 @@
|
||||
const x = if (undefined) true else false;
|
||||
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(x)); }
|
||||
|
||||
// branch on undefined value
|
||||
//
|
||||
// tmp.zig:1:15: error: use of undefined value here causes undefined behavior
|
||||
@ -0,0 +1,7 @@
|
||||
const c = @cImport(@cInclude("bogus.h"));
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(c.bogo)); }
|
||||
|
||||
// @cImport with bogus include
|
||||
//
|
||||
// tmp.zig:1:11: error: C import failed
|
||||
// .h:1:10: note: 'bogus.h' file not found
|
||||
22
test/compile_errors/stage1/obj/call_assigned_to_constant.zig
Normal file
22
test/compile_errors/stage1/obj/call_assigned_to_constant.zig
Normal file
@ -0,0 +1,22 @@
|
||||
const Foo = struct {
|
||||
x: i32,
|
||||
};
|
||||
fn foo() Foo {
|
||||
return .{ .x = 42 };
|
||||
}
|
||||
fn bar(val: anytype) Foo {
|
||||
return .{ .x = val };
|
||||
}
|
||||
export fn entry() void {
|
||||
const baz: Foo = undefined;
|
||||
baz = foo();
|
||||
}
|
||||
export fn entry1() void {
|
||||
const baz: Foo = undefined;
|
||||
baz = bar(42);
|
||||
}
|
||||
|
||||
// call assigned to constant
|
||||
//
|
||||
// tmp.zig:12:14: error: cannot assign to constant
|
||||
// tmp.zig:16:14: error: cannot assign to constant
|
||||
@ -0,0 +1,12 @@
|
||||
var foos = [_]fn(anytype) void { foo1, foo2 };
|
||||
|
||||
fn foo1(arg: anytype) void {_ = arg;}
|
||||
fn foo2(arg: anytype) void {_ = arg;}
|
||||
|
||||
pub fn main() !void {
|
||||
foos[0](true);
|
||||
}
|
||||
|
||||
// calling a generic function only known at runtime
|
||||
//
|
||||
// tmp.zig:7:9: error: calling a generic function requires compile-time known function value
|
||||
@ -0,0 +1,9 @@
|
||||
export fn entry() void {
|
||||
foo();
|
||||
}
|
||||
fn foo() callconv(.Naked) void { }
|
||||
|
||||
// calling function with naked calling convention
|
||||
//
|
||||
// tmp.zig:2:5: error: unable to call function with naked calling convention
|
||||
// tmp.zig:4:1: note: declared here
|
||||
@ -0,0 +1,8 @@
|
||||
export fn entry() void {
|
||||
foo("hello".*,);
|
||||
}
|
||||
pub extern fn foo(format: *const u8, ...) void;
|
||||
|
||||
// calling var args extern function, passing array instead of pointer
|
||||
//
|
||||
// tmp.zig:2:16: error: expected type '*const u8', found '[5:0]u8'
|
||||
@ -0,0 +1,11 @@
|
||||
export fn foo() void {
|
||||
while (true) {
|
||||
defer {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cannot break out of defer expression
|
||||
//
|
||||
// tmp.zig:4:13: error: cannot break out of defer expression
|
||||
@ -0,0 +1,11 @@
|
||||
export fn foo() void {
|
||||
while (true) {
|
||||
defer {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cannot continue out of defer expression
|
||||
//
|
||||
// tmp.zig:4:13: error: cannot continue out of defer expression
|
||||
@ -0,0 +1,19 @@
|
||||
const Union = union(enum) {
|
||||
A: usize,
|
||||
B: isize,
|
||||
};
|
||||
comptime {
|
||||
var u = Union{ .A = 8 };
|
||||
switch (u) {
|
||||
.A, .B => |e| {
|
||||
_ = e;
|
||||
unreachable;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// capture group on switch prong with incompatible payload types
|
||||
//
|
||||
// tmp.zig:8:20: error: capture group with incompatible types
|
||||
// tmp.zig:8:9: note: type 'usize' here
|
||||
// tmp.zig:8:13: note: type 'isize' here
|
||||
@ -0,0 +1,13 @@
|
||||
const Foo = enum {
|
||||
a,
|
||||
b,
|
||||
};
|
||||
export fn entry() void {
|
||||
const x: Foo = .c;
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// cast enum literal to enum but it doesn't match
|
||||
//
|
||||
// tmp.zig:6:20: error: enum 'Foo' has no field named 'c'
|
||||
// tmp.zig:1:13: note: 'Foo' declared here
|
||||
@ -0,0 +1,14 @@
|
||||
const SmallErrorSet = error{A};
|
||||
export fn entry() void {
|
||||
var x: SmallErrorSet!i32 = foo();
|
||||
_ = x;
|
||||
}
|
||||
fn foo() anyerror!i32 {
|
||||
return error.B;
|
||||
}
|
||||
|
||||
// cast error union of global error set to error union of smaller error set
|
||||
//
|
||||
// tmp.zig:3:35: error: expected type 'SmallErrorSet!i32', found 'anyerror!i32'
|
||||
// tmp.zig:3:35: note: error set 'anyerror' cannot cast into error set 'SmallErrorSet'
|
||||
// tmp.zig:3:35: note: cannot cast global error set into smaller set
|
||||
@ -0,0 +1,13 @@
|
||||
const SmallErrorSet = error{A};
|
||||
export fn entry() void {
|
||||
var x: SmallErrorSet = foo();
|
||||
_ = x;
|
||||
}
|
||||
fn foo() anyerror {
|
||||
return error.B;
|
||||
}
|
||||
|
||||
// cast global error set to error set
|
||||
//
|
||||
// tmp.zig:3:31: error: expected type 'SmallErrorSet', found 'anyerror'
|
||||
// tmp.zig:3:31: note: cannot cast global error set into smaller set
|
||||
@ -0,0 +1,8 @@
|
||||
export fn entry() void {
|
||||
const x = @as(usize, -10);
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// cast negative integer literal to usize
|
||||
//
|
||||
// tmp.zig:2:26: error: cannot cast negative value -10 to unsigned integer type 'usize'
|
||||
@ -0,0 +1,15 @@
|
||||
comptime {
|
||||
const value: i32 = -1;
|
||||
const unsigned = @intCast(u32, value);
|
||||
_ = unsigned;
|
||||
}
|
||||
export fn entry1() void {
|
||||
const value: i32 = -1;
|
||||
const unsigned: u32 = value;
|
||||
_ = unsigned;
|
||||
}
|
||||
|
||||
// cast negative value to unsigned integer
|
||||
//
|
||||
// tmp.zig:3:22: error: attempt to cast negative value to unsigned integer
|
||||
// tmp.zig:8:27: error: cannot cast negative value -1 to unsigned integer type 'u32'
|
||||
9
test/compile_errors/stage1/obj/cast_unreachable.zig
Normal file
9
test/compile_errors/stage1/obj/cast_unreachable.zig
Normal file
@ -0,0 +1,9 @@
|
||||
fn f() i32 {
|
||||
return @as(i32, return 1);
|
||||
}
|
||||
export fn entry() void { _ = f(); }
|
||||
|
||||
// cast unreachable
|
||||
//
|
||||
// tmp.zig:2:12: error: unreachable code
|
||||
// tmp.zig:2:21: note: control flow is diverted here
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user