fix regressed tests and update docs to use "type coercion"

This commit is contained in:
Andrew Kelley 2019-11-08 15:56:21 -05:00
parent 3834d3dac0
commit 3cf5c2c62b
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
14 changed files with 203 additions and 199 deletions

View File

@ -155,7 +155,7 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void {
) catch unreachable;
for (dep.system_libs.toSliceConst()) |lib| {
const static_bare_name = if (mem.eql(u8, lib, "curses"))
@as([]const u8,"libncurses.a")
@as([]const u8, "libncurses.a")
else
b.fmt("lib{}.a", lib);
const static_lib_name = fs.path.join(

View File

@ -10,8 +10,8 @@ const testing = std.testing;
const max_doc_file_size = 10 * 1024 * 1024;
const exe_ext = std.build.Target(std.build.Target.Native).exeFileExt();
const obj_ext = std.build.Target(std.build.Target.Native).oFileExt();
const exe_ext = @as(std.build.Target, std.build.Target.Native).exeFileExt();
const obj_ext = @as(std.build.Target, std.build.Target.Native).oFileExt();
const tmp_dir_name = "docgen_tmp";
const test_out_path = tmp_dir_name ++ fs.path.sep_str ++ "test" ++ exe_ext;

View File

@ -712,7 +712,7 @@ test "init with undefined" {
}
{#code_end#}
<p>
{#syntax#}undefined{#endsyntax#} can be {#link|implicitly cast|Implicit Casts#} to any type.
{#syntax#}undefined{#endsyntax#} can be {#link|coerced|Type Coercion#} to any type.
Once this happens, it is no longer possible to detect that the value is {#syntax#}undefined{#endsyntax#}.
{#syntax#}undefined{#endsyntax#} means the value could be anything, even something that is nonsense
according to the type. Translated into English, {#syntax#}undefined{#endsyntax#} means "Not a meaningful
@ -920,7 +920,7 @@ fn divide(a: i32, b: i32) i32 {
{#syntax#}f128{#endsyntax#}.
</p>
<p>
Float literals {#link|implicitly cast|Implicit Casts#} to any floating point type,
Float literals {#link|coerce|Type Coercion#} to any floating point type,
and to any {#link|integer|Integers#} type when there is no fractional component.
</p>
{#code_begin|syntax#}
@ -950,7 +950,7 @@ const nan = std.math.nan(f128);
{#code_begin|obj|foo#}
{#code_release_fast#}
const builtin = @import("builtin");
const big = f64(1 << 40);
const big = @as(f64, 1 << 40);
export fn foo_strict(x: f64) f64 {
return x + big - big;
@ -1652,7 +1652,7 @@ test "iterate over an array" {
for (message) |byte| {
sum += byte;
}
assert(sum == usize('h') + usize('e') + usize('l') * 2 + usize('o'));
assert(sum == 'h' + 'e' + 'l' * 2 + 'o');
}
// modifiable array
@ -2003,7 +2003,7 @@ test "variable alignment" {
}
}
{#code_end#}
<p>In the same way that a {#syntax#}*i32{#endsyntax#} can be {#link|implicitly cast|Implicit Casts#} to a
<p>In the same way that a {#syntax#}*i32{#endsyntax#} can be {#link|coerced|Type Coercion#} to a
{#syntax#}*const i32{#endsyntax#}, a pointer with a larger alignment can be implicitly
cast to a pointer with a smaller alignment, but not vice versa.
</p>
@ -2019,7 +2019,7 @@ var foo: u8 align(4) = 100;
test "global variable alignment" {
assert(@typeOf(&foo).alignment == 4);
assert(@typeOf(&foo) == *align(4) u8);
const slice = (*[1]u8)(&foo)[0..];
const slice = @as(*[1]u8, &foo)[0..];
assert(@typeOf(slice) == []align(4) u8);
}
@ -2114,7 +2114,7 @@ const fmt = @import("std").fmt;
test "using slices for strings" {
// Zig has no concept of strings. String literals are arrays of u8, and
// in general the string type is []u8 (slice of u8).
// Here we implicitly cast [5]u8 to []const u8
// Here we coerce [5]u8 to []const u8
const hello: []const u8 = "hello";
const world: []const u8 = "世界";
@ -2778,7 +2778,7 @@ test "simple union" {
This turns the union into a <em>tagged</em> union, which makes it eligible
to use with {#link|switch#} expressions. One can use {#link|@TagType#} to
obtain the enum type from the union type.
Tagged unions implicitly cast to their enum {#link|Implicit Cast: unions and enums#}
Tagged unions coerce to their enum {#link|Type Coercion: unions and enums#}
</p>
{#code_begin|test#}
const std = @import("std");
@ -2795,7 +2795,7 @@ const ComplexType = union(ComplexTypeTag) {
test "switch on tagged union" {
const c = ComplexType{ .Ok = 42 };
assert(ComplexTypeTag(c) == ComplexTypeTag.Ok);
assert(@as(ComplexTypeTag, c) == ComplexTypeTag.Ok);
switch (c) {
ComplexTypeTag.Ok => |value| assert(value == 42),
@ -2807,7 +2807,7 @@ test "@TagType" {
assert(@TagType(ComplexType) == ComplexTypeTag);
}
test "implicit cast to enum" {
test "coerce to enum" {
const c1 = ComplexType{ .Ok = 42 };
const c2 = ComplexType.NotOk;
@ -2833,7 +2833,7 @@ const ComplexType = union(ComplexTypeTag) {
test "modify tagged union in switch" {
var c = ComplexType{ .Ok = 42 };
assert(ComplexTypeTag(c) == ComplexTypeTag.Ok);
assert(@as(ComplexTypeTag, c) == ComplexTypeTag.Ok);
switch (c) {
ComplexTypeTag.Ok => |*value| value.* += 1,
@ -3943,7 +3943,7 @@ test "fn reflection" {
However right now it is hard coded to be a {#syntax#}u16{#endsyntax#}. See <a href="https://github.com/ziglang/zig/issues/786">#768</a>.
</p>
<p>
You can {#link|implicitly cast|Implicit Casts#} an error from a subset to a superset:
You can {#link|coerce|Type Coercion#} an error from a subset to a superset:
</p>
{#code_begin|test#}
const std = @import("std");
@ -3958,7 +3958,7 @@ const AllocationError = error {
OutOfMemory,
};
test "implicit cast subset to superset" {
test "coerce subset to superset" {
const err = foo(AllocationError.OutOfMemory);
std.debug.assert(err == FileOpenError.OutOfMemory);
}
@ -3968,7 +3968,7 @@ fn foo(err: AllocationError) FileOpenError {
}
{#code_end#}
<p>
But you cannot implicitly cast an error from a superset to a subset:
But you cannot {#link|coerce|Type Coercion#} an error from a superset to a subset:
</p>
{#code_begin|test_err|not a member of destination error set#}
const FileOpenError = error {
@ -3981,7 +3981,7 @@ const AllocationError = error {
OutOfMemory,
};
test "implicit cast superset to subset" {
test "coerce superset to subset" {
foo(FileOpenError.OutOfMemory) catch {};
}
@ -4008,7 +4008,7 @@ const err = (error {FileNotFound}).FileNotFound;
It is a superset of all other error sets and a subset of none of them.
</p>
<p>
You can implicitly cast any error set to the global one, and you can explicitly
You can {#link|coerce|Type Coercion#} any error set to the global one, and you can explicitly
cast an error of the global error set to a non-global one. This inserts a language-level
assert to make sure the error value is in fact in the destination error set.
</p>
@ -4079,7 +4079,7 @@ test "parse u64" {
<p>
Within the function definition, you can see some return statements that return
an error, and at the bottom a return statement that returns a {#syntax#}u64{#endsyntax#}.
Both types {#link|implicitly cast|Implicit Casts#} to {#syntax#}anyerror!u64{#endsyntax#}.
Both types {#link|coerce|Type Coercion#} to {#syntax#}anyerror!u64{#endsyntax#}.
</p>
<p>
What it looks like to use this function varies depending on what you're
@ -4218,10 +4218,10 @@ const assert = @import("std").debug.assert;
test "error union" {
var foo: anyerror!i32 = undefined;
// Implicitly cast from child type of an error union:
// Coerce from child type of an error union:
foo = 1234;
// Implicitly cast from an error set:
// Coerce from an error set:
foo = error.SomeError;
// Use compile-time reflection to access the payload type of an error union:
@ -4598,10 +4598,10 @@ fn doAThing(optional_foo: ?*Foo) void {
const assert = @import("std").debug.assert;
test "optional type" {
// Declare an optional and implicitly cast from null:
// Declare an optional and coerce from null:
var foo: ?i32 = null;
// Implicitly cast from child type of an optional
// Coerce from child type of an optional
foo = 1234;
// Use compile-time reflection to access the child type of the optional:
@ -4644,38 +4644,38 @@ test "optional pointers" {
{#header_open|Casting#}
<p>
A <strong>type cast</strong> converts a value of one type to another.
Zig has {#link|Implicit Casts#} for conversions that are known to be completely safe and unambiguous,
Zig has {#link|Type Coercion#} for conversions that are known to be completely safe and unambiguous,
and {#link|Explicit Casts#} for conversions that one would not want to happen on accident.
There is also a third kind of type conversion called {#link|Peer Type Resolution#} for
the case when a result type must be decided given multiple operand types.
</p>
{#header_open|Implicit Casts#}
{#header_open|Type Coercion#}
<p>
An implicit cast occurs when one type is expected, but different type is provided:
Type coercion occurs when one type is expected, but different type is provided:
</p>
{#code_begin|test#}
test "implicit cast - variable declaration" {
test "type coercion - variable declaration" {
var a: u8 = 1;
var b: u16 = a;
}
test "implicit cast - function call" {
test "type coercion - function call" {
var a: u8 = 1;
foo(a);
}
fn foo(b: u16) void {}
test "implicit cast - invoke a type as a function" {
test "type coercion - @as builtin" {
var a: u8 = 1;
var b = u16(a);
var b = @as(u16, a);
}
{#code_end#}
<p>
Implicit casts are only allowed when it is completely unambiguous how to get from one type to another,
Type coercions are only allowed when it is completely unambiguous how to get from one type to another,
and the transformation is guaranteed to be safe. There is one exception, which is {#link|C Pointers#}.
</p>
{#header_open|Implicit Cast: Stricter Qualification#}
{#header_open|Type Coercion: Stricter Qualification#}
<p>
Values which have the same representation at runtime can be cast to increase the strictness
of the qualifiers, no matter how nested the qualifiers are:
@ -4690,7 +4690,7 @@ test "implicit cast - invoke a type as a function" {
These casts are no-ops at runtime since the value representation does not change.
</p>
{#code_begin|test#}
test "implicit cast - const qualification" {
test "type coercion - const qualification" {
var a: i32 = 1;
var b: *i32 = &a;
foo(b);
@ -4699,7 +4699,7 @@ test "implicit cast - const qualification" {
fn foo(a: *const i32) void {}
{#code_end#}
<p>
In addition, pointers implicitly cast to const optional pointers:
In addition, pointers coerce to const optional pointers:
</p>
{#code_begin|test#}
const std = @import("std");
@ -4713,10 +4713,10 @@ test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
}
{#code_end#}
{#header_close#}
{#header_open|Implicit Cast: Integer and Float Widening#}
{#header_open|Type Coercion: Integer and Float Widening#}
<p>
{#link|Integers#} implicitly cast to integer types which can represent every value of the old type, and likewise
{#link|Floats#} implicitly cast to float types which can represent every value of the old type.
{#link|Integers#} coerce to integer types which can represent every value of the old type, and likewise
{#link|Floats#} coerce to float types which can represent every value of the old type.
</p>
{#code_begin|test#}
const std = @import("std");
@ -4748,7 +4748,7 @@ test "float widening" {
}
{#code_end#}
{#header_close#}
{#header_open|Implicit Cast: Arrays and Pointers#}
{#header_open|Type Coercion: Arrays and Pointers#}
{#code_begin|test#}
const std = @import("std");
const assert = std.debug.assert;
@ -4797,7 +4797,7 @@ test "*[N]T to []T" {
assert(std.mem.eql(f32, x2, [2]f32{ 1.2, 3.4 }));
}
// Single-item pointers to arrays can be implicitly casted to
// Single-item pointers to arrays can be coerced to
// unknown length pointers.
test "*[N]T to [*]T" {
var buf: [5]u8 = "hello";
@ -4823,15 +4823,15 @@ test "*T to *[1]T" {
{#code_end#}
{#see_also|C Pointers#}
{#header_close#}
{#header_open|Implicit Cast: Optionals#}
{#header_open|Type Coercion: Optionals#}
<p>
The payload type of {#link|Optionals#}, as well as {#link|null#}, implicitly cast to the optional type.
The payload type of {#link|Optionals#}, as well as {#link|null#}, coerce to the optional type.
</p>
{#code_begin|test#}
const std = @import("std");
const assert = std.debug.assert;
test "implicit casting to optionals" {
test "coerce to optionals" {
const x: ?i32 = 1234;
const y: ?i32 = null;
@ -4844,7 +4844,7 @@ test "implicit casting to optionals" {
const std = @import("std");
const assert = std.debug.assert;
test "implicit casting to optionals wrapped in error union" {
test "coerce to optionals wrapped in error union" {
const x: anyerror!?i32 = 1234;
const y: anyerror!?i32 = null;
@ -4853,15 +4853,15 @@ test "implicit casting to optionals wrapped in error union" {
}
{#code_end#}
{#header_close#}
{#header_open|Implicit Cast: Error Unions#}
{#header_open|Type Coercion: Error Unions#}
<p>The payload type of an {#link|Error Union Type#} as well as the {#link|Error Set Type#}
implicitly cast to the error union type:
coerce to the error union type:
</p>
{#code_begin|test#}
const std = @import("std");
const assert = std.debug.assert;
test "implicit casting to error unions" {
test "coercion to error unions" {
const x: anyerror!i32 = 1234;
const y: anyerror!i32 = error.Failure;
@ -4870,23 +4870,23 @@ test "implicit casting to error unions" {
}
{#code_end#}
{#header_close#}
{#header_open|Implicit Cast: Compile-Time Known Numbers#}
{#header_open|Type Coercion: Compile-Time Known Numbers#}
<p>When a number is {#link|comptime#}-known to be representable in the destination type,
it may be implicitly casted:
it may be coerced:
</p>
{#code_begin|test#}
const std = @import("std");
const assert = std.debug.assert;
test "implicit casting large integer type to smaller one when value is comptime known to fit" {
test "coercing large integer type to smaller one when value is comptime known to fit" {
const x: u64 = 255;
const y: u8 = x;
assert(y == 255);
}
{#code_end#}
{#header_close#}
{#header_open|Implicit Cast: unions and enums#}
<p>Tagged unions can be implicitly cast to enums, and enums can be implicitly casted to tagged unions
{#header_open|Type Coercion: unions and enums#}
<p>Tagged unions can be coerced to enums, and enums can be coerced to tagged unions
when they are {#link|comptime#}-known to be a field of the union that has only one possible value, such as
{#link|void#}:
</p>
@ -4906,7 +4906,7 @@ const U = union(E) {
Three,
};
test "implicit casting between unions and enums" {
test "coercion between unions and enums" {
var u = U{ .Two = 12.34 };
var e: E = u;
assert(e == E.Two);
@ -4918,20 +4918,20 @@ test "implicit casting between unions and enums" {
{#code_end#}
{#see_also|union|enum#}
{#header_close#}
{#header_open|Implicit Cast: Zero Bit Types#}
<p>{#link|Zero Bit Types#} may be implicitly casted to single-item {#link|Pointers#},
{#header_open|Type Coercion: Zero Bit Types#}
<p>{#link|Zero Bit Types#} may be coerced to single-item {#link|Pointers#},
regardless of const.</p>
<p>TODO document the reasoning for this</p>
<p>TODO document whether vice versa should work and why</p>
{#code_begin|test#}
test "implicit casting of zero bit types" {
test "coercion of zero bit types" {
var x: void = {};
var y: *void = x;
//var z: void = y; // TODO
}
{#code_end#}
{#header_close#}
{#header_open|Implicit Cast: undefined#}
{#header_open|Type Coercion: undefined#}
<p>{#link|undefined#} can be cast to any type.</p>
{#header_close#}
{#header_close#}
@ -4976,7 +4976,7 @@ test "implicit casting of zero bit types" {
<li>Some {#link|binary operations|Table of Operators#}</li>
</ul>
<p>
This kind of type resolution chooses a type that all peer types can implicitly cast into. Here are
This kind of type resolution chooses a type that all peer types can coerce into. Here are
some examples:
</p>
{#code_begin|test#}
@ -5007,8 +5007,8 @@ test "peer resolve array and const slice" {
comptime testPeerResolveArrayConstSlice(true);
}
fn testPeerResolveArrayConstSlice(b: bool) void {
const value1 = if (b) "aoeu" else ([]const u8)("zz");
const value2 = if (b) ([]const u8)("zz") else "aoeu";
const value1 = if (b) "aoeu" else @as([]const u8, "zz");
const value2 = if (b) @as([]const u8, "zz") else "aoeu";
assert(mem.eql(u8, value1, "aoeu"));
assert(mem.eql(u8, value2, "zz"));
}
@ -5023,10 +5023,10 @@ test "peer type resolution: ?T and T" {
}
fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {
if (c) {
return if (b) null else usize(0);
return if (b) null else @as(usize, 0);
}
return usize(3);
return @as(usize, 3);
}
test "peer type resolution: [0]u8 and []const u8" {
@ -5815,7 +5815,7 @@ test "printf too many arguments" {
</p>
<p>
Zig doesn't care whether the format argument is a string literal,
only that it is a compile-time known value that is implicitly castable to a {#syntax#}[]const u8{#endsyntax#}:
only that it is a compile-time known value that can be coerced to a {#syntax#}[]const u8{#endsyntax#}:
</p>
{#code_begin|exe|printf#}
const warn = @import("std").debug.warn;
@ -6185,7 +6185,7 @@ fn func() void {
</p>
<p>
{#syntax#}await{#endsyntax#} is a suspend point, and takes as an operand anything that
implicitly casts to {#syntax#}anyframe->T{#endsyntax#}.
coerces to {#syntax#}anyframe->T{#endsyntax#}.
</p>
<p>
There is a common misconception that {#syntax#}await{#endsyntax#} resumes the target function.
@ -7116,7 +7116,7 @@ test "field access by string" {
<pre>{#syntax#}@frame() *@Frame(func){#endsyntax#}</pre>
<p>
This function returns a pointer to the frame for a given function. This type
can be {#link|implicitly cast|Implicit Casts#} to {#syntax#}anyframe->T{#endsyntax#} and
can be {#link|coerced|Type Coercion#} to {#syntax#}anyframe->T{#endsyntax#} and
to {#syntax#}anyframe{#endsyntax#}, where {#syntax#}T{#endsyntax#} is the return type
of the function in scope.
</p>
@ -7835,7 +7835,7 @@ test "vector @splat" {
const scalar: u32 = 5;
const result = @splat(4, scalar);
comptime assert(@typeOf(result) == @Vector(4, u32));
assert(std.mem.eql(u32, ([4]u32)(result), [_]u32{ 5, 5, 5, 5 }));
assert(std.mem.eql(u32, @as([4]u32, result), [_]u32{ 5, 5, 5, 5 }));
}
{#code_end#}
<p>
@ -8033,7 +8033,7 @@ test "integer truncation" {
</p>
<p>
If {#syntax#}T{#endsyntax#} is {#syntax#}comptime_int{#endsyntax#},
then this is semantically equivalent to an {#link|implicit cast|Implicit Casts#}.
then this is semantically equivalent to {#link|Type Coercion#}.
</p>
{#header_close#}
@ -8537,7 +8537,7 @@ pub fn main() void {
{#header_close#}
{#header_open|Cast Truncates Data#}
<p>At compile-time:</p>
{#code_begin|test_err|integer value 300 cannot be implicitly casted to type 'u8'#}
{#code_begin|test_err|integer value 300 cannot be coerced to type 'u8'#}
comptime {
const spartan_count: u16 = 300;
const byte = @intCast(u8, spartan_count);
@ -8673,7 +8673,7 @@ test "wraparound addition and subtraction" {
<p>At compile-time:</p>
{#code_begin|test_err|operation caused overflow#}
comptime {
const x = @shlExact(u8(0b01010101), 2);
const x = @shlExact(@as(u8, 0b01010101), 2);
}
{#code_end#}
<p>At runtime:</p>
@ -8691,7 +8691,7 @@ pub fn main() void {
<p>At compile-time:</p>
{#code_begin|test_err|exact shift shifted out 1 bits#}
comptime {
const x = @shrExact(u8(0b10101010), 2);
const x = @shrExact(@as(u8, 0b10101010), 2);
}
{#code_end#}
<p>At runtime:</p>
@ -9543,8 +9543,8 @@ const c = @cImport({
<p>{#syntax#}[*c]T{#endsyntax#} - C pointer.</p>
<ul>
<li>Supports all the syntax of the other two pointer types.</li>
<li>Implicitly casts to other pointer types, as well as {#link|Optional Pointers#}.
When a C pointer is implicitly casted to a non-optional pointer, safety-checked
<li>Coerces to other pointer types, as well as {#link|Optional Pointers#}.
When a C pointer is coerced to a non-optional pointer, safety-checked
{#link|Undefined Behavior#} occurs if the address is 0.
</li>
<li>Allows address 0. On non-freestanding targets, dereferencing address 0 is safety-checked
@ -9552,7 +9552,7 @@ const c = @cImport({
null, just like {#syntax#}?usize{#endsyntax#}. Note that creating an optional C pointer
is unnecessary as one can use normal {#link|Optional Pointers#}.
</li>
<li>Supports {#link|implicit casting|Implicit Casts#} to and from integers.</li>
<li>Supports {#link|Type Coercion#} to and from integers.</li>
<li>Supports comparison with integers.</li>
<li>Does not support Zig-only pointer attributes such as alignment. Use normal {#link|Pointers#}
please!</li>

View File

@ -266,7 +266,7 @@ pub const Loop = struct {
},
};
const empty_kevs = ([*]os.Kevent)(undefined)[0..0];
const empty_kevs = &[0]os.Kevent{};
for (self.eventfd_resume_nodes) |*eventfd_node, i| {
eventfd_node.* = std.atomic.Stack(ResumeNode.EventFd).Node{
@ -289,7 +289,7 @@ pub const Loop = struct {
.next = undefined,
};
self.available_eventfd_resume_nodes.push(eventfd_node);
const kevent_array = (*const [1]os.Kevent)(&eventfd_node.data.kevent);
const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.data.kevent);
_ = try os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null);
eventfd_node.data.kevent.flags = os.EV_CLEAR | os.EV_ENABLE;
eventfd_node.data.kevent.fflags = os.NOTE_TRIGGER;
@ -305,7 +305,7 @@ pub const Loop = struct {
.data = 0,
.udata = @ptrToInt(&self.final_resume_node),
};
const final_kev_arr = (*const [1]os.Kevent)(&self.os_data.final_kevent);
const final_kev_arr = @as(*const [1]os.Kevent, &self.os_data.final_kevent);
_ = try os.kevent(self.os_data.kqfd, final_kev_arr, empty_kevs, null);
self.os_data.final_kevent.flags = os.EV_ENABLE;
self.os_data.final_kevent.fflags = os.NOTE_TRIGGER;
@ -572,8 +572,8 @@ pub const Loop = struct {
eventfd_node.base.handle = next_tick_node.data;
switch (builtin.os) {
.macosx, .freebsd, .netbsd, .dragonfly => {
const kevent_array = (*const [1]os.Kevent)(&eventfd_node.kevent);
const empty_kevs = ([*]os.Kevent)(undefined)[0..0];
const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.kevent);
const empty_kevs = &[0]os.Kevent{};
_ = os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch {
self.next_tick_queue.unget(next_tick_node);
self.available_eventfd_resume_nodes.push(resume_stack_node);
@ -695,8 +695,8 @@ pub const Loop = struct {
},
.macosx, .freebsd, .netbsd, .dragonfly => {
self.posixFsRequest(&self.os_data.fs_end_request);
const final_kevent = (*const [1]os.Kevent)(&self.os_data.final_kevent);
const empty_kevs = ([*]os.Kevent)(undefined)[0..0];
const final_kevent = @as(*const [1]os.Kevent, &self.os_data.final_kevent);
const empty_kevs = &[0]os.Kevent{};
// cannot fail because we already added it and this just enables it
_ = os.kevent(self.os_data.kqfd, final_kevent, empty_kevs, null) catch unreachable;
return;
@ -753,7 +753,7 @@ pub const Loop = struct {
},
.macosx, .freebsd, .netbsd, .dragonfly => {
var eventlist: [1]os.Kevent = undefined;
const empty_kevs = ([*]os.Kevent)(undefined)[0..0];
const empty_kevs = &[0]os.Kevent{};
const count = os.kevent(self.os_data.kqfd, empty_kevs, eventlist[0..], null) catch unreachable;
for (eventlist[0..count]) |ev| {
const resume_node = @intToPtr(*ResumeNode, ev.udata);
@ -815,8 +815,8 @@ pub const Loop = struct {
self.os_data.fs_queue.put(request_node);
switch (builtin.os) {
.macosx, .freebsd, .netbsd, .dragonfly => {
const fs_kevs = (*const [1]os.Kevent)(&self.os_data.fs_kevent_wake);
const empty_kevs = ([*]os.Kevent)(undefined)[0..0];
const fs_kevs = @as(*const [1]os.Kevent, &self.os_data.fs_kevent_wake);
const empty_kevs = &[0]os.Kevent{};
_ = os.kevent(self.os_data.fs_kqfd, fs_kevs, empty_kevs, null) catch unreachable;
},
.linux => {
@ -890,7 +890,7 @@ pub const Loop = struct {
}
},
.macosx, .freebsd, .netbsd, .dragonfly => {
const fs_kevs = (*const [1]os.Kevent)(&self.os_data.fs_kevent_wait);
const fs_kevs = @as(*const [1]os.Kevent, &self.os_data.fs_kevent_wait);
var out_kevs: [1]os.Kevent = undefined;
_ = os.kevent(self.os_data.fs_kqfd, fs_kevs, out_kevs[0..], null) catch unreachable;
},

View File

@ -584,7 +584,7 @@ pub const Dir = struct {
.FileBothDirectoryInformation,
w.FALSE,
null,
if (self.first) w.BOOLEAN(w.TRUE) else w.BOOLEAN(w.FALSE),
if (self.first) @as(w.BOOLEAN, w.TRUE) else @as(w.BOOLEAN, w.FALSE),
);
self.first = false;
if (io.Information == 0) return null;

View File

@ -1126,9 +1126,9 @@ pub fn unlinkatW(dirfd: fd_t, sub_path_w: [*]const u16, flags: u32) UnlinkatErro
const want_rmdir_behavior = (flags & AT_REMOVEDIR) != 0;
const create_options_flags = if (want_rmdir_behavior)
w.ULONG(w.FILE_DELETE_ON_CLOSE)
@as(w.ULONG, w.FILE_DELETE_ON_CLOSE)
else
w.ULONG(w.FILE_DELETE_ON_CLOSE | w.FILE_NON_DIRECTORY_FILE);
@as(w.ULONG, w.FILE_DELETE_ON_CLOSE | w.FILE_NON_DIRECTORY_FILE);
const path_len_bytes = @intCast(u16, mem.toSliceConst(u16, sub_path_w).len * 2);
var nt_name = w.UNICODE_STRING{

View File

@ -262,7 +262,7 @@ pub const ReadFileError = error{Unexpected};
pub fn ReadFile(in_hFile: HANDLE, buffer: []u8) ReadFileError!usize {
var index: usize = 0;
while (index < buffer.len) {
const want_read_count = @intCast(DWORD, math.min(DWORD(maxInt(DWORD)), buffer.len - index));
const want_read_count = @intCast(DWORD, math.min(@as(DWORD, maxInt(DWORD)), buffer.len - index));
var amt_read: DWORD = undefined;
if (kernel32.ReadFile(in_hFile, buffer.ptr + index, want_read_count, &amt_read, null) == 0) {
switch (kernel32.GetLastError()) {

View File

@ -69,7 +69,7 @@ pub const FALSE = 0;
pub const INVALID_HANDLE_VALUE = @intToPtr(HANDLE, maxInt(usize));
pub const INVALID_FILE_ATTRIBUTES = DWORD(maxInt(DWORD));
pub const INVALID_FILE_ATTRIBUTES = @as(DWORD, maxInt(DWORD));
pub const FILE_ALL_INFORMATION = extern struct {
BasicInformation: FILE_BASIC_INFORMATION,
@ -571,16 +571,16 @@ pub const KF_FLAG_SIMPLE_IDLIST = 256;
pub const KF_FLAG_ALIAS_ONLY = -2147483648;
pub const S_OK = 0;
pub const E_NOTIMPL = @bitCast(c_long, c_ulong(0x80004001));
pub const E_NOINTERFACE = @bitCast(c_long, c_ulong(0x80004002));
pub const E_POINTER = @bitCast(c_long, c_ulong(0x80004003));
pub const E_ABORT = @bitCast(c_long, c_ulong(0x80004004));
pub const E_FAIL = @bitCast(c_long, c_ulong(0x80004005));
pub const E_UNEXPECTED = @bitCast(c_long, c_ulong(0x8000FFFF));
pub const E_ACCESSDENIED = @bitCast(c_long, c_ulong(0x80070005));
pub const E_HANDLE = @bitCast(c_long, c_ulong(0x80070006));
pub const E_OUTOFMEMORY = @bitCast(c_long, c_ulong(0x8007000E));
pub const E_INVALIDARG = @bitCast(c_long, c_ulong(0x80070057));
pub const E_NOTIMPL = @bitCast(c_long, @as(c_ulong, 0x80004001));
pub const E_NOINTERFACE = @bitCast(c_long, @as(c_ulong, 0x80004002));
pub const E_POINTER = @bitCast(c_long, @as(c_ulong, 0x80004003));
pub const E_ABORT = @bitCast(c_long, @as(c_ulong, 0x80004004));
pub const E_FAIL = @bitCast(c_long, @as(c_ulong, 0x80004005));
pub const E_UNEXPECTED = @bitCast(c_long, @as(c_ulong, 0x8000FFFF));
pub const E_ACCESSDENIED = @bitCast(c_long, @as(c_ulong, 0x80070005));
pub const E_HANDLE = @bitCast(c_long, @as(c_ulong, 0x80070006));
pub const E_OUTOFMEMORY = @bitCast(c_long, @as(c_ulong, 0x8007000E));
pub const E_INVALIDARG = @bitCast(c_long, @as(c_ulong, 0x80070057));
pub const FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
pub const FILE_FLAG_DELETE_ON_CLOSE = 0x04000000;
@ -873,4 +873,4 @@ pub const CURDIR = extern struct {
Handle: HANDLE,
};
pub const DUPLICATE_SAME_ACCESS = 2;
pub const DUPLICATE_SAME_ACCESS = 2;

View File

@ -774,12 +774,14 @@ fn transCCast(
if (qualTypeIsPtr(dst_type) and qualTypeIsPtr(src_type))
return transCPtrCast(rp, loc, dst_type, src_type, expr);
if (cIsUnsignedInteger(dst_type) and qualTypeIsPtr(src_type)) {
const cast_node = try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc));
const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
try cast_node.params.push(try transQualType(rp, dst_type, loc));
_ = try appendToken(rp.c, .Comma, ",");
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");
try builtin_node.params.push(expr);
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
try cast_node.op.Call.params.push(&builtin_node.base);
cast_node.rtoken = try appendToken(rp.c, .RParen, ")");
try cast_node.params.push(&builtin_node.base);
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return &cast_node.base;
}
if (cIsUnsignedInteger(src_type) and qualTypeIsPtr(dst_type)) {
@ -793,9 +795,11 @@ fn transCCast(
// TODO: maybe widen to increase size
// TODO: maybe bitcast to change sign
// TODO: maybe truncate to reduce size
const cast_node = try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc));
try cast_node.op.Call.params.push(expr);
cast_node.rtoken = try appendToken(rp.c, .RParen, ")");
const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
try cast_node.params.push(try transQualType(rp, dst_type, loc));
_ = try appendToken(rp.c, .Comma, ",");
try cast_node.params.push(expr);
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return &cast_node.base;
}

View File

@ -6339,7 +6339,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
return irb->codegen->invalid_instruction;
if (result_loc_cast != nullptr) {
IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, init_value, result_loc_cast);
IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, init_value->source_node,
init_value, result_loc_cast);
ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base);
}
@ -9610,7 +9611,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
}
ir_add_error(ira, instruction,
buf_sprintf("%s value %s cannot be implicitly casted to type '%s'",
buf_sprintf("%s value %s cannot be coerced to type '%s'",
num_lit_str,
buf_ptr(val_buf),
buf_ptr(&other_type->name)));
@ -13065,8 +13066,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
return ira->codegen->invalid_instruction;
}
static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type,
ResultLoc *result_loc)
static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction *source_instr,
IrInstruction *value, ZigType *expected_type, ResultLoc *result_loc)
{
assert(value);
assert(value != ira->codegen->invalid_instruction);
@ -13080,11 +13081,11 @@ static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction
if (value->value.type->id == ZigTypeIdUnreachable)
return value;
return ir_analyze_cast(ira, value, expected_type, value, result_loc);
return ir_analyze_cast(ira, source_instr, expected_type, value, result_loc);
}
static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) {
return ir_implicit_cast_with_result(ira, value, expected_type, nullptr);
return ir_implicit_cast_with_result(ira, value, value, expected_type, nullptr);
}
static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr,
@ -26068,7 +26069,7 @@ static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrIns
ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child);
if (type_is_invalid(dest_type))
return ira->codegen->invalid_instruction;
return ir_implicit_cast(ira, operand, dest_type);
return ir_implicit_cast_with_result(ira, &instruction->base, operand, dest_type, nullptr);
}
static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) {

View File

@ -221,6 +221,15 @@ static AstNode *trans_create_node_opaque(Context *c) {
return trans_create_node_builtin_fn_call_str(c, "OpaqueType");
}
static AstNode *trans_create_node_cast(Context *c, AstNode *dest_type, AstNode *operand) {
AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
node->data.fn_call_expr.fn_ref_expr = trans_create_node_symbol(c, buf_create_from_str("as"));
node->data.fn_call_expr.modifier = CallModifierBuiltin;
node->data.fn_call_expr.params.append(dest_type);
node->data.fn_call_expr.params.append(operand);
return node;
}
static AstNode *trans_create_node_fn_call_1(Context *c, AstNode *fn_ref_expr, AstNode *arg1) {
AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
node->data.fn_call_expr.fn_ref_expr = fn_ref_expr;
@ -337,14 +346,6 @@ static AstNode *trans_create_node_unsigned(Context *c, uint64_t x) {
return trans_create_node_unsigned_negative(c, x, false);
}
static AstNode *trans_create_node_cast(Context *c, AstNode *dest, AstNode *src) {
AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
node->data.fn_call_expr.fn_ref_expr = dest;
node->data.fn_call_expr.params.resize(1);
node->data.fn_call_expr.params.items[0] = src;
return node;
}
static AstNode *trans_create_node_unsigned_negative_type(Context *c, uint64_t x, bool is_negative,
const char *type_name)
{
@ -701,7 +702,7 @@ static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location,
if (c_is_unsigned_integer(c, dest_type) && qual_type_is_ptr(src_type)) {
AstNode *addr_node = trans_create_node_builtin_fn_call_str(c, "ptrToInt");
addr_node->data.fn_call_expr.params.append(expr);
return trans_create_node_fn_call_1(c, trans_qual_type(c, dest_type, source_location), addr_node);
return trans_create_node_cast(c, trans_qual_type(c, dest_type, source_location), addr_node);
}
if (c_is_unsigned_integer(c, src_type) && qual_type_is_ptr(dest_type)) {
AstNode *ptr_node = trans_create_node_builtin_fn_call_str(c, "intToPtr");
@ -712,7 +713,7 @@ static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location,
// TODO: maybe widen to increase size
// TODO: maybe bitcast to change sign
// TODO: maybe truncate to reduce size
return trans_create_node_fn_call_1(c, trans_qual_type(c, dest_type, source_location), expr);
return trans_create_node_cast(c, trans_qual_type(c, dest_type, source_location), expr);
}
static bool c_is_signed_integer(Context *c, ZigClangQualType qt) {
@ -1527,7 +1528,7 @@ static AstNode *trans_create_shift_op(Context *c, TransScope *scope, ZigClangQua
AstNode *rhs = trans_expr(c, ResultUsedYes, scope, rhs_expr, TransRValue);
if (rhs == nullptr) return nullptr;
AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);
AstNode *coerced_rhs = trans_create_node_cast(c, rhs_type, rhs);
return trans_create_node_bin_op(c, lhs, bin_op, coerced_rhs);
}
@ -1702,7 +1703,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
AstNode *rhs = trans_expr(c, ResultUsedYes, scope, ZigClangCompoundAssignOperator_getRHS(stmt), TransRValue);
if (rhs == nullptr) return nullptr;
AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);
AstNode *coerced_rhs = trans_create_node_cast(c, rhs_type, rhs);
return trans_create_node_bin_op(c, lhs, assign_op, coerced_rhs);
} else {
@ -1733,7 +1734,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
AstNode *rhs = trans_expr(c, ResultUsedYes, &child_scope->base, ZigClangCompoundAssignOperator_getRHS(stmt), TransRValue);
if (rhs == nullptr) return nullptr;
AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);
AstNode *coerced_rhs = trans_create_node_cast(c, rhs_type, rhs);
// operation_type(*_ref)
AstNode *operation_type_cast = trans_c_cast(c, rhs_location,
@ -2684,7 +2685,7 @@ static AstNode *to_enum_zero_cmp(Context *c, AstNode *expr, AstNode *enum_type)
// @TagType(Enum)(0)
AstNode *zero = trans_create_node_unsigned_negative(c, 0, false);
AstNode *casted_zero = trans_create_node_fn_call_1(c, tag_type, zero);
AstNode *casted_zero = trans_create_node_cast(c, tag_type, zero);
// @bitCast(Enum, @TagType(Enum)(0))
AstNode *bitcast = trans_create_node_builtin_fn_call_str(c, "bitCast");

View File

@ -145,23 +145,23 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ _ = c._setmode(1, c._O_BINARY);
\\ }
\\ _ = c.printf(c"0: %llu\n",
\\ u64(0));
\\ @as(u64, 0));
\\ _ = c.printf(c"320402575052271: %llu\n",
\\ u64(320402575052271));
\\ @as(u64, 320402575052271));
\\ _ = c.printf(c"0x01236789abcdef: %llu\n",
\\ u64(0x01236789abcdef));
\\ @as(u64, 0x01236789abcdef));
\\ _ = c.printf(c"0xffffffffffffffff: %llu\n",
\\ u64(0xffffffffffffffff));
\\ @as(u64, 0xffffffffffffffff));
\\ _ = c.printf(c"0x000000ffffffffffffffff: %llu\n",
\\ u64(0x000000ffffffffffffffff));
\\ @as(u64, 0x000000ffffffffffffffff));
\\ _ = c.printf(c"0o1777777777777777777777: %llu\n",
\\ u64(0o1777777777777777777777));
\\ @as(u64, 0o1777777777777777777777));
\\ _ = c.printf(c"0o0000001777777777777777777777: %llu\n",
\\ u64(0o0000001777777777777777777777));
\\ @as(u64, 0o0000001777777777777777777777));
\\ _ = c.printf(c"0b1111111111111111111111111111111111111111111111111111111111111111: %llu\n",
\\ u64(0b1111111111111111111111111111111111111111111111111111111111111111));
\\ @as(u64, 0b1111111111111111111111111111111111111111111111111111111111111111));
\\ _ = c.printf(c"0b0000001111111111111111111111111111111111111111111111111111111111111111: %llu\n",
\\ u64(0b0000001111111111111111111111111111111111111111111111111111111111111111));
\\ @as(u64, 0b0000001111111111111111111111111111111111111111111111111111111111111111));
\\
\\ _ = c.printf(c"\n");
\\

View File

@ -189,7 +189,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ const x = 1 << &@as(u8, 10);
\\}
,
"tmp.zig:2:23: error: shift amount has to be an integer type, but found '*u8'",
"tmp.zig:2:21: error: shift amount has to be an integer type, but found '*u8'",
"tmp.zig:2:17: note: referenced here",
);
@ -199,8 +199,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ const x = &@as(u8, 1) << 10;
\\}
,
"tmp.zig:2:18: error: bit shifting operation expected integer type, found '*u8'",
"tmp.zig:2:22: note: referenced here",
"tmp.zig:2:16: error: bit shifting operation expected integer type, found '*u8'",
"tmp.zig:2:27: note: referenced here",
);
cases.add(
@ -245,7 +245,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\}
,
"tmp.zig:2:20: error: expected type 'u29', found 'bool'",
"tmp.zig:5:22: error: fractional component prevents float value 12.340000 from being casted to type 'u29'",
"tmp.zig:5:19: error: fractional component prevents float value 12.340000 from being casted to type 'u29'",
);
cases.addCase(x: {
@ -1243,7 +1243,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ var ptr: [*c]u8 = x;
\\}
,
"tmp.zig:2:33: error: integer value 18446744073709551617 cannot be implicitly casted to type 'usize'",
"tmp.zig:2:33: error: integer value 18446744073709551617 cannot be coerced to type 'usize'",
"tmp.zig:6:23: error: integer type 'u65' too big for implicit @intToPtr to type '[*c]u8'",
);
@ -1300,14 +1300,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ var z = @truncate(u8, @as(u16, undefined));
\\}
,
"tmp.zig:2:30: error: use of undefined value here causes undefined behavior",
"tmp.zig:2:27: error: use of undefined value here causes undefined behavior",
);
cases.addTest(
"return invalid type from test",
\\test "example" { return 1; }
,
"tmp.zig:1:25: error: integer value 1 cannot be implicitly casted to type 'void'",
"tmp.zig:1:25: error: integer value 1 cannot be coerced to type 'void'",
);
cases.add(
@ -1464,8 +1464,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ var byte: u8 = spartan_count;
\\}
,
"tmp.zig:3:31: error: integer value 300 cannot be implicitly casted to type 'u8'",
"tmp.zig:7:22: error: integer value 300 cannot be implicitly casted to type 'u8'",
"tmp.zig:3:31: error: integer value 300 cannot be coerced to type 'u8'",
"tmp.zig:7:22: error: integer value 300 cannot be coerced to type 'u8'",
"tmp.zig:11:20: error: expected type 'u8', found 'u16'",
);
@ -1498,7 +1498,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ var x: i65536 = 1;
\\}
,
"tmp.zig:2:31: error: integer value 65536 cannot be implicitly casted to type 'u16'",
"tmp.zig:2:31: error: integer value 65536 cannot be coerced to type 'u16'",
"tmp.zig:5:12: error: primitive integer type 'i65536' exceeds maximum bit width of 65535",
);
@ -1689,7 +1689,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ const x = @floatToInt(i32, @as(i32, 54));
\\}
,
"tmp.zig:2:35: error: expected float type, found 'i32'",
"tmp.zig:2:32: error: expected float type, found 'i32'",
);
cases.add(
@ -1698,7 +1698,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ const x = @floatToInt(i8, 200);
\\}
,
"tmp.zig:2:31: error: integer value 200 cannot be implicitly casted to type 'i8'",
"tmp.zig:2:31: error: integer value 200 cannot be coerced to type 'i8'",
);
cases.add(
@ -2207,7 +2207,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ var rule_set = try Foo.init();
\\}
,
"tmp.zig:2:13: error: expected type 'i32', found 'type'",
"tmp.zig:2:10: error: expected type 'i32', found 'type'",
);
cases.add(
@ -2357,10 +2357,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"comptime slice of undefined pointer non-zero len",
\\export fn entry() void {
\\ const slice = ([*]i32)(undefined)[0..1];
\\ const slice = @as([*]i32, undefined)[0..1];
\\}
,
"tmp.zig:2:38: error: non-zero length slice of undefined pointer",
"tmp.zig:2:41: error: non-zero length slice of undefined pointer",
);
cases.add(
@ -2660,7 +2660,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ const x = @as(usize, -10);
\\}
,
"tmp.zig:2:21: error: cannot cast negative value -10 to unsigned integer type 'usize'",
"tmp.zig:2:26: error: cannot cast negative value -10 to unsigned integer type 'usize'",
);
cases.add(
@ -3388,7 +3388,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\}
\\export fn entry() void { f(true); g(true); }
,
"tmp.zig:2:42: error: integer value 1 cannot be implicitly casted to type 'void'",
"tmp.zig:2:21: error: expected type 'i32', found 'void'",
"tmp.zig:5:15: error: incompatible types: 'i32' and 'void'",
);
@ -3524,7 +3524,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\}
\\export fn entry() void { _ = f(); }
,
"tmp.zig:2:15: error: unreachable code",
"tmp.zig:2:12: error: unreachable code",
);
cases.add(
@ -3765,7 +3765,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\const x : u8 = 300;
\\export fn entry() usize { return @sizeOf(@typeOf(x)); }
,
"tmp.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'",
"tmp.zig:1:16: error: integer value 300 cannot be coerced to type 'u8'",
);
cases.add(
@ -3897,8 +3897,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
,
"tmp.zig:1:21: error: division by zero",
"tmp.zig:2:25: error: division by zero",
"tmp.zig:3:22: error: division by zero",
"tmp.zig:4:26: error: division by zero",
"tmp.zig:3:27: error: division by zero",
"tmp.zig:4:31: error: division by zero",
);
cases.add(
@ -4908,7 +4908,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ var vga_mem: u16 = 0xB8000;
\\}
,
"tmp.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'",
"tmp.zig:2:24: error: integer value 753664 cannot be coerced to type 'u16'",
);
cases.add(
@ -5080,7 +5080,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"pass const ptr to mutable ptr fn",
\\fn foo() bool {
\\ const a = ([]const u8)("a",);
\\ const a = @as([]const u8, "a",);
\\ const b = &a;
\\ return ptrEql(b, b);
\\}
@ -5584,7 +5584,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ return @as(i32, 12.34);
\\}
,
"tmp.zig:2:16: error: fractional component prevents float value 12.340000 from being casted to type 'i32'",
"tmp.zig:2:21: error: fractional component prevents float value 12.340000 from being casted to type 'i32'",
);
cases.add(
@ -5671,16 +5671,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\export fn entry() void {
\\ var foo = Foo { .a = 1, .b = 10 };
\\ foo.b += 1;
\\ bar((*[1]u32)(&foo.b)[0..]);
\\ bar(@as(*[1]u32, &foo.b)[0..]);
\\}
\\
\\fn bar(x: []u32) void {
\\ x[0] += 1;
\\}
,
"tmp.zig:9:18: error: cast increases pointer alignment",
"tmp.zig:9:23: note: '*align(1) u32' has alignment 1",
"tmp.zig:9:18: note: '*[1]u32' has alignment 4",
"tmp.zig:9:9: error: cast increases pointer alignment",
"tmp.zig:9:26: note: '*align(1) u32' has alignment 1",
"tmp.zig:9:9: note: '*[1]u32' has alignment 4",
);
cases.add(
@ -5702,7 +5702,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ @alignCast(4, @as(u32, 3));
\\}
,
"tmp.zig:2:22: error: expected pointer or slice, found 'u32'",
"tmp.zig:2:19: error: expected pointer or slice, found 'u32'",
);
cases.add(
@ -5740,7 +5740,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
);
cases.add(
"wrong pointer implicitly casted to pointer to @OpaqueType()",
"wrong pointer coerced to pointer to @OpaqueType()",
\\const Derp = @OpaqueType();
\\extern fn bar(d: *Derp) void;
\\export fn foo() void {
@ -5793,7 +5793,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"tmp.zig:17:4: error: variable of type 'Opaque' not allowed",
"tmp.zig:20:4: error: variable of type 'type' must be const or comptime",
"tmp.zig:23:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime",
"tmp.zig:26:4: error: unreachable code",
"tmp.zig:26:22: error: unreachable code",
);
cases.add(
@ -5803,7 +5803,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, @as(u32, 1234), @as(u32, 1234))) {}
\\}
,
"tmp.zig:3:50: error: expected type 'std.builtin.AtomicOrder', found 'u32'",
"tmp.zig:3:47: error: expected type 'std.builtin.AtomicOrder', found 'u32'",
);
cases.add(
@ -5813,7 +5813,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ @export("entry", entry, @as(u32, 1234));
\\}
,
"tmp.zig:3:32: error: expected type 'std.builtin.GlobalLinkage', found 'u32'",
"tmp.zig:3:29: error: expected type 'std.builtin.GlobalLinkage', found 'u32'",
);
cases.add(
@ -6185,7 +6185,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\};
\\
\\export fn entry() void {
\\ var y = u3(3);
\\ var y = @as(u3, 3);
\\ var x = @intToEnum(Small, y);
\\}
,
@ -6722,8 +6722,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"tmp.zig:1:1: note: declared here",
);
// fixed bug #2032
cases.add(
cases.add( // fixed bug #2032
"compile diagnostic string for top level decl type",
\\export fn entry() void {
\\ var foo: u32 = @This(){};
@ -6731,6 +6730,5 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
,
"tmp.zig:2:27: error: expected type 'u32', found '(root)'",
"tmp.zig:1:1: note: (root) declared here",
"tmp.zig:2:5: note: referenced here",
);
}

View File

@ -144,7 +144,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub extern fn foo() void;
\\pub fn bar() void {
\\ var func_ptr: ?*c_void = @ptrCast(?*c_void, foo);
\\ var typed_func_ptr: ?extern fn () void = @intToPtr(?extern fn () void, c_ulong(@ptrToInt(func_ptr)));
\\ var typed_func_ptr: ?extern fn () void = @intToPtr(?extern fn () void, @as(c_ulong, @ptrToInt(func_ptr)));
\\}
);
@ -567,37 +567,37 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.add("l integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020l /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
,
\\pub const SDL_INIT_VIDEO = c_long(32);
\\pub const SDL_INIT_VIDEO = @as(c_long, 32);
);
cases.add("ul integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020ul /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
,
\\pub const SDL_INIT_VIDEO = c_ulong(32);
\\pub const SDL_INIT_VIDEO = @as(c_ulong, 32);
);
cases.add("lu integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020lu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
,
\\pub const SDL_INIT_VIDEO = c_ulong(32);
\\pub const SDL_INIT_VIDEO = @as(c_ulong, 32);
);
cases.add("ll integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020ll /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
,
\\pub const SDL_INIT_VIDEO = c_longlong(32);
\\pub const SDL_INIT_VIDEO = @as(c_longlong, 32);
);
cases.add("ull integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020ull /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
,
\\pub const SDL_INIT_VIDEO = c_ulonglong(32);
\\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32);
);
cases.add("llu integer suffix after hex literal",
\\#define SDL_INIT_VIDEO 0x00000020llu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
,
\\pub const SDL_INIT_VIDEO = c_ulonglong(32);
\\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32);
);
cases.add("zig keywords in C code",
@ -677,7 +677,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ var a = _arg_a;
\\ var i: c_int = 0;
\\ while (a > @as(c_uint, 0)) {
\\ a >>= @import("std").math.Log2Int(c_uint)(1);
\\ a >>= @as(@import("std").math.Log2Int(c_uint), 1);
\\ }
\\ return i;
\\}
@ -849,7 +849,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ var a = _arg_a;
\\ var i: c_int = 0;
\\ while (a > @as(c_uint, 0)) {
\\ a >>= u5(1);
\\ a >>= @as(u5, 1);
\\ }
\\ return i;
\\}
@ -1027,7 +1027,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
,
\\pub export fn foo() c_int {
\\ return (1 << @import("std").math.Log2Int(c_int)(2)) >> @import("std").math.Log2Int(c_int)(1);
\\ return (1 << @as(@import("std").math.Log2Int(c_int), 2)) >> @as(@import("std").math.Log2Int(c_int), 1);
\\}
);
@ -1076,14 +1076,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ _ref.* = (_ref.* ^ 1);
\\ break :x _ref.*;
\\ });
\\ a >>= @import("std").math.Log2Int(c_int)((x: {
\\ a >>= @as(@import("std").math.Log2Int(c_int), (x: {
\\ const _ref = &a;
\\ _ref.* = (_ref.* >> @import("std").math.Log2Int(c_int)(1));
\\ _ref.* = (_ref.* >> @as(@import("std").math.Log2Int(c_int), 1));
\\ break :x _ref.*;
\\ }));
\\ a <<= @import("std").math.Log2Int(c_int)((x: {
\\ a <<= @as(@import("std").math.Log2Int(c_int), (x: {
\\ const _ref = &a;
\\ _ref.* = (_ref.* << @import("std").math.Log2Int(c_int)(1));
\\ _ref.* = (_ref.* << @as(@import("std").math.Log2Int(c_int), 1));
\\ break :x _ref.*;
\\ }));
\\}
@ -1134,14 +1134,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ _ref.* = (_ref.* ^ @as(c_uint, 1));
\\ break :x _ref.*;
\\ });
\\ a >>= @import("std").math.Log2Int(c_uint)((x: {
\\ a >>= @as(@import("std").math.Log2Int(c_uint), (x: {
\\ const _ref = &a;
\\ _ref.* = (_ref.* >> @import("std").math.Log2Int(c_uint)(1));
\\ _ref.* = (_ref.* >> @as(@import("std").math.Log2Int(c_uint), 1));
\\ break :x _ref.*;
\\ }));
\\ a <<= @import("std").math.Log2Int(c_uint)((x: {
\\ a <<= @as(@import("std").math.Log2Int(c_uint), (x: {
\\ const _ref = &a;
\\ _ref.* = (_ref.* << @import("std").math.Log2Int(c_uint)(1));
\\ _ref.* = (_ref.* << @as(@import("std").math.Log2Int(c_uint), 1));
\\ break :x _ref.*;
\\ }));
\\}
@ -1539,7 +1539,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.add("macro pointer cast",
\\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
,
\\pub const NRF_GPIO = if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else ([*c]NRF_GPIO_Type)(NRF_GPIO_BASE);
\\pub const NRF_GPIO = if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE);
);
cases.add("if on non-bool",
@ -1564,7 +1564,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ if (a != 0) return 0;
\\ if (b != 0) return 1;
\\ if (c != null) return 2;
\\ if (d != @bitCast(enum_SomeEnum, @TagType(enum_SomeEnum)(0))) return 3;
\\ if (d != @bitCast(enum_SomeEnum, @as(@TagType(enum_SomeEnum), 0))) return 3;
\\ return 4;
\\}
);
@ -1652,37 +1652,37 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.addC(
"l integer suffix after 0 (zero) in macro definition",
"#define ZERO 0L",
"pub const ZERO = c_long(0);",
"pub const ZERO = @as(c_long, 0);",
);
cases.addC(
"ul integer suffix after 0 (zero) in macro definition",
"#define ZERO 0UL",
"pub const ZERO = c_ulong(0);",
"pub const ZERO = @as(c_ulong, 0);",
);
cases.addC(
"lu integer suffix after 0 (zero) in macro definition",
"#define ZERO 0LU",
"pub const ZERO = c_ulong(0);",
"pub const ZERO = @as(c_ulong, 0);",
);
cases.addC(
"ll integer suffix after 0 (zero) in macro definition",
"#define ZERO 0LL",
"pub const ZERO = c_longlong(0);",
"pub const ZERO = @as(c_longlong, 0);",
);
cases.addC(
"ull integer suffix after 0 (zero) in macro definition",
"#define ZERO 0ULL",
"pub const ZERO = c_ulonglong(0);",
"pub const ZERO = @as(c_ulonglong, 0);",
);
cases.addC(
"llu integer suffix after 0 (zero) in macro definition",
"#define ZERO 0LLU",
"pub const ZERO = c_ulonglong(0);",
"pub const ZERO = @as(c_ulonglong, 0);",
);
cases.addC(