authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-25 13:48:21+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-25 22:04:08+03:00
log2f34d06d01189ae6349e9c6341ba85ec50b92bb0
treeecf6ce792234a32bca10b0a1e145595f401b270d
parent370793a36b3de34ead8456553a2aa2c56f0d3de8

Sema: `analyzeInlineCallArg` needs a block for the arg and the param


3 files changed, 58 insertions(+), 22 deletions(-)

src/Module.zig+2
...@@ -5940,7 +5940,9 @@ pub fn argSrc(...@@ -5940,7 +5940,9 @@ pub fn argSrc(
5940 gpa: Allocator,5940 gpa: Allocator,
5941 decl: *Decl,5941 decl: *Decl,
5942 arg_i: usize,5942 arg_i: usize,
5943 bound_arg_src: ?LazySrcLoc,
5943) LazySrcLoc {5944) LazySrcLoc {
5945 if (arg_i == 0 and bound_arg_src != null) return bound_arg_src.?;
5944 @setCold(true);5946 @setCold(true);
5945 const tree = decl.getFileScope().getTree(gpa) catch |err| {5947 const tree = decl.getFileScope().getTree(gpa) catch |err| {
5946 // In this case we emit a warning + a less precise source location.5948 // In this case we emit a warning + a less precise source location.
src/Sema.zig+32-22
...@@ -5353,7 +5353,9 @@ fn zirCall(...@@ -5353,7 +5353,9 @@ fn zirCall(
5353 const func_type = sema.typeOf(func);5353 const func_type = sema.typeOf(func);
53545354
5355 // Desugar bound functions here5355 // Desugar bound functions here
5356 var bound_arg_src: ?LazySrcLoc = null;
5356 if (func_type.tag() == .bound_fn) {5357 if (func_type.tag() == .bound_fn) {
5358 bound_arg_src = func_src;
5357 const bound_func = try sema.resolveValue(block, .unneeded, func, undefined);5359 const bound_func = try sema.resolveValue(block, .unneeded, func, undefined);
5358 const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data;5360 const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data;
5359 func = bound_data.func_inst;5361 func = bound_data.func_inst;
...@@ -5369,7 +5371,7 @@ fn zirCall(...@@ -5369,7 +5371,7 @@ fn zirCall(
5369 }5371 }
5370 }5372 }
53715373
5372 return sema.analyzeCall(block, func, func_src, call_src, modifier, ensure_result_used, resolved_args);5374 return sema.analyzeCall(block, func, func_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src);
5373}5375}
53745376
5375const GenericCallAdapter = struct {5377const GenericCallAdapter = struct {
...@@ -5438,6 +5440,7 @@ fn analyzeCall(...@@ -5438,6 +5440,7 @@ fn analyzeCall(
5438 modifier: std.builtin.CallOptions.Modifier,5440 modifier: std.builtin.CallOptions.Modifier,
5439 ensure_result_used: bool,5441 ensure_result_used: bool,
5440 uncasted_args: []const Air.Inst.Ref,5442 uncasted_args: []const Air.Inst.Ref,
5443 bound_arg_src: ?LazySrcLoc,
5441) CompileError!Air.Inst.Ref {5444) CompileError!Air.Inst.Ref {
5442 const mod = sema.mod;5445 const mod = sema.mod;
54435446
...@@ -5532,6 +5535,7 @@ fn analyzeCall(...@@ -5532,6 +5535,7 @@ fn analyzeCall(
5532 ensure_result_used,5535 ensure_result_used,
5533 uncasted_args,5536 uncasted_args,
5534 call_tag,5537 call_tag,
5538 bound_arg_src,
5535 )) |some| {5539 )) |some| {
5536 return some;5540 return some;
5537 } else |err| switch (err) {5541 } else |err| switch (err) {
...@@ -5654,6 +5658,7 @@ fn analyzeCall(...@@ -5654,6 +5658,7 @@ fn analyzeCall(
5654 var arg_i: usize = 0;5658 var arg_i: usize = 0;
5655 for (fn_info.param_body) |inst| {5659 for (fn_info.param_body) |inst| {
5656 sema.analyzeInlineCallArg(5660 sema.analyzeInlineCallArg(
5661 block,
5657 &child_block,5662 &child_block,
5658 .unneeded,5663 .unneeded,
5659 inst,5664 inst,
...@@ -5665,12 +5670,13 @@ fn analyzeCall(...@@ -5665,12 +5670,13 @@ fn analyzeCall(
5665 memoized_call_key,5670 memoized_call_key,
5666 ) catch |err| switch (err) {5671 ) catch |err| switch (err) {
5667 error.NeededSourceLocation => {5672 error.NeededSourceLocation => {
5673 sema.inst_map.clearRetainingCapacity();
5668 const decl = sema.mod.declPtr(block.src_decl);5674 const decl = sema.mod.declPtr(block.src_decl);
5675 child_block.src_decl = block.src_decl;
5669 try sema.analyzeInlineCallArg(5676 try sema.analyzeInlineCallArg(
5670 // Intentionally use the wrong block here since we know it's
5671 // going to fail and `argSrc` is relative to `block.src_decl`.
5672 block,5677 block,
5673 Module.argSrc(call_src.node_offset.x, sema.gpa, decl, arg_i),5678 &child_block,
5679 Module.argSrc(call_src.node_offset.x, sema.gpa, decl, arg_i, bound_arg_src),
5674 inst,5680 inst,
5675 new_fn_info,5681 new_fn_info,
5676 &arg_i,5682 &arg_i,
...@@ -5832,7 +5838,7 @@ fn analyzeCall(...@@ -5832,7 +5838,7 @@ fn analyzeCall(
5832 const decl = sema.mod.declPtr(block.src_decl);5838 const decl = sema.mod.declPtr(block.src_decl);
5833 _ = try sema.analyzeCallArg(5839 _ = try sema.analyzeCallArg(
5834 block,5840 block,
5835 Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i),5841 Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i, bound_arg_src),
5836 param_ty,5842 param_ty,
5837 uncasted_arg,5843 uncasted_arg,
5838 );5844 );
...@@ -5873,7 +5879,8 @@ fn analyzeCall(...@@ -5873,7 +5879,8 @@ fn analyzeCall(
58735879
5874fn analyzeInlineCallArg(5880fn analyzeInlineCallArg(
5875 sema: *Sema,5881 sema: *Sema,
5876 block: *Block,5882 arg_block: *Block,
5883 param_block: *Block,
5877 arg_src: LazySrcLoc,5884 arg_src: LazySrcLoc,
5878 inst: Zir.Inst.Index,5885 inst: Zir.Inst.Index,
5879 new_fn_info: Type.Payload.Function.Data,5886 new_fn_info: Type.Payload.Function.Data,
...@@ -5892,19 +5899,19 @@ fn analyzeInlineCallArg(...@@ -5892,19 +5899,19 @@ fn analyzeInlineCallArg(
5892 const param_src = pl_tok.src();5899 const param_src = pl_tok.src();
5893 const extra = sema.code.extraData(Zir.Inst.Param, pl_tok.payload_index);5900 const extra = sema.code.extraData(Zir.Inst.Param, pl_tok.payload_index);
5894 const param_body = sema.code.extra[extra.end..][0..extra.data.body_len];5901 const param_body = sema.code.extra[extra.end..][0..extra.data.body_len];
5895 const param_ty_inst = try sema.resolveBody(block, param_body, inst);5902 const param_ty_inst = try sema.resolveBody(param_block, param_body, inst);
5896 const param_ty = try sema.analyzeAsType(block, param_src, param_ty_inst);5903 const param_ty = try sema.analyzeAsType(param_block, param_src, param_ty_inst);
5897 new_fn_info.param_types[arg_i.*] = param_ty;5904 new_fn_info.param_types[arg_i.*] = param_ty;
5898 const uncasted_arg = uncasted_args[arg_i.*];5905 const uncasted_arg = uncasted_args[arg_i.*];
5899 if (try sema.typeRequiresComptime(block, arg_src, param_ty)) {5906 if (try sema.typeRequiresComptime(arg_block, arg_src, param_ty)) {
5900 _ = try sema.resolveConstMaybeUndefVal(block, arg_src, uncasted_arg, "argument to parameter with comptime only type must be comptime known");5907 _ = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to parameter with comptime only type must be comptime known");
5901 }5908 }
5902 const casted_arg = try sema.coerce(block, param_ty, uncasted_arg, arg_src);5909 const casted_arg = try sema.coerce(arg_block, param_ty, uncasted_arg, arg_src);
5903 try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg);5910 try sema.inst_map.putNoClobber(sema.gpa, inst, casted_arg);
59045911
5905 if (is_comptime_call) {5912 if (is_comptime_call) {
5906 // TODO explain why function is being called at comptime5913 // TODO explain why function is being called at comptime
5907 const arg_val = try sema.resolveConstMaybeUndefVal(block, arg_src, casted_arg, "argument to function being called at comptime must be comptime known");5914 const arg_val = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, casted_arg, "argument to function being called at comptime must be comptime known");
5908 switch (arg_val.tag()) {5915 switch (arg_val.tag()) {
5909 .generic_poison, .generic_poison_type => {5916 .generic_poison, .generic_poison_type => {
5910 // This function is currently evaluated as part of an as-of-yet unresolvable5917 // This function is currently evaluated as part of an as-of-yet unresolvable
...@@ -5915,7 +5922,7 @@ fn analyzeInlineCallArg(...@@ -5915,7 +5922,7 @@ fn analyzeInlineCallArg(
5915 // Needed so that lazy values do not trigger5922 // Needed so that lazy values do not trigger
5916 // assertion due to type not being resolved5923 // assertion due to type not being resolved
5917 // when the hash function is called.5924 // when the hash function is called.
5918 try sema.resolveLazyValue(block, arg_src, arg_val);5925 try sema.resolveLazyValue(arg_block, arg_src, arg_val);
5919 },5926 },
5920 }5927 }
5921 should_memoize.* = should_memoize.* and !arg_val.canMutateComptimeVarState();5928 should_memoize.* = should_memoize.* and !arg_val.canMutateComptimeVarState();
...@@ -5935,7 +5942,7 @@ fn analyzeInlineCallArg(...@@ -5935,7 +5942,7 @@ fn analyzeInlineCallArg(
59355942
5936 if (is_comptime_call) {5943 if (is_comptime_call) {
5937 // TODO explain why function is being called at comptime5944 // TODO explain why function is being called at comptime
5938 const arg_val = try sema.resolveConstMaybeUndefVal(block, arg_src, uncasted_arg, "argument to function being called at comptime must be comptime known");5945 const arg_val = try sema.resolveConstMaybeUndefVal(arg_block, arg_src, uncasted_arg, "argument to function being called at comptime must be comptime known");
5939 switch (arg_val.tag()) {5946 switch (arg_val.tag()) {
5940 .generic_poison, .generic_poison_type => {5947 .generic_poison, .generic_poison_type => {
5941 // This function is currently evaluated as part of an as-of-yet unresolvable5948 // This function is currently evaluated as part of an as-of-yet unresolvable
...@@ -5946,7 +5953,7 @@ fn analyzeInlineCallArg(...@@ -5946,7 +5953,7 @@ fn analyzeInlineCallArg(
5946 // Needed so that lazy values do not trigger5953 // Needed so that lazy values do not trigger
5947 // assertion due to type not being resolved5954 // assertion due to type not being resolved
5948 // when the hash function is called.5955 // when the hash function is called.
5949 try sema.resolveLazyValue(block, arg_src, arg_val);5956 try sema.resolveLazyValue(arg_block, arg_src, arg_val);
5950 },5957 },
5951 }5958 }
5952 should_memoize.* = should_memoize.* and !arg_val.canMutateComptimeVarState();5959 should_memoize.* = should_memoize.* and !arg_val.canMutateComptimeVarState();
...@@ -6011,6 +6018,7 @@ fn instantiateGenericCall(...@@ -6011,6 +6018,7 @@ fn instantiateGenericCall(
6011 ensure_result_used: bool,6018 ensure_result_used: bool,
6012 uncasted_args: []const Air.Inst.Ref,6019 uncasted_args: []const Air.Inst.Ref,
6013 call_tag: Air.Inst.Tag,6020 call_tag: Air.Inst.Tag,
6021 bound_arg_src: ?LazySrcLoc,
6014) CompileError!Air.Inst.Ref {6022) CompileError!Air.Inst.Ref {
6015 const mod = sema.mod;6023 const mod = sema.mod;
6016 const gpa = sema.gpa;6024 const gpa = sema.gpa;
...@@ -6070,7 +6078,7 @@ fn instantiateGenericCall(...@@ -6070,7 +6078,7 @@ fn instantiateGenericCall(
6070 const arg_val = sema.analyzeGenericCallArgVal(block, .unneeded, uncasted_args[i]) catch |err| switch (err) {6078 const arg_val = sema.analyzeGenericCallArgVal(block, .unneeded, uncasted_args[i]) catch |err| switch (err) {
6071 error.NeededSourceLocation => {6079 error.NeededSourceLocation => {
6072 const decl = sema.mod.declPtr(block.src_decl);6080 const decl = sema.mod.declPtr(block.src_decl);
6073 const arg_src = Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i);6081 const arg_src = Module.argSrc(call_src.node_offset.x, sema.gpa, decl, i, bound_arg_src);
6074 _ = try sema.analyzeGenericCallArgVal(block, arg_src, uncasted_args[i]);6082 _ = try sema.analyzeGenericCallArgVal(block, arg_src, uncasted_args[i]);
6075 return error.AnalysisFail;6083 return error.AnalysisFail;
6076 },6084 },
...@@ -6392,7 +6400,7 @@ fn instantiateGenericCall(...@@ -6392,7 +6400,7 @@ fn instantiateGenericCall(
6392 const decl = sema.mod.declPtr(block.src_decl);6400 const decl = sema.mod.declPtr(block.src_decl);
6393 _ = try sema.analyzeGenericCallArg(6401 _ = try sema.analyzeGenericCallArg(
6394 block,6402 block,
6395 Module.argSrc(call_src.node_offset.x, sema.gpa, decl, total_i),6403 Module.argSrc(call_src.node_offset.x, sema.gpa, decl, total_i, bound_arg_src),
6396 uncasted_args[total_i],6404 uncasted_args[total_i],
6397 comptime_args[total_i],6405 comptime_args[total_i],
6398 runtime_args,6406 runtime_args,
...@@ -14263,7 +14271,7 @@ fn analyzeRet(...@@ -14263,7 +14271,7 @@ fn analyzeRet(
14263 const ptr_stack_trace_ty = try Type.Tag.optional_single_mut_pointer.create(sema.arena, stack_trace_ty);14271 const ptr_stack_trace_ty = try Type.Tag.optional_single_mut_pointer.create(sema.arena, stack_trace_ty);
14264 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);14272 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
14265 const args: [1]Air.Inst.Ref = .{err_return_trace};14273 const args: [1]Air.Inst.Ref = .{err_return_trace};
14266 _ = try sema.analyzeCall(block, return_err_fn, src, src, .never_inline, false, &args);14274 _ = try sema.analyzeCall(block, return_err_fn, src, src, .never_inline, false, &args, null);
14267 }14275 }
1426814276
14269 try sema.resolveTypeLayout(block, src, sema.fn_ret_ty);14277 try sema.resolveTypeLayout(block, src, sema.fn_ret_ty);
...@@ -17880,7 +17888,9 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -17880,7 +17888,9 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
17880 var resolved_args: []Air.Inst.Ref = undefined;17888 var resolved_args: []Air.Inst.Ref = undefined;
1788117889
17882 // Desugar bound functions here17890 // Desugar bound functions here
17891 var bound_arg_src: ?LazySrcLoc = null;
17883 if (sema.typeOf(func).tag() == .bound_fn) {17892 if (sema.typeOf(func).tag() == .bound_fn) {
17893 bound_arg_src = func_src;
17884 const bound_func = try sema.resolveValue(block, .unneeded, func, undefined);17894 const bound_func = try sema.resolveValue(block, .unneeded, func, undefined);
17885 const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data;17895 const bound_data = &bound_func.cast(Value.Payload.BoundFn).?.data;
17886 func = bound_data.func_inst;17896 func = bound_data.func_inst;
...@@ -17896,7 +17906,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -17896,7 +17906,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
17896 }17906 }
17897 }17907 }
17898 const ensure_result_used = extra.flags.ensure_result_used;17908 const ensure_result_used = extra.flags.ensure_result_used;
17899 return sema.analyzeCall(block, func, func_src, call_src, modifier, ensure_result_used, resolved_args);17909 return sema.analyzeCall(block, func, func_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src);
17900}17910}
1790117911
17902fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {17912fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -19182,7 +19192,7 @@ fn panicWithMsg(...@@ -19182,7 +19192,7 @@ fn panicWithMsg(
19182 Value.@"null",19192 Value.@"null",
19183 );19193 );
19184 const args: [2]Air.Inst.Ref = .{ msg_inst, null_stack_trace };19194 const args: [2]Air.Inst.Ref = .{ msg_inst, null_stack_trace };
19185 _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, &args);19195 _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, &args, null);
19186 return always_noreturn;19196 return always_noreturn;
19187}19197}
1918819198
...@@ -19223,7 +19233,7 @@ fn panicUnwrapError(...@@ -19223,7 +19233,7 @@ fn panicUnwrapError(
19223 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);19233 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);
19224 const err_return_trace = try sema.getErrorReturnTrace(&fail_block, src);19234 const err_return_trace = try sema.getErrorReturnTrace(&fail_block, src);
19225 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };19235 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };
19226 _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, &args);19236 _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, &args, null);
19227 }19237 }
19228 }19238 }
19229 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);19239 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
...@@ -19264,7 +19274,7 @@ fn panicIndexOutOfBounds(...@@ -19264,7 +19274,7 @@ fn panicIndexOutOfBounds(
19264 } else {19274 } else {
19265 const panic_fn = try sema.getBuiltin(&fail_block, src, "panicOutOfBounds");19275 const panic_fn = try sema.getBuiltin(&fail_block, src, "panicOutOfBounds");
19266 const args: [2]Air.Inst.Ref = .{ index, len };19276 const args: [2]Air.Inst.Ref = .{ index, len };
19267 _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, &args);19277 _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, &args, null);
19268 }19278 }
19269 }19279 }
19270 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);19280 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
test/compile_errors.zig+24
...@@ -183,6 +183,30 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -183,6 +183,30 @@ pub fn addCases(ctx: *TestContext) !void {
183 });183 });
184 }184 }
185185
186 {
187 const case = ctx.obj("argument causes error ", .{});
188 case.backend = .stage2;
189
190 case.addSourceFile("b.zig",
191 \\pub const ElfDynLib = struct {
192 \\ pub fn lookup(self: *ElfDynLib, comptime T: type) ?T {
193 \\ _ = self;
194 \\ return undefined;
195 \\ }
196 \\};
197 );
198
199 case.addError(
200 \\pub export fn entry() void {
201 \\ var lib: @import("b.zig").ElfDynLib = undefined;
202 \\ _ = lib.lookup(fn () void);
203 \\}
204 , &[_][]const u8{
205 ":3:12: error: unable to resolve comptime value",
206 ":3:12: note: argument to function being called at comptime must be comptime known",
207 });
208 }
209
186 // TODO test this in stage2, but we won't even try in stage1210 // TODO test this in stage2, but we won't even try in stage1
187 //ctx.objErrStage1("inline fn calls itself indirectly",211 //ctx.objErrStage1("inline fn calls itself indirectly",
188 // \\export fn foo() void {212 // \\export fn foo() void {