authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-02-01 23:31:52-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-02-01 23:31:52-05:00
log6b7ad22981867cbf6ec40d540f5571f276d6801b
tree4c1665cf0c03fcaa5d6c2a09aa49c49f5b804236
parente712d5f03e6e3ddde6a4a6f7d2d82e786efd543a
parent629c3108aa71f94bd26dba8d4f20c9f3a3945bd4
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #14477 from Vexu/fixes

Improve `@ptrCast` errors, fix some bugs

30 files changed, 280 insertions(+), 36 deletions(-)

doc/langref.html.in+16
...@@ -8809,6 +8809,15 @@ pub const PrefetchOptions = struct {...@@ -8809,6 +8809,15 @@ pub const PrefetchOptions = struct {
8809 {#link|Optional Pointers#} are allowed. Casting an optional pointer which is {#link|null#}8809 {#link|Optional Pointers#} are allowed. Casting an optional pointer which is {#link|null#}
8810 to a non-optional pointer invokes safety-checked {#link|Undefined Behavior#}.8810 to a non-optional pointer invokes safety-checked {#link|Undefined Behavior#}.
8811 </p>8811 </p>
8812 <p>
8813 {#syntax#}@ptrCast{#endsyntax#} cannot be used for:
8814 </p>
8815 <ul>
8816 <li>Removing {#syntax#}const{#endsyntax#} or {#syntax#}volatile{#endsyntax#} qualifier, use {#link|@qualCast#}.</li>
8817 <li>Changing pointer address space, use {#link|@addrSpaceCast#}.</li>
8818 <li>Increasing pointer alignment, use {#link|@alignCast#}.</li>
8819 <li>Casting a non-slice pointer to a slice, use slicing syntax {#syntax#}ptr[start..end]{#endsyntax#}.</li>
8820 </ul>
8812 {#header_close#}8821 {#header_close#}
88138822
8814 {#header_open|@ptrToInt#}8823 {#header_open|@ptrToInt#}
...@@ -8821,6 +8830,13 @@ pub const PrefetchOptions = struct {...@@ -8821,6 +8830,13 @@ pub const PrefetchOptions = struct {
88218830
8822 {#header_close#}8831 {#header_close#}
88238832
8833 {#header_open|@qualCast#}
8834 <pre>{#syntax#}@qualCast(comptime DestType: type, value: anytype) DestType{#endsyntax#}</pre>
8835 <p>
8836 Remove {#syntax#}const{#endsyntax#} or {#syntax#}volatile{#endsyntax#} qualifier from a pointer.
8837 </p>
8838 {#header_close#}
8839
8824 {#header_open|@rem#}8840 {#header_open|@rem#}
8825 <pre>{#syntax#}@rem(numerator: T, denominator: T) T{#endsyntax#}</pre>8841 <pre>{#syntax#}@rem(numerator: T, denominator: T) T{#endsyntax#}</pre>
8826 <p>8842 <p>
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 = @intToPtr([*]u16, @ptrToInt(app_name_wildcard.ptr)),1167 .Buffer = @qualCast([*:0]u16, 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 = @intToPtr([*]u16, @ptrToInt(app_name_appended.ptr)),1264 .Buffer = @qualCast([*:0]u16, app_name_appended.ptr),
1265 };1265 };
12661266
1267 // Re-use the directory handle but this time we call with the appended app name1267 // 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 = @intToPtr([*]u16, @ptrToInt(sub_path_w)),1766 .Buffer = @qualCast([*:0]u16, 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/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 = @intToPtr([*]u16, @ptrToInt(sub_path_w)),4516 .Buffer = @qualCast([*:0]u16, 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 = @intToPtr([*]u16, @ptrToInt(sub_path_w.ptr)),88 .Buffer = @qualCast([*]u16, 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 = @intToPtr([*]u16, @ptrToInt(path_name.ptr)),637 .Buffer = @qualCast([*]u16, path_name.ptr),
638 };638 };
639639
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 = @intToPtr([*]u16, @ptrToInt(sub_path_w.ptr)),769 .Buffer = @qualCast([*]u16, 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 = @intToPtr([*]u16, @ptrToInt(sub_path_w.ptr)),879 .Buffer = @qualCast([*]u16, sub_path_w.ptr),
880 };880 };
881881
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}
14151415
1416pub 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 {1416pub 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 = @intToPtr([*]u8, @ptrToInt(buf)) };1417 var buffer = ws2_32.WSABUF{ .len = @truncate(u31, len), .buf = @qualCast([*]u8, 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 = @intToPtr([*]u16, @ptrToInt(a.ptr)),1879 .Buffer = @qualCast([*]u16, 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 = @intToPtr([*]u16, @ptrToInt(b.ptr)),1885 .Buffer = @qualCast([*]u16, 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+1-1
...@@ -75,7 +75,7 @@ fn castPtr(comptime DestType: type, target: anytype) DestType {...@@ -75,7 +75,7 @@ fn castPtr(comptime DestType: type, target: anytype) DestType {
75 const source = ptrInfo(@TypeOf(target));75 const source = ptrInfo(@TypeOf(target));
7676
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 or source.is_volatile and !dest.is_volatile)
78 return @intToPtr(DestType, @ptrToInt(target))78 return @qualCast(DestType, target)
79 else if (@typeInfo(dest.child) == .Opaque)79 else if (@typeInfo(dest.child) == .Opaque)
80 // dest.alignment would error out80 // dest.alignment would error out
81 return @ptrCast(DestType, target)81 return @ptrCast(DestType, target)
src/AstGen.zig+37-2
...@@ -2530,6 +2530,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As...@@ -2530,6 +2530,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
2530 .bit_size_of,2530 .bit_size_of,
2531 .typeof_log2_int_type,2531 .typeof_log2_int_type,
2532 .ptr_to_int,2532 .ptr_to_int,
2533 .qual_cast,
2533 .align_of,2534 .align_of,
2534 .bool_to_int,2535 .bool_to_int,
2535 .embed_file,2536 .embed_file,
...@@ -4278,7 +4279,34 @@ fn testDecl(...@@ -4278,7 +4279,34 @@ fn testDecl(
4278 var num_namespaces_out: u32 = 0;4279 var num_namespaces_out: u32 = 0;
4279 var capturing_namespace: ?*Scope.Namespace = null;4280 var capturing_namespace: ?*Scope.Namespace = null;
4280 while (true) switch (s.tag) {4281 while (true) switch (s.tag) {
4281 .local_val, .local_ptr => unreachable, // a test cannot be in a local scope4282 .local_val => {
4283 const local_val = s.cast(Scope.LocalVal).?;
4284 if (local_val.name == name_str_index) {
4285 local_val.used = test_name_token;
4286 return astgen.failTokNotes(test_name_token, "cannot test a {s}", .{
4287 @tagName(local_val.id_cat),
4288 }, &[_]u32{
4289 try astgen.errNoteTok(local_val.token_src, "{s} declared here", .{
4290 @tagName(local_val.id_cat),
4291 }),
4292 });
4293 }
4294 s = local_val.parent;
4295 },
4296 .local_ptr => {
4297 const local_ptr = s.cast(Scope.LocalPtr).?;
4298 if (local_ptr.name == name_str_index) {
4299 local_ptr.used = test_name_token;
4300 return astgen.failTokNotes(test_name_token, "cannot test a {s}", .{
4301 @tagName(local_ptr.id_cat),
4302 }, &[_]u32{
4303 try astgen.errNoteTok(local_ptr.token_src, "{s} declared here", .{
4304 @tagName(local_ptr.id_cat),
4305 }),
4306 });
4307 }
4308 s = local_ptr.parent;
4309 },
4282 .gen_zir => s = s.cast(GenZir).?.parent,4310 .gen_zir => s = s.cast(GenZir).?.parent,
4283 .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,4311 .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
4284 .namespace, .enum_namespace => {4312 .namespace, .enum_namespace => {
...@@ -8010,6 +8038,7 @@ fn builtinCall(...@@ -8010,6 +8038,7 @@ fn builtinCall(
8010 .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),
8011 .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),
8012 .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),
8041 .qual_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .qual_cast),
8013 .truncate => return typeCast(gz, scope, ri, node, params[0], params[1], .truncate),8042 .truncate => return typeCast(gz, scope, ri, node, params[0], params[1], .truncate),
8014 // zig fmt: on8043 // zig fmt: on
80158044
...@@ -8692,6 +8721,7 @@ fn callExpr(...@@ -8692,6 +8721,7 @@ fn callExpr(
8692 defer arg_block.unstack();8721 defer arg_block.unstack();
86938722
8694 // `call_inst` is reused to provide the param type.8723 // `call_inst` is reused to provide the param type.
8724 arg_block.rl_ty_inst = call_inst;
8695 const arg_ref = try expr(&arg_block, &arg_block.base, .{ .rl = .{ .coerced_ty = call_inst }, .ctx = .fn_arg }, param_node);8725 const arg_ref = try expr(&arg_block, &arg_block.base, .{ .rl = .{ .coerced_ty = call_inst }, .ctx = .fn_arg }, param_node);
8696 _ = try arg_block.addBreak(.break_inline, call_index, arg_ref);8726 _ = try arg_block.addBreak(.break_inline, call_index, arg_ref);
86978727
...@@ -10840,7 +10870,12 @@ const GenZir = struct {...@@ -10840,7 +10870,12 @@ const GenZir = struct {
10840 // we emit ZIR for the block break instructions to have the result values,10870 // we emit ZIR for the block break instructions to have the result values,
10841 // and then rvalue() on that to pass the value to the result location.10871 // and then rvalue() on that to pass the value to the result location.
10842 switch (parent_ri.rl) {10872 switch (parent_ri.rl) {
10843 .ty, .coerced_ty => |ty_inst| {10873 .coerced_ty => |ty_inst| {
10874 // Type coercion needs to happend before breaks.
10875 gz.rl_ty_inst = ty_inst;
10876 gz.break_result_info = .{ .rl = .{ .ty = ty_inst } };
10877 },
10878 .ty => |ty_inst| {
10844 gz.rl_ty_inst = ty_inst;10879 gz.rl_ty_inst = ty_inst;
10845 gz.break_result_info = parent_ri;10880 gz.break_result_info = parent_ri;
10846 },10881 },
src/BuiltinFn.zig+8
...@@ -75,6 +75,7 @@ pub const Tag = enum {...@@ -75,6 +75,7 @@ pub const Tag = enum {
75 prefetch,75 prefetch,
76 ptr_cast,76 ptr_cast,
77 ptr_to_int,77 ptr_to_int,
78 qual_cast,
78 rem,79 rem,
79 return_address,80 return_address,
80 select,81 select,
...@@ -674,6 +675,13 @@ pub const list = list: {...@@ -674,6 +675,13 @@ pub const list = list: {
674 .param_count = 1,675 .param_count = 1,
675 },676 },
676 },677 },
678 .{
679 "@qualCast",
680 .{
681 .tag = .qual_cast,
682 .param_count = 2,
683 },
684 },
677 .{685 .{
678 "@rem",686 "@rem",
679 .{687 .{
src/Sema.zig+92-9
...@@ -1015,6 +1015,7 @@ fn analyzeBodyInner(...@@ -1015,6 +1015,7 @@ 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),
1018 .truncate => try sema.zirTruncate(block, inst),1019 .truncate => try sema.zirTruncate(block, inst),
1019 .align_cast => try sema.zirAlignCast(block, inst),1020 .align_cast => try sema.zirAlignCast(block, inst),
1020 .has_decl => try sema.zirHasDecl(block, inst),1021 .has_decl => try sema.zirHasDecl(block, inst),
...@@ -3294,7 +3295,7 @@ fn ensureResultUsed(...@@ -3294,7 +3295,7 @@ fn ensureResultUsed(
3294 const msg = msg: {3295 const msg = msg: {
3295 const msg = try sema.errMsg(block, src, "error is ignored", .{});3296 const msg = try sema.errMsg(block, src, "error is ignored", .{});
3296 errdefer msg.destroy(sema.gpa);3297 errdefer msg.destroy(sema.gpa);
3297 try sema.errNote(block, src, msg, "consider using `try`, `catch`, or `if`", .{});3298 try sema.errNote(block, src, msg, "consider using 'try', 'catch', or 'if'", .{});
3298 break :msg msg;3299 break :msg msg;
3299 };3300 };
3300 return sema.failWithOwnedErrorMsg(msg);3301 return sema.failWithOwnedErrorMsg(msg);
...@@ -3325,7 +3326,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -3325,7 +3326,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
3325 const msg = msg: {3326 const msg = msg: {
3326 const msg = try sema.errMsg(block, src, "error is discarded", .{});3327 const msg = try sema.errMsg(block, src, "error is discarded", .{});
3327 errdefer msg.destroy(sema.gpa);3328 errdefer msg.destroy(sema.gpa);
3328 try sema.errNote(block, src, msg, "consider using `try`, `catch`, or `if`", .{});3329 try sema.errNote(block, src, msg, "consider using 'try', 'catch', or 'if'", .{});
3329 break :msg msg;3330 break :msg msg;
3330 };3331 };
3331 return sema.failWithOwnedErrorMsg(msg);3332 return sema.failWithOwnedErrorMsg(msg);
...@@ -6874,6 +6875,8 @@ fn analyzeInlineCallArg(...@@ -6874,6 +6875,8 @@ fn analyzeInlineCallArg(
6874 if (err == error.AnalysisFail and param_block.comptime_reason != null) try param_block.comptime_reason.?.explain(sema, sema.err);6875 if (err == error.AnalysisFail and param_block.comptime_reason != null) try param_block.comptime_reason.?.explain(sema, sema.err);
6875 return err;6876 return err;
6876 };6877 };
6878 } else if (!is_comptime_call and zir_tags[inst] == .param_comptime) {
6879 _ = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "parameter is comptime");
6877 }6880 }
6878 const casted_arg = sema.coerceExtra(arg_block, param_ty, uncasted_arg, arg_src, .{ .param_src = .{6881 const casted_arg = sema.coerceExtra(arg_block, param_ty, uncasted_arg, arg_src, .{ .param_src = .{
6879 .func_inst = func_inst,6882 .func_inst = func_inst,
...@@ -6947,6 +6950,9 @@ fn analyzeInlineCallArg(...@@ -6947,6 +6950,9 @@ fn analyzeInlineCallArg(
6947 .val = arg_val,6950 .val = arg_val,
6948 };6951 };
6949 } else {6952 } else {
6953 if (zir_tags[inst] == .param_anytype_comptime) {
6954 _ = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "parameter is comptime");
6955 }
6950 sema.inst_map.putAssumeCapacityNoClobber(inst, uncasted_arg);6956 sema.inst_map.putAssumeCapacityNoClobber(inst, uncasted_arg);
6951 }6957 }
69526958
...@@ -8467,7 +8473,7 @@ fn handleExternLibName(...@@ -8467,7 +8473,7 @@ fn handleExternLibName(
8467 return sema.fail(8473 return sema.fail(
8468 block,8474 block,
8469 src_loc,8475 src_loc,
8470 "dependency on dynamic library '{s}' requires enabling Position Independent Code. Fixed by `-l{s}` or `-fPIC`.",8476 "dependency on dynamic library '{s}' requires enabling Position Independent Code. Fixed by '-l{s}' or '-fPIC'.",
8471 .{ lib_name, lib_name },8477 .{ lib_name, lib_name },
8472 );8478 );
8473 }8479 }
...@@ -9004,7 +9010,18 @@ fn zirParam(...@@ -9004,7 +9010,18 @@ fn zirParam(
9004 if (is_comptime and sema.preallocated_new_func != null) {9010 if (is_comptime and sema.preallocated_new_func != null) {
9005 // We have a comptime value for this parameter so it should be elided from the9011 // We have a comptime value for this parameter so it should be elided from the
9006 // function type of the function instruction in this block.9012 // function type of the function instruction in this block.
9007 const coerced_arg = try sema.coerce(block, param_ty, arg, src);9013 const coerced_arg = sema.coerce(block, param_ty, arg, .unneeded) catch |err| switch (err) {
9014 error.NeededSourceLocation => {
9015 // We are instantiating a generic function and a comptime arg
9016 // cannot be coerced to the param type, but since we don't
9017 // have the callee source location return `GenericPoison`
9018 // so that the instantiation is failed and the coercion
9019 // is handled by comptime call logic instead.
9020 assert(sema.is_generic_instantiation);
9021 return error.GenericPoison;
9022 },
9023 else => return err,
9024 };
9008 sema.inst_map.putAssumeCapacity(inst, coerced_arg);9025 sema.inst_map.putAssumeCapacity(inst, coerced_arg);
9009 return;9026 return;
9010 }9027 }
...@@ -19519,13 +19536,34 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19519,13 +19536,34 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19519 const operand_info = operand_ty.ptrInfo().data;19536 const operand_info = operand_ty.ptrInfo().data;
19520 const dest_info = dest_ty.ptrInfo().data;19537 const dest_info = dest_ty.ptrInfo().data;
19521 if (!operand_info.mutable and dest_info.mutable) {19538 if (!operand_info.mutable and dest_info.mutable) {
19522 return sema.fail(block, src, "cast discards const qualifier", .{});19539 const msg = msg: {
19540 const msg = try sema.errMsg(block, src, "cast discards const qualifier", .{});
19541 errdefer msg.destroy(sema.gpa);
19542
19543 try sema.errNote(block, src, msg, "consider using '@qualCast'", .{});
19544 break :msg msg;
19545 };
19546 return sema.failWithOwnedErrorMsg(msg);
19523 }19547 }
19524 if (operand_info.@"volatile" and !dest_info.@"volatile") {19548 if (operand_info.@"volatile" and !dest_info.@"volatile") {
19525 return sema.fail(block, src, "cast discards volatile qualifier", .{});19549 const msg = msg: {
19550 const msg = try sema.errMsg(block, src, "cast discards volatile qualifier", .{});
19551 errdefer msg.destroy(sema.gpa);
19552
19553 try sema.errNote(block, src, msg, "consider using '@qualCast'", .{});
19554 break :msg msg;
19555 };
19556 return sema.failWithOwnedErrorMsg(msg);
19526 }19557 }
19527 if (operand_info.@"addrspace" != dest_info.@"addrspace") {19558 if (operand_info.@"addrspace" != dest_info.@"addrspace") {
19528 return sema.fail(block, src, "cast changes pointer address space", .{});19559 const msg = msg: {
19560 const msg = try sema.errMsg(block, src, "cast changes pointer address space", .{});
19561 errdefer msg.destroy(sema.gpa);
19562
19563 try sema.errNote(block, src, msg, "consider using '@addrSpaceCast'", .{});
19564 break :msg msg;
19565 };
19566 return sema.failWithOwnedErrorMsg(msg);
19529 }19567 }
1953019568
19531 const dest_is_slice = dest_ty.isSlice();19569 const dest_is_slice = dest_ty.isSlice();
...@@ -19580,6 +19618,8 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19580,6 +19618,8 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19580 try sema.errNote(block, dest_ty_src, msg, "'{}' has alignment '{d}'", .{19618 try sema.errNote(block, dest_ty_src, msg, "'{}' has alignment '{d}'", .{
19581 dest_ty.fmt(sema.mod), dest_align,19619 dest_ty.fmt(sema.mod), dest_align,
19582 });19620 });
19621
19622 try sema.errNote(block, src, msg, "consider using '@alignCast'", .{});
19583 break :msg msg;19623 break :msg msg;
19584 };19624 };
19585 return sema.failWithOwnedErrorMsg(msg);19625 return sema.failWithOwnedErrorMsg(msg);
...@@ -19615,6 +19655,49 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19615,6 +19655,49 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19615 return block.addBitCast(aligned_dest_ty, ptr);19655 return block.addBitCast(aligned_dest_ty, ptr);
19616}19656}
1961719657
19658fn zirQualCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
19659 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
19660 const src = inst_data.src();
19661 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
19662 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
19663 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
19664 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
19665 const operand = try sema.resolveInst(extra.rhs);
19666 const operand_ty = sema.typeOf(operand);
19667
19668 try sema.checkPtrType(block, dest_ty_src, dest_ty);
19669 try sema.checkPtrOperand(block, operand_src, operand_ty);
19670
19671 var operand_payload = operand_ty.ptrInfo();
19672 var dest_info = dest_ty.ptrInfo();
19673
19674 operand_payload.data.mutable = dest_info.data.mutable;
19675 operand_payload.data.@"volatile" = dest_info.data.@"volatile";
19676
19677 const altered_operand_ty = Type.initPayload(&operand_payload.base);
19678 if (!altered_operand_ty.eql(dest_ty, sema.mod)) {
19679 const msg = msg: {
19680 const msg = try sema.errMsg(block, src, "'@qualCast' can only modify 'const' and 'volatile' qualifiers", .{});
19681 errdefer msg.destroy(sema.gpa);
19682
19683 dest_info.data.mutable = !operand_ty.isConstPtr();
19684 dest_info.data.@"volatile" = operand_ty.isVolatilePtr();
19685 const altered_dest_ty = Type.initPayload(&dest_info.base);
19686 try sema.errNote(block, src, msg, "expected type '{}'", .{altered_dest_ty.fmt(sema.mod)});
19687 try sema.errNote(block, src, msg, "got type '{}'", .{operand_ty.fmt(sema.mod)});
19688 break :msg msg;
19689 };
19690 return sema.failWithOwnedErrorMsg(msg);
19691 }
19692
19693 if (try sema.resolveMaybeUndefVal(operand)) |operand_val| {
19694 return sema.addConstant(dest_ty, operand_val);
19695 }
19696
19697 try sema.requireRuntimeBlock(block, src, null);
19698 return block.addBitCast(dest_ty, operand);
19699}
19700
19618fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {19701fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
19619 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;19702 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
19620 const src = inst_data.src();19703 const src = inst_data.src();
...@@ -25131,7 +25214,7 @@ fn coerceExtra(...@@ -25131,7 +25214,7 @@ fn coerceExtra(
25131 (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)25214 (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)
25132 {25215 {
25133 try sema.errNote(block, inst_src, msg, "cannot convert error union to payload type", .{});25216 try sema.errNote(block, inst_src, msg, "cannot convert error union to payload type", .{});
25134 try sema.errNote(block, inst_src, msg, "consider using `try`, `catch`, or `if`", .{});25217 try sema.errNote(block, inst_src, msg, "consider using 'try', 'catch', or 'if'", .{});
25135 }25218 }
2513625219
25137 // ?T to T25220 // ?T to T
...@@ -25140,7 +25223,7 @@ fn coerceExtra(...@@ -25140,7 +25223,7 @@ fn coerceExtra(
25140 (try sema.coerceInMemoryAllowed(block, inst_ty.optionalChild(&buf), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)25223 (try sema.coerceInMemoryAllowed(block, inst_ty.optionalChild(&buf), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)
25141 {25224 {
25142 try sema.errNote(block, inst_src, msg, "cannot convert optional to payload type", .{});25225 try sema.errNote(block, inst_src, msg, "cannot convert optional to payload type", .{});
25143 try sema.errNote(block, inst_src, msg, "consider using `.?`, `orelse`, or `if`", .{});25226 try sema.errNote(block, inst_src, msg, "consider using '.?', 'orelse', or 'if'", .{});
25144 }25227 }
2514525228
25146 try in_memory_result.report(sema, block, inst_src, msg);25229 try in_memory_result.report(sema, block, inst_src, msg);
src/TypedValue.zig+4-1
...@@ -176,7 +176,9 @@ pub fn print(...@@ -176,7 +176,9 @@ pub fn print(
176176
177 var i: u32 = 0;177 var i: u32 = 0;
178 while (i < max_len) : (i += 1) {178 while (i < max_len) : (i += 1) {
179 buf[i] = std.math.cast(u8, val.fieldValue(ty, i).toUnsignedInt(target)) orelse break :str;179 const elem = val.fieldValue(ty, i);
180 if (elem.isUndef()) break :str;
181 buf[i] = std.math.cast(u8, elem.toUnsignedInt(target)) orelse break :str;
180 }182 }
181183
182 const truncated = if (len > max_string_len) " (truncated)" else "";184 const truncated = if (len > max_string_len) " (truncated)" else "";
...@@ -390,6 +392,7 @@ pub fn print(...@@ -390,6 +392,7 @@ pub fn print(
390 while (i < max_len) : (i += 1) {392 while (i < max_len) : (i += 1) {
391 var elem_buf: Value.ElemValueBuffer = undefined;393 var elem_buf: Value.ElemValueBuffer = undefined;
392 const elem_val = payload.ptr.elemValueBuffer(mod, i, &elem_buf);394 const elem_val = payload.ptr.elemValueBuffer(mod, i, &elem_buf);
395 if (elem_val.isUndef()) break :str;
393 buf[i] = std.math.cast(u8, elem_val.toUnsignedInt(target)) orelse break :str;396 buf[i] = std.math.cast(u8, elem_val.toUnsignedInt(target)) orelse break :str;
394 }397 }
395398
src/Zir.zig+6
...@@ -857,6 +857,9 @@ pub const Inst = struct {...@@ -857,6 +857,9 @@ 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,
860 /// Implements the `@truncate` builtin.863 /// Implements the `@truncate` builtin.
861 /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.864 /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
862 truncate,865 truncate,
...@@ -1195,6 +1198,7 @@ pub const Inst = struct {...@@ -1195,6 +1198,7 @@ pub const Inst = struct {
1195 .float_cast,1198 .float_cast,
1196 .int_cast,1199 .int_cast,
1197 .ptr_cast,1200 .ptr_cast,
1201 .qual_cast,
1198 .truncate,1202 .truncate,
1199 .align_cast,1203 .align_cast,
1200 .has_field,1204 .has_field,
...@@ -1484,6 +1488,7 @@ pub const Inst = struct {...@@ -1484,6 +1488,7 @@ pub const Inst = struct {
1484 .float_cast,1488 .float_cast,
1485 .int_cast,1489 .int_cast,
1486 .ptr_cast,1490 .ptr_cast,
1491 .qual_cast,
1487 .truncate,1492 .truncate,
1488 .align_cast,1493 .align_cast,
1489 .has_field,1494 .has_field,
...@@ -1755,6 +1760,7 @@ pub const Inst = struct {...@@ -1755,6 +1760,7 @@ pub const Inst = struct {
1755 .float_cast = .pl_node,1760 .float_cast = .pl_node,
1756 .int_cast = .pl_node,1761 .int_cast = .pl_node,
1757 .ptr_cast = .pl_node,1762 .ptr_cast = .pl_node,
1763 .qual_cast = .pl_node,
1758 .truncate = .pl_node,1764 .truncate = .pl_node,
1759 .align_cast = .pl_node,1765 .align_cast = .pl_node,
1760 .typeof_builtin = .pl_node,1766 .typeof_builtin = .pl_node,
src/print_zir.zig+1
...@@ -332,6 +332,7 @@ const Writer = struct {...@@ -332,6 +332,7 @@ const Writer = struct {
332 .float_cast,332 .float_cast,
333 .int_cast,333 .int_cast,
334 .ptr_cast,334 .ptr_cast,
335 .qual_cast,
335 .truncate,336 .truncate,
336 .align_cast,337 .align_cast,
337 .div_exact,338 .div_exact,
stage1/zig1.wasm
Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ
test/behavior/basic.zig+18
...@@ -1125,3 +1125,21 @@ test "returning an opaque type from a function" {...@@ -1125,3 +1125,21 @@ test "returning an opaque type from a function" {
1125 };1125 };
1126 try expect(S.foo(123).b == 123);1126 try expect(S.foo(123).b == 123);
1127}1127}
1128
1129test "orelse coercion as function argument" {
1130 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1131 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1132
1133 const Loc = struct { start: i32 = -1 };
1134 const Container = struct {
1135 a: ?Loc = null,
1136 fn init(a: Loc) @This() {
1137 return .{
1138 .a = a,
1139 };
1140 }
1141 };
1142 var optional: ?Loc = .{};
1143 var foo = Container.init(optional orelse .{});
1144 try expect(foo.a.?.start == -1);
1145}
test/behavior/sizeof_and_typeof.zig+9
...@@ -292,3 +292,12 @@ test "@sizeOf optional of previously unresolved union" {...@@ -292,3 +292,12 @@ test "@sizeOf optional of previously unresolved union" {
292 const Node = union { a: usize };292 const Node = union { a: usize };
293 try expect(@sizeOf(?Node) == @sizeOf(Node) + @alignOf(Node));293 try expect(@sizeOf(?Node) == @sizeOf(Node) + @alignOf(Node));
294}294}
295
296test "@offsetOf zero-bit field" {
297 const S = packed struct {
298 a: u32,
299 b: u0,
300 c: u32,
301 };
302 try expect(@offsetOf(S, "b") == @offsetOf(S, "c"));
303}
test/cases/compile_errors/assigning_to_struct_or_union_fields_that_are_not_optionals_with_a_function_that_returns_an_optional.zig+1-1
...@@ -20,4 +20,4 @@ export fn entry() void {...@@ -20,4 +20,4 @@ export fn entry() void {
20//20//
21// :11:27: error: expected type 'u8', found '?u8'21// :11:27: error: expected type 'u8', found '?u8'
22// :11:27: note: cannot convert optional to payload type22// :11:27: note: cannot convert optional to payload type
23// :11:27: note: consider using `.?`, `orelse`, or `if`23// :11:27: note: consider using '.?', 'orelse', or 'if'
test/cases/compile_errors/comptime_arg_to_generic_fn_callee_error.zig created+21
...@@ -0,0 +1,21 @@
1const std = @import("std");
2const MyStruct = struct {
3 a: i32,
4 b: i32,
5
6 pub fn getA(self: *List) i32 {
7 return self.items(.c);
8 }
9};
10const List = std.MultiArrayList(MyStruct);
11pub export fn entry() void {
12 var list = List{};
13 _ = MyStruct.getA(&list);
14}
15
16// error
17// backend=stage2
18// target=native
19//
20// :7:28: error: no field named 'c' in enum 'meta.FieldEnum(tmp.MyStruct)'
21// :?:?: note: enum declared here
test/cases/compile_errors/discarding_error_value.zig+1-1
...@@ -10,4 +10,4 @@ fn foo() !void {...@@ -10,4 +10,4 @@ fn foo() !void {
10// target=native10// target=native
11//11//
12// :2:12: error: error is discarded12// :2:12: error: error is discarded
13// :2:12: note: consider using `try`, `catch`, or `if`13// :2:12: note: consider using 'try', 'catch', or 'if'
test/cases/compile_errors/helpful_return_type_error_message.zig+2-2
...@@ -26,7 +26,7 @@ export fn quux() u32 {...@@ -26,7 +26,7 @@ export fn quux() u32 {
26// :11:15: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(tmp.bar)).Fn.return_type.?).ErrorUnion.error_set!u32'26// :11:15: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(tmp.bar)).Fn.return_type.?).ErrorUnion.error_set!u32'
27// :10:17: note: function cannot return an error27// :10:17: note: function cannot return an error
28// :11:15: note: cannot convert error union to payload type28// :11:15: note: cannot convert error union to payload type
29// :11:15: note: consider using `try`, `catch`, or `if`29// :11:15: note: consider using 'try', 'catch', or 'if'
30// :15:14: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(tmp.bar)).Fn.return_type.?).ErrorUnion.error_set!u32'30// :15:14: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(tmp.bar)).Fn.return_type.?).ErrorUnion.error_set!u32'
31// :15:14: note: cannot convert error union to payload type31// :15:14: note: cannot convert error union to payload type
32// :15:14: note: consider using `try`, `catch`, or `if`32// :15:14: note: consider using 'try', 'catch', or 'if'
test/cases/compile_errors/ignored_deferred_function_call.zig+1-1
...@@ -8,4 +8,4 @@ fn bar() anyerror!i32 { return 0; }...@@ -8,4 +8,4 @@ fn bar() anyerror!i32 { return 0; }
8// target=native8// target=native
9//9//
10// :2:14: error: error is ignored10// :2:14: error: error is ignored
11// :2:14: note: consider using `try`, `catch`, or `if`11// :2:14: note: consider using 'try', 'catch', or 'if'
test/cases/compile_errors/ignored_expression_in_while_continuation.zig+3-3
...@@ -18,8 +18,8 @@ fn bad() anyerror!void {...@@ -18,8 +18,8 @@ fn bad() anyerror!void {
18// target=native18// target=native
19//19//
20// :2:24: error: error is ignored20// :2:24: error: error is ignored
21// :2:24: note: consider using `try`, `catch`, or `if`21// :2:24: note: consider using 'try', 'catch', or 'if'
22// :6:25: error: error is ignored22// :6:25: error: error is ignored
23// :6:25: note: consider using `try`, `catch`, or `if`23// :6:25: note: consider using 'try', 'catch', or 'if'
24// :10:25: error: error is ignored24// :10:25: error: error is ignored
25// :10:25: note: consider using `try`, `catch`, or `if`25// :10:25: note: consider using 'try', 'catch', or 'if'
test/cases/compile_errors/increase_pointer_alignment_in_ptrCast.zig+1
...@@ -11,3 +11,4 @@ export fn entry() u32 {...@@ -11,3 +11,4 @@ export fn entry() u32 {
11// :3:17: error: cast increases pointer alignment11// :3:17: error: cast increases pointer alignment
12// :3:32: note: '*u8' has alignment '1'12// :3:32: note: '*u8' has alignment '1'
13// :3:26: note: '*u32' has alignment '4'13// :3:26: note: '*u32' has alignment '4'
14// :3:17: note: consider using '@alignCast'
test/cases/compile_errors/inline_call_runtime_value_to_comptime_param.zig created+17
...@@ -0,0 +1,17 @@
1inline fn needComptime(comptime a: u64) void {
2 if (a != 0) @compileError("foo");
3}
4fn acceptRuntime(value: u64) void {
5 needComptime(value);
6}
7pub export fn entry() void {
8 var value: u64 = 0;
9 acceptRuntime(value);
10}
11
12// error
13// backend=stage2
14// target=native
15//
16// :5:18: error: unable to resolve comptime value
17// :5:18: note: parameter is comptime
test/cases/compile_errors/invalid_decltest.zig created+13
...@@ -0,0 +1,13 @@
1export fn foo() void {
2 const a = 1;
3 struct {
4 test a {}
5 };
6}
7
8// error
9// backend=stage2
10// target=native
11//
12// :4:14: error: cannot test a local constant
13// :2:11: note: local constant declared here
test/cases/compile_errors/invalid_qualcast.zig created+12
...@@ -0,0 +1,12 @@
1pub 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/issue_5618_coercion_of_optional_anyopaque_to_anyopaque_must_fail.zig+1-1
...@@ -10,5 +10,5 @@ export fn foo() void {...@@ -10,5 +10,5 @@ export fn foo() void {
10//10//
11// :4:9: error: expected type '*anyopaque', found '?*anyopaque'11// :4:9: error: expected type '*anyopaque', found '?*anyopaque'
12// :4:9: note: cannot convert optional to payload type12// :4:9: note: cannot convert optional to payload type
13// :4:9: note: consider using `.?`, `orelse`, or `if`13// :4:9: note: consider using '.?', 'orelse', or 'if'
14// :4:9: note: '?*anyopaque' could have null values which are illegal in type '*anyopaque'14// :4:9: note: '?*anyopaque' could have null values which are illegal in type '*anyopaque'
test/cases/compile_errors/ptrCast_discards_const_qualifier.zig+1
...@@ -9,3 +9,4 @@ export fn entry() void {...@@ -9,3 +9,4 @@ export fn entry() void {
9// target=native9// target=native
10//10//
11// :3:15: error: cast discards const qualifier11// :3:15: error: cast discards const qualifier
12// :3:15: note: consider using '@qualCast'
test/cases/compile_errors/regression_test_2980_base_type_u32_is_not_type_checked_properly_when_assigning_a_value_within_a_struct.zig+1-1
...@@ -20,4 +20,4 @@ export fn entry() void {...@@ -20,4 +20,4 @@ export fn entry() void {
20//20//
21// :12:25: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(tmp.get_uval)).Fn.return_type.?).ErrorUnion.error_set!u32'21// :12:25: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(tmp.get_uval)).Fn.return_type.?).ErrorUnion.error_set!u32'
22// :12:25: note: cannot convert error union to payload type22// :12:25: note: cannot convert error union to payload type
23// :12:25: note: consider using `try`, `catch`, or `if`23// :12:25: note: consider using 'try', 'catch', or 'if'
test/cases/compile_errors/result_location_incompatibility_mismatching_handle_is_ptr.zig+1-1
...@@ -17,4 +17,4 @@ pub const Container = struct {...@@ -17,4 +17,4 @@ pub const Container = struct {
17//17//
18// :3:36: error: expected type 'i32', found '?i32'18// :3:36: error: expected type 'i32', found '?i32'
19// :3:36: note: cannot convert optional to payload type19// :3:36: note: cannot convert optional to payload type
20// :3:36: note: consider using `.?`, `orelse`, or `if`20// :3:36: note: consider using '.?', 'orelse', or 'if'
test/cases/compile_errors/result_location_incompatibility_mismatching_handle_is_ptr_generic_call.zig+1-1
...@@ -17,4 +17,4 @@ pub const Container = struct {...@@ -17,4 +17,4 @@ pub const Container = struct {
17//17//
18// :3:36: error: expected type 'i32', found '?i32'18// :3:36: error: expected type 'i32', found '?i32'
19// :3:36: note: cannot convert optional to payload type19// :3:36: note: cannot convert optional to payload type
20// :3:36: note: consider using `.?`, `orelse`, or `if`20// :3:36: note: consider using '.?', 'orelse', or 'if'