mirror of
https://github.com/ziglang/zig.git
synced 2025-02-05 20:30:37 +00:00
fix regressed tests and update docs to use "type coercion"
This commit is contained in:
parent
3834d3dac0
commit
3cf5c2c62b
@ -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(
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
},
|
||||
|
@ -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;
|
||||
|
@ -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{
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
15
src/ir.cpp
15
src/ir.cpp
@ -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) {
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
\\
|
||||
|
@ -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",
|
||||
);
|
||||
}
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user