| author | |
| committer | |
| log | 3cf5c2c62b12aa0615633a150a1ea8c279e53004 |
| tree | 70c8fdf0c5613c0cfb1a2265ba107b2e282ec226 |
| parent | 3834d3dac0d901e8319aa515b64ade8604fe1ecf |
| signature |
14 files changed, 203 insertions(+), 199 deletions(-)
build.zig+1-1| ... | ... | @@ -155,7 +155,7 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void { |
| 155 | 155 | ) catch unreachable; |
| 156 | 156 | for (dep.system_libs.toSliceConst()) |lib| { |
| 157 | 157 | const static_bare_name = if (mem.eql(u8, lib, "curses")) |
| 158 | @as([]const u8,"libncurses.a") | |
| 158 | @as([]const u8, "libncurses.a") | |
| 159 | 159 | else |
| 160 | 160 | b.fmt("lib{}.a", lib); |
| 161 | 161 | const static_lib_name = fs.path.join( |
doc/docgen.zig+2-2| ... | ... | @@ -10,8 +10,8 @@ const testing = std.testing; |
| 10 | 10 | |
| 11 | 11 | const max_doc_file_size = 10 * 1024 * 1024; |
| 12 | 12 | |
| 13 | const exe_ext = std.build.Target(std.build.Target.Native).exeFileExt(); | |
| 14 | const obj_ext = std.build.Target(std.build.Target.Native).oFileExt(); | |
| 13 | const exe_ext = @as(std.build.Target, std.build.Target.Native).exeFileExt(); | |
| 14 | const obj_ext = @as(std.build.Target, std.build.Target.Native).oFileExt(); | |
| 15 | 15 | const tmp_dir_name = "docgen_tmp"; |
| 16 | 16 | const test_out_path = tmp_dir_name ++ fs.path.sep_str ++ "test" ++ exe_ext; |
| 17 | 17 |
doc/langref.html.in+70-70| ... | ... | @@ -712,7 +712,7 @@ test "init with undefined" { |
| 712 | 712 | } |
| 713 | 713 | {#code_end#} |
| 714 | 714 | <p> |
| 715 | {#syntax#}undefined{#endsyntax#} can be {#link|implicitly cast|Implicit Casts#} to any type. | |
| 715 | {#syntax#}undefined{#endsyntax#} can be {#link|coerced|Type Coercion#} to any type. | |
| 716 | 716 | Once this happens, it is no longer possible to detect that the value is {#syntax#}undefined{#endsyntax#}. |
| 717 | 717 | {#syntax#}undefined{#endsyntax#} means the value could be anything, even something that is nonsense |
| 718 | 718 | 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 { |
| 920 | 920 | {#syntax#}f128{#endsyntax#}. |
| 921 | 921 | </p> |
| 922 | 922 | <p> |
| 923 | Float literals {#link|implicitly cast|Implicit Casts#} to any floating point type, | |
| 923 | Float literals {#link|coerce|Type Coercion#} to any floating point type, | |
| 924 | 924 | and to any {#link|integer|Integers#} type when there is no fractional component. |
| 925 | 925 | </p> |
| 926 | 926 | {#code_begin|syntax#} |
| ... | ... | @@ -950,7 +950,7 @@ const nan = std.math.nan(f128); |
| 950 | 950 | {#code_begin|obj|foo#} |
| 951 | 951 | {#code_release_fast#} |
| 952 | 952 | const builtin = @import("builtin"); |
| 953 | const big = f64(1 << 40); | |
| 953 | const big = @as(f64, 1 << 40); | |
| 954 | 954 | |
| 955 | 955 | export fn foo_strict(x: f64) f64 { |
| 956 | 956 | return x + big - big; |
| ... | ... | @@ -1652,7 +1652,7 @@ test "iterate over an array" { |
| 1652 | 1652 | for (message) |byte| { |
| 1653 | 1653 | sum += byte; |
| 1654 | 1654 | } |
| 1655 | assert(sum == usize('h') + usize('e') + usize('l') * 2 + usize('o')); | |
| 1655 | assert(sum == 'h' + 'e' + 'l' * 2 + 'o'); | |
| 1656 | 1656 | } |
| 1657 | 1657 | |
| 1658 | 1658 | // modifiable array |
| ... | ... | @@ -2003,7 +2003,7 @@ test "variable alignment" { |
| 2003 | 2003 | } |
| 2004 | 2004 | } |
| 2005 | 2005 | {#code_end#} |
| 2006 | <p>In the same way that a {#syntax#}*i32{#endsyntax#} can be {#link|implicitly cast|Implicit Casts#} to a | |
| 2006 | <p>In the same way that a {#syntax#}*i32{#endsyntax#} can be {#link|coerced|Type Coercion#} to a | |
| 2007 | 2007 | {#syntax#}*const i32{#endsyntax#}, a pointer with a larger alignment can be implicitly |
| 2008 | 2008 | cast to a pointer with a smaller alignment, but not vice versa. |
| 2009 | 2009 | </p> |
| ... | ... | @@ -2019,7 +2019,7 @@ var foo: u8 align(4) = 100; |
| 2019 | 2019 | test "global variable alignment" { |
| 2020 | 2020 | assert(@typeOf(&foo).alignment == 4); |
| 2021 | 2021 | assert(@typeOf(&foo) == *align(4) u8); |
| 2022 | const slice = (*[1]u8)(&foo)[0..]; | |
| 2022 | const slice = @as(*[1]u8, &foo)[0..]; | |
| 2023 | 2023 | assert(@typeOf(slice) == []align(4) u8); |
| 2024 | 2024 | } |
| 2025 | 2025 | |
| ... | ... | @@ -2114,7 +2114,7 @@ const fmt = @import("std").fmt; |
| 2114 | 2114 | test "using slices for strings" { |
| 2115 | 2115 | // Zig has no concept of strings. String literals are arrays of u8, and |
| 2116 | 2116 | // in general the string type is []u8 (slice of u8). |
| 2117 | // Here we implicitly cast [5]u8 to []const u8 | |
| 2117 | // Here we coerce [5]u8 to []const u8 | |
| 2118 | 2118 | const hello: []const u8 = "hello"; |
| 2119 | 2119 | const world: []const u8 = "世界"; |
| 2120 | 2120 | |
| ... | ... | @@ -2778,7 +2778,7 @@ test "simple union" { |
| 2778 | 2778 | This turns the union into a <em>tagged</em> union, which makes it eligible |
| 2779 | 2779 | to use with {#link|switch#} expressions. One can use {#link|@TagType#} to |
| 2780 | 2780 | obtain the enum type from the union type. |
| 2781 | Tagged unions implicitly cast to their enum {#link|Implicit Cast: unions and enums#} | |
| 2781 | Tagged unions coerce to their enum {#link|Type Coercion: unions and enums#} | |
| 2782 | 2782 | </p> |
| 2783 | 2783 | {#code_begin|test#} |
| 2784 | 2784 | const std = @import("std"); |
| ... | ... | @@ -2795,7 +2795,7 @@ const ComplexType = union(ComplexTypeTag) { |
| 2795 | 2795 | |
| 2796 | 2796 | test "switch on tagged union" { |
| 2797 | 2797 | const c = ComplexType{ .Ok = 42 }; |
| 2798 | assert(ComplexTypeTag(c) == ComplexTypeTag.Ok); | |
| 2798 | assert(@as(ComplexTypeTag, c) == ComplexTypeTag.Ok); | |
| 2799 | 2799 | |
| 2800 | 2800 | switch (c) { |
| 2801 | 2801 | ComplexTypeTag.Ok => |value| assert(value == 42), |
| ... | ... | @@ -2807,7 +2807,7 @@ test "@TagType" { |
| 2807 | 2807 | assert(@TagType(ComplexType) == ComplexTypeTag); |
| 2808 | 2808 | } |
| 2809 | 2809 | |
| 2810 | test "implicit cast to enum" { | |
| 2810 | test "coerce to enum" { | |
| 2811 | 2811 | const c1 = ComplexType{ .Ok = 42 }; |
| 2812 | 2812 | const c2 = ComplexType.NotOk; |
| 2813 | 2813 | |
| ... | ... | @@ -2833,7 +2833,7 @@ const ComplexType = union(ComplexTypeTag) { |
| 2833 | 2833 | |
| 2834 | 2834 | test "modify tagged union in switch" { |
| 2835 | 2835 | var c = ComplexType{ .Ok = 42 }; |
| 2836 | assert(ComplexTypeTag(c) == ComplexTypeTag.Ok); | |
| 2836 | assert(@as(ComplexTypeTag, c) == ComplexTypeTag.Ok); | |
| 2837 | 2837 | |
| 2838 | 2838 | switch (c) { |
| 2839 | 2839 | ComplexTypeTag.Ok => |*value| value.* += 1, |
| ... | ... | @@ -3943,7 +3943,7 @@ test "fn reflection" { |
| 3943 | 3943 | 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>. |
| 3944 | 3944 | </p> |
| 3945 | 3945 | <p> |
| 3946 | You can {#link|implicitly cast|Implicit Casts#} an error from a subset to a superset: | |
| 3946 | You can {#link|coerce|Type Coercion#} an error from a subset to a superset: | |
| 3947 | 3947 | </p> |
| 3948 | 3948 | {#code_begin|test#} |
| 3949 | 3949 | const std = @import("std"); |
| ... | ... | @@ -3958,7 +3958,7 @@ const AllocationError = error { |
| 3958 | 3958 | OutOfMemory, |
| 3959 | 3959 | }; |
| 3960 | 3960 | |
| 3961 | test "implicit cast subset to superset" { | |
| 3961 | test "coerce subset to superset" { | |
| 3962 | 3962 | const err = foo(AllocationError.OutOfMemory); |
| 3963 | 3963 | std.debug.assert(err == FileOpenError.OutOfMemory); |
| 3964 | 3964 | } |
| ... | ... | @@ -3968,7 +3968,7 @@ fn foo(err: AllocationError) FileOpenError { |
| 3968 | 3968 | } |
| 3969 | 3969 | {#code_end#} |
| 3970 | 3970 | <p> |
| 3971 | But you cannot implicitly cast an error from a superset to a subset: | |
| 3971 | But you cannot {#link|coerce|Type Coercion#} an error from a superset to a subset: | |
| 3972 | 3972 | </p> |
| 3973 | 3973 | {#code_begin|test_err|not a member of destination error set#} |
| 3974 | 3974 | const FileOpenError = error { |
| ... | ... | @@ -3981,7 +3981,7 @@ const AllocationError = error { |
| 3981 | 3981 | OutOfMemory, |
| 3982 | 3982 | }; |
| 3983 | 3983 | |
| 3984 | test "implicit cast superset to subset" { | |
| 3984 | test "coerce superset to subset" { | |
| 3985 | 3985 | foo(FileOpenError.OutOfMemory) catch {}; |
| 3986 | 3986 | } |
| 3987 | 3987 | |
| ... | ... | @@ -4008,7 +4008,7 @@ const err = (error {FileNotFound}).FileNotFound; |
| 4008 | 4008 | It is a superset of all other error sets and a subset of none of them. |
| 4009 | 4009 | </p> |
| 4010 | 4010 | <p> |
| 4011 | You can implicitly cast any error set to the global one, and you can explicitly | |
| 4011 | You can {#link|coerce|Type Coercion#} any error set to the global one, and you can explicitly | |
| 4012 | 4012 | cast an error of the global error set to a non-global one. This inserts a language-level |
| 4013 | 4013 | assert to make sure the error value is in fact in the destination error set. |
| 4014 | 4014 | </p> |
| ... | ... | @@ -4079,7 +4079,7 @@ test "parse u64" { |
| 4079 | 4079 | <p> |
| 4080 | 4080 | Within the function definition, you can see some return statements that return |
| 4081 | 4081 | an error, and at the bottom a return statement that returns a {#syntax#}u64{#endsyntax#}. |
| 4082 | Both types {#link|implicitly cast|Implicit Casts#} to {#syntax#}anyerror!u64{#endsyntax#}. | |
| 4082 | Both types {#link|coerce|Type Coercion#} to {#syntax#}anyerror!u64{#endsyntax#}. | |
| 4083 | 4083 | </p> |
| 4084 | 4084 | <p> |
| 4085 | 4085 | What it looks like to use this function varies depending on what you're |
| ... | ... | @@ -4218,10 +4218,10 @@ const assert = @import("std").debug.assert; |
| 4218 | 4218 | test "error union" { |
| 4219 | 4219 | var foo: anyerror!i32 = undefined; |
| 4220 | 4220 | |
| 4221 | // Implicitly cast from child type of an error union: | |
| 4221 | // Coerce from child type of an error union: | |
| 4222 | 4222 | foo = 1234; |
| 4223 | 4223 | |
| 4224 | // Implicitly cast from an error set: | |
| 4224 | // Coerce from an error set: | |
| 4225 | 4225 | foo = error.SomeError; |
| 4226 | 4226 | |
| 4227 | 4227 | // Use compile-time reflection to access the payload type of an error union: |
| ... | ... | @@ -4598,10 +4598,10 @@ fn doAThing(optional_foo: ?*Foo) void { |
| 4598 | 4598 | const assert = @import("std").debug.assert; |
| 4599 | 4599 | |
| 4600 | 4600 | test "optional type" { |
| 4601 | // Declare an optional and implicitly cast from null: | |
| 4601 | // Declare an optional and coerce from null: | |
| 4602 | 4602 | var foo: ?i32 = null; |
| 4603 | 4603 | |
| 4604 | // Implicitly cast from child type of an optional | |
| 4604 | // Coerce from child type of an optional | |
| 4605 | 4605 | foo = 1234; |
| 4606 | 4606 | |
| 4607 | 4607 | // Use compile-time reflection to access the child type of the optional: |
| ... | ... | @@ -4644,38 +4644,38 @@ test "optional pointers" { |
| 4644 | 4644 | {#header_open|Casting#} |
| 4645 | 4645 | <p> |
| 4646 | 4646 | A <strong>type cast</strong> converts a value of one type to another. |
| 4647 | Zig has {#link|Implicit Casts#} for conversions that are known to be completely safe and unambiguous, | |
| 4647 | Zig has {#link|Type Coercion#} for conversions that are known to be completely safe and unambiguous, | |
| 4648 | 4648 | and {#link|Explicit Casts#} for conversions that one would not want to happen on accident. |
| 4649 | 4649 | There is also a third kind of type conversion called {#link|Peer Type Resolution#} for |
| 4650 | 4650 | the case when a result type must be decided given multiple operand types. |
| 4651 | 4651 | </p> |
| 4652 | {#header_open|Implicit Casts#} | |
| 4652 | {#header_open|Type Coercion#} | |
| 4653 | 4653 | <p> |
| 4654 | An implicit cast occurs when one type is expected, but different type is provided: | |
| 4654 | Type coercion occurs when one type is expected, but different type is provided: | |
| 4655 | 4655 | </p> |
| 4656 | 4656 | {#code_begin|test#} |
| 4657 | test "implicit cast - variable declaration" { | |
| 4657 | test "type coercion - variable declaration" { | |
| 4658 | 4658 | var a: u8 = 1; |
| 4659 | 4659 | var b: u16 = a; |
| 4660 | 4660 | } |
| 4661 | 4661 | |
| 4662 | test "implicit cast - function call" { | |
| 4662 | test "type coercion - function call" { | |
| 4663 | 4663 | var a: u8 = 1; |
| 4664 | 4664 | foo(a); |
| 4665 | 4665 | } |
| 4666 | 4666 | |
| 4667 | 4667 | fn foo(b: u16) void {} |
| 4668 | 4668 | |
| 4669 | test "implicit cast - invoke a type as a function" { | |
| 4669 | test "type coercion - @as builtin" { | |
| 4670 | 4670 | var a: u8 = 1; |
| 4671 | var b = u16(a); | |
| 4671 | var b = @as(u16, a); | |
| 4672 | 4672 | } |
| 4673 | 4673 | {#code_end#} |
| 4674 | 4674 | <p> |
| 4675 | Implicit casts are only allowed when it is completely unambiguous how to get from one type to another, | |
| 4675 | Type coercions are only allowed when it is completely unambiguous how to get from one type to another, | |
| 4676 | 4676 | and the transformation is guaranteed to be safe. There is one exception, which is {#link|C Pointers#}. |
| 4677 | 4677 | </p> |
| 4678 | {#header_open|Implicit Cast: Stricter Qualification#} | |
| 4678 | {#header_open|Type Coercion: Stricter Qualification#} | |
| 4679 | 4679 | <p> |
| 4680 | 4680 | Values which have the same representation at runtime can be cast to increase the strictness |
| 4681 | 4681 | of the qualifiers, no matter how nested the qualifiers are: |
| ... | ... | @@ -4690,7 +4690,7 @@ test "implicit cast - invoke a type as a function" { |
| 4690 | 4690 | These casts are no-ops at runtime since the value representation does not change. |
| 4691 | 4691 | </p> |
| 4692 | 4692 | {#code_begin|test#} |
| 4693 | test "implicit cast - const qualification" { | |
| 4693 | test "type coercion - const qualification" { | |
| 4694 | 4694 | var a: i32 = 1; |
| 4695 | 4695 | var b: *i32 = &a; |
| 4696 | 4696 | foo(b); |
| ... | ... | @@ -4699,7 +4699,7 @@ test "implicit cast - const qualification" { |
| 4699 | 4699 | fn foo(a: *const i32) void {} |
| 4700 | 4700 | {#code_end#} |
| 4701 | 4701 | <p> |
| 4702 | In addition, pointers implicitly cast to const optional pointers: | |
| 4702 | In addition, pointers coerce to const optional pointers: | |
| 4703 | 4703 | </p> |
| 4704 | 4704 | {#code_begin|test#} |
| 4705 | 4705 | const std = @import("std"); |
| ... | ... | @@ -4713,10 +4713,10 @@ test "cast *[1][*]const u8 to [*]const ?[*]const u8" { |
| 4713 | 4713 | } |
| 4714 | 4714 | {#code_end#} |
| 4715 | 4715 | {#header_close#} |
| 4716 | {#header_open|Implicit Cast: Integer and Float Widening#} | |
| 4716 | {#header_open|Type Coercion: Integer and Float Widening#} | |
| 4717 | 4717 | <p> |
| 4718 | {#link|Integers#} implicitly cast to integer types which can represent every value of the old type, and likewise | |
| 4719 | {#link|Floats#} implicitly cast to float types which can represent every value of the old type. | |
| 4718 | {#link|Integers#} coerce to integer types which can represent every value of the old type, and likewise | |
| 4719 | {#link|Floats#} coerce to float types which can represent every value of the old type. | |
| 4720 | 4720 | </p> |
| 4721 | 4721 | {#code_begin|test#} |
| 4722 | 4722 | const std = @import("std"); |
| ... | ... | @@ -4748,7 +4748,7 @@ test "float widening" { |
| 4748 | 4748 | } |
| 4749 | 4749 | {#code_end#} |
| 4750 | 4750 | {#header_close#} |
| 4751 | {#header_open|Implicit Cast: Arrays and Pointers#} | |
| 4751 | {#header_open|Type Coercion: Arrays and Pointers#} | |
| 4752 | 4752 | {#code_begin|test#} |
| 4753 | 4753 | const std = @import("std"); |
| 4754 | 4754 | const assert = std.debug.assert; |
| ... | ... | @@ -4797,7 +4797,7 @@ test "*[N]T to []T" { |
| 4797 | 4797 | assert(std.mem.eql(f32, x2, [2]f32{ 1.2, 3.4 })); |
| 4798 | 4798 | } |
| 4799 | 4799 | |
| 4800 | // Single-item pointers to arrays can be implicitly casted to | |
| 4800 | // Single-item pointers to arrays can be coerced to | |
| 4801 | 4801 | // unknown length pointers. |
| 4802 | 4802 | test "*[N]T to [*]T" { |
| 4803 | 4803 | var buf: [5]u8 = "hello"; |
| ... | ... | @@ -4823,15 +4823,15 @@ test "*T to *[1]T" { |
| 4823 | 4823 | {#code_end#} |
| 4824 | 4824 | {#see_also|C Pointers#} |
| 4825 | 4825 | {#header_close#} |
| 4826 | {#header_open|Implicit Cast: Optionals#} | |
| 4826 | {#header_open|Type Coercion: Optionals#} | |
| 4827 | 4827 | <p> |
| 4828 | The payload type of {#link|Optionals#}, as well as {#link|null#}, implicitly cast to the optional type. | |
| 4828 | The payload type of {#link|Optionals#}, as well as {#link|null#}, coerce to the optional type. | |
| 4829 | 4829 | </p> |
| 4830 | 4830 | {#code_begin|test#} |
| 4831 | 4831 | const std = @import("std"); |
| 4832 | 4832 | const assert = std.debug.assert; |
| 4833 | 4833 | |
| 4834 | test "implicit casting to optionals" { | |
| 4834 | test "coerce to optionals" { | |
| 4835 | 4835 | const x: ?i32 = 1234; |
| 4836 | 4836 | const y: ?i32 = null; |
| 4837 | 4837 | |
| ... | ... | @@ -4844,7 +4844,7 @@ test "implicit casting to optionals" { |
| 4844 | 4844 | const std = @import("std"); |
| 4845 | 4845 | const assert = std.debug.assert; |
| 4846 | 4846 | |
| 4847 | test "implicit casting to optionals wrapped in error union" { | |
| 4847 | test "coerce to optionals wrapped in error union" { | |
| 4848 | 4848 | const x: anyerror!?i32 = 1234; |
| 4849 | 4849 | const y: anyerror!?i32 = null; |
| 4850 | 4850 | |
| ... | ... | @@ -4853,15 +4853,15 @@ test "implicit casting to optionals wrapped in error union" { |
| 4853 | 4853 | } |
| 4854 | 4854 | {#code_end#} |
| 4855 | 4855 | {#header_close#} |
| 4856 | {#header_open|Implicit Cast: Error Unions#} | |
| 4856 | {#header_open|Type Coercion: Error Unions#} | |
| 4857 | 4857 | <p>The payload type of an {#link|Error Union Type#} as well as the {#link|Error Set Type#} |
| 4858 | implicitly cast to the error union type: | |
| 4858 | coerce to the error union type: | |
| 4859 | 4859 | </p> |
| 4860 | 4860 | {#code_begin|test#} |
| 4861 | 4861 | const std = @import("std"); |
| 4862 | 4862 | const assert = std.debug.assert; |
| 4863 | 4863 | |
| 4864 | test "implicit casting to error unions" { | |
| 4864 | test "coercion to error unions" { | |
| 4865 | 4865 | const x: anyerror!i32 = 1234; |
| 4866 | 4866 | const y: anyerror!i32 = error.Failure; |
| 4867 | 4867 | |
| ... | ... | @@ -4870,23 +4870,23 @@ test "implicit casting to error unions" { |
| 4870 | 4870 | } |
| 4871 | 4871 | {#code_end#} |
| 4872 | 4872 | {#header_close#} |
| 4873 | {#header_open|Implicit Cast: Compile-Time Known Numbers#} | |
| 4873 | {#header_open|Type Coercion: Compile-Time Known Numbers#} | |
| 4874 | 4874 | <p>When a number is {#link|comptime#}-known to be representable in the destination type, |
| 4875 | it may be implicitly casted: | |
| 4875 | it may be coerced: | |
| 4876 | 4876 | </p> |
| 4877 | 4877 | {#code_begin|test#} |
| 4878 | 4878 | const std = @import("std"); |
| 4879 | 4879 | const assert = std.debug.assert; |
| 4880 | 4880 | |
| 4881 | test "implicit casting large integer type to smaller one when value is comptime known to fit" { | |
| 4881 | test "coercing large integer type to smaller one when value is comptime known to fit" { | |
| 4882 | 4882 | const x: u64 = 255; |
| 4883 | 4883 | const y: u8 = x; |
| 4884 | 4884 | assert(y == 255); |
| 4885 | 4885 | } |
| 4886 | 4886 | {#code_end#} |
| 4887 | 4887 | {#header_close#} |
| 4888 | {#header_open|Implicit Cast: unions and enums#} | |
| 4889 | <p>Tagged unions can be implicitly cast to enums, and enums can be implicitly casted to tagged unions | |
| 4888 | {#header_open|Type Coercion: unions and enums#} | |
| 4889 | <p>Tagged unions can be coerced to enums, and enums can be coerced to tagged unions | |
| 4890 | 4890 | when they are {#link|comptime#}-known to be a field of the union that has only one possible value, such as |
| 4891 | 4891 | {#link|void#}: |
| 4892 | 4892 | </p> |
| ... | ... | @@ -4906,7 +4906,7 @@ const U = union(E) { |
| 4906 | 4906 | Three, |
| 4907 | 4907 | }; |
| 4908 | 4908 | |
| 4909 | test "implicit casting between unions and enums" { | |
| 4909 | test "coercion between unions and enums" { | |
| 4910 | 4910 | var u = U{ .Two = 12.34 }; |
| 4911 | 4911 | var e: E = u; |
| 4912 | 4912 | assert(e == E.Two); |
| ... | ... | @@ -4918,20 +4918,20 @@ test "implicit casting between unions and enums" { |
| 4918 | 4918 | {#code_end#} |
| 4919 | 4919 | {#see_also|union|enum#} |
| 4920 | 4920 | {#header_close#} |
| 4921 | {#header_open|Implicit Cast: Zero Bit Types#} | |
| 4922 | <p>{#link|Zero Bit Types#} may be implicitly casted to single-item {#link|Pointers#}, | |
| 4921 | {#header_open|Type Coercion: Zero Bit Types#} | |
| 4922 | <p>{#link|Zero Bit Types#} may be coerced to single-item {#link|Pointers#}, | |
| 4923 | 4923 | regardless of const.</p> |
| 4924 | 4924 | <p>TODO document the reasoning for this</p> |
| 4925 | 4925 | <p>TODO document whether vice versa should work and why</p> |
| 4926 | 4926 | {#code_begin|test#} |
| 4927 | test "implicit casting of zero bit types" { | |
| 4927 | test "coercion of zero bit types" { | |
| 4928 | 4928 | var x: void = {}; |
| 4929 | 4929 | var y: *void = x; |
| 4930 | 4930 | //var z: void = y; // TODO |
| 4931 | 4931 | } |
| 4932 | 4932 | {#code_end#} |
| 4933 | 4933 | {#header_close#} |
| 4934 | {#header_open|Implicit Cast: undefined#} | |
| 4934 | {#header_open|Type Coercion: undefined#} | |
| 4935 | 4935 | <p>{#link|undefined#} can be cast to any type.</p> |
| 4936 | 4936 | {#header_close#} |
| 4937 | 4937 | {#header_close#} |
| ... | ... | @@ -4976,7 +4976,7 @@ test "implicit casting of zero bit types" { |
| 4976 | 4976 | <li>Some {#link|binary operations|Table of Operators#}</li> |
| 4977 | 4977 | </ul> |
| 4978 | 4978 | <p> |
| 4979 | This kind of type resolution chooses a type that all peer types can implicitly cast into. Here are | |
| 4979 | This kind of type resolution chooses a type that all peer types can coerce into. Here are | |
| 4980 | 4980 | some examples: |
| 4981 | 4981 | </p> |
| 4982 | 4982 | {#code_begin|test#} |
| ... | ... | @@ -5007,8 +5007,8 @@ test "peer resolve array and const slice" { |
| 5007 | 5007 | comptime testPeerResolveArrayConstSlice(true); |
| 5008 | 5008 | } |
| 5009 | 5009 | fn testPeerResolveArrayConstSlice(b: bool) void { |
| 5010 | const value1 = if (b) "aoeu" else ([]const u8)("zz"); | |
| 5011 | const value2 = if (b) ([]const u8)("zz") else "aoeu"; | |
| 5010 | const value1 = if (b) "aoeu" else @as([]const u8, "zz"); | |
| 5011 | const value2 = if (b) @as([]const u8, "zz") else "aoeu"; | |
| 5012 | 5012 | assert(mem.eql(u8, value1, "aoeu")); |
| 5013 | 5013 | assert(mem.eql(u8, value2, "zz")); |
| 5014 | 5014 | } |
| ... | ... | @@ -5023,10 +5023,10 @@ test "peer type resolution: ?T and T" { |
| 5023 | 5023 | } |
| 5024 | 5024 | fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize { |
| 5025 | 5025 | if (c) { |
| 5026 | return if (b) null else usize(0); | |
| 5026 | return if (b) null else @as(usize, 0); | |
| 5027 | 5027 | } |
| 5028 | 5028 | |
| 5029 | return usize(3); | |
| 5029 | return @as(usize, 3); | |
| 5030 | 5030 | } |
| 5031 | 5031 | |
| 5032 | 5032 | test "peer type resolution: [0]u8 and []const u8" { |
| ... | ... | @@ -5815,7 +5815,7 @@ test "printf too many arguments" { |
| 5815 | 5815 | </p> |
| 5816 | 5816 | <p> |
| 5817 | 5817 | Zig doesn't care whether the format argument is a string literal, |
| 5818 | only that it is a compile-time known value that is implicitly castable to a {#syntax#}[]const u8{#endsyntax#}: | |
| 5818 | only that it is a compile-time known value that can be coerced to a {#syntax#}[]const u8{#endsyntax#}: | |
| 5819 | 5819 | </p> |
| 5820 | 5820 | {#code_begin|exe|printf#} |
| 5821 | 5821 | const warn = @import("std").debug.warn; |
| ... | ... | @@ -6185,7 +6185,7 @@ fn func() void { |
| 6185 | 6185 | </p> |
| 6186 | 6186 | <p> |
| 6187 | 6187 | {#syntax#}await{#endsyntax#} is a suspend point, and takes as an operand anything that |
| 6188 | implicitly casts to {#syntax#}anyframe->T{#endsyntax#}. | |
| 6188 | coerces to {#syntax#}anyframe->T{#endsyntax#}. | |
| 6189 | 6189 | </p> |
| 6190 | 6190 | <p> |
| 6191 | 6191 | There is a common misconception that {#syntax#}await{#endsyntax#} resumes the target function. |
| ... | ... | @@ -7116,7 +7116,7 @@ test "field access by string" { |
| 7116 | 7116 | <pre>{#syntax#}@frame() *@Frame(func){#endsyntax#}</pre> |
| 7117 | 7117 | <p> |
| 7118 | 7118 | This function returns a pointer to the frame for a given function. This type |
| 7119 | can be {#link|implicitly cast|Implicit Casts#} to {#syntax#}anyframe->T{#endsyntax#} and | |
| 7119 | can be {#link|coerced|Type Coercion#} to {#syntax#}anyframe->T{#endsyntax#} and | |
| 7120 | 7120 | to {#syntax#}anyframe{#endsyntax#}, where {#syntax#}T{#endsyntax#} is the return type |
| 7121 | 7121 | of the function in scope. |
| 7122 | 7122 | </p> |
| ... | ... | @@ -7835,7 +7835,7 @@ test "vector @splat" { |
| 7835 | 7835 | const scalar: u32 = 5; |
| 7836 | 7836 | const result = @splat(4, scalar); |
| 7837 | 7837 | comptime assert(@typeOf(result) == @Vector(4, u32)); |
| 7838 | assert(std.mem.eql(u32, ([4]u32)(result), [_]u32{ 5, 5, 5, 5 })); | |
| 7838 | assert(std.mem.eql(u32, @as([4]u32, result), [_]u32{ 5, 5, 5, 5 })); | |
| 7839 | 7839 | } |
| 7840 | 7840 | {#code_end#} |
| 7841 | 7841 | <p> |
| ... | ... | @@ -8033,7 +8033,7 @@ test "integer truncation" { |
| 8033 | 8033 | </p> |
| 8034 | 8034 | <p> |
| 8035 | 8035 | If {#syntax#}T{#endsyntax#} is {#syntax#}comptime_int{#endsyntax#}, |
| 8036 | then this is semantically equivalent to an {#link|implicit cast|Implicit Casts#}. | |
| 8036 | then this is semantically equivalent to {#link|Type Coercion#}. | |
| 8037 | 8037 | </p> |
| 8038 | 8038 | {#header_close#} |
| 8039 | 8039 | |
| ... | ... | @@ -8537,7 +8537,7 @@ pub fn main() void { |
| 8537 | 8537 | {#header_close#} |
| 8538 | 8538 | {#header_open|Cast Truncates Data#} |
| 8539 | 8539 | <p>At compile-time:</p> |
| 8540 | {#code_begin|test_err|integer value 300 cannot be implicitly casted to type 'u8'#} | |
| 8540 | {#code_begin|test_err|integer value 300 cannot be coerced to type 'u8'#} | |
| 8541 | 8541 | comptime { |
| 8542 | 8542 | const spartan_count: u16 = 300; |
| 8543 | 8543 | const byte = @intCast(u8, spartan_count); |
| ... | ... | @@ -8673,7 +8673,7 @@ test "wraparound addition and subtraction" { |
| 8673 | 8673 | <p>At compile-time:</p> |
| 8674 | 8674 | {#code_begin|test_err|operation caused overflow#} |
| 8675 | 8675 | comptime { |
| 8676 | const x = @shlExact(u8(0b01010101), 2); | |
| 8676 | const x = @shlExact(@as(u8, 0b01010101), 2); | |
| 8677 | 8677 | } |
| 8678 | 8678 | {#code_end#} |
| 8679 | 8679 | <p>At runtime:</p> |
| ... | ... | @@ -8691,7 +8691,7 @@ pub fn main() void { |
| 8691 | 8691 | <p>At compile-time:</p> |
| 8692 | 8692 | {#code_begin|test_err|exact shift shifted out 1 bits#} |
| 8693 | 8693 | comptime { |
| 8694 | const x = @shrExact(u8(0b10101010), 2); | |
| 8694 | const x = @shrExact(@as(u8, 0b10101010), 2); | |
| 8695 | 8695 | } |
| 8696 | 8696 | {#code_end#} |
| 8697 | 8697 | <p>At runtime:</p> |
| ... | ... | @@ -9543,8 +9543,8 @@ const c = @cImport({ |
| 9543 | 9543 | <p>{#syntax#}[*c]T{#endsyntax#} - C pointer.</p> |
| 9544 | 9544 | <ul> |
| 9545 | 9545 | <li>Supports all the syntax of the other two pointer types.</li> |
| 9546 | <li>Implicitly casts to other pointer types, as well as {#link|Optional Pointers#}. | |
| 9547 | When a C pointer is implicitly casted to a non-optional pointer, safety-checked | |
| 9546 | <li>Coerces to other pointer types, as well as {#link|Optional Pointers#}. | |
| 9547 | When a C pointer is coerced to a non-optional pointer, safety-checked | |
| 9548 | 9548 | {#link|Undefined Behavior#} occurs if the address is 0. |
| 9549 | 9549 | </li> |
| 9550 | 9550 | <li>Allows address 0. On non-freestanding targets, dereferencing address 0 is safety-checked |
| ... | ... | @@ -9552,7 +9552,7 @@ const c = @cImport({ |
| 9552 | 9552 | null, just like {#syntax#}?usize{#endsyntax#}. Note that creating an optional C pointer |
| 9553 | 9553 | is unnecessary as one can use normal {#link|Optional Pointers#}. |
| 9554 | 9554 | </li> |
| 9555 | <li>Supports {#link|implicit casting|Implicit Casts#} to and from integers.</li> | |
| 9555 | <li>Supports {#link|Type Coercion#} to and from integers.</li> | |
| 9556 | 9556 | <li>Supports comparison with integers.</li> |
| 9557 | 9557 | <li>Does not support Zig-only pointer attributes such as alignment. Use normal {#link|Pointers#} |
| 9558 | 9558 | please!</li> |
lib/std/event/loop.zig+11-11| ... | ... | @@ -266,7 +266,7 @@ pub const Loop = struct { |
| 266 | 266 | }, |
| 267 | 267 | }; |
| 268 | 268 | |
| 269 | const empty_kevs = ([*]os.Kevent)(undefined)[0..0]; | |
| 269 | const empty_kevs = &[0]os.Kevent{}; | |
| 270 | 270 | |
| 271 | 271 | for (self.eventfd_resume_nodes) |*eventfd_node, i| { |
| 272 | 272 | eventfd_node.* = std.atomic.Stack(ResumeNode.EventFd).Node{ |
| ... | ... | @@ -289,7 +289,7 @@ pub const Loop = struct { |
| 289 | 289 | .next = undefined, |
| 290 | 290 | }; |
| 291 | 291 | self.available_eventfd_resume_nodes.push(eventfd_node); |
| 292 | const kevent_array = (*const [1]os.Kevent)(&eventfd_node.data.kevent); | |
| 292 | const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.data.kevent); | |
| 293 | 293 | _ = try os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null); |
| 294 | 294 | eventfd_node.data.kevent.flags = os.EV_CLEAR | os.EV_ENABLE; |
| 295 | 295 | eventfd_node.data.kevent.fflags = os.NOTE_TRIGGER; |
| ... | ... | @@ -305,7 +305,7 @@ pub const Loop = struct { |
| 305 | 305 | .data = 0, |
| 306 | 306 | .udata = @ptrToInt(&self.final_resume_node), |
| 307 | 307 | }; |
| 308 | const final_kev_arr = (*const [1]os.Kevent)(&self.os_data.final_kevent); | |
| 308 | const final_kev_arr = @as(*const [1]os.Kevent, &self.os_data.final_kevent); | |
| 309 | 309 | _ = try os.kevent(self.os_data.kqfd, final_kev_arr, empty_kevs, null); |
| 310 | 310 | self.os_data.final_kevent.flags = os.EV_ENABLE; |
| 311 | 311 | self.os_data.final_kevent.fflags = os.NOTE_TRIGGER; |
| ... | ... | @@ -572,8 +572,8 @@ pub const Loop = struct { |
| 572 | 572 | eventfd_node.base.handle = next_tick_node.data; |
| 573 | 573 | switch (builtin.os) { |
| 574 | 574 | .macosx, .freebsd, .netbsd, .dragonfly => { |
| 575 | const kevent_array = (*const [1]os.Kevent)(&eventfd_node.kevent); | |
| 576 | const empty_kevs = ([*]os.Kevent)(undefined)[0..0]; | |
| 575 | const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.kevent); | |
| 576 | const empty_kevs = &[0]os.Kevent{}; | |
| 577 | 577 | _ = os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch { |
| 578 | 578 | self.next_tick_queue.unget(next_tick_node); |
| 579 | 579 | self.available_eventfd_resume_nodes.push(resume_stack_node); |
| ... | ... | @@ -695,8 +695,8 @@ pub const Loop = struct { |
| 695 | 695 | }, |
| 696 | 696 | .macosx, .freebsd, .netbsd, .dragonfly => { |
| 697 | 697 | self.posixFsRequest(&self.os_data.fs_end_request); |
| 698 | const final_kevent = (*const [1]os.Kevent)(&self.os_data.final_kevent); | |
| 699 | const empty_kevs = ([*]os.Kevent)(undefined)[0..0]; | |
| 698 | const final_kevent = @as(*const [1]os.Kevent, &self.os_data.final_kevent); | |
| 699 | const empty_kevs = &[0]os.Kevent{}; | |
| 700 | 700 | // cannot fail because we already added it and this just enables it |
| 701 | 701 | _ = os.kevent(self.os_data.kqfd, final_kevent, empty_kevs, null) catch unreachable; |
| 702 | 702 | return; |
| ... | ... | @@ -753,7 +753,7 @@ pub const Loop = struct { |
| 753 | 753 | }, |
| 754 | 754 | .macosx, .freebsd, .netbsd, .dragonfly => { |
| 755 | 755 | var eventlist: [1]os.Kevent = undefined; |
| 756 | const empty_kevs = ([*]os.Kevent)(undefined)[0..0]; | |
| 756 | const empty_kevs = &[0]os.Kevent{}; | |
| 757 | 757 | const count = os.kevent(self.os_data.kqfd, empty_kevs, eventlist[0..], null) catch unreachable; |
| 758 | 758 | for (eventlist[0..count]) |ev| { |
| 759 | 759 | const resume_node = @intToPtr(*ResumeNode, ev.udata); |
| ... | ... | @@ -815,8 +815,8 @@ pub const Loop = struct { |
| 815 | 815 | self.os_data.fs_queue.put(request_node); |
| 816 | 816 | switch (builtin.os) { |
| 817 | 817 | .macosx, .freebsd, .netbsd, .dragonfly => { |
| 818 | const fs_kevs = (*const [1]os.Kevent)(&self.os_data.fs_kevent_wake); | |
| 819 | const empty_kevs = ([*]os.Kevent)(undefined)[0..0]; | |
| 818 | const fs_kevs = @as(*const [1]os.Kevent, &self.os_data.fs_kevent_wake); | |
| 819 | const empty_kevs = &[0]os.Kevent{}; | |
| 820 | 820 | _ = os.kevent(self.os_data.fs_kqfd, fs_kevs, empty_kevs, null) catch unreachable; |
| 821 | 821 | }, |
| 822 | 822 | .linux => { |
| ... | ... | @@ -890,7 +890,7 @@ pub const Loop = struct { |
| 890 | 890 | } |
| 891 | 891 | }, |
| 892 | 892 | .macosx, .freebsd, .netbsd, .dragonfly => { |
| 893 | const fs_kevs = (*const [1]os.Kevent)(&self.os_data.fs_kevent_wait); | |
| 893 | const fs_kevs = @as(*const [1]os.Kevent, &self.os_data.fs_kevent_wait); | |
| 894 | 894 | var out_kevs: [1]os.Kevent = undefined; |
| 895 | 895 | _ = os.kevent(self.os_data.fs_kqfd, fs_kevs, out_kevs[0..], null) catch unreachable; |
| 896 | 896 | }, |
lib/std/fs.zig+1-1| ... | ... | @@ -584,7 +584,7 @@ pub const Dir = struct { |
| 584 | 584 | .FileBothDirectoryInformation, |
| 585 | 585 | w.FALSE, |
| 586 | 586 | null, |
| 587 | if (self.first) w.BOOLEAN(w.TRUE) else w.BOOLEAN(w.FALSE), | |
| 587 | if (self.first) @as(w.BOOLEAN, w.TRUE) else @as(w.BOOLEAN, w.FALSE), | |
| 588 | 588 | ); |
| 589 | 589 | self.first = false; |
| 590 | 590 | if (io.Information == 0) return null; |
lib/std/os.zig+2-2| ... | ... | @@ -1126,9 +1126,9 @@ pub fn unlinkatW(dirfd: fd_t, sub_path_w: [*]const u16, flags: u32) UnlinkatErro |
| 1126 | 1126 | |
| 1127 | 1127 | const want_rmdir_behavior = (flags & AT_REMOVEDIR) != 0; |
| 1128 | 1128 | const create_options_flags = if (want_rmdir_behavior) |
| 1129 | w.ULONG(w.FILE_DELETE_ON_CLOSE) | |
| 1129 | @as(w.ULONG, w.FILE_DELETE_ON_CLOSE) | |
| 1130 | 1130 | else |
| 1131 | w.ULONG(w.FILE_DELETE_ON_CLOSE | w.FILE_NON_DIRECTORY_FILE); | |
| 1131 | @as(w.ULONG, w.FILE_DELETE_ON_CLOSE | w.FILE_NON_DIRECTORY_FILE); | |
| 1132 | 1132 | |
| 1133 | 1133 | const path_len_bytes = @intCast(u16, mem.toSliceConst(u16, sub_path_w).len * 2); |
| 1134 | 1134 | var nt_name = w.UNICODE_STRING{ |
lib/std/os/windows.zig+1-1| ... | ... | @@ -262,7 +262,7 @@ pub const ReadFileError = error{Unexpected}; |
| 262 | 262 | pub fn ReadFile(in_hFile: HANDLE, buffer: []u8) ReadFileError!usize { |
| 263 | 263 | var index: usize = 0; |
| 264 | 264 | while (index < buffer.len) { |
| 265 | const want_read_count = @intCast(DWORD, math.min(DWORD(maxInt(DWORD)), buffer.len - index)); | |
| 265 | const want_read_count = @intCast(DWORD, math.min(@as(DWORD, maxInt(DWORD)), buffer.len - index)); | |
| 266 | 266 | var amt_read: DWORD = undefined; |
| 267 | 267 | if (kernel32.ReadFile(in_hFile, buffer.ptr + index, want_read_count, &amt_read, null) == 0) { |
| 268 | 268 | switch (kernel32.GetLastError()) { |
lib/std/os/windows/bits.zig+12-12| ... | ... | @@ -69,7 +69,7 @@ pub const FALSE = 0; |
| 69 | 69 | |
| 70 | 70 | pub const INVALID_HANDLE_VALUE = @intToPtr(HANDLE, maxInt(usize)); |
| 71 | 71 | |
| 72 | pub const INVALID_FILE_ATTRIBUTES = DWORD(maxInt(DWORD)); | |
| 72 | pub const INVALID_FILE_ATTRIBUTES = @as(DWORD, maxInt(DWORD)); | |
| 73 | 73 | |
| 74 | 74 | pub const FILE_ALL_INFORMATION = extern struct { |
| 75 | 75 | BasicInformation: FILE_BASIC_INFORMATION, |
| ... | ... | @@ -571,16 +571,16 @@ pub const KF_FLAG_SIMPLE_IDLIST = 256; |
| 571 | 571 | pub const KF_FLAG_ALIAS_ONLY = -2147483648; |
| 572 | 572 | |
| 573 | 573 | pub const S_OK = 0; |
| 574 | pub const E_NOTIMPL = @bitCast(c_long, c_ulong(0x80004001)); | |
| 575 | pub const E_NOINTERFACE = @bitCast(c_long, c_ulong(0x80004002)); | |
| 576 | pub const E_POINTER = @bitCast(c_long, c_ulong(0x80004003)); | |
| 577 | pub const E_ABORT = @bitCast(c_long, c_ulong(0x80004004)); | |
| 578 | pub const E_FAIL = @bitCast(c_long, c_ulong(0x80004005)); | |
| 579 | pub const E_UNEXPECTED = @bitCast(c_long, c_ulong(0x8000FFFF)); | |
| 580 | pub const E_ACCESSDENIED = @bitCast(c_long, c_ulong(0x80070005)); | |
| 581 | pub const E_HANDLE = @bitCast(c_long, c_ulong(0x80070006)); | |
| 582 | pub const E_OUTOFMEMORY = @bitCast(c_long, c_ulong(0x8007000E)); | |
| 583 | pub const E_INVALIDARG = @bitCast(c_long, c_ulong(0x80070057)); | |
| 574 | pub const E_NOTIMPL = @bitCast(c_long, @as(c_ulong, 0x80004001)); | |
| 575 | pub const E_NOINTERFACE = @bitCast(c_long, @as(c_ulong, 0x80004002)); | |
| 576 | pub const E_POINTER = @bitCast(c_long, @as(c_ulong, 0x80004003)); | |
| 577 | pub const E_ABORT = @bitCast(c_long, @as(c_ulong, 0x80004004)); | |
| 578 | pub const E_FAIL = @bitCast(c_long, @as(c_ulong, 0x80004005)); | |
| 579 | pub const E_UNEXPECTED = @bitCast(c_long, @as(c_ulong, 0x8000FFFF)); | |
| 580 | pub const E_ACCESSDENIED = @bitCast(c_long, @as(c_ulong, 0x80070005)); | |
| 581 | pub const E_HANDLE = @bitCast(c_long, @as(c_ulong, 0x80070006)); | |
| 582 | pub const E_OUTOFMEMORY = @bitCast(c_long, @as(c_ulong, 0x8007000E)); | |
| 583 | pub const E_INVALIDARG = @bitCast(c_long, @as(c_ulong, 0x80070057)); | |
| 584 | 584 | |
| 585 | 585 | pub const FILE_FLAG_BACKUP_SEMANTICS = 0x02000000; |
| 586 | 586 | pub const FILE_FLAG_DELETE_ON_CLOSE = 0x04000000; |
| ... | ... | @@ -873,4 +873,4 @@ pub const CURDIR = extern struct { |
| 873 | 873 | Handle: HANDLE, |
| 874 | 874 | }; |
| 875 | 875 | |
| 876 | pub const DUPLICATE_SAME_ACCESS = 2; | |
| \ No newline at end of file | ||
| 876 | pub const DUPLICATE_SAME_ACCESS = 2; |
src-self-hosted/translate_c.zig+10-6| ... | ... | @@ -774,12 +774,14 @@ fn transCCast( |
| 774 | 774 | if (qualTypeIsPtr(dst_type) and qualTypeIsPtr(src_type)) |
| 775 | 775 | return transCPtrCast(rp, loc, dst_type, src_type, expr); |
| 776 | 776 | if (cIsUnsignedInteger(dst_type) and qualTypeIsPtr(src_type)) { |
| 777 | const cast_node = try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc)); | |
| 777 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as"); | |
| 778 | try cast_node.params.push(try transQualType(rp, dst_type, loc)); | |
| 779 | _ = try appendToken(rp.c, .Comma, ","); | |
| 778 | 780 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt"); |
| 779 | 781 | try builtin_node.params.push(expr); |
| 780 | 782 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 781 | try cast_node.op.Call.params.push(&builtin_node.base); | |
| 782 | cast_node.rtoken = try appendToken(rp.c, .RParen, ")"); | |
| 783 | try cast_node.params.push(&builtin_node.base); | |
| 784 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | |
| 783 | 785 | return &cast_node.base; |
| 784 | 786 | } |
| 785 | 787 | if (cIsUnsignedInteger(src_type) and qualTypeIsPtr(dst_type)) { |
| ... | ... | @@ -793,9 +795,11 @@ fn transCCast( |
| 793 | 795 | // TODO: maybe widen to increase size |
| 794 | 796 | // TODO: maybe bitcast to change sign |
| 795 | 797 | // TODO: maybe truncate to reduce size |
| 796 | const cast_node = try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc)); | |
| 797 | try cast_node.op.Call.params.push(expr); | |
| 798 | cast_node.rtoken = try appendToken(rp.c, .RParen, ")"); | |
| 798 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as"); | |
| 799 | try cast_node.params.push(try transQualType(rp, dst_type, loc)); | |
| 800 | _ = try appendToken(rp.c, .Comma, ","); | |
| 801 | try cast_node.params.push(expr); | |
| 802 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | |
| 799 | 803 | return &cast_node.base; |
| 800 | 804 | } |
| 801 | 805 |
src/ir.cpp+8-7| ... | ... | @@ -6339,7 +6339,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 6339 | 6339 | return irb->codegen->invalid_instruction; |
| 6340 | 6340 | |
| 6341 | 6341 | if (result_loc_cast != nullptr) { |
| 6342 | IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, init_value, result_loc_cast); | |
| 6342 | IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, init_value->source_node, | |
| 6343 | init_value, result_loc_cast); | |
| 6343 | 6344 | ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base); |
| 6344 | 6345 | } |
| 6345 | 6346 | |
| ... | ... | @@ -9610,7 +9611,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc |
| 9610 | 9611 | } |
| 9611 | 9612 | |
| 9612 | 9613 | ir_add_error(ira, instruction, |
| 9613 | buf_sprintf("%s value %s cannot be implicitly casted to type '%s'", | |
| 9614 | buf_sprintf("%s value %s cannot be coerced to type '%s'", | |
| 9614 | 9615 | num_lit_str, |
| 9615 | 9616 | buf_ptr(val_buf), |
| 9616 | 9617 | buf_ptr(&other_type->name))); |
| ... | ... | @@ -13065,8 +13066,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 13065 | 13066 | return ira->codegen->invalid_instruction; |
| 13066 | 13067 | } |
| 13067 | 13068 | |
| 13068 | static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type, | |
| 13069 | ResultLoc *result_loc) | |
| 13069 | static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction *source_instr, | |
| 13070 | IrInstruction *value, ZigType *expected_type, ResultLoc *result_loc) | |
| 13070 | 13071 | { |
| 13071 | 13072 | assert(value); |
| 13072 | 13073 | assert(value != ira->codegen->invalid_instruction); |
| ... | ... | @@ -13080,11 +13081,11 @@ static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction |
| 13080 | 13081 | if (value->value.type->id == ZigTypeIdUnreachable) |
| 13081 | 13082 | return value; |
| 13082 | 13083 | |
| 13083 | return ir_analyze_cast(ira, value, expected_type, value, result_loc); | |
| 13084 | return ir_analyze_cast(ira, source_instr, expected_type, value, result_loc); | |
| 13084 | 13085 | } |
| 13085 | 13086 | |
| 13086 | 13087 | static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) { |
| 13087 | return ir_implicit_cast_with_result(ira, value, expected_type, nullptr); | |
| 13088 | return ir_implicit_cast_with_result(ira, value, value, expected_type, nullptr); | |
| 13088 | 13089 | } |
| 13089 | 13090 | |
| 13090 | 13091 | 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 |
| 26068 | 26069 | ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child); |
| 26069 | 26070 | if (type_is_invalid(dest_type)) |
| 26070 | 26071 | return ira->codegen->invalid_instruction; |
| 26071 | return ir_implicit_cast(ira, operand, dest_type); | |
| 26072 | return ir_implicit_cast_with_result(ira, &instruction->base, operand, dest_type, nullptr); | |
| 26072 | 26073 | } |
| 26073 | 26074 | |
| 26074 | 26075 | static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) { |
src/translate_c.cpp+15-14| ... | ... | @@ -221,6 +221,15 @@ static AstNode *trans_create_node_opaque(Context *c) { |
| 221 | 221 | return trans_create_node_builtin_fn_call_str(c, "OpaqueType"); |
| 222 | 222 | } |
| 223 | 223 | |
| 224 | static AstNode *trans_create_node_cast(Context *c, AstNode *dest_type, AstNode *operand) { | |
| 225 | AstNode *node = trans_create_node(c, NodeTypeFnCallExpr); | |
| 226 | node->data.fn_call_expr.fn_ref_expr = trans_create_node_symbol(c, buf_create_from_str("as")); | |
| 227 | node->data.fn_call_expr.modifier = CallModifierBuiltin; | |
| 228 | node->data.fn_call_expr.params.append(dest_type); | |
| 229 | node->data.fn_call_expr.params.append(operand); | |
| 230 | return node; | |
| 231 | } | |
| 232 | ||
| 224 | 233 | static AstNode *trans_create_node_fn_call_1(Context *c, AstNode *fn_ref_expr, AstNode *arg1) { |
| 225 | 234 | AstNode *node = trans_create_node(c, NodeTypeFnCallExpr); |
| 226 | 235 | 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) { |
| 337 | 346 | return trans_create_node_unsigned_negative(c, x, false); |
| 338 | 347 | } |
| 339 | 348 | |
| 340 | static AstNode *trans_create_node_cast(Context *c, AstNode *dest, AstNode *src) { | |
| 341 | AstNode *node = trans_create_node(c, NodeTypeFnCallExpr); | |
| 342 | node->data.fn_call_expr.fn_ref_expr = dest; | |
| 343 | node->data.fn_call_expr.params.resize(1); | |
| 344 | node->data.fn_call_expr.params.items[0] = src; | |
| 345 | return node; | |
| 346 | } | |
| 347 | ||
| 348 | 349 | static AstNode *trans_create_node_unsigned_negative_type(Context *c, uint64_t x, bool is_negative, |
| 349 | 350 | const char *type_name) |
| 350 | 351 | { |
| ... | ... | @@ -701,7 +702,7 @@ static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location, |
| 701 | 702 | if (c_is_unsigned_integer(c, dest_type) && qual_type_is_ptr(src_type)) { |
| 702 | 703 | AstNode *addr_node = trans_create_node_builtin_fn_call_str(c, "ptrToInt"); |
| 703 | 704 | addr_node->data.fn_call_expr.params.append(expr); |
| 704 | return trans_create_node_fn_call_1(c, trans_qual_type(c, dest_type, source_location), addr_node); | |
| 705 | return trans_create_node_cast(c, trans_qual_type(c, dest_type, source_location), addr_node); | |
| 705 | 706 | } |
| 706 | 707 | if (c_is_unsigned_integer(c, src_type) && qual_type_is_ptr(dest_type)) { |
| 707 | 708 | 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, |
| 712 | 713 | // TODO: maybe widen to increase size |
| 713 | 714 | // TODO: maybe bitcast to change sign |
| 714 | 715 | // TODO: maybe truncate to reduce size |
| 715 | return trans_create_node_fn_call_1(c, trans_qual_type(c, dest_type, source_location), expr); | |
| 716 | return trans_create_node_cast(c, trans_qual_type(c, dest_type, source_location), expr); | |
| 716 | 717 | } |
| 717 | 718 | |
| 718 | 719 | 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 |
| 1527 | 1528 | |
| 1528 | 1529 | AstNode *rhs = trans_expr(c, ResultUsedYes, scope, rhs_expr, TransRValue); |
| 1529 | 1530 | if (rhs == nullptr) return nullptr; |
| 1530 | AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs); | |
| 1531 | AstNode *coerced_rhs = trans_create_node_cast(c, rhs_type, rhs); | |
| 1531 | 1532 | |
| 1532 | 1533 | return trans_create_node_bin_op(c, lhs, bin_op, coerced_rhs); |
| 1533 | 1534 | } |
| ... | ... | @@ -1702,7 +1703,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result |
| 1702 | 1703 | |
| 1703 | 1704 | AstNode *rhs = trans_expr(c, ResultUsedYes, scope, ZigClangCompoundAssignOperator_getRHS(stmt), TransRValue); |
| 1704 | 1705 | if (rhs == nullptr) return nullptr; |
| 1705 | AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs); | |
| 1706 | AstNode *coerced_rhs = trans_create_node_cast(c, rhs_type, rhs); | |
| 1706 | 1707 | |
| 1707 | 1708 | return trans_create_node_bin_op(c, lhs, assign_op, coerced_rhs); |
| 1708 | 1709 | } else { |
| ... | ... | @@ -1733,7 +1734,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result |
| 1733 | 1734 | |
| 1734 | 1735 | AstNode *rhs = trans_expr(c, ResultUsedYes, &child_scope->base, ZigClangCompoundAssignOperator_getRHS(stmt), TransRValue); |
| 1735 | 1736 | if (rhs == nullptr) return nullptr; |
| 1736 | AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs); | |
| 1737 | AstNode *coerced_rhs = trans_create_node_cast(c, rhs_type, rhs); | |
| 1737 | 1738 | |
| 1738 | 1739 | // operation_type(*_ref) |
| 1739 | 1740 | 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) |
| 2684 | 2685 | |
| 2685 | 2686 | // @TagType(Enum)(0) |
| 2686 | 2687 | AstNode *zero = trans_create_node_unsigned_negative(c, 0, false); |
| 2687 | AstNode *casted_zero = trans_create_node_fn_call_1(c, tag_type, zero); | |
| 2688 | AstNode *casted_zero = trans_create_node_cast(c, tag_type, zero); | |
| 2688 | 2689 | |
| 2689 | 2690 | // @bitCast(Enum, @TagType(Enum)(0)) |
| 2690 | 2691 | AstNode *bitcast = trans_create_node_builtin_fn_call_str(c, "bitCast"); |
test/compare_output.zig+9-9| ... | ... | @@ -145,23 +145,23 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 145 | 145 | \\ _ = c._setmode(1, c._O_BINARY); |
| 146 | 146 | \\ } |
| 147 | 147 | \\ _ = c.printf(c"0: %llu\n", |
| 148 | \\ u64(0)); | |
| 148 | \\ @as(u64, 0)); | |
| 149 | 149 | \\ _ = c.printf(c"320402575052271: %llu\n", |
| 150 | \\ u64(320402575052271)); | |
| 150 | \\ @as(u64, 320402575052271)); | |
| 151 | 151 | \\ _ = c.printf(c"0x01236789abcdef: %llu\n", |
| 152 | \\ u64(0x01236789abcdef)); | |
| 152 | \\ @as(u64, 0x01236789abcdef)); | |
| 153 | 153 | \\ _ = c.printf(c"0xffffffffffffffff: %llu\n", |
| 154 | \\ u64(0xffffffffffffffff)); | |
| 154 | \\ @as(u64, 0xffffffffffffffff)); | |
| 155 | 155 | \\ _ = c.printf(c"0x000000ffffffffffffffff: %llu\n", |
| 156 | \\ u64(0x000000ffffffffffffffff)); | |
| 156 | \\ @as(u64, 0x000000ffffffffffffffff)); | |
| 157 | 157 | \\ _ = c.printf(c"0o1777777777777777777777: %llu\n", |
| 158 | \\ u64(0o1777777777777777777777)); | |
| 158 | \\ @as(u64, 0o1777777777777777777777)); | |
| 159 | 159 | \\ _ = c.printf(c"0o0000001777777777777777777777: %llu\n", |
| 160 | \\ u64(0o0000001777777777777777777777)); | |
| 160 | \\ @as(u64, 0o0000001777777777777777777777)); | |
| 161 | 161 | \\ _ = c.printf(c"0b1111111111111111111111111111111111111111111111111111111111111111: %llu\n", |
| 162 | \\ u64(0b1111111111111111111111111111111111111111111111111111111111111111)); | |
| 162 | \\ @as(u64, 0b1111111111111111111111111111111111111111111111111111111111111111)); | |
| 163 | 163 | \\ _ = c.printf(c"0b0000001111111111111111111111111111111111111111111111111111111111111111: %llu\n", |
| 164 | \\ u64(0b0000001111111111111111111111111111111111111111111111111111111111111111)); | |
| 164 | \\ @as(u64, 0b0000001111111111111111111111111111111111111111111111111111111111111111)); | |
| 165 | 165 | \\ |
| 166 | 166 | \\ _ = c.printf(c"\n"); |
| 167 | 167 | \\ |
test/compile_errors.zig+35-37| ... | ... | @@ -189,7 +189,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 189 | 189 | \\ const x = 1 << &@as(u8, 10); |
| 190 | 190 | \\} |
| 191 | 191 | , |
| 192 | "tmp.zig:2:23: error: shift amount has to be an integer type, but found '*u8'", | |
| 192 | "tmp.zig:2:21: error: shift amount has to be an integer type, but found '*u8'", | |
| 193 | 193 | "tmp.zig:2:17: note: referenced here", |
| 194 | 194 | ); |
| 195 | 195 | |
| ... | ... | @@ -199,8 +199,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 199 | 199 | \\ const x = &@as(u8, 1) << 10; |
| 200 | 200 | \\} |
| 201 | 201 | , |
| 202 | "tmp.zig:2:18: error: bit shifting operation expected integer type, found '*u8'", | |
| 203 | "tmp.zig:2:22: note: referenced here", | |
| 202 | "tmp.zig:2:16: error: bit shifting operation expected integer type, found '*u8'", | |
| 203 | "tmp.zig:2:27: note: referenced here", | |
| 204 | 204 | ); |
| 205 | 205 | |
| 206 | 206 | cases.add( |
| ... | ... | @@ -245,7 +245,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 245 | 245 | \\} |
| 246 | 246 | , |
| 247 | 247 | "tmp.zig:2:20: error: expected type 'u29', found 'bool'", |
| 248 | "tmp.zig:5:22: error: fractional component prevents float value 12.340000 from being casted to type 'u29'", | |
| 248 | "tmp.zig:5:19: error: fractional component prevents float value 12.340000 from being casted to type 'u29'", | |
| 249 | 249 | ); |
| 250 | 250 | |
| 251 | 251 | cases.addCase(x: { |
| ... | ... | @@ -1243,7 +1243,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1243 | 1243 | \\ var ptr: [*c]u8 = x; |
| 1244 | 1244 | \\} |
| 1245 | 1245 | , |
| 1246 | "tmp.zig:2:33: error: integer value 18446744073709551617 cannot be implicitly casted to type 'usize'", | |
| 1246 | "tmp.zig:2:33: error: integer value 18446744073709551617 cannot be coerced to type 'usize'", | |
| 1247 | 1247 | "tmp.zig:6:23: error: integer type 'u65' too big for implicit @intToPtr to type '[*c]u8'", |
| 1248 | 1248 | ); |
| 1249 | 1249 | |
| ... | ... | @@ -1300,14 +1300,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1300 | 1300 | \\ var z = @truncate(u8, @as(u16, undefined)); |
| 1301 | 1301 | \\} |
| 1302 | 1302 | , |
| 1303 | "tmp.zig:2:30: error: use of undefined value here causes undefined behavior", | |
| 1303 | "tmp.zig:2:27: error: use of undefined value here causes undefined behavior", | |
| 1304 | 1304 | ); |
| 1305 | 1305 | |
| 1306 | 1306 | cases.addTest( |
| 1307 | 1307 | "return invalid type from test", |
| 1308 | 1308 | \\test "example" { return 1; } |
| 1309 | 1309 | , |
| 1310 | "tmp.zig:1:25: error: integer value 1 cannot be implicitly casted to type 'void'", | |
| 1310 | "tmp.zig:1:25: error: integer value 1 cannot be coerced to type 'void'", | |
| 1311 | 1311 | ); |
| 1312 | 1312 | |
| 1313 | 1313 | cases.add( |
| ... | ... | @@ -1464,8 +1464,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1464 | 1464 | \\ var byte: u8 = spartan_count; |
| 1465 | 1465 | \\} |
| 1466 | 1466 | , |
| 1467 | "tmp.zig:3:31: error: integer value 300 cannot be implicitly casted to type 'u8'", | |
| 1468 | "tmp.zig:7:22: error: integer value 300 cannot be implicitly casted to type 'u8'", | |
| 1467 | "tmp.zig:3:31: error: integer value 300 cannot be coerced to type 'u8'", | |
| 1468 | "tmp.zig:7:22: error: integer value 300 cannot be coerced to type 'u8'", | |
| 1469 | 1469 | "tmp.zig:11:20: error: expected type 'u8', found 'u16'", |
| 1470 | 1470 | ); |
| 1471 | 1471 | |
| ... | ... | @@ -1498,7 +1498,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1498 | 1498 | \\ var x: i65536 = 1; |
| 1499 | 1499 | \\} |
| 1500 | 1500 | , |
| 1501 | "tmp.zig:2:31: error: integer value 65536 cannot be implicitly casted to type 'u16'", | |
| 1501 | "tmp.zig:2:31: error: integer value 65536 cannot be coerced to type 'u16'", | |
| 1502 | 1502 | "tmp.zig:5:12: error: primitive integer type 'i65536' exceeds maximum bit width of 65535", |
| 1503 | 1503 | ); |
| 1504 | 1504 | |
| ... | ... | @@ -1689,7 +1689,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1689 | 1689 | \\ const x = @floatToInt(i32, @as(i32, 54)); |
| 1690 | 1690 | \\} |
| 1691 | 1691 | , |
| 1692 | "tmp.zig:2:35: error: expected float type, found 'i32'", | |
| 1692 | "tmp.zig:2:32: error: expected float type, found 'i32'", | |
| 1693 | 1693 | ); |
| 1694 | 1694 | |
| 1695 | 1695 | cases.add( |
| ... | ... | @@ -1698,7 +1698,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1698 | 1698 | \\ const x = @floatToInt(i8, 200); |
| 1699 | 1699 | \\} |
| 1700 | 1700 | , |
| 1701 | "tmp.zig:2:31: error: integer value 200 cannot be implicitly casted to type 'i8'", | |
| 1701 | "tmp.zig:2:31: error: integer value 200 cannot be coerced to type 'i8'", | |
| 1702 | 1702 | ); |
| 1703 | 1703 | |
| 1704 | 1704 | cases.add( |
| ... | ... | @@ -2207,7 +2207,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2207 | 2207 | \\ var rule_set = try Foo.init(); |
| 2208 | 2208 | \\} |
| 2209 | 2209 | , |
| 2210 | "tmp.zig:2:13: error: expected type 'i32', found 'type'", | |
| 2210 | "tmp.zig:2:10: error: expected type 'i32', found 'type'", | |
| 2211 | 2211 | ); |
| 2212 | 2212 | |
| 2213 | 2213 | cases.add( |
| ... | ... | @@ -2357,10 +2357,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2357 | 2357 | cases.add( |
| 2358 | 2358 | "comptime slice of undefined pointer non-zero len", |
| 2359 | 2359 | \\export fn entry() void { |
| 2360 | \\ const slice = ([*]i32)(undefined)[0..1]; | |
| 2360 | \\ const slice = @as([*]i32, undefined)[0..1]; | |
| 2361 | 2361 | \\} |
| 2362 | 2362 | , |
| 2363 | "tmp.zig:2:38: error: non-zero length slice of undefined pointer", | |
| 2363 | "tmp.zig:2:41: error: non-zero length slice of undefined pointer", | |
| 2364 | 2364 | ); |
| 2365 | 2365 | |
| 2366 | 2366 | cases.add( |
| ... | ... | @@ -2660,7 +2660,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 2660 | 2660 | \\ const x = @as(usize, -10); |
| 2661 | 2661 | \\} |
| 2662 | 2662 | , |
| 2663 | "tmp.zig:2:21: error: cannot cast negative value -10 to unsigned integer type 'usize'", | |
| 2663 | "tmp.zig:2:26: error: cannot cast negative value -10 to unsigned integer type 'usize'", | |
| 2664 | 2664 | ); |
| 2665 | 2665 | |
| 2666 | 2666 | cases.add( |
| ... | ... | @@ -3388,7 +3388,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 3388 | 3388 | \\} |
| 3389 | 3389 | \\export fn entry() void { f(true); g(true); } |
| 3390 | 3390 | , |
| 3391 | "tmp.zig:2:42: error: integer value 1 cannot be implicitly casted to type 'void'", | |
| 3391 | "tmp.zig:2:21: error: expected type 'i32', found 'void'", | |
| 3392 | 3392 | "tmp.zig:5:15: error: incompatible types: 'i32' and 'void'", |
| 3393 | 3393 | ); |
| 3394 | 3394 | |
| ... | ... | @@ -3524,7 +3524,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 3524 | 3524 | \\} |
| 3525 | 3525 | \\export fn entry() void { _ = f(); } |
| 3526 | 3526 | , |
| 3527 | "tmp.zig:2:15: error: unreachable code", | |
| 3527 | "tmp.zig:2:12: error: unreachable code", | |
| 3528 | 3528 | ); |
| 3529 | 3529 | |
| 3530 | 3530 | cases.add( |
| ... | ... | @@ -3765,7 +3765,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 3765 | 3765 | \\const x : u8 = 300; |
| 3766 | 3766 | \\export fn entry() usize { return @sizeOf(@typeOf(x)); } |
| 3767 | 3767 | , |
| 3768 | "tmp.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'", | |
| 3768 | "tmp.zig:1:16: error: integer value 300 cannot be coerced to type 'u8'", | |
| 3769 | 3769 | ); |
| 3770 | 3770 | |
| 3771 | 3771 | cases.add( |
| ... | ... | @@ -3897,8 +3897,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 3897 | 3897 | , |
| 3898 | 3898 | "tmp.zig:1:21: error: division by zero", |
| 3899 | 3899 | "tmp.zig:2:25: error: division by zero", |
| 3900 | "tmp.zig:3:22: error: division by zero", | |
| 3901 | "tmp.zig:4:26: error: division by zero", | |
| 3900 | "tmp.zig:3:27: error: division by zero", | |
| 3901 | "tmp.zig:4:31: error: division by zero", | |
| 3902 | 3902 | ); |
| 3903 | 3903 | |
| 3904 | 3904 | cases.add( |
| ... | ... | @@ -4908,7 +4908,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 4908 | 4908 | \\ var vga_mem: u16 = 0xB8000; |
| 4909 | 4909 | \\} |
| 4910 | 4910 | , |
| 4911 | "tmp.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'", | |
| 4911 | "tmp.zig:2:24: error: integer value 753664 cannot be coerced to type 'u16'", | |
| 4912 | 4912 | ); |
| 4913 | 4913 | |
| 4914 | 4914 | cases.add( |
| ... | ... | @@ -5080,7 +5080,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5080 | 5080 | cases.add( |
| 5081 | 5081 | "pass const ptr to mutable ptr fn", |
| 5082 | 5082 | \\fn foo() bool { |
| 5083 | \\ const a = ([]const u8)("a",); | |
| 5083 | \\ const a = @as([]const u8, "a",); | |
| 5084 | 5084 | \\ const b = &a; |
| 5085 | 5085 | \\ return ptrEql(b, b); |
| 5086 | 5086 | \\} |
| ... | ... | @@ -5584,7 +5584,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5584 | 5584 | \\ return @as(i32, 12.34); |
| 5585 | 5585 | \\} |
| 5586 | 5586 | , |
| 5587 | "tmp.zig:2:16: error: fractional component prevents float value 12.340000 from being casted to type 'i32'", | |
| 5587 | "tmp.zig:2:21: error: fractional component prevents float value 12.340000 from being casted to type 'i32'", | |
| 5588 | 5588 | ); |
| 5589 | 5589 | |
| 5590 | 5590 | cases.add( |
| ... | ... | @@ -5671,16 +5671,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5671 | 5671 | \\export fn entry() void { |
| 5672 | 5672 | \\ var foo = Foo { .a = 1, .b = 10 }; |
| 5673 | 5673 | \\ foo.b += 1; |
| 5674 | \\ bar((*[1]u32)(&foo.b)[0..]); | |
| 5674 | \\ bar(@as(*[1]u32, &foo.b)[0..]); | |
| 5675 | 5675 | \\} |
| 5676 | 5676 | \\ |
| 5677 | 5677 | \\fn bar(x: []u32) void { |
| 5678 | 5678 | \\ x[0] += 1; |
| 5679 | 5679 | \\} |
| 5680 | 5680 | , |
| 5681 | "tmp.zig:9:18: error: cast increases pointer alignment", | |
| 5682 | "tmp.zig:9:23: note: '*align(1) u32' has alignment 1", | |
| 5683 | "tmp.zig:9:18: note: '*[1]u32' has alignment 4", | |
| 5681 | "tmp.zig:9:9: error: cast increases pointer alignment", | |
| 5682 | "tmp.zig:9:26: note: '*align(1) u32' has alignment 1", | |
| 5683 | "tmp.zig:9:9: note: '*[1]u32' has alignment 4", | |
| 5684 | 5684 | ); |
| 5685 | 5685 | |
| 5686 | 5686 | cases.add( |
| ... | ... | @@ -5702,7 +5702,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5702 | 5702 | \\ @alignCast(4, @as(u32, 3)); |
| 5703 | 5703 | \\} |
| 5704 | 5704 | , |
| 5705 | "tmp.zig:2:22: error: expected pointer or slice, found 'u32'", | |
| 5705 | "tmp.zig:2:19: error: expected pointer or slice, found 'u32'", | |
| 5706 | 5706 | ); |
| 5707 | 5707 | |
| 5708 | 5708 | cases.add( |
| ... | ... | @@ -5740,7 +5740,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5740 | 5740 | ); |
| 5741 | 5741 | |
| 5742 | 5742 | cases.add( |
| 5743 | "wrong pointer implicitly casted to pointer to @OpaqueType()", | |
| 5743 | "wrong pointer coerced to pointer to @OpaqueType()", | |
| 5744 | 5744 | \\const Derp = @OpaqueType(); |
| 5745 | 5745 | \\extern fn bar(d: *Derp) void; |
| 5746 | 5746 | \\export fn foo() void { |
| ... | ... | @@ -5793,7 +5793,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5793 | 5793 | "tmp.zig:17:4: error: variable of type 'Opaque' not allowed", |
| 5794 | 5794 | "tmp.zig:20:4: error: variable of type 'type' must be const or comptime", |
| 5795 | 5795 | "tmp.zig:23:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime", |
| 5796 | "tmp.zig:26:4: error: unreachable code", | |
| 5796 | "tmp.zig:26:22: error: unreachable code", | |
| 5797 | 5797 | ); |
| 5798 | 5798 | |
| 5799 | 5799 | cases.add( |
| ... | ... | @@ -5803,7 +5803,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5803 | 5803 | \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, @as(u32, 1234), @as(u32, 1234))) {} |
| 5804 | 5804 | \\} |
| 5805 | 5805 | , |
| 5806 | "tmp.zig:3:50: error: expected type 'std.builtin.AtomicOrder', found 'u32'", | |
| 5806 | "tmp.zig:3:47: error: expected type 'std.builtin.AtomicOrder', found 'u32'", | |
| 5807 | 5807 | ); |
| 5808 | 5808 | |
| 5809 | 5809 | cases.add( |
| ... | ... | @@ -5813,7 +5813,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5813 | 5813 | \\ @export("entry", entry, @as(u32, 1234)); |
| 5814 | 5814 | \\} |
| 5815 | 5815 | , |
| 5816 | "tmp.zig:3:32: error: expected type 'std.builtin.GlobalLinkage', found 'u32'", | |
| 5816 | "tmp.zig:3:29: error: expected type 'std.builtin.GlobalLinkage', found 'u32'", | |
| 5817 | 5817 | ); |
| 5818 | 5818 | |
| 5819 | 5819 | cases.add( |
| ... | ... | @@ -6185,7 +6185,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 6185 | 6185 | \\}; |
| 6186 | 6186 | \\ |
| 6187 | 6187 | \\export fn entry() void { |
| 6188 | \\ var y = u3(3); | |
| 6188 | \\ var y = @as(u3, 3); | |
| 6189 | 6189 | \\ var x = @intToEnum(Small, y); |
| 6190 | 6190 | \\} |
| 6191 | 6191 | , |
| ... | ... | @@ -6722,8 +6722,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 6722 | 6722 | "tmp.zig:1:1: note: declared here", |
| 6723 | 6723 | ); |
| 6724 | 6724 | |
| 6725 | // fixed bug #2032 | |
| 6726 | cases.add( | |
| 6725 | cases.add( // fixed bug #2032 | |
| 6727 | 6726 | "compile diagnostic string for top level decl type", |
| 6728 | 6727 | \\export fn entry() void { |
| 6729 | 6728 | \\ var foo: u32 = @This(){}; |
| ... | ... | @@ -6731,6 +6730,5 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 6731 | 6730 | , |
| 6732 | 6731 | "tmp.zig:2:27: error: expected type 'u32', found '(root)'", |
| 6733 | 6732 | "tmp.zig:1:1: note: (root) declared here", |
| 6734 | "tmp.zig:2:5: note: referenced here", | |
| 6735 | 6733 | ); |
| 6736 | 6734 | } |
test/translate_c.zig+26-26| ... | ... | @@ -144,7 +144,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 144 | 144 | \\pub extern fn foo() void; |
| 145 | 145 | \\pub fn bar() void { |
| 146 | 146 | \\ var func_ptr: ?*c_void = @ptrCast(?*c_void, foo); |
| 147 | \\ var typed_func_ptr: ?extern fn () void = @intToPtr(?extern fn () void, c_ulong(@ptrToInt(func_ptr))); | |
| 147 | \\ var typed_func_ptr: ?extern fn () void = @intToPtr(?extern fn () void, @as(c_ulong, @ptrToInt(func_ptr))); | |
| 148 | 148 | \\} |
| 149 | 149 | ); |
| 150 | 150 | |
| ... | ... | @@ -567,37 +567,37 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 567 | 567 | cases.add("l integer suffix after hex literal", |
| 568 | 568 | \\#define SDL_INIT_VIDEO 0x00000020l /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ |
| 569 | 569 | , |
| 570 | \\pub const SDL_INIT_VIDEO = c_long(32); | |
| 570 | \\pub const SDL_INIT_VIDEO = @as(c_long, 32); | |
| 571 | 571 | ); |
| 572 | 572 | |
| 573 | 573 | cases.add("ul integer suffix after hex literal", |
| 574 | 574 | \\#define SDL_INIT_VIDEO 0x00000020ul /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ |
| 575 | 575 | , |
| 576 | \\pub const SDL_INIT_VIDEO = c_ulong(32); | |
| 576 | \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32); | |
| 577 | 577 | ); |
| 578 | 578 | |
| 579 | 579 | cases.add("lu integer suffix after hex literal", |
| 580 | 580 | \\#define SDL_INIT_VIDEO 0x00000020lu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ |
| 581 | 581 | , |
| 582 | \\pub const SDL_INIT_VIDEO = c_ulong(32); | |
| 582 | \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32); | |
| 583 | 583 | ); |
| 584 | 584 | |
| 585 | 585 | cases.add("ll integer suffix after hex literal", |
| 586 | 586 | \\#define SDL_INIT_VIDEO 0x00000020ll /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ |
| 587 | 587 | , |
| 588 | \\pub const SDL_INIT_VIDEO = c_longlong(32); | |
| 588 | \\pub const SDL_INIT_VIDEO = @as(c_longlong, 32); | |
| 589 | 589 | ); |
| 590 | 590 | |
| 591 | 591 | cases.add("ull integer suffix after hex literal", |
| 592 | 592 | \\#define SDL_INIT_VIDEO 0x00000020ull /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ |
| 593 | 593 | , |
| 594 | \\pub const SDL_INIT_VIDEO = c_ulonglong(32); | |
| 594 | \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32); | |
| 595 | 595 | ); |
| 596 | 596 | |
| 597 | 597 | cases.add("llu integer suffix after hex literal", |
| 598 | 598 | \\#define SDL_INIT_VIDEO 0x00000020llu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ |
| 599 | 599 | , |
| 600 | \\pub const SDL_INIT_VIDEO = c_ulonglong(32); | |
| 600 | \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32); | |
| 601 | 601 | ); |
| 602 | 602 | |
| 603 | 603 | cases.add("zig keywords in C code", |
| ... | ... | @@ -677,7 +677,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 677 | 677 | \\ var a = _arg_a; |
| 678 | 678 | \\ var i: c_int = 0; |
| 679 | 679 | \\ while (a > @as(c_uint, 0)) { |
| 680 | \\ a >>= @import("std").math.Log2Int(c_uint)(1); | |
| 680 | \\ a >>= @as(@import("std").math.Log2Int(c_uint), 1); | |
| 681 | 681 | \\ } |
| 682 | 682 | \\ return i; |
| 683 | 683 | \\} |
| ... | ... | @@ -849,7 +849,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 849 | 849 | \\ var a = _arg_a; |
| 850 | 850 | \\ var i: c_int = 0; |
| 851 | 851 | \\ while (a > @as(c_uint, 0)) { |
| 852 | \\ a >>= u5(1); | |
| 852 | \\ a >>= @as(u5, 1); | |
| 853 | 853 | \\ } |
| 854 | 854 | \\ return i; |
| 855 | 855 | \\} |
| ... | ... | @@ -1027,7 +1027,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1027 | 1027 | \\} |
| 1028 | 1028 | , |
| 1029 | 1029 | \\pub export fn foo() c_int { |
| 1030 | \\ return (1 << @import("std").math.Log2Int(c_int)(2)) >> @import("std").math.Log2Int(c_int)(1); | |
| 1030 | \\ return (1 << @as(@import("std").math.Log2Int(c_int), 2)) >> @as(@import("std").math.Log2Int(c_int), 1); | |
| 1031 | 1031 | \\} |
| 1032 | 1032 | ); |
| 1033 | 1033 | |
| ... | ... | @@ -1076,14 +1076,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1076 | 1076 | \\ _ref.* = (_ref.* ^ 1); |
| 1077 | 1077 | \\ break :x _ref.*; |
| 1078 | 1078 | \\ }); |
| 1079 | \\ a >>= @import("std").math.Log2Int(c_int)((x: { | |
| 1079 | \\ a >>= @as(@import("std").math.Log2Int(c_int), (x: { | |
| 1080 | 1080 | \\ const _ref = &a; |
| 1081 | \\ _ref.* = (_ref.* >> @import("std").math.Log2Int(c_int)(1)); | |
| 1081 | \\ _ref.* = (_ref.* >> @as(@import("std").math.Log2Int(c_int), 1)); | |
| 1082 | 1082 | \\ break :x _ref.*; |
| 1083 | 1083 | \\ })); |
| 1084 | \\ a <<= @import("std").math.Log2Int(c_int)((x: { | |
| 1084 | \\ a <<= @as(@import("std").math.Log2Int(c_int), (x: { | |
| 1085 | 1085 | \\ const _ref = &a; |
| 1086 | \\ _ref.* = (_ref.* << @import("std").math.Log2Int(c_int)(1)); | |
| 1086 | \\ _ref.* = (_ref.* << @as(@import("std").math.Log2Int(c_int), 1)); | |
| 1087 | 1087 | \\ break :x _ref.*; |
| 1088 | 1088 | \\ })); |
| 1089 | 1089 | \\} |
| ... | ... | @@ -1134,14 +1134,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1134 | 1134 | \\ _ref.* = (_ref.* ^ @as(c_uint, 1)); |
| 1135 | 1135 | \\ break :x _ref.*; |
| 1136 | 1136 | \\ }); |
| 1137 | \\ a >>= @import("std").math.Log2Int(c_uint)((x: { | |
| 1137 | \\ a >>= @as(@import("std").math.Log2Int(c_uint), (x: { | |
| 1138 | 1138 | \\ const _ref = &a; |
| 1139 | \\ _ref.* = (_ref.* >> @import("std").math.Log2Int(c_uint)(1)); | |
| 1139 | \\ _ref.* = (_ref.* >> @as(@import("std").math.Log2Int(c_uint), 1)); | |
| 1140 | 1140 | \\ break :x _ref.*; |
| 1141 | 1141 | \\ })); |
| 1142 | \\ a <<= @import("std").math.Log2Int(c_uint)((x: { | |
| 1142 | \\ a <<= @as(@import("std").math.Log2Int(c_uint), (x: { | |
| 1143 | 1143 | \\ const _ref = &a; |
| 1144 | \\ _ref.* = (_ref.* << @import("std").math.Log2Int(c_uint)(1)); | |
| 1144 | \\ _ref.* = (_ref.* << @as(@import("std").math.Log2Int(c_uint), 1)); | |
| 1145 | 1145 | \\ break :x _ref.*; |
| 1146 | 1146 | \\ })); |
| 1147 | 1147 | \\} |
| ... | ... | @@ -1539,7 +1539,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1539 | 1539 | cases.add("macro pointer cast", |
| 1540 | 1540 | \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE) |
| 1541 | 1541 | , |
| 1542 | \\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); | |
| 1542 | \\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); | |
| 1543 | 1543 | ); |
| 1544 | 1544 | |
| 1545 | 1545 | cases.add("if on non-bool", |
| ... | ... | @@ -1564,7 +1564,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1564 | 1564 | \\ if (a != 0) return 0; |
| 1565 | 1565 | \\ if (b != 0) return 1; |
| 1566 | 1566 | \\ if (c != null) return 2; |
| 1567 | \\ if (d != @bitCast(enum_SomeEnum, @TagType(enum_SomeEnum)(0))) return 3; | |
| 1567 | \\ if (d != @bitCast(enum_SomeEnum, @as(@TagType(enum_SomeEnum), 0))) return 3; | |
| 1568 | 1568 | \\ return 4; |
| 1569 | 1569 | \\} |
| 1570 | 1570 | ); |
| ... | ... | @@ -1652,37 +1652,37 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1652 | 1652 | cases.addC( |
| 1653 | 1653 | "l integer suffix after 0 (zero) in macro definition", |
| 1654 | 1654 | "#define ZERO 0L", |
| 1655 | "pub const ZERO = c_long(0);", | |
| 1655 | "pub const ZERO = @as(c_long, 0);", | |
| 1656 | 1656 | ); |
| 1657 | 1657 | |
| 1658 | 1658 | cases.addC( |
| 1659 | 1659 | "ul integer suffix after 0 (zero) in macro definition", |
| 1660 | 1660 | "#define ZERO 0UL", |
| 1661 | "pub const ZERO = c_ulong(0);", | |
| 1661 | "pub const ZERO = @as(c_ulong, 0);", | |
| 1662 | 1662 | ); |
| 1663 | 1663 | |
| 1664 | 1664 | cases.addC( |
| 1665 | 1665 | "lu integer suffix after 0 (zero) in macro definition", |
| 1666 | 1666 | "#define ZERO 0LU", |
| 1667 | "pub const ZERO = c_ulong(0);", | |
| 1667 | "pub const ZERO = @as(c_ulong, 0);", | |
| 1668 | 1668 | ); |
| 1669 | 1669 | |
| 1670 | 1670 | cases.addC( |
| 1671 | 1671 | "ll integer suffix after 0 (zero) in macro definition", |
| 1672 | 1672 | "#define ZERO 0LL", |
| 1673 | "pub const ZERO = c_longlong(0);", | |
| 1673 | "pub const ZERO = @as(c_longlong, 0);", | |
| 1674 | 1674 | ); |
| 1675 | 1675 | |
| 1676 | 1676 | cases.addC( |
| 1677 | 1677 | "ull integer suffix after 0 (zero) in macro definition", |
| 1678 | 1678 | "#define ZERO 0ULL", |
| 1679 | "pub const ZERO = c_ulonglong(0);", | |
| 1679 | "pub const ZERO = @as(c_ulonglong, 0);", | |
| 1680 | 1680 | ); |
| 1681 | 1681 | |
| 1682 | 1682 | cases.addC( |
| 1683 | 1683 | "llu integer suffix after 0 (zero) in macro definition", |
| 1684 | 1684 | "#define ZERO 0LLU", |
| 1685 | "pub const ZERO = c_ulonglong(0);", | |
| 1685 | "pub const ZERO = @as(c_ulonglong, 0);", | |
| 1686 | 1686 | ); |
| 1687 | 1687 | |
| 1688 | 1688 | cases.addC( |