| author | |
| committer | |
| log | 7199d7c77715fe06606c5c89595e6852b3fa8c20 |
| tree | 7ffd59e66cc2074d2da5284c9c22d69ddfc92968 |
| parent | 4e6f21e2cb2c557b5c019f4acf445665a26edcba |
18 files changed, 126 insertions(+), 87 deletions(-)
doc/langref.html.in+16-8| ... | @@ -8129,6 +8129,13 @@ test "main" { | ... | @@ -8129,6 +8129,13 @@ test "main" { |
| 8129 | {#code_end#} | 8129 | {#code_end#} |
| 8130 | {#header_close#} | 8130 | {#header_close#} |
| 8131 | 8131 | ||
| 8132 | {#header_open|@constCast#} | ||
| 8133 | <pre>{#syntax#}@constCast(value: anytype) DestType{#endsyntax#}</pre> | ||
| 8134 | <p> | ||
| 8135 | Remove {#syntax#}const{#endsyntax#} qualifier from a pointer. | ||
| 8136 | </p> | ||
| 8137 | {#header_close#} | ||
| 8138 | |||
| 8132 | {#header_open|@ctz#} | 8139 | {#header_open|@ctz#} |
| 8133 | <pre>{#syntax#}@ctz(operand: anytype){#endsyntax#}</pre> | 8140 | <pre>{#syntax#}@ctz(operand: anytype){#endsyntax#}</pre> |
| 8134 | <p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type or an integer vector type.</p> | 8141 | <p>{#syntax#}@TypeOf(operand){#endsyntax#} must be an integer type or an integer vector type.</p> |
| ... | @@ -8814,7 +8821,8 @@ pub const PrefetchOptions = struct { | ... | @@ -8814,7 +8821,8 @@ pub const PrefetchOptions = struct { |
| 8814 | {#syntax#}@ptrCast{#endsyntax#} cannot be used for: | 8821 | {#syntax#}@ptrCast{#endsyntax#} cannot be used for: |
| 8815 | </p> | 8822 | </p> |
| 8816 | <ul> | 8823 | <ul> |
| 8817 | <li>Removing {#syntax#}const{#endsyntax#} or {#syntax#}volatile{#endsyntax#} qualifier, use {#link|@qualCast#}.</li> | 8824 | <li>Removing {#syntax#}const{#endsyntax#} qualifier, use {#link|@constCast#}.</li> |
| 8825 | <li>Removing {#syntax#}volatile{#endsyntax#} qualifier, use {#link|@volatileCast#}.</li> | ||
| 8818 | <li>Changing pointer address space, use {#link|@addrSpaceCast#}.</li> | 8826 | <li>Changing pointer address space, use {#link|@addrSpaceCast#}.</li> |
| 8819 | <li>Increasing pointer alignment, use {#link|@alignCast#}.</li> | 8827 | <li>Increasing pointer alignment, use {#link|@alignCast#}.</li> |
| 8820 | <li>Casting a non-slice pointer to a slice, use slicing syntax {#syntax#}ptr[start..end]{#endsyntax#}.</li> | 8828 | <li>Casting a non-slice pointer to a slice, use slicing syntax {#syntax#}ptr[start..end]{#endsyntax#}.</li> |
| ... | @@ -8831,13 +8839,6 @@ pub const PrefetchOptions = struct { | ... | @@ -8831,13 +8839,6 @@ pub const PrefetchOptions = struct { |
| 8831 | 8839 | ||
| 8832 | {#header_close#} | 8840 | {#header_close#} |
| 8833 | 8841 | ||
| 8834 | {#header_open|@qualCast#} | ||
| 8835 | <pre>{#syntax#}@qualCast(comptime DestType: type, value: anytype) DestType{#endsyntax#}</pre> | ||
| 8836 | <p> | ||
| 8837 | Remove {#syntax#}const{#endsyntax#} or {#syntax#}volatile{#endsyntax#} qualifier from a pointer. | ||
| 8838 | </p> | ||
| 8839 | {#header_close#} | ||
| 8840 | |||
| 8841 | {#header_open|@rem#} | 8842 | {#header_open|@rem#} |
| 8842 | <pre>{#syntax#}@rem(numerator: T, denominator: T) T{#endsyntax#}</pre> | 8843 | <pre>{#syntax#}@rem(numerator: T, denominator: T) T{#endsyntax#}</pre> |
| 8843 | <p> | 8844 | <p> |
| ... | @@ -9525,6 +9526,13 @@ fn foo(comptime T: type, ptr: *T) T { | ... | @@ -9525,6 +9526,13 @@ fn foo(comptime T: type, ptr: *T) T { |
| 9525 | <pre>{#syntax#}@Vector(len: comptime_int, Element: type) type{#endsyntax#}</pre> | 9526 | <pre>{#syntax#}@Vector(len: comptime_int, Element: type) type{#endsyntax#}</pre> |
| 9526 | <p>Creates {#link|Vectors#}.</p> | 9527 | <p>Creates {#link|Vectors#}.</p> |
| 9527 | {#header_close#} | 9528 | {#header_close#} |
| 9529 | |||
| 9530 | {#header_open|@volatileCast#} | ||
| 9531 | <pre>{#syntax#}@volatileCast(value: anytype) DestType{#endsyntax#}</pre> | ||
| 9532 | <p> | ||
| 9533 | Remove {#syntax#}volatile{#endsyntax#} qualifier from a pointer. | ||
| 9534 | </p> | ||
| 9535 | {#header_close#} | ||
| 9528 | {#header_close#} | 9536 | {#header_close#} |
| 9529 | 9537 | ||
| 9530 | {#header_open|Build Mode#} | 9538 | {#header_open|Build Mode#} |
lib/docs/main.js+6-2| ... | @@ -1354,8 +1354,12 @@ const NAV_MODES = { | ... | @@ -1354,8 +1354,12 @@ const NAV_MODES = { |
| 1354 | payloadHtml += "ptrCast"; | 1354 | payloadHtml += "ptrCast"; |
| 1355 | break; | 1355 | break; |
| 1356 | } | 1356 | } |
| 1357 | case "qual_cast": { | 1357 | case "const_cast": { |
| 1358 | payloadHtml += "qualCast"; | 1358 | payloadHtml += "constCast"; |
| 1359 | break; | ||
| 1360 | } | ||
| 1361 | case "volatile_cast": { | ||
| 1362 | payloadHtml += "volatileCast"; | ||
| 1359 | break; | 1363 | break; |
| 1360 | } | 1364 | } |
| 1361 | case "truncate": { | 1365 | case "truncate": { |
lib/std/child_process.zig+2-2| ... | @@ -1164,7 +1164,7 @@ fn windowsCreateProcessPathExt( | ... | @@ -1164,7 +1164,7 @@ fn windowsCreateProcessPathExt( |
| 1164 | var app_name_unicode_string = windows.UNICODE_STRING{ | 1164 | var app_name_unicode_string = windows.UNICODE_STRING{ |
| 1165 | .Length = app_name_len_bytes, | 1165 | .Length = app_name_len_bytes, |
| 1166 | .MaximumLength = app_name_len_bytes, | 1166 | .MaximumLength = app_name_len_bytes, |
| 1167 | .Buffer = @qualCast([*:0]u16, app_name_wildcard.ptr), | 1167 | .Buffer = @constCast(app_name_wildcard.ptr), |
| 1168 | }; | 1168 | }; |
| 1169 | const rc = windows.ntdll.NtQueryDirectoryFile( | 1169 | const rc = windows.ntdll.NtQueryDirectoryFile( |
| 1170 | dir.fd, | 1170 | dir.fd, |
| ... | @@ -1261,7 +1261,7 @@ fn windowsCreateProcessPathExt( | ... | @@ -1261,7 +1261,7 @@ fn windowsCreateProcessPathExt( |
| 1261 | var app_name_unicode_string = windows.UNICODE_STRING{ | 1261 | var app_name_unicode_string = windows.UNICODE_STRING{ |
| 1262 | .Length = app_name_len_bytes, | 1262 | .Length = app_name_len_bytes, |
| 1263 | .MaximumLength = app_name_len_bytes, | 1263 | .MaximumLength = app_name_len_bytes, |
| 1264 | .Buffer = @qualCast([*:0]u16, app_name_appended.ptr), | 1264 | .Buffer = @constCast(app_name_appended.ptr), |
| 1265 | }; | 1265 | }; |
| 1266 | 1266 | ||
| 1267 | // Re-use the directory handle but this time we call with the appended app name | 1267 | // Re-use the directory handle but this time we call with the appended app name |
lib/std/fs.zig+1-1| ... | @@ -1763,7 +1763,7 @@ pub const Dir = struct { | ... | @@ -1763,7 +1763,7 @@ pub const Dir = struct { |
| 1763 | var nt_name = w.UNICODE_STRING{ | 1763 | var nt_name = w.UNICODE_STRING{ |
| 1764 | .Length = path_len_bytes, | 1764 | .Length = path_len_bytes, |
| 1765 | .MaximumLength = path_len_bytes, | 1765 | .MaximumLength = path_len_bytes, |
| 1766 | .Buffer = @qualCast([*:0]u16, sub_path_w), | 1766 | .Buffer = @constCast(sub_path_w), |
| 1767 | }; | 1767 | }; |
| 1768 | var attr = w.OBJECT_ATTRIBUTES{ | 1768 | var attr = w.OBJECT_ATTRIBUTES{ |
| 1769 | .Length = @sizeOf(w.OBJECT_ATTRIBUTES), | 1769 | .Length = @sizeOf(w.OBJECT_ATTRIBUTES), |
lib/std/mem/Allocator.zig+2-2| ... | @@ -112,7 +112,7 @@ pub fn destroy(self: Allocator, ptr: anytype) void { | ... | @@ -112,7 +112,7 @@ pub fn destroy(self: Allocator, ptr: anytype) void { |
| 112 | const info = @typeInfo(@TypeOf(ptr)).Pointer; | 112 | const info = @typeInfo(@TypeOf(ptr)).Pointer; |
| 113 | const T = info.child; | 113 | const T = info.child; |
| 114 | if (@sizeOf(T) == 0) return; | 114 | if (@sizeOf(T) == 0) return; |
| 115 | const non_const_ptr = @intToPtr([*]u8, @ptrToInt(ptr)); | 115 | const non_const_ptr = @ptrCast([*]u8, @constCast(ptr)); |
| 116 | self.rawFree(non_const_ptr[0..@sizeOf(T)], math.log2(info.alignment), @returnAddress()); | 116 | self.rawFree(non_const_ptr[0..@sizeOf(T)], math.log2(info.alignment), @returnAddress()); |
| 117 | } | 117 | } |
| 118 | 118 | ||
| ... | @@ -297,7 +297,7 @@ pub fn free(self: Allocator, memory: anytype) void { | ... | @@ -297,7 +297,7 @@ pub fn free(self: Allocator, memory: anytype) void { |
| 297 | const bytes = mem.sliceAsBytes(memory); | 297 | const bytes = mem.sliceAsBytes(memory); |
| 298 | const bytes_len = bytes.len + if (Slice.sentinel != null) @sizeOf(Slice.child) else 0; | 298 | const bytes_len = bytes.len + if (Slice.sentinel != null) @sizeOf(Slice.child) else 0; |
| 299 | if (bytes_len == 0) return; | 299 | if (bytes_len == 0) return; |
| 300 | const non_const_ptr = @intToPtr([*]u8, @ptrToInt(bytes.ptr)); | 300 | const non_const_ptr = @constCast(bytes.ptr); |
| 301 | // TODO: https://github.com/ziglang/zig/issues/4298 | 301 | // TODO: https://github.com/ziglang/zig/issues/4298 |
| 302 | @memset(non_const_ptr, undefined, bytes_len); | 302 | @memset(non_const_ptr, undefined, bytes_len); |
| 303 | self.rawFree(non_const_ptr[0..bytes_len], log2a(Slice.alignment), @returnAddress()); | 303 | self.rawFree(non_const_ptr[0..bytes_len], log2a(Slice.alignment), @returnAddress()); |
lib/std/os.zig+1-1| ... | @@ -4513,7 +4513,7 @@ pub fn faccessatW(dirfd: fd_t, sub_path_w: [*:0]const u16, mode: u32, flags: u32 | ... | @@ -4513,7 +4513,7 @@ pub fn faccessatW(dirfd: fd_t, sub_path_w: [*:0]const u16, mode: u32, flags: u32 |
| 4513 | var nt_name = windows.UNICODE_STRING{ | 4513 | var nt_name = windows.UNICODE_STRING{ |
| 4514 | .Length = path_len_bytes, | 4514 | .Length = path_len_bytes, |
| 4515 | .MaximumLength = path_len_bytes, | 4515 | .MaximumLength = path_len_bytes, |
| 4516 | .Buffer = @qualCast([*:0]u16, sub_path_w), | 4516 | .Buffer = @constCast(sub_path_w), |
| 4517 | }; | 4517 | }; |
| 4518 | var attr = windows.OBJECT_ATTRIBUTES{ | 4518 | var attr = windows.OBJECT_ATTRIBUTES{ |
| 4519 | .Length = @sizeOf(windows.OBJECT_ATTRIBUTES), | 4519 | .Length = @sizeOf(windows.OBJECT_ATTRIBUTES), |
lib/std/os/windows.zig+7-7| ... | @@ -85,7 +85,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN | ... | @@ -85,7 +85,7 @@ pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HAN |
| 85 | var nt_name = UNICODE_STRING{ | 85 | var nt_name = UNICODE_STRING{ |
| 86 | .Length = path_len_bytes, | 86 | .Length = path_len_bytes, |
| 87 | .MaximumLength = path_len_bytes, | 87 | .MaximumLength = path_len_bytes, |
| 88 | .Buffer = @qualCast([*]u16, sub_path_w.ptr), | 88 | .Buffer = @constCast(sub_path_w.ptr), |
| 89 | }; | 89 | }; |
| 90 | var attr = OBJECT_ATTRIBUTES{ | 90 | var attr = OBJECT_ATTRIBUTES{ |
| 91 | .Length = @sizeOf(OBJECT_ATTRIBUTES), | 91 | .Length = @sizeOf(OBJECT_ATTRIBUTES), |
| ... | @@ -634,7 +634,7 @@ pub fn SetCurrentDirectory(path_name: []const u16) SetCurrentDirectoryError!void | ... | @@ -634,7 +634,7 @@ pub fn SetCurrentDirectory(path_name: []const u16) SetCurrentDirectoryError!void |
| 634 | var nt_name = UNICODE_STRING{ | 634 | var nt_name = UNICODE_STRING{ |
| 635 | .Length = path_len_bytes, | 635 | .Length = path_len_bytes, |
| 636 | .MaximumLength = path_len_bytes, | 636 | .MaximumLength = path_len_bytes, |
| 637 | .Buffer = @qualCast([*]u16, path_name.ptr), | 637 | .Buffer = @constCast(path_name.ptr), |
| 638 | }; | 638 | }; |
| 639 | 639 | ||
| 640 | const rc = ntdll.RtlSetCurrentDirectory_U(&nt_name); | 640 | const rc = ntdll.RtlSetCurrentDirectory_U(&nt_name); |
| ... | @@ -766,7 +766,7 @@ pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u8) ReadLin | ... | @@ -766,7 +766,7 @@ pub fn ReadLink(dir: ?HANDLE, sub_path_w: []const u16, out_buffer: []u8) ReadLin |
| 766 | var nt_name = UNICODE_STRING{ | 766 | var nt_name = UNICODE_STRING{ |
| 767 | .Length = path_len_bytes, | 767 | .Length = path_len_bytes, |
| 768 | .MaximumLength = path_len_bytes, | 768 | .MaximumLength = path_len_bytes, |
| 769 | .Buffer = @qualCast([*]u16, sub_path_w.ptr), | 769 | .Buffer = @constCast(sub_path_w.ptr), |
| 770 | }; | 770 | }; |
| 771 | var attr = OBJECT_ATTRIBUTES{ | 771 | var attr = OBJECT_ATTRIBUTES{ |
| 772 | .Length = @sizeOf(OBJECT_ATTRIBUTES), | 772 | .Length = @sizeOf(OBJECT_ATTRIBUTES), |
| ... | @@ -876,7 +876,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil | ... | @@ -876,7 +876,7 @@ pub fn DeleteFile(sub_path_w: []const u16, options: DeleteFileOptions) DeleteFil |
| 876 | .Length = path_len_bytes, | 876 | .Length = path_len_bytes, |
| 877 | .MaximumLength = path_len_bytes, | 877 | .MaximumLength = path_len_bytes, |
| 878 | // The Windows API makes this mutable, but it will not mutate here. | 878 | // The Windows API makes this mutable, but it will not mutate here. |
| 879 | .Buffer = @qualCast([*]u16, sub_path_w.ptr), | 879 | .Buffer = @constCast(sub_path_w.ptr), |
| 880 | }; | 880 | }; |
| 881 | 881 | ||
| 882 | if (sub_path_w[0] == '.' and sub_path_w[1] == 0) { | 882 | if (sub_path_w[0] == '.' and sub_path_w[1] == 0) { |
| ... | @@ -1414,7 +1414,7 @@ pub fn sendmsg( | ... | @@ -1414,7 +1414,7 @@ pub fn sendmsg( |
| 1414 | } | 1414 | } |
| 1415 | 1415 | ||
| 1416 | pub fn sendto(s: ws2_32.SOCKET, buf: [*]const u8, len: usize, flags: u32, to: ?*const ws2_32.sockaddr, to_len: ws2_32.socklen_t) i32 { | 1416 | pub fn sendto(s: ws2_32.SOCKET, buf: [*]const u8, len: usize, flags: u32, to: ?*const ws2_32.sockaddr, to_len: ws2_32.socklen_t) i32 { |
| 1417 | var buffer = ws2_32.WSABUF{ .len = @truncate(u31, len), .buf = @qualCast([*]u8, buf) }; | 1417 | var buffer = ws2_32.WSABUF{ .len = @truncate(u31, len), .buf = @constCast(buf) }; |
| 1418 | var bytes_send: DWORD = undefined; | 1418 | var bytes_send: DWORD = undefined; |
| 1419 | if (ws2_32.WSASendTo(s, @ptrCast([*]ws2_32.WSABUF, &buffer), 1, &bytes_send, flags, to, @intCast(i32, to_len), null, null) == ws2_32.SOCKET_ERROR) { | 1419 | if (ws2_32.WSASendTo(s, @ptrCast([*]ws2_32.WSABUF, &buffer), 1, &bytes_send, flags, to, @intCast(i32, to_len), null, null) == ws2_32.SOCKET_ERROR) { |
| 1420 | return ws2_32.SOCKET_ERROR; | 1420 | return ws2_32.SOCKET_ERROR; |
| ... | @@ -1876,13 +1876,13 @@ pub fn eqlIgnoreCaseWTF16(a: []const u16, b: []const u16) bool { | ... | @@ -1876,13 +1876,13 @@ pub fn eqlIgnoreCaseWTF16(a: []const u16, b: []const u16) bool { |
| 1876 | const a_string = UNICODE_STRING{ | 1876 | const a_string = UNICODE_STRING{ |
| 1877 | .Length = a_bytes, | 1877 | .Length = a_bytes, |
| 1878 | .MaximumLength = a_bytes, | 1878 | .MaximumLength = a_bytes, |
| 1879 | .Buffer = @qualCast([*]u16, a.ptr), | 1879 | .Buffer = @constCast(a.ptr), |
| 1880 | }; | 1880 | }; |
| 1881 | const b_bytes = @intCast(u16, b.len * 2); | 1881 | const b_bytes = @intCast(u16, b.len * 2); |
| 1882 | const b_string = UNICODE_STRING{ | 1882 | const b_string = UNICODE_STRING{ |
| 1883 | .Length = b_bytes, | 1883 | .Length = b_bytes, |
| 1884 | .MaximumLength = b_bytes, | 1884 | .MaximumLength = b_bytes, |
| 1885 | .Buffer = @qualCast([*]u16, b.ptr), | 1885 | .Buffer = @constCast(b.ptr), |
| 1886 | }; | 1886 | }; |
| 1887 | return ntdll.RtlEqualUnicodeString(&a_string, &b_string, TRUE) == TRUE; | 1887 | return ntdll.RtlEqualUnicodeString(&a_string, &b_string, TRUE) == TRUE; |
| 1888 | } | 1888 | } |
lib/std/zig/c_translation.zig+4-2| ... | @@ -74,8 +74,10 @@ fn castPtr(comptime DestType: type, target: anytype) DestType { | ... | @@ -74,8 +74,10 @@ fn castPtr(comptime DestType: type, target: anytype) DestType { |
| 74 | const dest = ptrInfo(DestType); | 74 | const dest = ptrInfo(DestType); |
| 75 | const source = ptrInfo(@TypeOf(target)); | 75 | const source = ptrInfo(@TypeOf(target)); |
| 76 | 76 | ||
| 77 | if (source.is_const and !dest.is_const or source.is_volatile and !dest.is_volatile) | 77 | if (source.is_const and !dest.is_const) |
| 78 | return @qualCast(DestType, target) | 78 | return @constCast(target) |
| 79 | else if (source.is_volatile and !dest.is_volatile) | ||
| 80 | return @volatileCast(target) | ||
| 79 | else if (@typeInfo(dest.child) == .Opaque) | 81 | else if (@typeInfo(dest.child) == .Opaque) |
| 80 | // dest.alignment would error out | 82 | // dest.alignment would error out |
| 81 | return @ptrCast(DestType, target) | 83 | return @ptrCast(DestType, target) |
src/AstGen.zig+16-2| ... | @@ -2531,7 +2531,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As | ... | @@ -2531,7 +2531,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2531 | .bit_size_of, | 2531 | .bit_size_of, |
| 2532 | .typeof_log2_int_type, | 2532 | .typeof_log2_int_type, |
| 2533 | .ptr_to_int, | 2533 | .ptr_to_int, |
| 2534 | .qual_cast, | ||
| 2535 | .align_of, | 2534 | .align_of, |
| 2536 | .bool_to_int, | 2535 | .bool_to_int, |
| 2537 | .embed_file, | 2536 | .embed_file, |
| ... | @@ -8039,7 +8038,6 @@ fn builtinCall( | ... | @@ -8039,7 +8038,6 @@ fn builtinCall( |
| 8039 | .float_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .float_cast), | 8038 | .float_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .float_cast), |
| 8040 | .int_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .int_cast), | 8039 | .int_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .int_cast), |
| 8041 | .ptr_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .ptr_cast), | 8040 | .ptr_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .ptr_cast), |
| 8042 | .qual_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .qual_cast), | ||
| 8043 | .truncate => return typeCast(gz, scope, ri, node, params[0], params[1], .truncate), | 8041 | .truncate => return typeCast(gz, scope, ri, node, params[0], params[1], .truncate), |
| 8044 | // zig fmt: on | 8042 | // zig fmt: on |
| 8045 | 8043 | ||
| ... | @@ -8115,6 +8113,22 @@ fn builtinCall( | ... | @@ -8115,6 +8113,22 @@ fn builtinCall( |
| 8115 | }); | 8113 | }); |
| 8116 | return rvalue(gz, ri, result, node); | 8114 | return rvalue(gz, ri, result, node); |
| 8117 | }, | 8115 | }, |
| 8116 | .const_cast => { | ||
| 8117 | const operand = try expr(gz, scope, .{ .rl = .none }, params[0]); | ||
| 8118 | const result = try gz.addExtendedPayload(.const_cast, Zir.Inst.UnNode{ | ||
| 8119 | .node = gz.nodeIndexToRelative(node), | ||
| 8120 | .operand = operand, | ||
| 8121 | }); | ||
| 8122 | return rvalue(gz, ri, result, node); | ||
| 8123 | }, | ||
| 8124 | .volatile_cast => { | ||
| 8125 | const operand = try expr(gz, scope, .{ .rl = .none }, params[0]); | ||
| 8126 | const result = try gz.addExtendedPayload(.volatile_cast, Zir.Inst.UnNode{ | ||
| 8127 | .node = gz.nodeIndexToRelative(node), | ||
| 8128 | .operand = operand, | ||
| 8129 | }); | ||
| 8130 | return rvalue(gz, ri, result, node); | ||
| 8131 | }, | ||
| 8118 | 8132 | ||
| 8119 | // zig fmt: off | 8133 | // zig fmt: off |
| 8120 | .has_decl => return hasDeclOrField(gz, scope, ri, node, params[0], params[1], .has_decl), | 8134 | .has_decl => return hasDeclOrField(gz, scope, ri, node, params[0], params[1], .has_decl), |
src/Autodoc.zig+2-1| ... | @@ -1400,7 +1400,6 @@ fn walkInstruction( | ... | @@ -1400,7 +1400,6 @@ fn walkInstruction( |
| 1400 | .float_cast, | 1400 | .float_cast, |
| 1401 | .int_cast, | 1401 | .int_cast, |
| 1402 | .ptr_cast, | 1402 | .ptr_cast, |
| 1403 | .qual_cast, | ||
| 1404 | .truncate, | 1403 | .truncate, |
| 1405 | .align_cast, | 1404 | .align_cast, |
| 1406 | .has_decl, | 1405 | .has_decl, |
| ... | @@ -2983,6 +2982,8 @@ fn walkInstruction( | ... | @@ -2983,6 +2982,8 @@ fn walkInstruction( |
| 2983 | .error_to_int, | 2982 | .error_to_int, |
| 2984 | .int_to_error, | 2983 | .int_to_error, |
| 2985 | .reify, | 2984 | .reify, |
| 2985 | .const_cast, | ||
| 2986 | .volatile_cast, | ||
| 2986 | => { | 2987 | => { |
| 2987 | const extra = file.zir.extraData(Zir.Inst.UnNode, extended.operand).data; | 2988 | const extra = file.zir.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 2988 | const bin_index = self.exprs.items.len; | 2989 | const bin_index = self.exprs.items.len; |
src/BuiltinFn.zig+16-8| ... | @@ -28,6 +28,7 @@ pub const Tag = enum { | ... | @@ -28,6 +28,7 @@ pub const Tag = enum { |
| 28 | cmpxchg_weak, | 28 | cmpxchg_weak, |
| 29 | compile_error, | 29 | compile_error, |
| 30 | compile_log, | 30 | compile_log, |
| 31 | const_cast, | ||
| 31 | ctz, | 32 | ctz, |
| 32 | c_undef, | 33 | c_undef, |
| 33 | c_va_arg, | 34 | c_va_arg, |
| ... | @@ -75,7 +76,6 @@ pub const Tag = enum { | ... | @@ -75,7 +76,6 @@ pub const Tag = enum { |
| 75 | prefetch, | 76 | prefetch, |
| 76 | ptr_cast, | 77 | ptr_cast, |
| 77 | ptr_to_int, | 78 | ptr_to_int, |
| 78 | qual_cast, | ||
| 79 | rem, | 79 | rem, |
| 80 | return_address, | 80 | return_address, |
| 81 | select, | 81 | select, |
| ... | @@ -116,6 +116,7 @@ pub const Tag = enum { | ... | @@ -116,6 +116,7 @@ pub const Tag = enum { |
| 116 | TypeOf, | 116 | TypeOf, |
| 117 | union_init, | 117 | union_init, |
| 118 | Vector, | 118 | Vector, |
| 119 | volatile_cast, | ||
| 119 | }; | 120 | }; |
| 120 | 121 | ||
| 121 | pub const MemLocRequirement = enum { | 122 | pub const MemLocRequirement = enum { |
| ... | @@ -345,6 +346,13 @@ pub const list = list: { | ... | @@ -345,6 +346,13 @@ pub const list = list: { |
| 345 | .param_count = null, | 346 | .param_count = null, |
| 346 | }, | 347 | }, |
| 347 | }, | 348 | }, |
| 349 | .{ | ||
| 350 | "@constCast", | ||
| 351 | .{ | ||
| 352 | .tag = .const_cast, | ||
| 353 | .param_count = 1, | ||
| 354 | }, | ||
| 355 | }, | ||
| 348 | .{ | 356 | .{ |
| 349 | "@ctz", | 357 | "@ctz", |
| 350 | .{ | 358 | .{ |
| ... | @@ -675,13 +683,6 @@ pub const list = list: { | ... | @@ -675,13 +683,6 @@ pub const list = list: { |
| 675 | .param_count = 1, | 683 | .param_count = 1, |
| 676 | }, | 684 | }, |
| 677 | }, | 685 | }, |
| 678 | .{ | ||
| 679 | "@qualCast", | ||
| 680 | .{ | ||
| 681 | .tag = .qual_cast, | ||
| 682 | .param_count = 2, | ||
| 683 | }, | ||
| 684 | }, | ||
| 685 | .{ | 686 | .{ |
| 686 | "@rem", | 687 | "@rem", |
| 687 | .{ | 688 | .{ |
| ... | @@ -964,5 +965,12 @@ pub const list = list: { | ... | @@ -964,5 +965,12 @@ pub const list = list: { |
| 964 | .param_count = 2, | 965 | .param_count = 2, |
| 965 | }, | 966 | }, |
| 966 | }, | 967 | }, |
| 968 | .{ | ||
| 969 | "@volatileCast", | ||
| 970 | .{ | ||
| 971 | .tag = .volatile_cast, | ||
| 972 | .param_count = 1, | ||
| 973 | }, | ||
| 974 | }, | ||
| 967 | }); | 975 | }); |
| 968 | }; | 976 | }; |
src/Sema.zig+29-31| ... | @@ -1015,7 +1015,6 @@ fn analyzeBodyInner( | ... | @@ -1015,7 +1015,6 @@ fn analyzeBodyInner( |
| 1015 | .float_cast => try sema.zirFloatCast(block, inst), | 1015 | .float_cast => try sema.zirFloatCast(block, inst), |
| 1016 | .int_cast => try sema.zirIntCast(block, inst), | 1016 | .int_cast => try sema.zirIntCast(block, inst), |
| 1017 | .ptr_cast => try sema.zirPtrCast(block, inst), | 1017 | .ptr_cast => try sema.zirPtrCast(block, inst), |
| 1018 | .qual_cast => try sema.zirQualCast(block, inst), | ||
| 1019 | .truncate => try sema.zirTruncate(block, inst), | 1018 | .truncate => try sema.zirTruncate(block, inst), |
| 1020 | .align_cast => try sema.zirAlignCast(block, inst), | 1019 | .align_cast => try sema.zirAlignCast(block, inst), |
| 1021 | .has_decl => try sema.zirHasDecl(block, inst), | 1020 | .has_decl => try sema.zirHasDecl(block, inst), |
| ... | @@ -1147,6 +1146,8 @@ fn analyzeBodyInner( | ... | @@ -1147,6 +1146,8 @@ fn analyzeBodyInner( |
| 1147 | .c_va_copy => try sema.zirCVaCopy( block, extended), | 1146 | .c_va_copy => try sema.zirCVaCopy( block, extended), |
| 1148 | .c_va_end => try sema.zirCVaEnd( block, extended), | 1147 | .c_va_end => try sema.zirCVaEnd( block, extended), |
| 1149 | .c_va_start => try sema.zirCVaStart( block, extended), | 1148 | .c_va_start => try sema.zirCVaStart( block, extended), |
| 1149 | .const_cast, => try sema.zirConstCast( block, extended), | ||
| 1150 | .volatile_cast, => try sema.zirVolatileCast( block, extended), | ||
| 1150 | // zig fmt: on | 1151 | // zig fmt: on |
| 1151 | 1152 | ||
| 1152 | .fence => { | 1153 | .fence => { |
| ... | @@ -19545,7 +19546,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -19545,7 +19546,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19545 | const msg = try sema.errMsg(block, src, "cast discards const qualifier", .{}); | 19546 | const msg = try sema.errMsg(block, src, "cast discards const qualifier", .{}); |
| 19546 | errdefer msg.destroy(sema.gpa); | 19547 | errdefer msg.destroy(sema.gpa); |
| 19547 | 19548 | ||
| 19548 | try sema.errNote(block, src, msg, "consider using '@qualCast'", .{}); | 19549 | try sema.errNote(block, src, msg, "consider using '@constCast'", .{}); |
| 19549 | break :msg msg; | 19550 | break :msg msg; |
| 19550 | }; | 19551 | }; |
| 19551 | return sema.failWithOwnedErrorMsg(msg); | 19552 | return sema.failWithOwnedErrorMsg(msg); |
| ... | @@ -19555,7 +19556,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -19555,7 +19556,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19555 | const msg = try sema.errMsg(block, src, "cast discards volatile qualifier", .{}); | 19556 | const msg = try sema.errMsg(block, src, "cast discards volatile qualifier", .{}); |
| 19556 | errdefer msg.destroy(sema.gpa); | 19557 | errdefer msg.destroy(sema.gpa); |
| 19557 | 19558 | ||
| 19558 | try sema.errNote(block, src, msg, "consider using '@qualCast'", .{}); | 19559 | try sema.errNote(block, src, msg, "consider using '@volatileCast'", .{}); |
| 19559 | break :msg msg; | 19560 | break :msg msg; |
| 19560 | }; | 19561 | }; |
| 19561 | return sema.failWithOwnedErrorMsg(msg); | 19562 | return sema.failWithOwnedErrorMsg(msg); |
| ... | @@ -19660,40 +19661,37 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -19660,40 +19661,37 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 19660 | return block.addBitCast(aligned_dest_ty, ptr); | 19661 | return block.addBitCast(aligned_dest_ty, ptr); |
| 19661 | } | 19662 | } |
| 19662 | 19663 | ||
| 19663 | fn zirQualCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 19664 | fn zirConstCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 19664 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 19665 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 19665 | const src = inst_data.src(); | 19666 | const src = LazySrcLoc.nodeOffset(extra.node); |
| 19666 | const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 19667 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; |
| 19667 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; | 19668 | const operand = try sema.resolveInst(extra.operand); |
| 19668 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | ||
| 19669 | const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs); | ||
| 19670 | const operand = try sema.resolveInst(extra.rhs); | ||
| 19671 | const operand_ty = sema.typeOf(operand); | 19669 | const operand_ty = sema.typeOf(operand); |
| 19672 | |||
| 19673 | try sema.checkPtrType(block, dest_ty_src, dest_ty); | ||
| 19674 | try sema.checkPtrOperand(block, operand_src, operand_ty); | 19670 | try sema.checkPtrOperand(block, operand_src, operand_ty); |
| 19675 | 19671 | ||
| 19676 | var operand_payload = operand_ty.ptrInfo(); | 19672 | var ptr_info = operand_ty.ptrInfo().data; |
| 19677 | var dest_info = dest_ty.ptrInfo(); | 19673 | ptr_info.mutable = true; |
| 19674 | const dest_ty = try Type.ptr(sema.arena, sema.mod, ptr_info); | ||
| 19675 | |||
| 19676 | if (try sema.resolveMaybeUndefVal(operand)) |operand_val| { | ||
| 19677 | return sema.addConstant(dest_ty, operand_val); | ||
| 19678 | } | ||
| 19678 | 19679 | ||
| 19679 | operand_payload.data.mutable = dest_info.data.mutable; | 19680 | try sema.requireRuntimeBlock(block, src, null); |
| 19680 | operand_payload.data.@"volatile" = dest_info.data.@"volatile"; | 19681 | return block.addBitCast(dest_ty, operand); |
| 19682 | } | ||
| 19681 | 19683 | ||
| 19682 | const altered_operand_ty = Type.initPayload(&operand_payload.base); | 19684 | fn zirVolatileCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 19683 | if (!altered_operand_ty.eql(dest_ty, sema.mod)) { | 19685 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 19684 | const msg = msg: { | 19686 | const src = LazySrcLoc.nodeOffset(extra.node); |
| 19685 | const msg = try sema.errMsg(block, src, "'@qualCast' can only modify 'const' and 'volatile' qualifiers", .{}); | 19687 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; |
| 19686 | errdefer msg.destroy(sema.gpa); | 19688 | const operand = try sema.resolveInst(extra.operand); |
| 19689 | const operand_ty = sema.typeOf(operand); | ||
| 19690 | try sema.checkPtrOperand(block, operand_src, operand_ty); | ||
| 19687 | 19691 | ||
| 19688 | dest_info.data.mutable = !operand_ty.isConstPtr(); | 19692 | var ptr_info = operand_ty.ptrInfo().data; |
| 19689 | dest_info.data.@"volatile" = operand_ty.isVolatilePtr(); | 19693 | ptr_info.@"volatile" = false; |
| 19690 | const altered_dest_ty = Type.initPayload(&dest_info.base); | 19694 | const dest_ty = try Type.ptr(sema.arena, sema.mod, ptr_info); |
| 19691 | try sema.errNote(block, src, msg, "expected type '{}'", .{altered_dest_ty.fmt(sema.mod)}); | ||
| 19692 | try sema.errNote(block, src, msg, "got type '{}'", .{operand_ty.fmt(sema.mod)}); | ||
| 19693 | break :msg msg; | ||
| 19694 | }; | ||
| 19695 | return sema.failWithOwnedErrorMsg(msg); | ||
| 19696 | } | ||
| 19697 | 19695 | ||
| 19698 | if (try sema.resolveMaybeUndefVal(operand)) |operand_val| { | 19696 | if (try sema.resolveMaybeUndefVal(operand)) |operand_val| { |
| 19699 | return sema.addConstant(dest_ty, operand_val); | 19697 | return sema.addConstant(dest_ty, operand_val); |
src/Zir.zig+6-6| ... | @@ -857,9 +857,6 @@ pub const Inst = struct { | ... | @@ -857,9 +857,6 @@ pub const Inst = struct { |
| 857 | /// Implements the `@ptrCast` builtin. | 857 | /// Implements the `@ptrCast` builtin. |
| 858 | /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand. | 858 | /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand. |
| 859 | ptr_cast, | 859 | ptr_cast, |
| 860 | /// Implements the `@qualCast` builtin. | ||
| 861 | /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand. | ||
| 862 | qual_cast, | ||
| 863 | /// Implements the `@truncate` builtin. | 860 | /// Implements the `@truncate` builtin. |
| 864 | /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand. | 861 | /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand. |
| 865 | truncate, | 862 | truncate, |
| ... | @@ -1198,7 +1195,6 @@ pub const Inst = struct { | ... | @@ -1198,7 +1195,6 @@ pub const Inst = struct { |
| 1198 | .float_cast, | 1195 | .float_cast, |
| 1199 | .int_cast, | 1196 | .int_cast, |
| 1200 | .ptr_cast, | 1197 | .ptr_cast, |
| 1201 | .qual_cast, | ||
| 1202 | .truncate, | 1198 | .truncate, |
| 1203 | .align_cast, | 1199 | .align_cast, |
| 1204 | .has_field, | 1200 | .has_field, |
| ... | @@ -1488,7 +1484,6 @@ pub const Inst = struct { | ... | @@ -1488,7 +1484,6 @@ pub const Inst = struct { |
| 1488 | .float_cast, | 1484 | .float_cast, |
| 1489 | .int_cast, | 1485 | .int_cast, |
| 1490 | .ptr_cast, | 1486 | .ptr_cast, |
| 1491 | .qual_cast, | ||
| 1492 | .truncate, | 1487 | .truncate, |
| 1493 | .align_cast, | 1488 | .align_cast, |
| 1494 | .has_field, | 1489 | .has_field, |
| ... | @@ -1760,7 +1755,6 @@ pub const Inst = struct { | ... | @@ -1760,7 +1755,6 @@ pub const Inst = struct { |
| 1760 | .float_cast = .pl_node, | 1755 | .float_cast = .pl_node, |
| 1761 | .int_cast = .pl_node, | 1756 | .int_cast = .pl_node, |
| 1762 | .ptr_cast = .pl_node, | 1757 | .ptr_cast = .pl_node, |
| 1763 | .qual_cast = .pl_node, | ||
| 1764 | .truncate = .pl_node, | 1758 | .truncate = .pl_node, |
| 1765 | .align_cast = .pl_node, | 1759 | .align_cast = .pl_node, |
| 1766 | .typeof_builtin = .pl_node, | 1760 | .typeof_builtin = .pl_node, |
| ... | @@ -2004,6 +1998,12 @@ pub const Inst = struct { | ... | @@ -2004,6 +1998,12 @@ pub const Inst = struct { |
| 2004 | /// Implement builtin `@cVaStart`. | 1998 | /// Implement builtin `@cVaStart`. |
| 2005 | /// `operand` is `src_node: i32`. | 1999 | /// `operand` is `src_node: i32`. |
| 2006 | c_va_start, | 2000 | c_va_start, |
| 2001 | /// Implements the `@constCast` builtin. | ||
| 2002 | /// `operand` is payload index to `UnNode`. | ||
| 2003 | const_cast, | ||
| 2004 | /// Implements the `@volatileCast` builtin. | ||
| 2005 | /// `operand` is payload index to `UnNode`. | ||
| 2006 | volatile_cast, | ||
| 2007 | 2007 | ||
| 2008 | pub const InstData = struct { | 2008 | pub const InstData = struct { |
| 2009 | opcode: Extended, | 2009 | opcode: Extended, |
src/print_zir.zig+2-1| ... | @@ -332,7 +332,6 @@ const Writer = struct { | ... | @@ -332,7 +332,6 @@ const Writer = struct { |
| 332 | .float_cast, | 332 | .float_cast, |
| 333 | .int_cast, | 333 | .int_cast, |
| 334 | .ptr_cast, | 334 | .ptr_cast, |
| 335 | .qual_cast, | ||
| 336 | .truncate, | 335 | .truncate, |
| 337 | .align_cast, | 336 | .align_cast, |
| 338 | .div_exact, | 337 | .div_exact, |
| ... | @@ -507,6 +506,8 @@ const Writer = struct { | ... | @@ -507,6 +506,8 @@ const Writer = struct { |
| 507 | .reify, | 506 | .reify, |
| 508 | .c_va_copy, | 507 | .c_va_copy, |
| 509 | .c_va_end, | 508 | .c_va_end, |
| 509 | .const_cast, | ||
| 510 | .volatile_cast, | ||
| 510 | => { | 511 | => { |
| 511 | const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data; | 512 | const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 512 | const src = LazySrcLoc.nodeOffset(inst_data.node); | 513 | const src = LazySrcLoc.nodeOffset(inst_data.node); |
stage1/zig1.wasm| Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ | |||
test/behavior/cast.zig+15| ... | @@ -1553,3 +1553,18 @@ test "peer type resolution forms error union" { | ... | @@ -1553,3 +1553,18 @@ test "peer type resolution forms error union" { |
| 1553 | } else @intCast(u32, foo); | 1553 | } else @intCast(u32, foo); |
| 1554 | try expect(try result == 123); | 1554 | try expect(try result == 123); |
| 1555 | } | 1555 | } |
| 1556 | |||
| 1557 | test "@constCast without a result location" { | ||
| 1558 | const x: i32 = 1234; | ||
| 1559 | const y = @constCast(&x); | ||
| 1560 | try expect(@TypeOf(y) == *i32); | ||
| 1561 | try expect(y.* == 1234); | ||
| 1562 | } | ||
| 1563 | |||
| 1564 | test "@volatileCast without a result location" { | ||
| 1565 | var x: i32 = 1234; | ||
| 1566 | var y: *volatile i32 = &x; | ||
| 1567 | const z = @volatileCast(y); | ||
| 1568 | try expect(@TypeOf(z) == *i32); | ||
| 1569 | try expect(z.* == 1234); | ||
| 1570 | } |
test/cases/compile_errors/invalid_qualcast.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | pub export fn entry() void { | ||
| 2 | var a: [*:0]const volatile u16 = undefined; | ||
| 3 | _ = @qualCast([*]u16, a); | ||
| 4 | } | ||
| 5 | |||
| 6 | // error | ||
| 7 | // backend=stage2 | ||
| 8 | // target=native | ||
| 9 | // | ||
| 10 | // :3:9: error: '@qualCast' can only modify 'const' and 'volatile' qualifiers | ||
| 11 | // :3:9: note: expected type '[*]const volatile u16' | ||
| 12 | // :3:9: note: got type '[*:0]const volatile u16' | ||
test/cases/compile_errors/ptrCast_discards_const_qualifier.zig+1-1| ... | @@ -9,4 +9,4 @@ export fn entry() void { | ... | @@ -9,4 +9,4 @@ export fn entry() void { |
| 9 | // target=native | 9 | // target=native |
| 10 | // | 10 | // |
| 11 | // :3:15: error: cast discards const qualifier | 11 | // :3:15: error: cast discards const qualifier |
| 12 | // :3:15: note: consider using '@qualCast' | 12 | // :3:15: note: consider using '@constCast' |