authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-03 00:42:11-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-09 14:55:12-07:00
logaf958e95cc0a78404e604400f509ea0c219614d1
tree899f3b4d0a2de3c89b9fb5d66fd4934a38cdad9f
parentfd57487e3593dfd0bc9c62a945bcf57f16ff6fae

Merge pull request #13744 from Vexu/stage2-fixes

Improve error messages, fix dependency loops

40 files changed, 377 insertions(+), 94 deletions(-)

lib/std/fs.zig-2
......@@ -809,8 +809,6 @@ pub const IterableDir = struct {
809809 // and we avoid the code complexity here.
810810 const w = os.wasi;
811811 start_over: while (true) {
812 // TODO https://github.com/ziglang/zig/issues/12498
813 _ = @sizeOf(w.dirent_t) + 1;
814812 // According to the WASI spec, the last entry might be truncated,
815813 // so we need to check if the left buffer contains the whole dirent.
816814 if (self.end_index - self.index < @sizeOf(w.dirent_t)) {
src/AstGen.zig+41-7
......@@ -2625,7 +2625,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
26252625 .compile_error,
26262626 .ret_node,
26272627 .ret_load,
2628 .ret_tok,
2628 .ret_implicit,
26292629 .ret_err_value,
26302630 .@"unreachable",
26312631 .repeat,
......@@ -3689,6 +3689,29 @@ fn fnDecl(
36893689 if (param.anytype_ellipsis3) |tok| {
36903690 return astgen.failTok(tok, "missing parameter name", .{});
36913691 } else {
3692 ambiguous: {
3693 if (tree.nodes.items(.tag)[param.type_expr] != .identifier) break :ambiguous;
3694 const main_token = tree.nodes.items(.main_token)[param.type_expr];
3695 const identifier_str = tree.tokenSlice(main_token);
3696 if (isPrimitive(identifier_str)) break :ambiguous;
3697 return astgen.failNodeNotes(
3698 param.type_expr,
3699 "missing parameter name or type",
3700 .{},
3701 &[_]u32{
3702 try astgen.errNoteNode(
3703 param.type_expr,
3704 "if this is a name, annotate its type '{s}: T'",
3705 .{identifier_str},
3706 ),
3707 try astgen.errNoteNode(
3708 param.type_expr,
3709 "if this is a type, give it a name '<name>: {s}'",
3710 .{identifier_str},
3711 ),
3712 },
3713 );
3714 }
36923715 return astgen.failNode(param.type_expr, "missing parameter name", .{});
36933716 }
36943717 } else 0;
......@@ -3884,9 +3907,8 @@ fn fnDecl(
38843907 // As our last action before the return, "pop" the error trace if needed
38853908 _ = try gz.addRestoreErrRetIndex(.ret, .always);
38863909
3887 // Since we are adding the return instruction here, we must handle the coercion.
3888 // We do this by using the `ret_tok` instruction.
3889 _ = try fn_gz.addUnTok(.ret_tok, .void_value, tree.lastToken(body_node));
3910 // Add implicit return at end of function.
3911 _ = try fn_gz.addUnTok(.ret_implicit, .void_value, tree.lastToken(body_node));
38903912 }
38913913
38923914 break :func try decl_gz.addFunc(.{
......@@ -4330,9 +4352,8 @@ fn testDecl(
43304352 // As our last action before the return, "pop" the error trace if needed
43314353 _ = try gz.addRestoreErrRetIndex(.ret, .always);
43324354
4333 // Since we are adding the return instruction here, we must handle the coercion.
4334 // We do this by using the `ret_tok` instruction.
4335 _ = try fn_block.addUnTok(.ret_tok, .void_value, tree.lastToken(body_node));
4355 // Add implicit return at end of function.
4356 _ = try fn_block.addUnTok(.ret_implicit, .void_value, tree.lastToken(body_node));
43364357 }
43374358
43384359 const func_inst = try decl_block.addFunc(.{
......@@ -5580,6 +5601,14 @@ fn simpleBinOp(
55805601 const tree = astgen.tree;
55815602 const node_datas = tree.nodes.items(.data);
55825603
5604 if (op_inst_tag == .cmp_neq or op_inst_tag == .cmp_eq) {
5605 const node_tags = tree.nodes.items(.tag);
5606 const str = if (op_inst_tag == .cmp_eq) "==" else "!=";
5607 if (node_tags[node_datas[node].lhs] == .string_literal or
5608 node_tags[node_datas[node].rhs] == .string_literal)
5609 return astgen.failNode(node, "cannot compare strings with {s}", .{str});
5610 }
5611
55835612 const lhs = try reachableExpr(gz, scope, .{ .rl = .none }, node_datas[node].lhs, node);
55845613 var line: u32 = undefined;
55855614 var column: u32 = undefined;
......@@ -6577,6 +6606,11 @@ fn switchExpr(
65776606 continue;
65786607 }
65796608
6609 for (case.ast.values) |val| {
6610 if (node_tags[val] == .string_literal)
6611 return astgen.failNode(val, "cannot switch on strings", .{});
6612 }
6613
65806614 if (case.ast.values.len == 1 and node_tags[case.ast.values[0]] != .switch_range) {
65816615 scalar_cases_len += 1;
65826616 } else {
src/Module.zig+2
......@@ -938,6 +938,7 @@ pub const Struct = struct {
938938 known_non_opv: bool,
939939 requires_comptime: PropertyBoolean = .unknown,
940940 have_field_inits: bool = false,
941 assumed_runtime_bits: bool = false,
941942
942943 pub const Fields = std.StringArrayHashMapUnmanaged(Field);
943944
......@@ -1203,6 +1204,7 @@ pub const Union = struct {
12031204 fully_resolved,
12041205 },
12051206 requires_comptime: PropertyBoolean = .unknown,
1207 assumed_runtime_bits: bool = false,
12061208
12071209 pub const Field = struct {
12081210 /// undefined until `status` is `have_field_types` or `have_layout`.
src/Sema.zig+106-27
......@@ -195,8 +195,8 @@ pub const Block = struct {
195195 try sema.errNote(ci.block, ci.src, parent, prefix ++ "it is inside a @cImport", .{});
196196 },
197197 .comptime_ret_ty => |rt| {
198 const src_loc = if (try sema.funcDeclSrc(rt.func)) |capture| blk: {
199 var src_loc = capture;
198 const src_loc = if (try sema.funcDeclSrc(rt.func)) |fn_decl| blk: {
199 var src_loc = fn_decl.srcLoc();
200200 src_loc.lazy = .{ .node_offset_fn_type_ret_ty = 0 };
201201 break :blk src_loc;
202202 } else blk: {
......@@ -1000,7 +1000,7 @@ fn analyzeBodyInner(
10001000 // These functions match the return type of analyzeBody so that we can
10011001 // tail call them here.
10021002 .compile_error => break sema.zirCompileError(block, inst),
1003 .ret_tok => break sema.zirRetTok(block, inst),
1003 .ret_implicit => break sema.zirRetImplicit(block, inst),
10041004 .ret_node => break sema.zirRetNode(block, inst),
10051005 .ret_load => break sema.zirRetLoad(block, inst),
10061006 .ret_err_value => break sema.zirRetErrValue(block, inst),
......@@ -5745,7 +5745,7 @@ fn lookupInNamespace(
57455745 return null;
57465746}
57475747
5748fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?Module.SrcLoc {
5748fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl {
57495749 const func_val = (try sema.resolveMaybeUndefVal(func_inst)) orelse return null;
57505750 if (func_val.isUndef()) return null;
57515751 const owner_decl_index = switch (func_val.tag()) {
......@@ -5754,8 +5754,7 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?Module.SrcLoc {
57545754 .decl_ref => sema.mod.declPtr(func_val.castTag(.decl_ref).?.data).val.castTag(.function).?.data.owner_decl,
57555755 else => return null,
57565756 };
5757 const owner_decl = sema.mod.declPtr(owner_decl_index);
5758 return owner_decl.srcLoc();
5757 return sema.mod.declPtr(owner_decl_index);
57595758}
57605759
57615760pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref {
......@@ -5933,7 +5932,7 @@ fn zirCall(
59335932 break :check_args;
59345933 }
59355934
5936 const decl_src = try sema.funcDeclSrc(func);
5935 const maybe_decl = try sema.funcDeclSrc(func);
59375936 const member_str = if (bound_arg_src != null) "member function " else "";
59385937 const variadic_str = if (func_ty_info.is_var_args) "at least " else "";
59395938 const msg = msg: {
......@@ -5950,7 +5949,7 @@ fn zirCall(
59505949 );
59515950 errdefer msg.destroy(sema.gpa);
59525951
5953 if (decl_src) |some| try sema.mod.errNoteNonLazy(some, msg, "function declared here", .{});
5952 if (maybe_decl) |fn_decl| try sema.mod.errNoteNonLazy(fn_decl.srcLoc(), msg, "function declared here", .{});
59545953 break :msg msg;
59555954 };
59565955 return sema.failWithOwnedErrorMsg(msg);
......@@ -6144,7 +6143,7 @@ fn analyzeCall(
61446143 const func_ty_info = func_ty.fnInfo();
61456144 const cc = func_ty_info.cc;
61466145 if (cc == .Naked) {
6147 const decl_src = try sema.funcDeclSrc(func);
6146 const maybe_decl = try sema.funcDeclSrc(func);
61486147 const msg = msg: {
61496148 const msg = try sema.errMsg(
61506149 block,
......@@ -6154,7 +6153,7 @@ fn analyzeCall(
61546153 );
61556154 errdefer msg.destroy(sema.gpa);
61566155
6157 if (decl_src) |some| try sema.mod.errNoteNonLazy(some, msg, "function declared here", .{});
6156 if (maybe_decl) |fn_decl| try sema.mod.errNoteNonLazy(fn_decl.srcLoc(), msg, "function declared here", .{});
61586157 break :msg msg;
61596158 };
61606159 return sema.failWithOwnedErrorMsg(msg);
......@@ -6388,6 +6387,7 @@ fn analyzeCall(
63886387 &should_memoize,
63896388 memoized_call_key,
63906389 func_ty_info.param_types,
6390 func,
63916391 ) catch |err| switch (err) {
63926392 error.NeededSourceLocation => {
63936393 _ = sema.inst_map.remove(inst);
......@@ -6404,6 +6404,7 @@ fn analyzeCall(
64046404 &should_memoize,
64056405 memoized_call_key,
64066406 func_ty_info.param_types,
6407 func,
64076408 );
64086409 return error.AnalysisFail;
64096410 },
......@@ -6546,12 +6547,17 @@ fn analyzeCall(
65466547 const args = try sema.arena.alloc(Air.Inst.Ref, uncasted_args.len);
65476548 for (uncasted_args) |uncasted_arg, i| {
65486549 if (i < fn_params_len) {
6550 const opts: CoerceOpts = .{ .param_src = .{
6551 .func_inst = func,
6552 .param_i = @intCast(u32, i),
6553 } };
65496554 const param_ty = func_ty.fnParamType(i);
65506555 args[i] = sema.analyzeCallArg(
65516556 block,
65526557 .unneeded,
65536558 param_ty,
65546559 uncasted_arg,
6560 opts,
65556561 ) catch |err| switch (err) {
65566562 error.NeededSourceLocation => {
65576563 const decl = sema.mod.declPtr(block.src_decl);
......@@ -6560,6 +6566,7 @@ fn analyzeCall(
65606566 Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i, bound_arg_src),
65616567 param_ty,
65626568 uncasted_arg,
6569 opts,
65636570 );
65646571 return error.AnalysisFail;
65656572 },
......@@ -6641,6 +6648,7 @@ fn analyzeInlineCallArg(
66416648 should_memoize: *bool,
66426649 memoized_call_key: Module.MemoizedCall.Key,
66436650 raw_param_types: []const Type,
6651 func_inst: Air.Inst.Ref,
66446652) !void {
66456653 const zir_tags = sema.code.instructions.items(.tag);
66466654 switch (zir_tags[inst]) {
......@@ -6665,7 +6673,13 @@ fn analyzeInlineCallArg(
66656673 return err;
66666674 };
66676675 }
6668 const casted_arg = try sema.coerce(arg_block, param_ty, uncasted_arg, arg_src);
6676 const casted_arg = sema.coerceExtra(arg_block, param_ty, uncasted_arg, arg_src, .{ .param_src = .{
6677 .func_inst = func_inst,
6678 .param_i = @intCast(u32, arg_i.*),
6679 } }) catch |err| switch (err) {
6680 error.NotCoercible => unreachable,
6681 else => |e| return e,
6682 };
66696683
66706684 if (is_comptime_call) {
66716685 try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg);
......@@ -6755,9 +6769,13 @@ fn analyzeCallArg(
67556769 arg_src: LazySrcLoc,
67566770 param_ty: Type,
67576771 uncasted_arg: Air.Inst.Ref,
6772 opts: CoerceOpts,
67586773) !Air.Inst.Ref {
67596774 try sema.resolveTypeFully(param_ty);
6760 return sema.coerce(block, param_ty, uncasted_arg, arg_src);
6775 return sema.coerceExtra(block, param_ty, uncasted_arg, arg_src, opts) catch |err| switch (err) {
6776 error.NotCoercible => unreachable,
6777 else => |e| return e,
6778 };
67616779}
67626780
67636781fn analyzeGenericCallArg(
......@@ -16398,7 +16416,7 @@ fn zirRetErrValue(
1639816416 return sema.analyzeRet(block, result_inst, src);
1639916417}
1640016418
16401fn zirRetTok(
16419fn zirRetImplicit(
1640216420 sema: *Sema,
1640316421 block: *Block,
1640416422 inst: Zir.Inst.Index,
......@@ -16408,9 +16426,33 @@ fn zirRetTok(
1640816426
1640916427 const inst_data = sema.code.instructions.items(.data)[inst].un_tok;
1641016428 const operand = try sema.resolveInst(inst_data.operand);
16411 const src = inst_data.src();
1641216429
16413 return sema.analyzeRet(block, operand, src);
16430 const r_brace_src = inst_data.src();
16431 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };
16432 const base_tag = sema.fn_ret_ty.baseZigTypeTag();
16433 if (base_tag == .NoReturn) {
16434 const msg = msg: {
16435 const msg = try sema.errMsg(block, ret_ty_src, "function declared '{}' implicitly returns", .{
16436 sema.fn_ret_ty.fmt(sema.mod),
16437 });
16438 errdefer msg.destroy(sema.gpa);
16439 try sema.errNote(block, r_brace_src, msg, "control flow reaches end of body here", .{});
16440 break :msg msg;
16441 };
16442 return sema.failWithOwnedErrorMsg(msg);
16443 } else if (base_tag != .Void) {
16444 const msg = msg: {
16445 const msg = try sema.errMsg(block, ret_ty_src, "function with non-void return type '{}' implicitly returns", .{
16446 sema.fn_ret_ty.fmt(sema.mod),
16447 });
16448 errdefer msg.destroy(sema.gpa);
16449 try sema.errNote(block, r_brace_src, msg, "control flow reaches end of body here", .{});
16450 break :msg msg;
16451 };
16452 return sema.failWithOwnedErrorMsg(msg);
16453 }
16454
16455 return sema.analyzeRet(block, operand, .unneeded);
1641416456}
1641516457
1641616458fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {
......@@ -16677,7 +16719,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1667716719 const bitoffset_src: LazySrcLoc = .{ .node_offset_ptr_bitoffset = extra.data.src_node };
1667816720 const hostsize_src: LazySrcLoc = .{ .node_offset_ptr_hostsize = extra.data.src_node };
1667916721
16680 const unresolved_elem_ty = blk: {
16722 const elem_ty = blk: {
1668116723 const air_inst = try sema.resolveInst(extra.data.elem_type);
1668216724 const ty = sema.analyzeAsType(block, elem_ty_src, air_inst) catch |err| {
1668316725 if (err == error.AnalysisFail and sema.err != null and sema.typeOf(air_inst).isSinglePointer()) {
......@@ -16706,7 +16748,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1670616748 // Check if this happens to be the lazy alignment of our element type, in
1670716749 // which case we can make this 0 without resolving it.
1670816750 if (val.castTag(.lazy_align)) |payload| {
16709 if (payload.data.eql(unresolved_elem_ty, sema.mod)) {
16751 if (payload.data.eql(elem_ty, sema.mod)) {
1671016752 break :blk 0;
1671116753 }
1671216754 }
......@@ -16739,14 +16781,6 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1673916781 return sema.fail(block, bitoffset_src, "bit offset starts after end of host integer", .{});
1674016782 }
1674116783
16742 const elem_ty = if (abi_align == 0)
16743 unresolved_elem_ty
16744 else t: {
16745 const elem_ty = try sema.resolveTypeFields(unresolved_elem_ty);
16746 try sema.resolveTypeLayout(elem_ty);
16747 break :t elem_ty;
16748 };
16749
1675016784 if (elem_ty.zigTypeTag() == .NoReturn) {
1675116785 return sema.fail(block, elem_ty_src, "pointer to noreturn not allowed", .{});
1675216786 } else if (elem_ty.zigTypeTag() == .Fn) {
......@@ -20173,7 +20207,7 @@ fn analyzeShuffle(
2017320207 var buf: Value.ElemValueBuffer = undefined;
2017420208 const elem = mask.elemValueBuffer(sema.mod, i, &buf);
2017520209 if (elem.isUndef()) continue;
20176 const int = elem.toSignedInt();
20210 const int = elem.toSignedInt(sema.mod.getTarget());
2017720211 var unsigned: u32 = undefined;
2017820212 var chosen: u32 = undefined;
2017920213 if (int >= 0) {
......@@ -20215,7 +20249,7 @@ fn analyzeShuffle(
2021520249 values[i] = Value.undef;
2021620250 continue;
2021720251 }
20218 const int = mask_elem_val.toSignedInt();
20252 const int = mask_elem_val.toSignedInt(sema.mod.getTarget());
2021920253 const unsigned = if (int >= 0) @intCast(u32, int) else @intCast(u32, ~int);
2022020254 if (int >= 0) {
2022120255 values[i] = try a_val.elemValue(sema.mod, sema.arena, unsigned);
......@@ -23957,6 +23991,25 @@ const CoerceOpts = struct {
2395723991 is_ret: bool = false,
2395823992 /// Should coercion to comptime_int ermit an error message.
2395923993 no_cast_to_comptime_int: bool = false,
23994
23995 param_src: struct {
23996 func_inst: Air.Inst.Ref = .none,
23997 param_i: u32 = undefined,
23998
23999 fn get(info: @This(), sema: *Sema) !?Module.SrcLoc {
24000 if (info.func_inst == .none) return null;
24001 const fn_decl = (try sema.funcDeclSrc(info.func_inst)) orelse return null;
24002 const param_src = Module.paramSrc(0, sema.gpa, fn_decl, info.param_i);
24003 if (param_src == .node_offset_param) {
24004 return Module.SrcLoc{
24005 .file_scope = fn_decl.getFileScope(),
24006 .parent_decl_node = fn_decl.src_node,
24007 .lazy = LazySrcLoc.nodeOffset(param_src.node_offset_param),
24008 };
24009 }
24010 return param_src.toSrcLoc(fn_decl);
24011 }
24012 } = .{},
2396024013};
2396124014
2396224015fn coerceExtra(
......@@ -24610,6 +24663,10 @@ fn coerceExtra(
2461024663 }
2461124664 }
2461224665
24666 if (try opts.param_src.get(sema)) |param_src| {
24667 try sema.mod.errNoteNonLazy(param_src, msg, "parameter type declared here", .{});
24668 }
24669
2461324670 // TODO maybe add "cannot store an error in type '{}'" note
2461424671
2461524672 break :msg msg;
......@@ -28212,6 +28269,7 @@ fn cmpNumeric(
2821228269
2821328270 var lhs_bits: usize = undefined;
2821428271 if (try sema.resolveMaybeUndefVal(lhs)) |lhs_val| {
28272 try sema.resolveLazyValue(lhs_val);
2821528273 if (lhs_val.isUndef())
2821628274 return sema.addConstUndef(Type.bool);
2821728275 if (lhs_val.isNan()) switch (op) {
......@@ -28265,6 +28323,7 @@ fn cmpNumeric(
2826528323
2826628324 var rhs_bits: usize = undefined;
2826728325 if (try sema.resolveMaybeUndefVal(rhs)) |rhs_val| {
28326 try sema.resolveLazyValue(rhs_val);
2826828327 if (rhs_val.isUndef())
2826928328 return sema.addConstUndef(Type.bool);
2827028329 if (rhs_val.isNan()) switch (op) {
......@@ -29132,6 +29191,16 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
2913229191
2913329192 struct_obj.status = .have_layout;
2913429193 _ = try sema.resolveTypeRequiresComptime(resolved_ty);
29194
29195 if (struct_obj.assumed_runtime_bits and !resolved_ty.hasRuntimeBits()) {
29196 const msg = try Module.ErrorMsg.create(
29197 sema.gpa,
29198 struct_obj.srcLoc(sema.mod),
29199 "struct layout depends on it having runtime bits",
29200 .{},
29201 );
29202 return sema.failWithOwnedErrorMsg(msg);
29203 }
2913529204 }
2913629205 // otherwise it's a tuple; no need to resolve anything
2913729206}
......@@ -29296,6 +29365,16 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
2929629365 }
2929729366 union_obj.status = .have_layout;
2929829367 _ = try sema.resolveTypeRequiresComptime(resolved_ty);
29368
29369 if (union_obj.assumed_runtime_bits and !resolved_ty.hasRuntimeBits()) {
29370 const msg = try Module.ErrorMsg.create(
29371 sema.gpa,
29372 union_obj.srcLoc(sema.mod),
29373 "union layout depends on it having runtime bits",
29374 .{},
29375 );
29376 return sema.failWithOwnedErrorMsg(msg);
29377 }
2929929378}
2930029379
2930129380// In case of querying the ABI alignment of this struct, we will ask
src/Zir.zig+4-4
......@@ -519,7 +519,7 @@ pub const Inst = struct {
519519 /// Includes an operand as the return value.
520520 /// Includes a token source location.
521521 /// Uses the `un_tok` union field.
522 ret_tok,
522 ret_implicit,
523523 /// Sends control flow back to the function's callee.
524524 /// The return operand is `error.foo` where `foo` is given by the string.
525525 /// If the current function has an inferred error set, the error given by the
......@@ -1256,7 +1256,7 @@ pub const Inst = struct {
12561256 .compile_error,
12571257 .ret_node,
12581258 .ret_load,
1259 .ret_tok,
1259 .ret_implicit,
12601260 .ret_err_value,
12611261 .@"unreachable",
12621262 .repeat,
......@@ -1530,7 +1530,7 @@ pub const Inst = struct {
15301530 .compile_error,
15311531 .ret_node,
15321532 .ret_load,
1533 .ret_tok,
1533 .ret_implicit,
15341534 .ret_err_value,
15351535 .ret_ptr,
15361536 .ret_type,
......@@ -1659,7 +1659,7 @@ pub const Inst = struct {
16591659 .ref = .un_tok,
16601660 .ret_node = .un_node,
16611661 .ret_load = .un_node,
1662 .ret_tok = .un_tok,
1662 .ret_implicit = .un_tok,
16631663 .ret_err_value = .str_tok,
16641664 .ret_err_value_code = .str_tok,
16651665 .ret_ptr = .node,
src/arch/aarch64/CodeGen.zig+1-1
......@@ -6083,7 +6083,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
60836083 if (info.bits <= 64) {
60846084 const unsigned = switch (info.signedness) {
60856085 .signed => blk: {
6086 const signed = typed_value.val.toSignedInt();
6086 const signed = typed_value.val.toSignedInt(target);
60876087 break :blk @bitCast(u64, signed);
60886088 },
60896089 .unsigned => typed_value.val.toUnsignedInt(target),
src/arch/arm/CodeGen.zig+1-1
......@@ -6121,7 +6121,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
61216121 if (info.bits <= ptr_bits) {
61226122 const unsigned = switch (info.signedness) {
61236123 .signed => blk: {
6124 const signed = @intCast(i32, typed_value.val.toSignedInt());
6124 const signed = @intCast(i32, typed_value.val.toSignedInt(target));
61256125 break :blk @bitCast(u32, signed);
61266126 },
61276127 .unsigned => @intCast(u32, typed_value.val.toUnsignedInt(target)),
src/arch/sparc64/CodeGen.zig+1-1
......@@ -3786,7 +3786,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
37863786 if (info.bits <= 64) {
37873787 const unsigned = switch (info.signedness) {
37883788 .signed => blk: {
3789 const signed = typed_value.val.toSignedInt();
3789 const signed = typed_value.val.toSignedInt(target);
37903790 break :blk @bitCast(u64, signed);
37913791 },
37923792 .unsigned => typed_value.val.toUnsignedInt(target),
src/arch/wasm/CodeGen.zig+5-5
......@@ -2604,11 +2604,11 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
26042604 switch (int_info.signedness) {
26052605 .signed => switch (int_info.bits) {
26062606 0...32 => return WValue{ .imm32 = @intCast(u32, toTwosComplement(
2607 val.toSignedInt(),
2607 val.toSignedInt(target),
26082608 @intCast(u6, int_info.bits),
26092609 )) },
26102610 33...64 => return WValue{ .imm64 = toTwosComplement(
2611 val.toSignedInt(),
2611 val.toSignedInt(target),
26122612 @intCast(u7, int_info.bits),
26132613 ) },
26142614 else => unreachable,
......@@ -2758,15 +2758,15 @@ fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {
27582758 }
27592759 },
27602760 .Int => switch (ty.intInfo(func.target).signedness) {
2761 .signed => return @truncate(i32, val.toSignedInt()),
2761 .signed => return @truncate(i32, val.toSignedInt(target)),
27622762 .unsigned => return @bitCast(i32, @truncate(u32, val.toUnsignedInt(target))),
27632763 },
27642764 .ErrorSet => {
27652765 const kv = func.bin_file.base.options.module.?.getErrorValue(val.getError().?) catch unreachable; // passed invalid `Value` to function
27662766 return @bitCast(i32, kv.value);
27672767 },
2768 .Bool => return @intCast(i32, val.toSignedInt()),
2769 .Pointer => return @intCast(i32, val.toSignedInt()),
2768 .Bool => return @intCast(i32, val.toSignedInt(target)),
2769 .Pointer => return @intCast(i32, val.toSignedInt(target)),
27702770 else => unreachable, // Programmer called this function for an illegal type
27712771 }
27722772}
src/arch/x86_64/CodeGen.zig+1-1
......@@ -7007,7 +7007,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
70077007 .Int => {
70087008 const info = typed_value.ty.intInfo(self.target.*);
70097009 if (info.bits <= ptr_bits and info.signedness == .signed) {
7010 return MCValue{ .immediate = @bitCast(u64, typed_value.val.toSignedInt()) };
7010 return MCValue{ .immediate = @bitCast(u64, typed_value.val.toSignedInt(target)) };
70117011 }
70127012 if (!(info.bits > ptr_bits or info.signedness == .signed)) {
70137013 return MCValue{ .immediate = typed_value.val.toUnsignedInt(target) };
src/codegen.zig+7-7
......@@ -459,7 +459,7 @@ pub fn generateSymbol(
459459 if (info.bits <= 8) {
460460 const x: u8 = switch (info.signedness) {
461461 .unsigned => @intCast(u8, typed_value.val.toUnsignedInt(target)),
462 .signed => @bitCast(u8, @intCast(i8, typed_value.val.toSignedInt())),
462 .signed => @bitCast(u8, @intCast(i8, typed_value.val.toSignedInt(target))),
463463 };
464464 try code.append(x);
465465 return Result{ .appended = {} };
......@@ -488,13 +488,13 @@ pub fn generateSymbol(
488488 },
489489 .signed => {
490490 if (info.bits <= 16) {
491 const x = @intCast(i16, typed_value.val.toSignedInt());
491 const x = @intCast(i16, typed_value.val.toSignedInt(target));
492492 mem.writeInt(i16, try code.addManyAsArray(2), x, endian);
493493 } else if (info.bits <= 32) {
494 const x = @intCast(i32, typed_value.val.toSignedInt());
494 const x = @intCast(i32, typed_value.val.toSignedInt(target));
495495 mem.writeInt(i32, try code.addManyAsArray(4), x, endian);
496496 } else {
497 const x = typed_value.val.toSignedInt();
497 const x = typed_value.val.toSignedInt(target);
498498 mem.writeInt(i64, try code.addManyAsArray(8), x, endian);
499499 }
500500 },
......@@ -536,13 +536,13 @@ pub fn generateSymbol(
536536 },
537537 .signed => {
538538 if (info.bits <= 16) {
539 const x = @intCast(i16, int_val.toSignedInt());
539 const x = @intCast(i16, int_val.toSignedInt(target));
540540 mem.writeInt(i16, try code.addManyAsArray(2), x, endian);
541541 } else if (info.bits <= 32) {
542 const x = @intCast(i32, int_val.toSignedInt());
542 const x = @intCast(i32, int_val.toSignedInt(target));
543543 mem.writeInt(i32, try code.addManyAsArray(4), x, endian);
544544 } else {
545 const x = int_val.toSignedInt();
545 const x = int_val.toSignedInt(target);
546546 mem.writeInt(i64, try code.addManyAsArray(8), x, endian);
547547 }
548548 },
src/codegen/llvm.zig+1-1
......@@ -8934,7 +8934,7 @@ pub const FuncGen = struct {
89348934 if (elem.isUndef()) {
89358935 val.* = llvm_i32.getUndef();
89368936 } else {
8937 const int = elem.toSignedInt();
8937 const int = elem.toSignedInt(self.dg.module.getTarget());
89388938 const unsigned = if (int >= 0) @intCast(u32, int) else @intCast(u32, ~int + a_len);
89398939 val.* = llvm_i32.constInt(unsigned, .False);
89408940 }
src/codegen/spirv.zig+1-1
......@@ -345,7 +345,7 @@ pub const DeclGen = struct {
345345
346346 // Note, value is required to be sign-extended, so we don't need to mask off the upper bits.
347347 // See https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html#Literal
348 var int_bits = if (ty.isSignedInt()) @bitCast(u64, val.toSignedInt()) else val.toUnsignedInt(target);
348 var int_bits = if (ty.isSignedInt()) @bitCast(u64, val.toSignedInt(target)) else val.toUnsignedInt(target);
349349
350350 const value: spec.LiteralContextDependentNumber = switch (backing_bits) {
351351 1...32 => .{ .uint32 = @truncate(u32, int_bits) },
src/link/Dwarf.zig+1-1
......@@ -409,7 +409,7 @@ pub const DeclState = struct {
409409 // See https://github.com/ziglang/zig/issues/645
410410 var int_buffer: Value.Payload.U64 = undefined;
411411 const field_int_val = value.enumToInt(ty, &int_buffer);
412 break :value @bitCast(u64, field_int_val.toSignedInt());
412 break :value @bitCast(u64, field_int_val.toSignedInt(target));
413413 } else @intCast(u64, field_i);
414414 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), value, target_endian);
415415 }
src/print_zir.zig+1-1
......@@ -235,7 +235,7 @@ const Writer = struct {
235235 => try self.writeUnNode(stream, inst),
236236
237237 .ref,
238 .ret_tok,
238 .ret_implicit,
239239 .closure_capture,
240240 .switch_capture_tag,
241241 => try self.writeUnTok(stream, inst),
src/type.zig+46-8
......@@ -160,6 +160,17 @@ pub const Type = extern union {
160160 }
161161 }
162162
163 pub fn baseZigTypeTag(self: Type) std.builtin.TypeId {
164 return switch (self.zigTypeTag()) {
165 .ErrorUnion => self.errorUnionPayload().baseZigTypeTag(),
166 .Optional => {
167 var buf: Payload.ElemType = undefined;
168 return self.optionalChild(&buf).baseZigTypeTag();
169 },
170 else => |t| t,
171 };
172 }
173
163174 pub fn isSelfComparable(ty: Type, is_equality_cmp: bool) bool {
164175 return switch (ty.zigTypeTag()) {
165176 .Int,
......@@ -2459,6 +2470,7 @@ pub const Type = extern union {
24592470 if (struct_obj.status == .field_types_wip) {
24602471 // In this case, we guess that hasRuntimeBits() for this type is true,
24612472 // and then later if our guess was incorrect, we emit a compile error.
2473 struct_obj.assumed_runtime_bits = true;
24622474 return true;
24632475 }
24642476 switch (strat) {
......@@ -2491,6 +2503,12 @@ pub const Type = extern union {
24912503
24922504 .@"union" => {
24932505 const union_obj = ty.castTag(.@"union").?.data;
2506 if (union_obj.status == .field_types_wip) {
2507 // In this case, we guess that hasRuntimeBits() for this type is true,
2508 // and then later if our guess was incorrect, we emit a compile error.
2509 union_obj.assumed_runtime_bits = true;
2510 return true;
2511 }
24942512 switch (strat) {
24952513 .sema => |sema| _ = try sema.resolveTypeFields(ty),
24962514 .eager => assert(union_obj.haveFieldTypes()),
......@@ -3027,8 +3045,9 @@ pub const Type = extern union {
30273045 const struct_obj = ty.castTag(.@"struct").?.data;
30283046 if (opt_sema) |sema| {
30293047 if (struct_obj.status == .field_types_wip) {
3030 // We'll guess "pointer-aligned" and if we guess wrong, emit
3031 // a compile error later.
3048 // We'll guess "pointer-aligned", if the struct has an
3049 // underaligned pointer field then some allocations
3050 // might require explicit alignment.
30323051 return AbiAlignmentAdvanced{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) };
30333052 }
30343053 _ = try sema.resolveTypeFields(ty);
......@@ -3153,8 +3172,9 @@ pub const Type = extern union {
31533172 };
31543173 if (opt_sema) |sema| {
31553174 if (union_obj.status == .field_types_wip) {
3156 // We'll guess "pointer-aligned" and if we guess wrong, emit
3157 // a compile error later.
3175 // We'll guess "pointer-aligned", if the union has an
3176 // underaligned pointer field then some allocations
3177 // might require explicit alignment.
31583178 return AbiAlignmentAdvanced{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) };
31593179 }
31603180 _ = try sema.resolveTypeFields(ty);
......@@ -5233,7 +5253,12 @@ pub const Type = extern union {
52335253 .@"struct" => {
52345254 const struct_obj = ty.castTag(.@"struct").?.data;
52355255 switch (struct_obj.requires_comptime) {
5236 .wip, .unknown => unreachable, // This function asserts types already resolved.
5256 .wip, .unknown => {
5257 // Return false to avoid incorrect dependency loops.
5258 // This will be handled correctly once merged with
5259 // `Sema.typeRequiresComptime`.
5260 return false;
5261 },
52375262 .no => return false,
52385263 .yes => return true,
52395264 }
......@@ -5242,7 +5267,12 @@ pub const Type = extern union {
52425267 .@"union", .union_safety_tagged, .union_tagged => {
52435268 const union_obj = ty.cast(Type.Payload.Union).?.data;
52445269 switch (union_obj.requires_comptime) {
5245 .wip, .unknown => unreachable, // This function asserts types already resolved.
5270 .wip, .unknown => {
5271 // Return false to avoid incorrect dependency loops.
5272 // This will be handled correctly once merged with
5273 // `Sema.typeRequiresComptime`.
5274 return false;
5275 },
52465276 .no => return false,
52475277 .yes => return true,
52485278 }
......@@ -6454,8 +6484,16 @@ pub const Type = extern union {
64546484 // type, we change it to 0 here. If this causes an assertion trip because the
64556485 // pointee type needs to be resolved more, that needs to be done before calling
64566486 // this ptr() function.
6457 if (d.@"align" != 0 and d.@"align" == d.pointee_type.abiAlignment(target)) {
6458 d.@"align" = 0;
6487 if (d.@"align" != 0) canonicalize: {
6488 if (d.pointee_type.castTag(.@"struct")) |struct_ty| {
6489 if (!struct_ty.data.haveLayout()) break :canonicalize;
6490 }
6491 if (d.pointee_type.cast(Payload.Union)) |union_ty| {
6492 if (!union_ty.data.haveLayout()) break :canonicalize;
6493 }
6494 if (d.@"align" == d.pointee_type.abiAlignment(target)) {
6495 d.@"align" = 0;
6496 }
64596497 }
64606498
64616499 // Canonicalize host_size. If it matches the bit size of the pointee type,
src/value.zig+16-7
......@@ -187,7 +187,7 @@ pub const Value = extern union {
187187 bound_fn,
188188 /// The ABI alignment of the payload type.
189189 lazy_align,
190 /// The ABI alignment of the payload type.
190 /// The ABI size of the payload type.
191191 lazy_size,
192192
193193 pub const last_no_payload_tag = Tag.empty_array;
......@@ -1201,8 +1201,8 @@ pub const Value = extern union {
12011201 }
12021202
12031203 /// Asserts the value is an integer and it fits in a i64
1204 pub fn toSignedInt(self: Value) i64 {
1205 switch (self.tag()) {
1204 pub fn toSignedInt(val: Value, target: Target) i64 {
1205 switch (val.tag()) {
12061206 .zero,
12071207 .bool_false,
12081208 .the_only_possible_value, // i0, u0
......@@ -1212,10 +1212,19 @@ pub const Value = extern union {
12121212 .bool_true,
12131213 => return 1,
12141214
1215 .int_u64 => return @intCast(i64, self.castTag(.int_u64).?.data),
1216 .int_i64 => return self.castTag(.int_i64).?.data,
1217 .int_big_positive => return self.castTag(.int_big_positive).?.asBigInt().to(i64) catch unreachable,
1218 .int_big_negative => return self.castTag(.int_big_negative).?.asBigInt().to(i64) catch unreachable,
1215 .int_u64 => return @intCast(i64, val.castTag(.int_u64).?.data),
1216 .int_i64 => return val.castTag(.int_i64).?.data,
1217 .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt().to(i64) catch unreachable,
1218 .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(i64) catch unreachable,
1219
1220 .lazy_align => {
1221 const ty = val.castTag(.lazy_align).?.data;
1222 return @intCast(i64, ty.abiAlignment(target));
1223 },
1224 .lazy_size => {
1225 const ty = val.castTag(.lazy_size).?.data;
1226 return @intCast(i64, ty.abiSize(target));
1227 },
12191228
12201229 .undef => unreachable,
12211230 else => unreachable,
test/behavior.zig+1
......@@ -90,6 +90,7 @@ test {
9090 _ = @import("behavior/bugs/12430.zig");
9191 _ = @import("behavior/bugs/12486.zig");
9292 _ = @import("behavior/bugs/12488.zig");
93 _ = @import("behavior/bugs/12498.zig");
9394 _ = @import("behavior/bugs/12551.zig");
9495 _ = @import("behavior/bugs/12644.zig");
9596 _ = @import("behavior/bugs/12680.zig");
test/behavior/bugs/12498.zig created+8
......@@ -0,0 +1,8 @@
1const std = @import("std");
2const expect = std.testing.expect;
3
4const S = struct { a: usize };
5test "lazy abi size used in comparison" {
6 var rhs: i32 = 100;
7 try expect(@sizeOf(S) < rhs);
8}
test/behavior/struct.zig+12
......@@ -1418,3 +1418,15 @@ test "address of zero-bit field is equal to address of only field" {
14181418 try std.testing.expectEqual(&a, a_ptr);
14191419 }
14201420}
1421
1422test "struct field has a pointer to an aligned version of itself" {
1423 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1424
1425 const E = struct {
1426 next: *align(1) @This(),
1427 };
1428 var e: E = undefined;
1429 e = .{ .next = &e };
1430
1431 try expect(&e == e.next);
1432}
test/cases/aarch64-macos/hello_world_with_updates.1.zig+2-2
......@@ -2,5 +2,5 @@ pub export fn main() noreturn {}
22
33// error
44//
5// :1:32: error: function declared 'noreturn' returns
6// :1:22: note: 'noreturn' declared here
5// :1:22: error: function declared 'noreturn' implicitly returns
6// :1:32: note: control flow reaches end of body here
test/cases/compile_errors/calling_var_args_extern_function_passing_array_instead_of_pointer.zig+1
......@@ -8,3 +8,4 @@ pub extern fn foo(format: *const u8, ...) void;
88// target=native
99//
1010// :2:16: error: expected type '*const u8', found '[5:0]u8'
11// :4:27: note: parameter type declared here
test/cases/compile_errors/casting_bit_offset_pointer_to_regular_pointer.zig+1
......@@ -21,3 +21,4 @@ export fn entry() usize { return @sizeOf(@TypeOf(&foo)); }
2121// :8:16: error: expected type '*const u3', found '*align(0:3:1) const u3'
2222// :8:16: note: pointer host size '1' cannot cast into pointer host size '0'
2323// :8:16: note: pointer bit offset '3' cannot cast into pointer bit offset '0'
24// :11:11: note: parameter type declared here
test/cases/compile_errors/closure_get_in_param_ty_instantiate_incorrectly.zig+1
......@@ -22,3 +22,4 @@ pub export fn entry() void {
2222// target=native
2323//
2424// :17:25: error: expected type 'u32', found 'type'
25// :3:21: note: parameter type declared here
test/cases/compile_errors/control_reaches_end_of_non-void_function.zig deleted-9
......@@ -1,9 +0,0 @@
1fn a() i32 {}
2export fn entry() void { _ = a(); }
3
4// error
5// backend=stage2
6// target=native
7//
8// :1:13: error: expected type 'i32', found 'void'
9// :1:8: note: function return type declared here
test/cases/compile_errors/disallow_coercion_from_non-null-terminated_pointer_to_null-terminated_pointer.zig+1
......@@ -11,3 +11,4 @@ pub export fn entry() void {
1111//
1212// :5:14: error: expected type '[*:0]const u8', found '[*]const u8'
1313// :5:14: note: destination pointer requires '0' sentinel
14// :1:20: note: parameter type declared here
test/cases/compile_errors/double_pointer_to_anyopaque_pointer.zig+1
......@@ -24,5 +24,6 @@ pub export fn entry3() void {
2424// :4:35: note: cannot implicitly cast double pointer '*const *const usize' to anyopaque pointer '*const anyopaque'
2525// :9:10: error: expected type '?*anyopaque', found '*[*:0]u8'
2626// :9:10: note: cannot implicitly cast double pointer '*[*:0]u8' to anyopaque pointer '?*anyopaque'
27// :11:12: note: parameter type declared here
2728// :15:35: error: expected type '*const anyopaque', found '*?*usize'
2829// :15:35: note: cannot implicitly cast double pointer '*?*usize' to anyopaque pointer '*const anyopaque'
test/cases/compile_errors/implicitly_increasing_pointer_alignment.zig+1
......@@ -18,3 +18,4 @@ fn bar(x: *u32) void {
1818//
1919// :8:9: error: expected type '*u32', found '*align(1) u32'
2020// :8:9: note: pointer alignment '1' cannot cast into pointer alignment '4'
21// :11:11: note: parameter type declared here
test/cases/compile_errors/invalid_compare_string.zig created+29
......@@ -0,0 +1,29 @@
1comptime {
2 var a = "foo";
3 if (a == "foo") unreachable;
4}
5comptime {
6 var a = "foo";
7 if (a == ("foo")) unreachable; // intentionally allow
8}
9comptime {
10 var a = "foo";
11 switch (a) {
12 "foo" => unreachable,
13 else => {},
14 }
15}
16comptime {
17 var a = "foo";
18 switch (a) {
19 ("foo") => unreachable, // intentionally allow
20 else => {},
21 }
22}
23
24// error
25// backend=stage2
26// target=native
27//
28// :3:11: error: cannot compare strings with ==
29// :12:9: error: cannot switch on strings
test/cases/compile_errors/invalid_dependency_on_struct_size.zig created+19
......@@ -0,0 +1,19 @@
1comptime {
2 const S = struct {
3 const Foo = struct {
4 y: Bar,
5 };
6 const Bar = struct {
7 y: if (@sizeOf(Foo) == 0) u64 else void,
8 };
9 };
10
11 _ = @sizeOf(S.Foo) + 1;
12}
13
14// error
15// backend=stage2
16// target=native
17//
18// :6:21: error: struct layout depends on it having runtime bits
19// :4:13: note: while checking this field
test/cases/compile_errors/missing_parameter_name.zig created+19
......@@ -0,0 +1,19 @@
1fn f2(u64) u64 {
2 return x;
3}
4fn f3(*x) u64 {
5 return x;
6}
7fn f1(x) u64 {
8 return x;
9}
10
11// error
12// backend=stage2
13// target=native
14//
15// :1:7: error: missing parameter name
16// :4:7: error: missing parameter name
17// :7:7: error: missing parameter name or type
18// :7:7: note: if this is a name, annotate its type 'x: T'
19// :7:7: note: if this is a type, give it a name '<name>: x'
test/cases/compile_errors/pass_const_ptr_to_mutable_ptr_fn.zig+1
......@@ -16,3 +16,4 @@ export fn entry() usize { return @sizeOf(@TypeOf(&foo)); }
1616//
1717// :4:19: error: expected type '*[]const u8', found '*const []const u8'
1818// :4:19: note: cast discards const qualifier
19// :6:14: note: parameter type declared here
test/cases/compile_errors/struct_init_passed_to_type_param.zig+1
......@@ -12,3 +12,4 @@ export const value = hi(MyStruct{ .x = 12 });
1212//
1313// :7:33: error: expected type 'type', found 'tmp.MyStruct'
1414// :1:18: note: struct declared here
15// :3:19: note: parameter type declared here
test/cases/compile_errors/struct_type_mismatch_in_arg.zig created+18
......@@ -0,0 +1,18 @@
1const Foo = struct { i: i32 };
2const Bar = struct { j: i32 };
3
4pub fn helper(_: Foo, _: Bar) void { }
5
6comptime {
7 helper(Bar { .j = 10 }, Bar { .j = 10 });
8 helper(Bar { .i = 10 }, Bar { .j = 10 });
9}
10
11// error
12// backend=stage2
13// target=native
14//
15// :7:16: error: expected type 'tmp.Foo', found 'tmp.Bar'
16// :1:13: note: struct declared here
17// :2:13: note: struct declared here
18// :4:18: note: parameter type declared here
test/cases/compile_errors/switch_on_slice.zig+1-1
......@@ -1,7 +1,7 @@
11pub export fn entry() void {
22 var a: [:0]const u8 = "foo";
33 switch (a) {
4 "--version", "version" => unreachable,
4 ("--version"), ("version") => unreachable,
55 else => {},
66 }
77}
test/cases/compile_errors/type_error_in_implicit_return.zig created+17
......@@ -0,0 +1,17 @@
1fn f1(x: bool) u32 {
2 if (x) return 1;
3}
4fn f2() noreturn {}
5pub export fn entry() void {
6 _ = f1(true);
7 _ = f2();
8}
9
10// error
11// backend=stage2
12// target=native
13//
14// :1:16: error: function with non-void return type 'u32' implicitly returns
15// :3:1: note: control flow reaches end of body here
16// :4:9: error: function declared 'noreturn' implicitly returns
17// :4:19: note: control flow reaches end of body here
test/cases/compile_errors/wrong_pointer_coerced_to_pointer_to_opaque_{}.zig+1
......@@ -12,3 +12,4 @@ export fn foo() void {
1212// :5:9: error: expected type '*tmp.Derp', found '*anyopaque'
1313// :5:9: note: pointer type child 'anyopaque' cannot cast into pointer type child 'tmp.Derp'
1414// :1:14: note: opaque declared here
15// :2:18: note: parameter type declared here
test/cases/x86_64-linux/hello_world_with_updates.1.zig+3-3
......@@ -1,6 +1,6 @@
1pub export fn _start() noreturn {}
1pub export fn main() noreturn {}
22
33// error
44//
5// :1:34: error: function declared 'noreturn' returns
6// :1:24: note: 'noreturn' declared here
5// :1:22: error: function declared 'noreturn' implicitly returns
6// :1:32: note: control flow reaches end of body here
test/cases/x86_64-macos/hello_world_with_updates.1.zig+2-2
......@@ -2,5 +2,5 @@ pub export fn main() noreturn {}
22
33// error
44//
5// :1:32: error: function declared 'noreturn' returns
6// :1:22: note: 'noreturn' declared here
5// :1:22: error: function declared 'noreturn' implicitly returns
6// :1:32: note: control flow reaches end of body here
test/cases/x86_64-windows/hello_world_with_updates.1.zig+2-2
......@@ -2,5 +2,5 @@ pub export fn main() noreturn {}
22
33// error
44//
5// :1:32: error: function declared 'noreturn' returns
6// :1:22: note: 'noreturn' declared here
5// :1:22: error: function declared 'noreturn' implicitly returns
6// :1:32: note: control flow reaches end of body here