authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-20 00:02:20+03:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-21 12:21:30-07:00
log821e4063f9f32f71cce263265fdbacc632bd5af9
tree7c4b2683520ab47a6a4a4e5cb7340554dade7913
parent79ef0cdf306c48d3cc447ce14530db4021f8c5de

Sema: better source location for function call args


25 files changed, 378 insertions(+), 230 deletions(-)

src/Module.zig+25
......@@ -5911,6 +5911,31 @@ pub fn paramSrc(
59115911 }
59125912}
59135913
5914pub fn argSrc(
5915 call_node_offset: i32,
5916 gpa: Allocator,
5917 decl: *Decl,
5918 arg_i: usize,
5919) LazySrcLoc {
5920 @setCold(true);
5921 const tree = decl.getFileScope().getTree(gpa) catch |err| {
5922 // In this case we emit a warning + a less precise source location.
5923 log.warn("unable to load {s}: {s}", .{
5924 decl.getFileScope().sub_file_path, @errorName(err),
5925 });
5926 return LazySrcLoc.nodeOffset(0);
5927 };
5928 const node_tags = tree.nodes.items(.tag);
5929 const node = decl.relativeToNodeIndex(call_node_offset);
5930 var args: [1]Ast.Node.Index = undefined;
5931 const full = switch (node_tags[node]) {
5932 .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => tree.callOne(&args, node),
5933 .call, .call_comma, .async_call, .async_call_comma => tree.callFull(node),
5934 else => unreachable,
5935 };
5936 return LazySrcLoc.nodeOffset(decl.nodeIndexToRelative(full.ast.params[arg_i]));
5937}
5938
59145939/// Called from `performAllTheWork`, after all AstGen workers have finished,
59155940/// and before the main semantic analysis loop begins.
59165941pub fn processOutdatedAndDeletedDecls(mod: *Module) !void {
src/Sema.zig+219-102
......@@ -5613,84 +5613,39 @@ fn analyzeCall(
56135613 // which means its parameter type expressions must be resolved in order and used
56145614 // to successively coerce the arguments.
56155615 const fn_info = sema.code.getFnInfo(module_fn.zir_body_inst);
5616 const zir_tags = sema.code.instructions.items(.tag);
56175616 var arg_i: usize = 0;
5618 for (fn_info.param_body) |inst| switch (zir_tags[inst]) {
5619 .param, .param_comptime => {
5620 // Evaluate the parameter type expression now that previous ones have
5621 // been mapped, and coerce the corresponding argument to it.
5622 const pl_tok = sema.code.instructions.items(.data)[inst].pl_tok;
5623 const param_src = pl_tok.src();
5624 const extra = sema.code.extraData(Zir.Inst.Param, pl_tok.payload_index);
5625 const param_body = sema.code.extra[extra.end..][0..extra.data.body_len];
5626 const param_ty_inst = try sema.resolveBody(&child_block, param_body, inst);
5627 const param_ty = try sema.analyzeAsType(&child_block, param_src, param_ty_inst);
5628 new_fn_info.param_types[arg_i] = param_ty;
5629 const arg_src = call_src; // TODO: better source location
5630 const casted_arg = try sema.coerce(&child_block, param_ty, uncasted_args[arg_i], arg_src);
5631 try sema.inst_map.putNoClobber(gpa, inst, casted_arg);
5632
5633 if (is_comptime_call) {
5634 // TODO explain why function is being called at comptime
5635 const arg_val = try sema.resolveConstMaybeUndefVal(&child_block, arg_src, casted_arg, "argument to function being called at comptime must be comptime known");
5636 switch (arg_val.tag()) {
5637 .generic_poison, .generic_poison_type => {
5638 // This function is currently evaluated as part of an as-of-yet unresolvable
5639 // parameter or return type.
5640 return error.GenericPoison;
5641 },
5642 else => {
5643 // Needed so that lazy values do not trigger
5644 // assertion due to type not being resolved
5645 // when the hash function is called.
5646 try sema.resolveLazyValue(&child_block, arg_src, arg_val);
5647 },
5648 }
5649 should_memoize = should_memoize and !arg_val.canMutateComptimeVarState();
5650 memoized_call_key.args[arg_i] = .{
5651 .ty = param_ty,
5652 .val = arg_val,
5653 };
5654 }
5655
5656 arg_i += 1;
5657 continue;
5658 },
5659 .param_anytype, .param_anytype_comptime => {
5660 // No coercion needed.
5661 const uncasted_arg = uncasted_args[arg_i];
5662 new_fn_info.param_types[arg_i] = sema.typeOf(uncasted_arg);
5663 try sema.inst_map.putNoClobber(gpa, inst, uncasted_arg);
5664
5665 if (is_comptime_call) {
5666 const arg_src = call_src; // TODO: better source location
5667 // TODO explain why function is being called at comptime
5668 const arg_val = try sema.resolveConstMaybeUndefVal(&child_block, arg_src, uncasted_arg, "argument to function being called at comptime must be comptime known");
5669 switch (arg_val.tag()) {
5670 .generic_poison, .generic_poison_type => {
5671 // This function is currently evaluated as part of an as-of-yet unresolvable
5672 // parameter or return type.
5673 return error.GenericPoison;
5674 },
5675 else => {
5676 // Needed so that lazy values do not trigger
5677 // assertion due to type not being resolved
5678 // when the hash function is called.
5679 try sema.resolveLazyValue(&child_block, arg_src, arg_val);
5680 },
5681 }
5682 should_memoize = should_memoize and !arg_val.canMutateComptimeVarState();
5683 memoized_call_key.args[arg_i] = .{
5684 .ty = sema.typeOf(uncasted_arg),
5685 .val = arg_val,
5686 };
5687 }
5688
5689 arg_i += 1;
5690 continue;
5691 },
5692 else => continue,
5693 };
5617 for (fn_info.param_body) |inst| {
5618 sema.analyzeInlineCallArg(
5619 &child_block,
5620 .unneeded,
5621 inst,
5622 new_fn_info,
5623 &arg_i,
5624 uncasted_args,
5625 is_comptime_call,
5626 &should_memoize,
5627 memoized_call_key,
5628 ) catch |err| switch (err) {
5629 error.NeededSourceLocation => {
5630 const decl = sema.mod.declPtr(block.src_decl);
5631 try sema.analyzeInlineCallArg(
5632 // Intentionally use the wrong block here since we know it's
5633 // going to fail and `argSrc` is relative to `block.src_decl`.
5634 block,
5635 Module.argSrc(call_src.node_offset.x, sema.gpa, decl, arg_i),
5636 inst,
5637 new_fn_info,
5638 &arg_i,
5639 uncasted_args,
5640 is_comptime_call,
5641 &should_memoize,
5642 memoized_call_key,
5643 );
5644 return error.AnalysisFail;
5645 },
5646 else => |e| return e,
5647 };
5648 }
56945649
56955650 // In case it is a generic function with an expression for the return type that depends
56965651 // on parameters, we must now do the same for the return type as we just did with
......@@ -5746,6 +5701,7 @@ fn analyzeCall(
57465701 if (!is_comptime_call) {
57475702 try sema.emitDbgInline(block, parent_func.?, module_fn, new_func_resolved_ty, .dbg_inline_begin);
57485703
5704 const zir_tags = sema.code.instructions.items(.tag);
57495705 for (fn_info.param_body) |param| switch (zir_tags[param]) {
57505706 .param, .param_comptime => {
57515707 const inst_data = sema.code.instructions.items(.data)[param].pl_tok;
......@@ -5826,11 +5782,26 @@ fn analyzeCall(
58265782
58275783 const args = try sema.arena.alloc(Air.Inst.Ref, uncasted_args.len);
58285784 for (uncasted_args) |uncasted_arg, i| {
5829 const arg_src = call_src; // TODO: better source location
58305785 if (i < fn_params_len) {
58315786 const param_ty = func_ty.fnParamType(i);
5832 try sema.resolveTypeFully(block, arg_src, param_ty);
5833 args[i] = try sema.coerce(block, param_ty, uncasted_arg, arg_src);
5787 args[i] = sema.analyzeCallArg(
5788 block,
5789 .unneeded,
5790 param_ty,
5791 uncasted_arg,
5792 ) catch |err| switch (err) {
5793 error.NeededSourceLocation => {
5794 const decl = sema.mod.declPtr(block.src_decl);
5795 _ = try sema.analyzeCallArg(
5796 block,
5797 Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i),
5798 param_ty,
5799 uncasted_arg,
5800 );
5801 return error.AnalysisFail;
5802 },
5803 else => |e| return e,
5804 };
58345805 } else {
58355806 args[i] = uncasted_arg;
58365807 }
......@@ -5862,6 +5833,136 @@ fn analyzeCall(
58625833 return result;
58635834}
58645835
5836fn analyzeInlineCallArg(
5837 sema: *Sema,
5838 block: *Block,
5839 arg_src: LazySrcLoc,
5840 inst: Zir.Inst.Index,
5841 new_fn_info: Type.Payload.Function.Data,
5842 arg_i: *usize,
5843 uncasted_args: []const Air.Inst.Ref,
5844 is_comptime_call: bool,
5845 should_memoize: *bool,
5846 memoized_call_key: Module.MemoizedCall.Key,
5847) !void {
5848 const zir_tags = sema.code.instructions.items(.tag);
5849 switch (zir_tags[inst]) {
5850 .param, .param_comptime => {
5851 // Evaluate the parameter type expression now that previous ones have
5852 // been mapped, and coerce the corresponding argument to it.
5853 const pl_tok = sema.code.instructions.items(.data)[inst].pl_tok;
5854 const param_src = pl_tok.src();
5855 const extra = sema.code.extraData(Zir.Inst.Param, pl_tok.payload_index);
5856 const param_body = sema.code.extra[extra.end..][0..extra.data.body_len];
5857 const param_ty_inst = try sema.resolveBody(block, param_body, inst);
5858 const param_ty = try sema.analyzeAsType(block, param_src, param_ty_inst);
5859 new_fn_info.param_types[arg_i.*] = param_ty;
5860 const uncasted_arg = uncasted_args[arg_i.*];
5861 if (try sema.typeRequiresComptime(block, arg_src, param_ty)) {
5862 _ = try sema.resolveConstMaybeUndefVal(block, arg_src, uncasted_arg, "argument to parameter with comptime only type must be comptime known");
5863 }
5864 const casted_arg = try sema.coerce(block, param_ty, uncasted_arg, arg_src);
5865 try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg);
5866
5867 if (is_comptime_call) {
5868 // TODO explain why function is being called at comptime
5869 const arg_val = try sema.resolveConstMaybeUndefVal(block, arg_src, casted_arg, "argument to function being called at comptime must be comptime known");
5870 switch (arg_val.tag()) {
5871 .generic_poison, .generic_poison_type => {
5872 // This function is currently evaluated as part of an as-of-yet unresolvable
5873 // parameter or return type.
5874 return error.GenericPoison;
5875 },
5876 else => {
5877 // Needed so that lazy values do not trigger
5878 // assertion due to type not being resolved
5879 // when the hash function is called.
5880 try sema.resolveLazyValue(block, arg_src, arg_val);
5881 },
5882 }
5883 should_memoize.* = should_memoize.* and !arg_val.canMutateComptimeVarState();
5884 memoized_call_key.args[arg_i.*] = .{
5885 .ty = param_ty,
5886 .val = arg_val,
5887 };
5888 }
5889
5890 arg_i.* += 1;
5891 },
5892 .param_anytype, .param_anytype_comptime => {
5893 // No coercion needed.
5894 const uncasted_arg = uncasted_args[arg_i.*];
5895 new_fn_info.param_types[arg_i.*] = sema.typeOf(uncasted_arg);
5896 try sema.inst_map.putNoClobber(sema.gpa, inst, uncasted_arg);
5897
5898 if (is_comptime_call) {
5899 // TODO explain why function is being called at comptime
5900 const arg_val = try sema.resolveConstMaybeUndefVal(block, arg_src, uncasted_arg, "argument to function being called at comptime must be comptime known");
5901 switch (arg_val.tag()) {
5902 .generic_poison, .generic_poison_type => {
5903 // This function is currently evaluated as part of an as-of-yet unresolvable
5904 // parameter or return type.
5905 return error.GenericPoison;
5906 },
5907 else => {
5908 // Needed so that lazy values do not trigger
5909 // assertion due to type not being resolved
5910 // when the hash function is called.
5911 try sema.resolveLazyValue(block, arg_src, arg_val);
5912 },
5913 }
5914 should_memoize.* = should_memoize.* and !arg_val.canMutateComptimeVarState();
5915 memoized_call_key.args[arg_i.*] = .{
5916 .ty = sema.typeOf(uncasted_arg),
5917 .val = arg_val,
5918 };
5919 }
5920
5921 arg_i.* += 1;
5922 },
5923 else => {},
5924 }
5925}
5926
5927fn analyzeCallArg(
5928 sema: *Sema,
5929 block: *Block,
5930 arg_src: LazySrcLoc,
5931 param_ty: Type,
5932 uncasted_arg: Air.Inst.Ref,
5933) !Air.Inst.Ref {
5934 try sema.resolveTypeFully(block, arg_src, param_ty);
5935 return sema.coerce(block, param_ty, uncasted_arg, arg_src);
5936}
5937
5938fn analyzeGenericCallArg(
5939 sema: *Sema,
5940 block: *Block,
5941 arg_src: LazySrcLoc,
5942 uncasted_arg: Air.Inst.Ref,
5943 comptime_arg: TypedValue,
5944 runtime_args: []Air.Inst.Ref,
5945 new_fn_info: Type.Payload.Function.Data,
5946 runtime_i: *u32,
5947) !void {
5948 const is_runtime = comptime_arg.val.tag() == .generic_poison and
5949 comptime_arg.ty.hasRuntimeBits() and
5950 !(try sema.typeRequiresComptime(block, arg_src, comptime_arg.ty));
5951 if (is_runtime) {
5952 const param_ty = new_fn_info.param_types[runtime_i.*];
5953 const casted_arg = try sema.coerce(block, param_ty, uncasted_arg, arg_src);
5954 try sema.queueFullTypeResolution(param_ty);
5955 runtime_args[runtime_i.*] = casted_arg;
5956 runtime_i.* += 1;
5957 }
5958}
5959
5960fn analyzeGenericCallArgVal(sema: *Sema, block: *Block, arg_src: LazySrcLoc, uncasted_arg: Air.Inst.Ref) !Value {
5961 const arg_val = try sema.resolveValue(block, arg_src, uncasted_arg, "parameter is comptime");
5962 try sema.resolveLazyValue(block, arg_src, arg_val);
5963 return arg_val;
5964}
5965
58655966fn instantiateGenericCall(
58665967 sema: *Sema,
58675968 block: *Block,
......@@ -5927,10 +6028,16 @@ fn instantiateGenericCall(
59276028 }
59286029
59296030 if (is_comptime) {
5930 const arg_src = call_src; // TODO better source location
59316031 const arg_ty = sema.typeOf(uncasted_args[i]);
5932 const arg_val = try sema.resolveValue(block, arg_src, uncasted_args[i], "parameter is comptime");
5933 try sema.resolveLazyValue(block, arg_src, arg_val);
6032 const arg_val = sema.analyzeGenericCallArgVal(block, .unneeded, uncasted_args[i]) catch |err| switch (err) {
6033 error.NeededSourceLocation => {
6034 const decl = sema.mod.declPtr(block.src_decl);
6035 const arg_src = Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i);
6036 _ = try sema.analyzeGenericCallArgVal(block, arg_src, uncasted_args[i]);
6037 return error.AnalysisFail;
6038 },
6039 else => |e| return e,
6040 };
59346041 arg_val.hash(arg_ty, &hasher, mod);
59356042 if (is_anytype) {
59366043 arg_ty.hashWithHasher(&hasher, mod);
......@@ -6086,19 +6193,18 @@ fn instantiateGenericCall(
60866193 },
60876194 else => continue,
60886195 }
6089 const arg_src = call_src; // TODO: better source location
60906196 const arg = uncasted_args[arg_i];
60916197 if (is_comptime) {
6092 if (try sema.resolveMaybeUndefVal(block, arg_src, arg)) |arg_val| {
6198 if (try sema.resolveMaybeUndefVal(block, .unneeded, arg)) |arg_val| {
60936199 const child_arg = try child_sema.addConstant(sema.typeOf(arg), arg_val);
60946200 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);
60956201 } else {
6096 return sema.failWithNeededComptime(block, arg_src, "parameter is comptime");
6202 return sema.failWithNeededComptime(block, .unneeded, undefined);
60976203 }
60986204 } else if (is_anytype) {
60996205 const arg_ty = sema.typeOf(arg);
6100 if (try sema.typeRequiresComptime(block, arg_src, arg_ty)) {
6101 const arg_val = try sema.resolveConstValue(block, arg_src, arg, "type of anytype parameter requires comptime");
6206 if (try sema.typeRequiresComptime(block, .unneeded, arg_ty)) {
6207 const arg_val = try sema.resolveConstValue(block, .unneeded, arg, undefined);
61026208 const child_arg = try child_sema.addConstant(arg_ty, arg_val);
61036209 child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);
61046210 } else {
......@@ -6156,8 +6262,7 @@ fn instantiateGenericCall(
61566262 const copied_arg_ty = try child_sema.typeOf(arg).copy(new_decl_arena_allocator);
61576263 anytype_args[arg_i] = is_anytype;
61586264
6159 const arg_src = call_src; // TODO: better source location
6160 if (try sema.typeRequiresComptime(block, arg_src, copied_arg_ty)) {
6265 if (try sema.typeRequiresComptime(block, .unneeded, copied_arg_ty)) {
61616266 is_comptime = true;
61626267 }
61636268
......@@ -6236,18 +6341,30 @@ fn instantiateGenericCall(
62366341 .param_comptime, .param_anytype_comptime, .param, .param_anytype => {},
62376342 else => continue,
62386343 }
6239 const arg_src = call_src; // TODO: better source location
6240 const is_runtime = comptime_args[total_i].val.tag() == .generic_poison and
6241 comptime_args[total_i].ty.hasRuntimeBits() and
6242 !(try sema.typeRequiresComptime(block, arg_src, comptime_args[total_i].ty));
6243 if (is_runtime) {
6244 const param_ty = new_fn_info.param_types[runtime_i];
6245 const uncasted_arg = uncasted_args[total_i];
6246 const casted_arg = try sema.coerce(block, param_ty, uncasted_arg, arg_src);
6247 try sema.queueFullTypeResolution(param_ty);
6248 runtime_args[runtime_i] = casted_arg;
6249 runtime_i += 1;
6250 }
6344 sema.analyzeGenericCallArg(
6345 block,
6346 .unneeded,
6347 uncasted_args[total_i],
6348 comptime_args[total_i],
6349 runtime_args,
6350 new_fn_info,
6351 &runtime_i,
6352 ) catch |err| switch (err) {
6353 error.NeededSourceLocation => {
6354 const decl = sema.mod.declPtr(block.src_decl);
6355 _ = try sema.analyzeGenericCallArg(
6356 block,
6357 Module.argSrc(call_src.node_offset.x, sema.gpa, decl, total_i),
6358 uncasted_args[total_i],
6359 comptime_args[total_i],
6360 runtime_args,
6361 new_fn_info,
6362 &runtime_i,
6363 );
6364 return error.AnalysisFail;
6365 },
6366 else => |e| return e,
6367 };
62516368 total_i += 1;
62526369 }
62536370
test/cases/compile_errors/calling_var_args_extern_function_passing_array_instead_of_pointer.zig+1-1
......@@ -7,4 +7,4 @@ pub extern fn foo(format: *const u8, ...) void;
77// backend=stage2
88// target=native
99//
10// :2:8: error: expected type '*const u8', found '[5:0]u8'
10// :2:16: error: expected type '*const u8', found '[5:0]u8'
test/cases/compile_errors/casting_bit_offset_pointer_to_regular_pointer.zig+3-3
......@@ -18,6 +18,6 @@ export fn entry() usize { return @sizeOf(@TypeOf(&foo)); }
1818// backend=stage2
1919// target=native
2020//
21// :8:15: error: expected type '*const u3', found '*align(0:3:1) const u3'
22// :8:15: note: pointer host size '1' cannot cast into pointer host size '0'
23// :8:15: note: pointer bit offset '3' cannot cast into pointer bit offset '0'
21// :8:16: error: expected type '*const u3', found '*align(0:3:1) const u3'
22// :8:16: note: pointer host size '1' cannot cast into pointer host size '0'
23// :8:16: note: pointer bit offset '3' cannot cast into pointer bit offset '0'
test/cases/compile_errors/disallow_coercion_from_non-null-terminated_pointer_to_null-terminated_pointer.zig created+13
......@@ -0,0 +1,13 @@
1extern fn puts(s: [*:0]const u8) c_int;
2pub export fn entry() void {
3 const no_zero_array = [_]u8{'h', 'e', 'l', 'l', 'o'};
4 const no_zero_ptr: [*]const u8 = &no_zero_array;
5 _ = puts(no_zero_ptr);
6}
7
8// error
9// backend=stage2
10// target=native
11//
12// :5:14: error: expected type '[*:0]const u8', found '[*]const u8'
13// :5:14: note: destination pointer requires '0' sentinel
test/cases/compile_errors/error_note_for_function_parameter_incompatibility.zig+3-3
......@@ -8,6 +8,6 @@ export fn entry() void {
88// backend=stage2
99// target=native
1010//
11// :4:17: error: expected type '*const fn(i32) void', found '*const fn(bool) void'
12// :4:17: note: pointer type child 'fn(bool) void' cannot cast into pointer type child 'fn(i32) void'
13// :4:17: note: parameter 0 'bool' cannot cast into 'i32'
11// :4:18: error: expected type '*const fn(i32) void', found '*const fn(bool) void'
12// :4:18: note: pointer type child 'fn(bool) void' cannot cast into pointer type child 'fn(i32) void'
13// :4:18: note: parameter 0 'bool' cannot cast into 'i32'
test/cases/compile_errors/function_parameter_is_opaque.zig-1
......@@ -27,5 +27,4 @@ export fn entry4() void {
2727// :1:17: note: opaque declared here
2828// :8:28: error: parameter of type '@TypeOf(null)' not allowed
2929// :12:8: error: parameter of opaque type 'tmp.FooType' not allowed
30// :1:17: note: opaque declared here
3130// :17:8: error: parameter of type '@TypeOf(null)' not allowed
test/cases/compile_errors/generic_function_instance_with_non-constant_expression.zig created+13
......@@ -0,0 +1,13 @@
1fn foo(comptime x: i32, y: i32) i32 { return x + y; }
2fn test1(a: i32, b: i32) i32 {
3 return foo(a, b);
4}
5
6export fn entry() usize { return @sizeOf(@TypeOf(&test1)); }
7
8// error
9// backend=stage2
10// target=native
11//
12// :3:16: error: unable to resolve comptime value
13// :3:16: note: parameter is comptime
test/cases/compile_errors/implicit_cast_from_array_to_mutable_slice.zig created+11
......@@ -0,0 +1,11 @@
1var global_array: [10]i32 = undefined;
2fn foo(param: []i32) void {_ = param;}
3export fn entry() void {
4 foo(global_array);
5}
6
7// error
8// backend=stage2
9// target=native
10//
11// :4:9: error: array literal requires address-of operator (&) to coerce to slice type '[]i32'
test/cases/compile_errors/implicitly_increasing_pointer_alignment.zig created+20
......@@ -0,0 +1,20 @@
1const Foo = packed struct {
2 a: u8,
3 b: u32,
4};
5
6export fn entry() void {
7 var foo = Foo { .a = 1, .b = 10 };
8 bar(&foo.b);
9}
10
11fn bar(x: *u32) void {
12 x.* += 1;
13}
14
15// error
16// backend=stage2
17// target=native
18//
19// :8:9: error: expected type '*u32', found '*align(1) u32'
20// :8:9: note: pointer alignment '1' cannot cast into pointer alignment '4'
test/cases/compile_errors/pass_const_ptr_to_mutable_ptr_fn.zig created+18
......@@ -0,0 +1,18 @@
1fn foo() bool {
2 const a = @as([]const u8, "a",);
3 const b = &a;
4 return ptrEql(b, b);
5}
6fn ptrEql(a: *[]const u8, b: *[]const u8) bool {
7 _ = a; _ = b;
8 return true;
9}
10
11export fn entry() usize { return @sizeOf(@TypeOf(&foo)); }
12
13// error
14// backend=stage2
15// target=native
16//
17// :4:19: error: expected type '*[]const u8', found '*const []const u8'
18// :4:19: note: cast discards const qualifier
test/cases/compile_errors/stage1/obj/disallow_coercion_from_non-null-terminated_pointer_to_null-terminated_pointer.zig deleted-12
......@@ -1,12 +0,0 @@
1extern fn puts(s: [*:0]const u8) c_int;
2pub fn main() void {
3 const no_zero_array = [_]u8{'h', 'e', 'l', 'l', 'o'};
4 const no_zero_ptr: [*]const u8 = &no_zero_array;
5 _ = puts(no_zero_ptr);
6}
7
8// error
9// backend=stage1
10// target=native
11//
12// tmp.zig:5:14: error: expected type '[*:0]const u8', found '[*]const u8'
test/cases/compile_errors/stage1/obj/generic_function_instance_with_non-constant_expression.zig deleted-12
......@@ -1,12 +0,0 @@
1fn foo(comptime x: i32, y: i32) i32 { return x + y; }
2fn test1(a: i32, b: i32) i32 {
3 return foo(a, b);
4}
5
6export fn entry() usize { return @sizeOf(@TypeOf(test1)); }
7
8// error
9// backend=stage1
10// target=native
11//
12// tmp.zig:3:16: error: runtime value cannot be passed to comptime arg
test/cases/compile_errors/stage1/obj/implicit_cast_from_array_to_mutable_slice.zig deleted-11
......@@ -1,11 +0,0 @@
1var global_array: [10]i32 = undefined;
2fn foo(param: []i32) void {_ = param;}
3export fn entry() void {
4 foo(global_array);
5}
6
7// error
8// backend=stage1
9// target=native
10//
11// tmp.zig:4:9: error: expected type '[]i32', found '[10]i32'
test/cases/compile_errors/stage1/obj/implicitly_increasing_pointer_alignment.zig deleted-19
......@@ -1,19 +0,0 @@
1const Foo = packed struct {
2 a: u8,
3 b: u32,
4};
5
6export fn entry() void {
7 var foo = Foo { .a = 1, .b = 10 };
8 bar(&foo.b);
9}
10
11fn bar(x: *u32) void {
12 x.* += 1;
13}
14
15// error
16// backend=stage1
17// target=native
18//
19// tmp.zig:8:13: error: expected type '*u32', found '*align(1) u32'
test/cases/compile_errors/stage1/obj/pass_const_ptr_to_mutable_ptr_fn.zig deleted-17
......@@ -1,17 +0,0 @@
1fn foo() bool {
2 const a = @as([]const u8, "a",);
3 const b = &a;
4 return ptrEql(b, b);
5}
6fn ptrEql(a: *[]const u8, b: *[]const u8) bool {
7 _ = a; _ = b;
8 return true;
9}
10
11export fn entry() usize { return @sizeOf(@TypeOf(foo)); }
12
13// error
14// backend=stage1
15// target=native
16//
17// tmp.zig:4:19: error: expected type '*[]const u8', found '*const []const u8'
test/cases/compile_errors/stage1/obj/unreachable_parameter.zig deleted-8
......@@ -1,8 +0,0 @@
1fn f(a: noreturn) void { _ = a; }
2export fn entry() void { f(); }
3
4// error
5// backend=stage1
6// target=native
7//
8// tmp.zig:1:9: error: parameter of type 'noreturn' not allowed
test/cases/compile_errors/stage1/obj/use_anyopaque_as_return_type_of_fn_ptr.zig deleted-10
......@@ -1,10 +0,0 @@
1export fn entry() void {
2 const a: fn () anyopaque = undefined;
3 _ = a;
4}
5
6// error
7// backend=stage1
8// target=native
9//
10// tmp.zig:2:20: error: return type cannot be opaque
test/cases/compile_errors/stage1/obj/wrong_initializer_for_union_payload_of_type_type.zig deleted-16
......@@ -1,16 +0,0 @@
1const U = union(enum) {
2 A: type,
3};
4const S = struct {
5 u: U,
6};
7export fn entry() void {
8 comptime var v: S = undefined;
9 v.u.A = U{ .A = i32 };
10}
11
12// error
13// backend=stage1
14// target=native
15//
16// tmp.zig:9:8: error: use of undefined value here causes undefined behavior
test/cases/compile_errors/stage1/obj/wrong_pointer_coerced_to_pointer_to_opaque_{}.zig deleted-12
......@@ -1,12 +0,0 @@
1const Derp = opaque {};
2extern fn bar(d: *Derp) void;
3export fn foo() void {
4 var x = @as(u8, 1);
5 bar(@ptrCast(*anyopaque, &x));
6}
7
8// error
9// backend=stage1
10// target=native
11//
12// tmp.zig:5:9: error: expected type '*Derp', found '*anyopaque'
test/cases/compile_errors/type_checking_function_pointers.zig+3-3
......@@ -10,6 +10,6 @@ export fn entry() void {
1010// backend=stage2
1111// target=native
1212//
13// :6:6: error: expected type '*const fn(*const u8) void', found '*const fn(u8) void'
14// :6:6: note: pointer type child 'fn(u8) void' cannot cast into pointer type child 'fn(*const u8) void'
15// :6:6: note: parameter 0 'u8' cannot cast into '*const u8'
13// :6:7: error: expected type '*const fn(*const u8) void', found '*const fn(u8) void'
14// :6:7: note: pointer type child 'fn(u8) void' cannot cast into pointer type child 'fn(*const u8) void'
15// :6:7: note: parameter 0 'u8' cannot cast into '*const u8'
test/cases/compile_errors/unreachable_parameter.zig created+8
......@@ -0,0 +1,8 @@
1fn f(a: noreturn) void { _ = a; }
2export fn entry() void { f(); }
3
4// error
5// backend=stage2
6// target=native
7//
8// :1:6: error: parameter of type 'noreturn' not allowed
test/cases/compile_errors/use_anyopaque_as_return_type_of_fn_ptr.zig created+10
......@@ -0,0 +1,10 @@
1export fn entry() void {
2 const a: fn () anyopaque = undefined;
3 _ = a;
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// :2:20: error: opaque return type 'anyopaque' not allowed
test/cases/compile_errors/wrong_initializer_for_union_payload_of_type_type.zig created+17
......@@ -0,0 +1,17 @@
1const U = union(enum) {
2 A: type,
3};
4const S = struct {
5 u: U,
6};
7export fn entry() void {
8 comptime var v: S = undefined;
9 v.u.A = U{ .A = i32 };
10}
11
12// error
13// backend=stage2
14// target=native
15//
16// :9:14: error: expected type 'type', found 'tmp.U'
17// :1:11: note: union declared here
test/cases/compile_errors/wrong_pointer_coerced_to_pointer_to_opaque_{}.zig created+14
......@@ -0,0 +1,14 @@
1const Derp = opaque {};
2extern fn bar(d: *Derp) void;
3export fn foo() void {
4 var x = @as(u8, 1);
5 bar(@ptrCast(*anyopaque, &x));
6}
7
8// error
9// backend=stage2
10// target=native
11//
12// :5:9: error: expected type '*tmp.Derp', found '*anyopaque'
13// :5:9: note: pointer type child 'anyopaque' cannot cast into pointer type child 'tmp.Derp'
14// :1:14: note: opaque declared here