authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-05-13 12:52:16+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-05-13 12:52:16+03:00
log68bacad8047df050c8ab6bf52c2921f482647d57
tree9b428c397ee0173b670dfbe34f4c9330dc257bb7
parent6f418c11e1ad1150fbdb002cfe1be92bda4e93cb
parent5aa9628de3c6637f45b9d8cf8cbd19c422a74f6f
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #15643 from Vexu/fixes

make `@call` compile errors match regular calls

11 files changed, 230 insertions(+), 132 deletions(-)

lib/std/os/linux/x86.zig+1-1
...@@ -108,7 +108,7 @@ pub fn syscall6(...@@ -108,7 +108,7 @@ pub fn syscall6(
108 );108 );
109}109}
110110
111pub fn socketcall(call: usize, args: [*]usize) usize {111pub fn socketcall(call: usize, args: [*]const usize) usize {
112 return asm volatile ("int $0x80"112 return asm volatile ("int $0x80"
113 : [ret] "={eax}" (-> usize),113 : [ret] "={eax}" (-> usize),
114 : [number] "{eax}" (@enumToInt(SYS.socketcall)),114 : [number] "{eax}" (@enumToInt(SYS.socketcall)),
src/Module.zig+1-1
...@@ -6098,7 +6098,7 @@ pub const PeerTypeCandidateSrc = union(enum) {...@@ -6098,7 +6098,7 @@ pub const PeerTypeCandidateSrc = union(enum) {
6098 none: void,6098 none: void,
6099 /// When we want to know the the src of candidate i, look up at6099 /// When we want to know the the src of candidate i, look up at
6100 /// index i in this slice6100 /// index i in this slice
6101 override: []?LazySrcLoc,6101 override: []const ?LazySrcLoc,
6102 /// resolvePeerTypes originates from a @TypeOf(...) call6102 /// resolvePeerTypes originates from a @TypeOf(...) call
6103 typeof_builtin_call_node_offset: i32,6103 typeof_builtin_call_node_offset: i32,
61046104
src/Sema.zig+160-111
...@@ -252,7 +252,6 @@ pub const Block = struct {...@@ -252,7 +252,6 @@ pub const Block = struct {
252 // TODO is_comptime and comptime_reason should probably be merged together.252 // TODO is_comptime and comptime_reason should probably be merged together.
253 is_comptime: bool,253 is_comptime: bool,
254 is_typeof: bool = false,254 is_typeof: bool = false,
255 is_coerce_result_ptr: bool = false,
256255
257 /// Keep track of the active error return trace index around blocks so that we can correctly256 /// Keep track of the active error return trace index around blocks so that we can correctly
258 /// pop the error trace upon block exit.257 /// pop the error trace upon block exit.
...@@ -2470,7 +2469,6 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -2470,7 +2469,6 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
2470 // kind of transformations to make on the result pointer.2469 // kind of transformations to make on the result pointer.
2471 var trash_block = block.makeSubBlock();2470 var trash_block = block.makeSubBlock();
2472 trash_block.is_comptime = false;2471 trash_block.is_comptime = false;
2473 trash_block.is_coerce_result_ptr = true;
2474 defer trash_block.instructions.deinit(sema.gpa);2472 defer trash_block.instructions.deinit(sema.gpa);
24752473
2476 const dummy_ptr = try trash_block.addTy(.alloc, sema.typeOf(ptr));2474 const dummy_ptr = try trash_block.addTy(.alloc, sema.typeOf(ptr));
...@@ -2580,6 +2578,9 @@ fn coerceResultPtr(...@@ -2580,6 +2578,9 @@ fn coerceResultPtr(
2580 .array_to_slice => {2578 .array_to_slice => {
2581 return sema.fail(block, src, "TODO coerce_result_ptr array_to_slice", .{});2579 return sema.fail(block, src, "TODO coerce_result_ptr array_to_slice", .{});
2582 },2580 },
2581 .get_union_tag => {
2582 return sema.fail(block, src, "TODO coerce_result_ptr get_union_tag", .{});
2583 },
2583 else => {2584 else => {
2584 if (std.debug.runtime_safety) {2585 if (std.debug.runtime_safety) {
2585 std.debug.panic("unexpected AIR tag for coerce_result_ptr: {}", .{2586 std.debug.panic("unexpected AIR tag for coerce_result_ptr: {}", .{
...@@ -2730,9 +2731,13 @@ fn createAnonymousDeclTypeNamed(...@@ -2730,9 +2731,13 @@ fn createAnonymousDeclTypeNamed(
2730 for (fn_info.param_body) |zir_inst| switch (zir_tags[zir_inst]) {2731 for (fn_info.param_body) |zir_inst| switch (zir_tags[zir_inst]) {
2731 .param, .param_comptime, .param_anytype, .param_anytype_comptime => {2732 .param, .param_comptime, .param_anytype, .param_anytype_comptime => {
2732 const arg = sema.inst_map.get(zir_inst).?;2733 const arg = sema.inst_map.get(zir_inst).?;
2733 // The comptime call code in analyzeCall already did this, so we're2734 // If this is being called in a generic function then analyzeCall will
2734 // just repeating it here and it's guaranteed to work.2735 // have already resolved the args and this will work.
2735 const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg, "") catch unreachable;2736 // If not then this is a struct type being returned from a non-generic
2737 // function and the name doesn't matter since it will later
2738 // result in a compile error.
2739 const arg_val = sema.resolveConstMaybeUndefVal(block, .unneeded, arg, "") catch
2740 return sema.createAnonymousDeclTypeNamed(block, src, typed_value, .anon, anon_prefix, null);
27362741
2737 if (arg_i != 0) try buf.appendSlice(",");2742 if (arg_i != 0) try buf.appendSlice(",");
2738 try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)});2743 try buf.writer().print("{}", .{arg_val.fmtValue(sema.typeOf(arg), sema.mod)});
...@@ -3564,6 +3569,13 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -3564,6 +3569,13 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
3564 ));3569 ));
3565 }3570 }
35663571
3572 return sema.makePtrConst(block, alloc);
3573}
3574
3575fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Air.Inst.Ref {
3576 const alloc_ty = sema.typeOf(alloc);
3577
3578 var ptr_info = alloc_ty.ptrInfo().data;
3567 ptr_info.mutable = false;3579 ptr_info.mutable = false;
3568 const const_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);3580 const const_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);
35693581
...@@ -3832,7 +3844,6 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -3832,7 +3844,6 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
38323844
3833 var trash_block = block.makeSubBlock();3845 var trash_block = block.makeSubBlock();
3834 trash_block.is_comptime = false;3846 trash_block.is_comptime = false;
3835 trash_block.is_coerce_result_ptr = true;
3836 defer trash_block.instructions.deinit(gpa);3847 defer trash_block.instructions.deinit(gpa);
38373848
3838 const mut_final_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{3849 const mut_final_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
...@@ -5211,7 +5222,7 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.I...@@ -5211,7 +5222,7 @@ fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.I
5211 if (block.is_comptime) {5222 if (block.is_comptime) {
5212 return sema.fail(block, src, "encountered @panic at comptime", .{});5223 return sema.fail(block, src, "encountered @panic at comptime", .{});
5213 }5224 }
5214 try sema.panicWithMsg(block, src, msg_inst);5225 try sema.panicWithMsg(block, msg_inst);
5215 return always_noreturn;5226 return always_noreturn;
5216}5227}
52175228
...@@ -6289,7 +6300,6 @@ fn zirCall(...@@ -6289,7 +6300,6 @@ fn zirCall(
6289 } else {6300 } else {
6290 resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_len);6301 resolved_args = try sema.arena.alloc(Air.Inst.Ref, args_len);
6291 }6302 }
6292 const total_args = args_len + @boolToInt(bound_arg_src != null);
62936303
6294 const callee_ty = sema.typeOf(func);6304 const callee_ty = sema.typeOf(func);
6295 const func_ty = func_ty: {6305 const func_ty = func_ty: {
...@@ -6305,45 +6315,16 @@ fn zirCall(...@@ -6305,45 +6315,16 @@ fn zirCall(
6305 }6315 }
6306 return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(sema.mod)});6316 return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(sema.mod)});
6307 };6317 };
6308 const func_ty_info = func_ty.fnInfo();6318 const total_args = args_len + @boolToInt(bound_arg_src != null);
63096319 try sema.checkCallArgumentCount(block, func, func_src, func_ty, total_args, bound_arg_src != null);
6310 const fn_params_len = func_ty_info.param_types.len;
6311 check_args: {
6312 if (func_ty_info.is_var_args) {
6313 assert(func_ty_info.cc == .C);
6314 if (total_args >= fn_params_len) break :check_args;
6315 } else if (fn_params_len == total_args) {
6316 break :check_args;
6317 }
6318
6319 const maybe_decl = try sema.funcDeclSrc(func);
6320 const member_str = if (bound_arg_src != null) "member function " else "";
6321 const variadic_str = if (func_ty_info.is_var_args) "at least " else "";
6322 const msg = msg: {
6323 const msg = try sema.errMsg(
6324 block,
6325 func_src,
6326 "{s}expected {s}{d} argument(s), found {d}",
6327 .{
6328 member_str,
6329 variadic_str,
6330 fn_params_len - @boolToInt(bound_arg_src != null),
6331 args_len,
6332 },
6333 );
6334 errdefer msg.destroy(sema.gpa);
6335
6336 if (maybe_decl) |fn_decl| try sema.mod.errNoteNonLazy(fn_decl.srcLoc(), msg, "function declared here", .{});
6337 break :msg msg;
6338 };
6339 return sema.failWithOwnedErrorMsg(msg);
6340 }
63416320
6342 const args_body = sema.code.extra[extra.end..];6321 const args_body = sema.code.extra[extra.end..];
63436322
6344 var input_is_error = false;6323 var input_is_error = false;
6345 const block_index = @intCast(Air.Inst.Index, block.instructions.items.len);6324 const block_index = @intCast(Air.Inst.Index, block.instructions.items.len);
63466325
6326 const func_ty_info = func_ty.fnInfo();
6327 const fn_params_len = func_ty_info.param_types.len;
6347 const parent_comptime = block.is_comptime;6328 const parent_comptime = block.is_comptime;
6348 // `extra_index` and `arg_index` are separate since the bound function is passed as the first argument.6329 // `extra_index` and `arg_index` are separate since the bound function is passed as the first argument.
6349 var extra_index: usize = 0;6330 var extra_index: usize = 0;
...@@ -6381,14 +6362,18 @@ fn zirCall(...@@ -6381,14 +6362,18 @@ fn zirCall(
6381 }6362 }
6382 resolved_args[arg_index] = resolved;6363 resolved_args[arg_index] = resolved;
6383 }6364 }
6384 if (sema.owner_func == null or !sema.owner_func.?.calls_or_awaits_errorable_fn)6365 if (sema.owner_func == null or !sema.owner_func.?.calls_or_awaits_errorable_fn) {
6385 input_is_error = false; // input was an error type, but no errorable fn's were actually called6366 input_is_error = false; // input was an error type, but no errorable fn's were actually called
6367 }
6368
6369 // AstGen ensures that a call instruction is always preceded by a dbg_stmt instruction.
6370 const call_dbg_node = inst - 1;
63866371
6387 if (sema.mod.backendSupportsFeature(.error_return_trace) and sema.mod.comp.bin_file.options.error_return_tracing and6372 if (sema.mod.backendSupportsFeature(.error_return_trace) and sema.mod.comp.bin_file.options.error_return_tracing and
6388 !block.is_comptime and !block.is_typeof and (input_is_error or pop_error_return_trace))6373 !block.is_comptime and !block.is_typeof and (input_is_error or pop_error_return_trace))
6389 {6374 {
6390 const call_inst: Air.Inst.Ref = if (modifier == .always_tail) undefined else b: {6375 const call_inst: Air.Inst.Ref = if (modifier == .always_tail) undefined else b: {
6391 break :b try sema.analyzeCall(block, func, func_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src);6376 break :b try sema.analyzeCall(block, func, func_ty, func_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src, call_dbg_node);
6392 };6377 };
63936378
6394 const return_ty = sema.typeOf(call_inst);6379 const return_ty = sema.typeOf(call_inst);
...@@ -6417,14 +6402,86 @@ fn zirCall(...@@ -6417,14 +6402,86 @@ fn zirCall(
6417 }6402 }
64186403
6419 if (modifier == .always_tail) // Perform the call *after* the restore, so that a tail call is possible.6404 if (modifier == .always_tail) // Perform the call *after* the restore, so that a tail call is possible.
6420 return sema.analyzeCall(block, func, func_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src);6405 return sema.analyzeCall(block, func, func_ty, func_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src, call_dbg_node);
64216406
6422 return call_inst;6407 return call_inst;
6423 } else {6408 } else {
6424 return sema.analyzeCall(block, func, func_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src);6409 return sema.analyzeCall(block, func, func_ty, func_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src, call_dbg_node);
6425 }6410 }
6426}6411}
64276412
6413fn checkCallArgumentCount(
6414 sema: *Sema,
6415 block: *Block,
6416 func: Air.Inst.Ref,
6417 func_src: LazySrcLoc,
6418 func_ty: Type,
6419 total_args: usize,
6420 member_fn: bool,
6421) !void {
6422 const func_ty_info = func_ty.fnInfo();
6423 const fn_params_len = func_ty_info.param_types.len;
6424 const args_len = total_args - @boolToInt(member_fn);
6425 if (func_ty_info.is_var_args) {
6426 assert(func_ty_info.cc == .C);
6427 if (total_args >= fn_params_len) return;
6428 } else if (fn_params_len == total_args) {
6429 return;
6430 }
6431
6432 const maybe_decl = try sema.funcDeclSrc(func);
6433 const member_str = if (member_fn) "member function " else "";
6434 const variadic_str = if (func_ty_info.is_var_args) "at least " else "";
6435 const msg = msg: {
6436 const msg = try sema.errMsg(
6437 block,
6438 func_src,
6439 "{s}expected {s}{d} argument(s), found {d}",
6440 .{
6441 member_str,
6442 variadic_str,
6443 fn_params_len - @boolToInt(member_fn),
6444 args_len,
6445 },
6446 );
6447 errdefer msg.destroy(sema.gpa);
6448
6449 if (maybe_decl) |fn_decl| try sema.mod.errNoteNonLazy(fn_decl.srcLoc(), msg, "function declared here", .{});
6450 break :msg msg;
6451 };
6452 return sema.failWithOwnedErrorMsg(msg);
6453}
6454
6455fn callBuiltin(
6456 sema: *Sema,
6457 block: *Block,
6458 builtin_fn: Air.Inst.Ref,
6459 modifier: std.builtin.CallModifier,
6460 args: []const Air.Inst.Ref,
6461) !void {
6462 const callee_ty = sema.typeOf(builtin_fn);
6463 const func_ty = func_ty: {
6464 switch (callee_ty.zigTypeTag()) {
6465 .Fn => break :func_ty callee_ty,
6466 .Pointer => {
6467 const ptr_info = callee_ty.ptrInfo().data;
6468 if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag() == .Fn) {
6469 break :func_ty ptr_info.pointee_type;
6470 }
6471 },
6472 else => {},
6473 }
6474 std.debug.panic("type '{}' is not a function calling builtin fn", .{callee_ty.fmt(sema.mod)});
6475 };
6476
6477 const func_ty_info = func_ty.fnInfo();
6478 const fn_params_len = func_ty_info.param_types.len;
6479 if (args.len != fn_params_len or (func_ty_info.is_var_args and args.len < fn_params_len)) {
6480 std.debug.panic("parameter count mismatch calling builtin fn, expected {d}, found {d}", .{ fn_params_len, args.len });
6481 }
6482 _ = try sema.analyzeCall(block, builtin_fn, func_ty, sema.src, sema.src, modifier, false, args, null, null);
6483}
6484
6428const GenericCallAdapter = struct {6485const GenericCallAdapter = struct {
6429 generic_fn: *Module.Fn,6486 generic_fn: *Module.Fn,
6430 precomputed_hash: u64,6487 precomputed_hash: u64,
...@@ -6499,31 +6556,20 @@ fn analyzeCall(...@@ -6499,31 +6556,20 @@ fn analyzeCall(
6499 sema: *Sema,6556 sema: *Sema,
6500 block: *Block,6557 block: *Block,
6501 func: Air.Inst.Ref,6558 func: Air.Inst.Ref,
6559 func_ty: Type,
6502 func_src: LazySrcLoc,6560 func_src: LazySrcLoc,
6503 call_src: LazySrcLoc,6561 call_src: LazySrcLoc,
6504 modifier: std.builtin.CallModifier,6562 modifier: std.builtin.CallModifier,
6505 ensure_result_used: bool,6563 ensure_result_used: bool,
6506 uncasted_args: []const Air.Inst.Ref,6564 uncasted_args: []const Air.Inst.Ref,
6507 bound_arg_src: ?LazySrcLoc,6565 bound_arg_src: ?LazySrcLoc,
6566 call_dbg_node: ?Zir.Inst.Index,
6508) CompileError!Air.Inst.Ref {6567) CompileError!Air.Inst.Ref {
6509 const mod = sema.mod;6568 const mod = sema.mod;
65106569
6511 const callee_ty = sema.typeOf(func);6570 const callee_ty = sema.typeOf(func);
6512 const func_ty = func_ty: {
6513 switch (callee_ty.zigTypeTag()) {
6514 .Fn => break :func_ty callee_ty,
6515 .Pointer => {
6516 const ptr_info = callee_ty.ptrInfo().data;
6517 if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag() == .Fn) {
6518 break :func_ty ptr_info.pointee_type;
6519 }
6520 },
6521 else => {},
6522 }
6523 return sema.fail(block, func_src, "type '{}' is not a function", .{callee_ty.fmt(sema.mod)});
6524 };
6525
6526 const func_ty_info = func_ty.fnInfo();6571 const func_ty_info = func_ty.fnInfo();
6572 const fn_params_len = func_ty_info.param_types.len;
6527 const cc = func_ty_info.cc;6573 const cc = func_ty_info.cc;
6528 if (cc == .Naked) {6574 if (cc == .Naked) {
6529 const maybe_decl = try sema.funcDeclSrc(func);6575 const maybe_decl = try sema.funcDeclSrc(func);
...@@ -6541,27 +6587,6 @@ fn analyzeCall(...@@ -6541,27 +6587,6 @@ fn analyzeCall(
6541 };6587 };
6542 return sema.failWithOwnedErrorMsg(msg);6588 return sema.failWithOwnedErrorMsg(msg);
6543 }6589 }
6544 const fn_params_len = func_ty_info.param_types.len;
6545 if (func_ty_info.is_var_args) {
6546 assert(cc == .C);
6547 if (uncasted_args.len < fn_params_len) {
6548 // TODO add error note: declared here
6549 return sema.fail(
6550 block,
6551 func_src,
6552 "expected at least {d} argument(s), found {d}",
6553 .{ fn_params_len, uncasted_args.len },
6554 );
6555 }
6556 } else if (fn_params_len != uncasted_args.len) {
6557 // TODO add error note: declared here
6558 return sema.fail(
6559 block,
6560 call_src,
6561 "expected {d} argument(s), found {d}",
6562 .{ fn_params_len, uncasted_args.len },
6563 );
6564 }
65656590
6566 const call_tag: Air.Inst.Tag = switch (modifier) {6591 const call_tag: Air.Inst.Tag = switch (modifier) {
6567 .auto,6592 .auto,
...@@ -6622,6 +6647,7 @@ fn analyzeCall(...@@ -6622,6 +6647,7 @@ fn analyzeCall(
6622 uncasted_args,6647 uncasted_args,
6623 call_tag,6648 call_tag,
6624 bound_arg_src,6649 bound_arg_src,
6650 call_dbg_node,
6625 )) |some| {6651 )) |some| {
6626 return some;6652 return some;
6627 } else |err| switch (err) {6653 } else |err| switch (err) {
...@@ -7010,6 +7036,8 @@ fn analyzeCall(...@@ -7010,6 +7036,8 @@ fn analyzeCall(
7010 }7036 }
7011 }7037 }
70127038
7039 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
7040
7013 try sema.queueFullTypeResolution(func_ty_info.return_type);7041 try sema.queueFullTypeResolution(func_ty_info.return_type);
7014 if (sema.owner_func != null and func_ty_info.return_type.isError()) {7042 if (sema.owner_func != null and func_ty_info.return_type.isError()) {
7015 sema.owner_func.?.calls_or_awaits_errorable_fn = true;7043 sema.owner_func.?.calls_or_awaits_errorable_fn = true;
...@@ -7246,6 +7274,7 @@ fn instantiateGenericCall(...@@ -7246,6 +7274,7 @@ fn instantiateGenericCall(
7246 uncasted_args: []const Air.Inst.Ref,7274 uncasted_args: []const Air.Inst.Ref,
7247 call_tag: Air.Inst.Tag,7275 call_tag: Air.Inst.Tag,
7248 bound_arg_src: ?LazySrcLoc,7276 bound_arg_src: ?LazySrcLoc,
7277 call_dbg_node: ?Zir.Inst.Index,
7249) CompileError!Air.Inst.Ref {7278) CompileError!Air.Inst.Ref {
7250 const mod = sema.mod;7279 const mod = sema.mod;
7251 const gpa = sema.gpa;7280 const gpa = sema.gpa;
...@@ -7502,6 +7531,8 @@ fn instantiateGenericCall(...@@ -7502,6 +7531,8 @@ fn instantiateGenericCall(
7502 try sema.queueFullTypeResolution(new_fn_info.return_type);7531 try sema.queueFullTypeResolution(new_fn_info.return_type);
7503 }7532 }
75047533
7534 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
7535
7505 if (sema.owner_func != null and new_fn_info.return_type.isError()) {7536 if (sema.owner_func != null and new_fn_info.return_type.isError()) {
7506 sema.owner_func.?.calls_or_awaits_errorable_fn = true;7537 sema.owner_func.?.calls_or_awaits_errorable_fn = true;
7507 }7538 }
...@@ -11827,9 +11858,6 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op...@@ -11827,9 +11858,6 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op
11827 .as_node => try sema.zirAsNode(block, inst),11858 .as_node => try sema.zirAsNode(block, inst),
11828 .field_val => try sema.zirFieldVal(block, inst),11859 .field_val => try sema.zirFieldVal(block, inst),
11829 .@"unreachable" => {11860 .@"unreachable" => {
11830 const inst_data = sema.code.instructions.items(.data)[inst].@"unreachable";
11831 const src = inst_data.src();
11832
11833 if (!sema.mod.comp.formatted_panics) {11861 if (!sema.mod.comp.formatted_panics) {
11834 try sema.safetyPanic(block, .unwrap_error);11862 try sema.safetyPanic(block, .unwrap_error);
11835 return true;11863 return true;
...@@ -11838,18 +11866,17 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op...@@ -11838,18 +11866,17 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op
11838 const panic_fn = try sema.getBuiltin("panicUnwrapError");11866 const panic_fn = try sema.getBuiltin("panicUnwrapError");
11839 const err_return_trace = try sema.getErrorReturnTrace(block);11867 const err_return_trace = try sema.getErrorReturnTrace(block);
11840 const args: [2]Air.Inst.Ref = .{ err_return_trace, operand };11868 const args: [2]Air.Inst.Ref = .{ err_return_trace, operand };
11841 _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, &args, null);11869 try sema.callBuiltin(block, panic_fn, .auto, &args);
11842 return true;11870 return true;
11843 },11871 },
11844 .panic => {11872 .panic => {
11845 const inst_data = sema.code.instructions.items(.data)[inst].un_node;11873 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
11846 const src = inst_data.src();
11847 const msg_inst = try sema.resolveInst(inst_data.operand);11874 const msg_inst = try sema.resolveInst(inst_data.operand);
1184811875
11849 const panic_fn = try sema.getBuiltin("panic");11876 const panic_fn = try sema.getBuiltin("panic");
11850 const err_return_trace = try sema.getErrorReturnTrace(block);11877 const err_return_trace = try sema.getErrorReturnTrace(block);
11851 const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value };11878 const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value };
11852 _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, &args, null);11879 try sema.callBuiltin(block, panic_fn, .auto, &args);
11853 return true;11880 return true;
11854 },11881 },
11855 else => unreachable,11882 else => unreachable,
...@@ -17263,7 +17290,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir...@@ -17263,7 +17290,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir
1726317290
17264 if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) {17291 if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) {
17265 const is_non_err = try sema.analyzePtrIsNonErr(block, src, ret_ptr);17292 const is_non_err = try sema.analyzePtrIsNonErr(block, src, ret_ptr);
17266 return sema.retWithErrTracing(block, src, is_non_err, .ret_load, ret_ptr);17293 return sema.retWithErrTracing(block, is_non_err, .ret_load, ret_ptr);
17267 }17294 }
1726817295
17269 _ = try block.addUnOp(.ret_load, ret_ptr);17296 _ = try block.addUnOp(.ret_load, ret_ptr);
...@@ -17273,7 +17300,6 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir...@@ -17273,7 +17300,6 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir
17273fn retWithErrTracing(17300fn retWithErrTracing(
17274 sema: *Sema,17301 sema: *Sema,
17275 block: *Block,17302 block: *Block,
17276 src: LazySrcLoc,
17277 is_non_err: Air.Inst.Ref,17303 is_non_err: Air.Inst.Ref,
17278 ret_tag: Air.Inst.Tag,17304 ret_tag: Air.Inst.Tag,
17279 operand: Air.Inst.Ref,17305 operand: Air.Inst.Ref,
...@@ -17295,7 +17321,7 @@ fn retWithErrTracing(...@@ -17295,7 +17321,7 @@ fn retWithErrTracing(
17295 const args: [1]Air.Inst.Ref = .{err_return_trace};17321 const args: [1]Air.Inst.Ref = .{err_return_trace};
1729617322
17297 if (!need_check) {17323 if (!need_check) {
17298 _ = try sema.analyzeCall(block, return_err_fn, src, src, .never_inline, false, &args, null);17324 try sema.callBuiltin(block, return_err_fn, .never_inline, &args);
17299 _ = try block.addUnOp(ret_tag, operand);17325 _ = try block.addUnOp(ret_tag, operand);
17300 return always_noreturn;17326 return always_noreturn;
17301 }17327 }
...@@ -17306,7 +17332,7 @@ fn retWithErrTracing(...@@ -17306,7 +17332,7 @@ fn retWithErrTracing(
1730617332
17307 var else_block = block.makeSubBlock();17333 var else_block = block.makeSubBlock();
17308 defer else_block.instructions.deinit(gpa);17334 defer else_block.instructions.deinit(gpa);
17309 _ = try sema.analyzeCall(&else_block, return_err_fn, src, src, .never_inline, false, &args, null);17335 try sema.callBuiltin(&else_block, return_err_fn, .never_inline, &args);
17310 _ = try else_block.addUnOp(ret_tag, operand);17336 _ = try else_block.addUnOp(ret_tag, operand);
1731117337
17312 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).Struct.fields.len +17338 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).Struct.fields.len +
...@@ -17452,7 +17478,7 @@ fn analyzeRet(...@@ -17452,7 +17478,7 @@ fn analyzeRet(
17452 // Avoid adding a frame to the error return trace in case the value is comptime-known17478 // Avoid adding a frame to the error return trace in case the value is comptime-known
17453 // to be not an error.17479 // to be not an error.
17454 const is_non_err = try sema.analyzeIsNonErr(block, src, operand);17480 const is_non_err = try sema.analyzeIsNonErr(block, src, operand);
17455 return sema.retWithErrTracing(block, src, is_non_err, .ret, operand);17481 return sema.retWithErrTracing(block, is_non_err, .ret, operand);
17456 }17482 }
1745717483
17458 _ = try block.addUnOp(.ret, operand);17484 _ = try block.addUnOp(.ret, operand);
...@@ -17796,7 +17822,7 @@ fn zirStructInit(...@@ -17796,7 +17822,7 @@ fn zirStructInit(
17796 try sema.storePtr(block, src, field_ptr, init_inst);17822 try sema.storePtr(block, src, field_ptr, init_inst);
17797 const new_tag = try sema.addConstant(resolved_ty.unionTagTypeHypothetical(), tag_val);17823 const new_tag = try sema.addConstant(resolved_ty.unionTagTypeHypothetical(), tag_val);
17798 _ = try block.addBinOp(.set_union_tag, alloc, new_tag);17824 _ = try block.addBinOp(.set_union_tag, alloc, new_tag);
17799 return alloc;17825 return sema.makePtrConst(block, alloc);
17800 }17826 }
1780117827
17802 try sema.requireRuntimeBlock(block, src, null);17828 try sema.requireRuntimeBlock(block, src, null);
...@@ -17923,7 +17949,7 @@ fn finishStructInit(...@@ -17923,7 +17949,7 @@ fn finishStructInit(
17923 try sema.storePtr(block, dest_src, field_ptr, field_init);17949 try sema.storePtr(block, dest_src, field_ptr, field_init);
17924 }17950 }
1792517951
17926 return alloc;17952 return sema.makePtrConst(block, alloc);
17927 }17953 }
1792817954
17929 try sema.requireRuntimeBlock(block, dest_src, null);17955 try sema.requireRuntimeBlock(block, dest_src, null);
...@@ -18040,7 +18066,7 @@ fn zirStructInitAnon(...@@ -18040,7 +18066,7 @@ fn zirStructInitAnon(
18040 }18066 }
18041 }18067 }
1804218068
18043 return alloc;18069 return sema.makePtrConst(block, alloc);
18044 }18070 }
1804518071
18046 const element_refs = try sema.arena.alloc(Air.Inst.Ref, types.len);18072 const element_refs = try sema.arena.alloc(Air.Inst.Ref, types.len);
...@@ -18143,7 +18169,7 @@ fn zirArrayInit(...@@ -18143,7 +18169,7 @@ fn zirArrayInit(
18143 const elem_ptr = try block.addPtrElemPtrTypeRef(alloc, index, elem_ptr_ty_ref);18169 const elem_ptr = try block.addPtrElemPtrTypeRef(alloc, index, elem_ptr_ty_ref);
18144 _ = try block.addBinOp(.store, elem_ptr, arg);18170 _ = try block.addBinOp(.store, elem_ptr, arg);
18145 }18171 }
18146 return alloc;18172 return sema.makePtrConst(block, alloc);
18147 }18173 }
1814818174
18149 const elem_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{18175 const elem_ptr_ty = try Type.ptr(sema.arena, sema.mod, .{
...@@ -18158,7 +18184,7 @@ fn zirArrayInit(...@@ -18158,7 +18184,7 @@ fn zirArrayInit(
18158 const elem_ptr = try block.addPtrElemPtrTypeRef(alloc, index, elem_ptr_ty_ref);18184 const elem_ptr = try block.addPtrElemPtrTypeRef(alloc, index, elem_ptr_ty_ref);
18159 _ = try block.addBinOp(.store, elem_ptr, arg);18185 _ = try block.addBinOp(.store, elem_ptr, arg);
18160 }18186 }
18161 return alloc;18187 return sema.makePtrConst(block, alloc);
18162 }18188 }
1816318189
18164 return block.addAggregateInit(array_ty, resolved_args);18190 return block.addAggregateInit(array_ty, resolved_args);
...@@ -18236,7 +18262,7 @@ fn zirArrayInitAnon(...@@ -18236,7 +18262,7 @@ fn zirArrayInitAnon(
18236 }18262 }
18237 }18263 }
1823818264
18239 return alloc;18265 return sema.makePtrConst(block, alloc);
18240 }18266 }
1824118267
18242 const element_refs = try sema.arena.alloc(Air.Inst.Ref, operands.len);18268 const element_refs = try sema.arena.alloc(Air.Inst.Ref, operands.len);
...@@ -21662,8 +21688,25 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -21662,8 +21688,25 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
21662 resolved.* = try sema.tupleFieldValByIndex(block, args_src, args, @intCast(u32, i), args_ty);21688 resolved.* = try sema.tupleFieldValByIndex(block, args_src, args, @intCast(u32, i), args_ty);
21663 }21689 }
21664 }21690 }
21691
21692 const callee_ty = sema.typeOf(func);
21693 const func_ty = func_ty: {
21694 switch (callee_ty.zigTypeTag()) {
21695 .Fn => break :func_ty callee_ty,
21696 .Pointer => {
21697 const ptr_info = callee_ty.ptrInfo().data;
21698 if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag() == .Fn) {
21699 break :func_ty ptr_info.pointee_type;
21700 }
21701 },
21702 else => {},
21703 }
21704 return sema.fail(block, func_src, "type '{}' not a function", .{callee_ty.fmt(sema.mod)});
21705 };
21706 try sema.checkCallArgumentCount(block, func, func_src, func_ty, resolved_args.len, bound_arg_src != null);
21707
21665 const ensure_result_used = extra.flags.ensure_result_used;21708 const ensure_result_used = extra.flags.ensure_result_used;
21666 return sema.analyzeCall(block, func, func_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src);21709 return sema.analyzeCall(block, func, func_ty, func_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src, null);
21667}21710}
2166821711
21669fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {21712fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -23474,7 +23517,6 @@ fn addSafetyCheckExtra(...@@ -23474,7 +23517,6 @@ fn addSafetyCheckExtra(
23474fn panicWithMsg(23517fn panicWithMsg(
23475 sema: *Sema,23518 sema: *Sema,
23476 block: *Block,23519 block: *Block,
23477 src: LazySrcLoc,
23478 msg_inst: Air.Inst.Ref,23520 msg_inst: Air.Inst.Ref,
23479) !void {23521) !void {
23480 const mod = sema.mod;23522 const mod = sema.mod;
...@@ -23497,7 +23539,7 @@ fn panicWithMsg(...@@ -23497,7 +23539,7 @@ fn panicWithMsg(
23497 Value.null,23539 Value.null,
23498 );23540 );
23499 const args: [3]Air.Inst.Ref = .{ msg_inst, null_stack_trace, .null_value };23541 const args: [3]Air.Inst.Ref = .{ msg_inst, null_stack_trace, .null_value };
23500 _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, &args, null);23542 try sema.callBuiltin(block, panic_fn, .auto, &args);
23501}23543}
2350223544
23503fn panicUnwrapError(23545fn panicUnwrapError(
...@@ -23535,7 +23577,7 @@ fn panicUnwrapError(...@@ -23535,7 +23577,7 @@ fn panicUnwrapError(
23535 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);23577 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);
23536 const err_return_trace = try sema.getErrorReturnTrace(&fail_block);23578 const err_return_trace = try sema.getErrorReturnTrace(&fail_block);
23537 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };23579 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };
23538 _ = try sema.analyzeCall(&fail_block, panic_fn, sema.src, sema.src, .auto, false, &args, null);23580 try sema.callBuiltin(&fail_block, panic_fn, .auto, &args);
23539 }23581 }
23540 }23582 }
23541 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);23583 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
...@@ -23620,7 +23662,7 @@ fn panicSentinelMismatch(...@@ -23620,7 +23662,7 @@ fn panicSentinelMismatch(
23620 else {23662 else {
23621 const panic_fn = try sema.getBuiltin("checkNonScalarSentinel");23663 const panic_fn = try sema.getBuiltin("checkNonScalarSentinel");
23622 const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel };23664 const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel };
23623 _ = try sema.analyzeCall(parent_block, panic_fn, sema.src, sema.src, .auto, false, &args, null);23665 try sema.callBuiltin(parent_block, panic_fn, .auto, &args);
23624 return;23666 return;
23625 };23667 };
2362623668
...@@ -23657,7 +23699,7 @@ fn safetyCheckFormatted(...@@ -23657,7 +23699,7 @@ fn safetyCheckFormatted(
23657 _ = try fail_block.addNoOp(.trap);23699 _ = try fail_block.addNoOp(.trap);
23658 } else {23700 } else {
23659 const panic_fn = try sema.getBuiltin(func);23701 const panic_fn = try sema.getBuiltin(func);
23660 _ = try sema.analyzeCall(&fail_block, panic_fn, sema.src, sema.src, .auto, false, args, null);23702 try sema.callBuiltin(&fail_block, panic_fn, .auto, args);
23661 }23703 }
23662 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);23704 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
23663}23705}
...@@ -23676,7 +23718,7 @@ fn safetyPanic(...@@ -23676,7 +23718,7 @@ fn safetyPanic(
23676 )).?;23718 )).?;
2367723719
23678 const msg_inst = try sema.analyzeDeclVal(block, sema.src, msg_decl_index);23720 const msg_inst = try sema.analyzeDeclVal(block, sema.src, msg_decl_index);
23679 try sema.panicWithMsg(block, sema.src, msg_inst);23721 try sema.panicWithMsg(block, msg_inst);
23680}23722}
2368123723
23682fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void {23724fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
...@@ -29134,8 +29176,6 @@ fn analyzeIsNonErrComptimeOnly(...@@ -29134,8 +29176,6 @@ fn analyzeIsNonErrComptimeOnly(
29134 if (ies.errors.count() != 0) break :blk;29176 if (ies.errors.count() != 0) break :blk;
29135 if (maybe_operand_val == null) {29177 if (maybe_operand_val == null) {
29136 // Try to avoid resolving inferred error set if possible.29178 // Try to avoid resolving inferred error set if possible.
29137 if (ies.errors.count() != 0) break :blk;
29138 if (ies.is_anyerror) break :blk;
29139 for (ies.inferred_error_sets.keys()) |other_ies| {29179 for (ies.inferred_error_sets.keys()) |other_ies| {
29140 if (ies == other_ies) continue;29180 if (ies == other_ies) continue;
29141 try sema.resolveInferredErrorSet(block, src, other_ies);29181 try sema.resolveInferredErrorSet(block, src, other_ies);
...@@ -29147,11 +29187,10 @@ fn analyzeIsNonErrComptimeOnly(...@@ -29147,11 +29187,10 @@ fn analyzeIsNonErrComptimeOnly(
2914729187
29148 if (other_ies.errors.count() != 0) break :blk;29188 if (other_ies.errors.count() != 0) break :blk;
29149 }29189 }
29150 if (ies.func == sema.owner_func) {29190 if (!ies.is_resolved and ies.func.state == .in_progress) {
29151 // We're checking the inferred errorset of the current function and none of29191 // Calling resolveInferredErrorSet would immediately fail
29152 // its child inferred error sets contained any errors meaning that any value29192 // so we'll have to rely on runtime checks.
29153 // so far with this type can't contain errors either.29193 return Air.Inst.Ref.none;
29154 return Air.Inst.Ref.bool_true;
29155 }29194 }
29156 try sema.resolveInferredErrorSet(block, src, ies);29195 try sema.resolveInferredErrorSet(block, src, ies);
29157 if (ies.is_anyerror) break :blk;29196 if (ies.is_anyerror) break :blk;
...@@ -31523,6 +31562,16 @@ fn resolveInferredErrorSet(...@@ -31523,6 +31562,16 @@ fn resolveInferredErrorSet(
31523 if (ies_func_info.return_type.tag() == .generic_poison) {31562 if (ies_func_info.return_type.tag() == .generic_poison) {
31524 assert(ies_func_info.cc == .Inline);31563 assert(ies_func_info.cc == .Inline);
31525 } else if (ies_func_info.return_type.errorUnionSet().castTag(.error_set_inferred).?.data == ies) {31564 } else if (ies_func_info.return_type.errorUnionSet().castTag(.error_set_inferred).?.data == ies) {
31565 if (ies_func_info.is_generic) {
31566 const msg = msg: {
31567 const msg = try sema.errMsg(block, src, "unable to resolve inferred error set of generic function", .{});
31568 errdefer msg.destroy(sema.gpa);
31569
31570 try sema.mod.errNoteNonLazy(ies_func_owner_decl.srcLoc(), msg, "generic function declared here", .{});
31571 break :msg msg;
31572 };
31573 return sema.failWithOwnedErrorMsg(msg);
31574 }
31526 // In this case we are dealing with the actual InferredErrorSet object that31575 // In this case we are dealing with the actual InferredErrorSet object that
31527 // corresponds to the function, not one created to track an inline/comptime call.31576 // corresponds to the function, not one created to track an inline/comptime call.
31528 try sema.ensureFuncBodyAnalyzed(ies.func);31577 try sema.ensureFuncBodyAnalyzed(ies.func);
src/link/MachO/Atom.zig+1-1
...@@ -116,7 +116,7 @@ pub fn addRelocation(macho_file: *MachO, atom_index: Index, reloc: Relocation) !...@@ -116,7 +116,7 @@ pub fn addRelocation(macho_file: *MachO, atom_index: Index, reloc: Relocation) !
116 return addRelocations(macho_file, atom_index, &[_]Relocation{reloc});116 return addRelocations(macho_file, atom_index, &[_]Relocation{reloc});
117}117}
118118
119pub fn addRelocations(macho_file: *MachO, atom_index: Index, relocs: []Relocation) !void {119pub fn addRelocations(macho_file: *MachO, atom_index: Index, relocs: []const Relocation) !void {
120 const gpa = macho_file.base.allocator;120 const gpa = macho_file.base.allocator;
121 const gop = try macho_file.relocs.getOrPut(gpa, atom_index);121 const gop = try macho_file.relocs.getOrPut(gpa, atom_index);
122 if (!gop.found_existing) {122 if (!gop.found_existing) {
src/print_air.zig-1
...@@ -917,7 +917,6 @@ const Writer = struct {...@@ -917,7 +917,6 @@ const Writer = struct {
917917
918 try s.writeAll("\n");918 try s.writeAll("\n");
919 try s.writeByteNTimes(' ', old_indent);919 try s.writeByteNTimes(' ', old_indent);
920 try s.writeAll("}");
921 }920 }
922921
923 fn writeWasmMemorySize(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {922 fn writeWasmMemorySize(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
test/behavior/array.zig+1-1
...@@ -696,7 +696,7 @@ test "array init of container level array variable" {...@@ -696,7 +696,7 @@ test "array init of container level array variable" {
696test "runtime initialized sentinel-terminated array literal" {696test "runtime initialized sentinel-terminated array literal" {
697 var c: u16 = 300;697 var c: u16 = 300;
698 const f = &[_:0x9999]u16{c};698 const f = &[_:0x9999]u16{c};
699 const g = @ptrCast(*[4]u8, f);699 const g = @ptrCast(*const [4]u8, f);
700 try std.testing.expect(g[2] == 0x99);700 try std.testing.expect(g[2] == 0x99);
701 try std.testing.expect(g[3] == 0x99);701 try std.testing.expect(g[3] == 0x99);
702}702}
test/behavior/basic.zig+7
...@@ -1200,3 +1200,10 @@ test "arrays and vectors with big integers" {...@@ -1200,3 +1200,10 @@ test "arrays and vectors with big integers" {
1200 try expect(b[0] == comptime std.math.maxInt(Int));1200 try expect(b[0] == comptime std.math.maxInt(Int));
1201 }1201 }
1202}1202}
1203
1204test "pointer to struct literal with runtime field is constant" {
1205 const S = struct { data: usize };
1206 var runtime_zero: usize = 0;
1207 const ptr = &S{ .data = runtime_zero };
1208 try expect(@typeInfo(@TypeOf(ptr)).Pointer.is_const);
1209}
test/behavior/error.zig+25-16
...@@ -705,22 +705,6 @@ test "error union payload is properly aligned" {...@@ -705,22 +705,6 @@ test "error union payload is properly aligned" {
705 if (blk.a != 1) unreachable;705 if (blk.a != 1) unreachable;
706}706}
707707
708test "ret_ptr doesn't cause own inferred error set to be resolved" {
709 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
710 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
711
712 const S = struct {
713 fn foo() !void {}
714
715 fn doTheTest() !void {
716 errdefer @compileError("bad");
717
718 return try @This().foo();
719 }
720 };
721 try S.doTheTest();
722}
723
724test "simple else prong allowed even when all errors handled" {708test "simple else prong allowed even when all errors handled" {
725 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO709 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
726 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO710 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -928,3 +912,28 @@ test "optional error set return type" {...@@ -928,3 +912,28 @@ test "optional error set return type" {
928 try expect(null == S.foo(true));912 try expect(null == S.foo(true));
929 try expect(E.A == S.foo(false).?);913 try expect(E.A == S.foo(false).?);
930}914}
915
916test "try used in recursive function with inferred error set" {
917 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
918 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
919
920 const Value = union(enum) {
921 values: []const @This(),
922 b,
923
924 fn x(value: @This()) !void {
925 switch (value.values[0]) {
926 .values => return try x(value.values[0]),
927 .b => return error.a,
928 }
929 }
930 };
931 const a = Value{
932 .values = &[1]Value{
933 .{
934 .values = &[1]Value{.{ .b = {} }},
935 },
936 },
937 };
938 try expectError(error.a, Value.x(a));
939}
test/cases/compile_errors/member_function_arg_mismatch.zig+6
...@@ -6,6 +6,10 @@ pub export fn entry() void {...@@ -6,6 +6,10 @@ pub export fn entry() void {
6 var s: S = undefined;6 var s: S = undefined;
7 s.foo(true);7 s.foo(true);
8}8}
9pub export fn entry2() void {
10 var s: S = undefined;
11 @call(.auto, s.foo, .{true});
12}
913
10// error14// error
11// backend=stage215// backend=stage2
...@@ -13,3 +17,5 @@ pub export fn entry() void {...@@ -13,3 +17,5 @@ pub export fn entry() void {
13//17//
14// :7:6: error: member function expected 2 argument(s), found 118// :7:6: error: member function expected 2 argument(s), found 1
15// :3:5: note: function declared here19// :3:5: note: function declared here
20// :11:19: error: member function expected 2 argument(s), found 1
21// :3:5: note: function declared here
test/cases/compile_errors/resolve_inferred_error_set_of_generic_fn.zig created+18
...@@ -0,0 +1,18 @@
1fn foo(a: anytype) !void {
2 if (a == 0) return error.A;
3 return error.B;
4}
5const Error = error{ A, B };
6export fn entry() void {
7 const info = @typeInfo(@TypeOf(foo));
8 const ret_type = info.Fn.return_type.?;
9 const error_set = @typeInfo(ret_type).ErrorUnion.error_set;
10 _ = Error || error_set;
11}
12
13// error
14// backend=stage2
15// target=native
16//
17// :10:15: error: unable to resolve inferred error set of generic function
18// :1:1: note: generic function declared here
test/cases/compile_errors/struct_type_returned_from_non-generic_function.zig created+10
...@@ -0,0 +1,10 @@
1pub export fn entry(param: usize) usize {
2 return struct{ param };
3}
4
5// error
6// backend=stage2
7// target=native
8//
9// :2:12: error: expected type 'usize', found 'type'
10// :1:35: note: function return type declared here