| author | |
| committer | |
| log | 1634d45f1d53c8d7bfefa56ab4d2fa4cc8218b6d |
| tree | 85ec2c108a227da13542385d601364d7394e853b |
| parent | 939bd52c8a389993ab168ec9bb88c4e395045ac7 |
| signature |
12 files changed, 119 insertions(+), 38 deletions(-)
src/Compilation.zig+13-12| ... | ... | @@ -1350,8 +1350,11 @@ pub fn totalErrorCount(self: *Compilation) usize { |
| 1350 | 1350 | var total: usize = self.failed_c_objects.items().len; |
| 1351 | 1351 | |
| 1352 | 1352 | if (self.bin_file.options.module) |module| { |
| 1353 | total += module.failed_decls.items().len + | |
| 1354 | module.failed_exports.items().len + | |
| 1353 | for (module.failed_decls.items()) |entry| { | |
| 1354 | assert(entry.value.items.len > 0); | |
| 1355 | total += entry.value.items.len; | |
| 1356 | } | |
| 1357 | total += module.failed_exports.items().len + | |
| 1355 | 1358 | module.failed_files.items().len + |
| 1356 | 1359 | @boolToInt(module.failed_root_src_file != null); |
| 1357 | 1360 | } |
| ... | ... | @@ -1385,9 +1388,11 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors { |
| 1385 | 1388 | } |
| 1386 | 1389 | for (module.failed_decls.items()) |entry| { |
| 1387 | 1390 | const decl = entry.key; |
| 1388 | const err_msg = entry.value; | |
| 1389 | const source = try decl.scope.getSource(module); | |
| 1390 | try AllErrors.add(&arena, &errors, decl.scope.subFilePath(), source, err_msg.*); | |
| 1391 | const err_msg_list = entry.value; | |
| 1392 | for (err_msg_list.items) |err_msg| { | |
| 1393 | const source = try decl.scope.getSource(module); | |
| 1394 | try AllErrors.add(&arena, &errors, decl.scope.subFilePath(), source, err_msg.*); | |
| 1395 | } | |
| 1391 | 1396 | } |
| 1392 | 1397 | for (module.failed_exports.items()) |entry| { |
| 1393 | 1398 | const decl = entry.key.owner_decl; |
| ... | ... | @@ -1480,7 +1485,6 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor |
| 1480 | 1485 | } |
| 1481 | 1486 | |
| 1482 | 1487 | assert(decl.typed_value.most_recent.typed_value.ty.hasCodeGenBits()); |
| 1483 | ||
| 1484 | 1488 | self.bin_file.updateDecl(module, decl) catch |err| { |
| 1485 | 1489 | switch (err) { |
| 1486 | 1490 | error.OutOfMemory => return error.OutOfMemory, |
| ... | ... | @@ -1488,8 +1492,7 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor |
| 1488 | 1492 | decl.analysis = .dependency_failure; |
| 1489 | 1493 | }, |
| 1490 | 1494 | else => { |
| 1491 | try module.failed_decls.ensureCapacity(module.gpa, module.failed_decls.items().len + 1); | |
| 1492 | module.failed_decls.putAssumeCapacityNoClobber(decl, try ErrorMsg.create( | |
| 1495 | try module.addDeclErr(decl, try ErrorMsg.create( | |
| 1493 | 1496 | module.gpa, |
| 1494 | 1497 | decl.src(), |
| 1495 | 1498 | "unable to codegen: {}", |
| ... | ... | @@ -1508,8 +1511,7 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor |
| 1508 | 1511 | decl.analysis = .dependency_failure; |
| 1509 | 1512 | }, |
| 1510 | 1513 | else => { |
| 1511 | try module.failed_decls.ensureCapacity(module.gpa, module.failed_decls.items().len + 1); | |
| 1512 | module.failed_decls.putAssumeCapacityNoClobber(decl, try ErrorMsg.create( | |
| 1514 | try module.addDeclErr(decl, try ErrorMsg.create( | |
| 1513 | 1515 | module.gpa, |
| 1514 | 1516 | decl.src(), |
| 1515 | 1517 | "unable to generate C header: {}", |
| ... | ... | @@ -1531,8 +1533,7 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor |
| 1531 | 1533 | .update_line_number => |decl| { |
| 1532 | 1534 | const module = self.bin_file.options.module.?; |
| 1533 | 1535 | self.bin_file.updateDeclLineNumber(module, decl) catch |err| { |
| 1534 | try module.failed_decls.ensureCapacity(module.gpa, module.failed_decls.items().len + 1); | |
| 1535 | module.failed_decls.putAssumeCapacityNoClobber(decl, try ErrorMsg.create( | |
| 1536 | try module.addDeclErr(decl, try ErrorMsg.create( | |
| 1536 | 1537 | module.gpa, |
| 1537 | 1538 | decl.src(), |
| 1538 | 1539 | "unable to update line number: {}", |
src/Module.zig+29-17| ... | ... | @@ -53,7 +53,7 @@ decl_table: std.ArrayHashMapUnmanaged(Scope.NameHash, *Decl, Scope.name_hash_has |
| 53 | 53 | /// The ErrorMsg memory is owned by the decl, using Module's general purpose allocator. |
| 54 | 54 | /// Note that a Decl can succeed but the Fn it represents can fail. In this case, |
| 55 | 55 | /// a Decl can have a failed_decls entry but have analysis status of success. |
| 56 | failed_decls: std.AutoArrayHashMapUnmanaged(*Decl, *Compilation.ErrorMsg) = .{}, | |
| 56 | failed_decls: std.AutoArrayHashMapUnmanaged(*Decl, ArrayListUnmanaged(*Compilation.ErrorMsg)) = .{}, | |
| 57 | 57 | /// Using a map here for consistency with the other fields here. |
| 58 | 58 | /// The ErrorMsg memory is owned by the `Scope`, using Module's general purpose allocator. |
| 59 | 59 | failed_files: std.AutoArrayHashMapUnmanaged(*Scope, *Compilation.ErrorMsg) = .{}, |
| ... | ... | @@ -845,8 +845,11 @@ pub fn deinit(self: *Module) void { |
| 845 | 845 | } |
| 846 | 846 | self.decl_table.deinit(gpa); |
| 847 | 847 | |
| 848 | for (self.failed_decls.items()) |entry| { | |
| 849 | entry.value.destroy(gpa); | |
| 848 | for (self.failed_decls.items()) |*entry| { | |
| 849 | for (entry.value.items) |compile_err| { | |
| 850 | compile_err.destroy(gpa); | |
| 851 | } | |
| 852 | entry.value.deinit(gpa); | |
| 850 | 853 | } |
| 851 | 854 | self.failed_decls.deinit(gpa); |
| 852 | 855 | |
| ... | ... | @@ -942,8 +945,7 @@ pub fn ensureDeclAnalyzed(self: *Module, decl: *Decl) InnerError!void { |
| 942 | 945 | error.OutOfMemory => return error.OutOfMemory, |
| 943 | 946 | error.AnalysisFail => return error.AnalysisFail, |
| 944 | 947 | else => { |
| 945 | try self.failed_decls.ensureCapacity(self.gpa, self.failed_decls.items().len + 1); | |
| 946 | self.failed_decls.putAssumeCapacityNoClobber(decl, try Compilation.ErrorMsg.create( | |
| 948 | try self.addDeclErr(decl, try Compilation.ErrorMsg.create( | |
| 947 | 949 | self.gpa, |
| 948 | 950 | decl.src(), |
| 949 | 951 | "unable to analyze: {}", |
| ... | ... | @@ -1550,7 +1552,7 @@ pub fn analyzeContainer(self: *Module, container_scope: *Scope.Container) !void |
| 1550 | 1552 | decl.analysis = .sema_failure; |
| 1551 | 1553 | const err_msg = try Compilation.ErrorMsg.create(self.gpa, tree.token_locs[name_tok].start, "redefinition of '{}'", .{decl.name}); |
| 1552 | 1554 | errdefer err_msg.destroy(self.gpa); |
| 1553 | try self.failed_decls.putNoClobber(self.gpa, decl, err_msg); | |
| 1555 | try self.addDeclErr(decl, err_msg); | |
| 1554 | 1556 | } else { |
| 1555 | 1557 | if (!srcHashEql(decl.contents_hash, contents_hash)) { |
| 1556 | 1558 | try self.markOutdatedDecl(decl); |
| ... | ... | @@ -1592,7 +1594,7 @@ pub fn analyzeContainer(self: *Module, container_scope: *Scope.Container) !void |
| 1592 | 1594 | decl.analysis = .sema_failure; |
| 1593 | 1595 | const err_msg = try Compilation.ErrorMsg.create(self.gpa, name_loc.start, "redefinition of '{}'", .{decl.name}); |
| 1594 | 1596 | errdefer err_msg.destroy(self.gpa); |
| 1595 | try self.failed_decls.putNoClobber(self.gpa, decl, err_msg); | |
| 1597 | try self.addDeclErr(decl, err_msg); | |
| 1596 | 1598 | } else if (!srcHashEql(decl.contents_hash, contents_hash)) { |
| 1597 | 1599 | try self.markOutdatedDecl(decl); |
| 1598 | 1600 | decl.contents_hash = contents_hash; |
| ... | ... | @@ -1718,8 +1720,11 @@ pub fn deleteDecl(self: *Module, decl: *Decl) !void { |
| 1718 | 1720 | try self.markOutdatedDecl(dep); |
| 1719 | 1721 | } |
| 1720 | 1722 | } |
| 1721 | if (self.failed_decls.remove(decl)) |entry| { | |
| 1722 | entry.value.destroy(self.gpa); | |
| 1723 | if (self.failed_decls.remove(decl)) |*entry| { | |
| 1724 | for (entry.value.items) |compile_err| { | |
| 1725 | compile_err.destroy(self.gpa); | |
| 1726 | } | |
| 1727 | entry.value.deinit(self.gpa); | |
| 1723 | 1728 | } |
| 1724 | 1729 | self.deleteDeclExports(decl); |
| 1725 | 1730 | self.comp.bin_file.freeDecl(decl); |
| ... | ... | @@ -1798,8 +1803,11 @@ pub fn analyzeFnBody(self: *Module, decl: *Decl, func: *Fn) !void { |
| 1798 | 1803 | fn markOutdatedDecl(self: *Module, decl: *Decl) !void { |
| 1799 | 1804 | log.debug("mark {} outdated\n", .{decl.name}); |
| 1800 | 1805 | try self.comp.work_queue.writeItem(.{ .analyze_decl = decl }); |
| 1801 | if (self.failed_decls.remove(decl)) |entry| { | |
| 1802 | entry.value.destroy(self.gpa); | |
| 1806 | if (self.failed_decls.remove(decl)) |*entry| { | |
| 1807 | for (entry.value.items) |compile_err| { | |
| 1808 | compile_err.destroy(self.gpa); | |
| 1809 | } | |
| 1810 | entry.value.deinit(self.gpa); | |
| 1803 | 1811 | } |
| 1804 | 1812 | decl.analysis = .outdated; |
| 1805 | 1813 | } |
| ... | ... | @@ -2944,10 +2952,14 @@ pub fn failNode( |
| 2944 | 2952 | return self.fail(scope, src, format, args); |
| 2945 | 2953 | } |
| 2946 | 2954 | |
| 2955 | pub fn addDeclErr(self: *Module, decl: *Decl, err: *Compilation.ErrorMsg) error{OutOfMemory}!void { | |
| 2956 | const entry = try self.failed_decls.getOrPutValue(self.gpa, decl, .{}); | |
| 2957 | try entry.value.append(self.gpa, err); | |
| 2958 | } | |
| 2959 | ||
| 2947 | 2960 | fn failWithOwnedErrorMsg(self: *Module, scope: *Scope, src: usize, err_msg: *Compilation.ErrorMsg) InnerError { |
| 2948 | 2961 | { |
| 2949 | 2962 | errdefer err_msg.destroy(self.gpa); |
| 2950 | try self.failed_decls.ensureCapacity(self.gpa, self.failed_decls.items().len + 1); | |
| 2951 | 2963 | try self.failed_files.ensureCapacity(self.gpa, self.failed_files.items().len + 1); |
| 2952 | 2964 | } |
| 2953 | 2965 | switch (scope.tag) { |
| ... | ... | @@ -2955,7 +2967,7 @@ fn failWithOwnedErrorMsg(self: *Module, scope: *Scope, src: usize, err_msg: *Com |
| 2955 | 2967 | const decl = scope.cast(Scope.DeclAnalysis).?.decl; |
| 2956 | 2968 | decl.analysis = .sema_failure; |
| 2957 | 2969 | decl.generation = self.generation; |
| 2958 | self.failed_decls.putAssumeCapacityNoClobber(decl, err_msg); | |
| 2970 | try self.addDeclErr(decl, err_msg); | |
| 2959 | 2971 | }, |
| 2960 | 2972 | .block => { |
| 2961 | 2973 | const block = scope.cast(Scope.Block).?; |
| ... | ... | @@ -2965,25 +2977,25 @@ fn failWithOwnedErrorMsg(self: *Module, scope: *Scope, src: usize, err_msg: *Com |
| 2965 | 2977 | block.decl.analysis = .sema_failure; |
| 2966 | 2978 | block.decl.generation = self.generation; |
| 2967 | 2979 | } |
| 2968 | self.failed_decls.putAssumeCapacityNoClobber(block.decl, err_msg); | |
| 2980 | try self.addDeclErr(block.decl, err_msg); | |
| 2969 | 2981 | }, |
| 2970 | 2982 | .gen_zir => { |
| 2971 | 2983 | const gen_zir = scope.cast(Scope.GenZIR).?; |
| 2972 | 2984 | gen_zir.decl.analysis = .sema_failure; |
| 2973 | 2985 | gen_zir.decl.generation = self.generation; |
| 2974 | self.failed_decls.putAssumeCapacityNoClobber(gen_zir.decl, err_msg); | |
| 2986 | try self.addDeclErr(gen_zir.decl, err_msg); | |
| 2975 | 2987 | }, |
| 2976 | 2988 | .local_val => { |
| 2977 | 2989 | const gen_zir = scope.cast(Scope.LocalVal).?.gen_zir; |
| 2978 | 2990 | gen_zir.decl.analysis = .sema_failure; |
| 2979 | 2991 | gen_zir.decl.generation = self.generation; |
| 2980 | self.failed_decls.putAssumeCapacityNoClobber(gen_zir.decl, err_msg); | |
| 2992 | try self.addDeclErr(gen_zir.decl, err_msg); | |
| 2981 | 2993 | }, |
| 2982 | 2994 | .local_ptr => { |
| 2983 | 2995 | const gen_zir = scope.cast(Scope.LocalPtr).?.gen_zir; |
| 2984 | 2996 | gen_zir.decl.analysis = .sema_failure; |
| 2985 | 2997 | gen_zir.decl.generation = self.generation; |
| 2986 | self.failed_decls.putAssumeCapacityNoClobber(gen_zir.decl, err_msg); | |
| 2998 | try self.addDeclErr(gen_zir.decl, err_msg); | |
| 2987 | 2999 | }, |
| 2988 | 3000 | .zir_module => { |
| 2989 | 3001 | const zir_module = scope.cast(Scope.ZIRModule).?; |
src/astgen.zig+13| ... | ... | @@ -2248,6 +2248,17 @@ fn import(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!* |
| 2248 | 2248 | return addZIRUnOp(mod, scope, src, .import, target); |
| 2249 | 2249 | } |
| 2250 | 2250 | |
| 2251 | fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst { | |
| 2252 | const tree = scope.tree(); | |
| 2253 | const arena = scope.arena(); | |
| 2254 | const src = tree.token_locs[call.builtin_token].start; | |
| 2255 | const params = call.params(); | |
| 2256 | var targets = try arena.alloc(*zir.Inst, params.len); | |
| 2257 | for (params) |param, param_i| | |
| 2258 | targets[param_i] = try expr(mod, scope, .none, param); | |
| 2259 | return addZIRInst(mod, scope, src, zir.Inst.CompileLog, .{ .to_log = targets }, .{}); | |
| 2260 | } | |
| 2261 | ||
| 2251 | 2262 | fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst { |
| 2252 | 2263 | const tree = scope.tree(); |
| 2253 | 2264 | const arena = scope.arena(); |
| ... | ... | @@ -2291,6 +2302,8 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.Built |
| 2291 | 2302 | return rlWrap(mod, scope, rl, try addZIRNoOp(mod, scope, src, .breakpoint)); |
| 2292 | 2303 | } else if (mem.eql(u8, builtin_name, "@import")) { |
| 2293 | 2304 | return rlWrap(mod, scope, rl, try import(mod, scope, call)); |
| 2305 | } else if (mem.eql(u8, builtin_name, "@compileLog")) { | |
| 2306 | return compileLog(mod, scope, call); | |
| 2294 | 2307 | } else { |
| 2295 | 2308 | return mod.failTok(scope, call.builtin_token, "invalid builtin function: '{}'", .{builtin_name}); |
| 2296 | 2309 | } |
src/codegen/c.zig+1-1| ... | ... | @@ -106,7 +106,7 @@ pub fn generateHeader( |
| 106 | 106 | const writer = header.buf.writer(); |
| 107 | 107 | renderFunctionSignature(&ctx, header, writer, decl) catch |err| { |
| 108 | 108 | if (err == error.AnalysisFail) { |
| 109 | try module.failed_decls.put(module.gpa, decl, ctx.error_msg); | |
| 109 | try module.addDeclErr(decl, ctx.error_msg); | |
| 110 | 110 | } |
| 111 | 111 | return err; |
| 112 | 112 | }; |
src/link/C.zig+1-1| ... | ... | @@ -106,7 +106,7 @@ pub fn deinit(self: *C) void { |
| 106 | 106 | pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void { |
| 107 | 107 | codegen.generate(self, decl) catch |err| { |
| 108 | 108 | if (err == error.AnalysisFail) { |
| 109 | try module.failed_decls.put(module.gpa, decl, self.error_msg); | |
| 109 | try module.addDeclErr(decl, self.error_msg); | |
| 110 | 110 | } |
| 111 | 111 | return err; |
| 112 | 112 | }; |
src/link/Coff.zig+1-1| ... | ... | @@ -658,7 +658,7 @@ pub fn updateDecl(self: *Coff, module: *Module, decl: *Module.Decl) !void { |
| 658 | 658 | .appended => code_buffer.items, |
| 659 | 659 | .fail => |em| { |
| 660 | 660 | decl.analysis = .codegen_failure; |
| 661 | try module.failed_decls.put(module.gpa, decl, em); | |
| 661 | try module.addDeclErr(decl, em); | |
| 662 | 662 | return; |
| 663 | 663 | }, |
| 664 | 664 | }; |
src/link/Elf.zig+1-1| ... | ... | @@ -2248,7 +2248,7 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void { |
| 2248 | 2248 | .appended => code_buffer.items, |
| 2249 | 2249 | .fail => |em| { |
| 2250 | 2250 | decl.analysis = .codegen_failure; |
| 2251 | try module.failed_decls.put(module.gpa, decl, em); | |
| 2251 | try module.addDeclErr(decl, em); | |
| 2252 | 2252 | return; |
| 2253 | 2253 | }, |
| 2254 | 2254 | }; |
src/link/MachO.zig+1-1| ... | ... | @@ -1062,7 +1062,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { |
| 1062 | 1062 | .appended => code_buffer.items, |
| 1063 | 1063 | .fail => |em| { |
| 1064 | 1064 | decl.analysis = .codegen_failure; |
| 1065 | try module.failed_decls.put(module.gpa, decl, em); | |
| 1065 | try module.addDeclErr(decl, em); | |
| 1066 | 1066 | return; |
| 1067 | 1067 | }, |
| 1068 | 1068 | }; |
src/value.zig+1-1| ... | ... | @@ -350,7 +350,7 @@ pub const Value = extern union { |
| 350 | 350 | val = elem_ptr.array_ptr; |
| 351 | 351 | }, |
| 352 | 352 | .empty_array => return out_stream.writeAll(".{}"), |
| 353 | .enum_literal => return out_stream.print(".{z}", .{self.cast(Payload.Bytes).?.data}), | |
| 353 | .enum_literal => return out_stream.print(".{z}", .{@fieldParentPtr(Payload.Bytes, "base", self.ptr_otherwise).data}), | |
| 354 | 354 | .bytes => return out_stream.print("\"{Z}\"", .{self.cast(Payload.Bytes).?.data}), |
| 355 | 355 | .repeated => { |
| 356 | 356 | try out_stream.writeAll("(repeated) "); |
src/zir.zig+20-3| ... | ... | @@ -122,6 +122,8 @@ pub const Inst = struct { |
| 122 | 122 | coerce_to_ptr_elem, |
| 123 | 123 | /// Emit an error message and fail compilation. |
| 124 | 124 | compileerror, |
| 125 | /// Log compile time variables and emit an error message. | |
| 126 | compilelog, | |
| 125 | 127 | /// Conditional branch. Splits control flow based on a boolean condition value. |
| 126 | 128 | condbr, |
| 127 | 129 | /// Special case, has no textual representation. |
| ... | ... | @@ -386,6 +388,7 @@ pub const Inst = struct { |
| 386 | 388 | .declval_in_module => DeclValInModule, |
| 387 | 389 | .coerce_result_block_ptr => CoerceResultBlockPtr, |
| 388 | 390 | .compileerror => CompileError, |
| 391 | .compilelog => CompileLog, | |
| 389 | 392 | .loop => Loop, |
| 390 | 393 | .@"const" => Const, |
| 391 | 394 | .str => Str, |
| ... | ... | @@ -513,6 +516,7 @@ pub const Inst = struct { |
| 513 | 516 | .slice_start, |
| 514 | 517 | .import, |
| 515 | 518 | .switch_range, |
| 519 | .compilelog, | |
| 516 | 520 | .typeof_peer, |
| 517 | 521 | => false, |
| 518 | 522 | |
| ... | ... | @@ -707,6 +711,19 @@ pub const Inst = struct { |
| 707 | 711 | kw_args: struct {}, |
| 708 | 712 | }; |
| 709 | 713 | |
| 714 | pub const CompileLog = struct { | |
| 715 | pub const base_tag = Tag.compilelog; | |
| 716 | base: Inst, | |
| 717 | ||
| 718 | positionals: struct { | |
| 719 | to_log: []*Inst, | |
| 720 | }, | |
| 721 | kw_args: struct { | |
| 722 | /// If we have seen it already so don't make another error | |
| 723 | seen: bool = false, | |
| 724 | }, | |
| 725 | }; | |
| 726 | ||
| 710 | 727 | pub const Const = struct { |
| 711 | 728 | pub const base_tag = Tag.@"const"; |
| 712 | 729 | base: Inst, |
| ... | ... | @@ -1925,7 +1942,7 @@ const EmitZIR = struct { |
| 1925 | 1942 | .sema_failure, |
| 1926 | 1943 | .sema_failure_retryable, |
| 1927 | 1944 | .dependency_failure, |
| 1928 | => if (self.old_module.failed_decls.get(ir_decl)) |err_msg| { | |
| 1945 | => if (self.old_module.failed_decls.get(ir_decl)) |err_msg_list| { | |
| 1929 | 1946 | const fail_inst = try self.arena.allocator.create(Inst.CompileError); |
| 1930 | 1947 | fail_inst.* = .{ |
| 1931 | 1948 | .base = .{ |
| ... | ... | @@ -1933,7 +1950,7 @@ const EmitZIR = struct { |
| 1933 | 1950 | .tag = Inst.CompileError.base_tag, |
| 1934 | 1951 | }, |
| 1935 | 1952 | .positionals = .{ |
| 1936 | .msg = try self.arena.allocator.dupe(u8, err_msg.msg), | |
| 1953 | .msg = try self.arena.allocator.dupe(u8, err_msg_list.items[0].msg), | |
| 1937 | 1954 | }, |
| 1938 | 1955 | .kw_args = .{}, |
| 1939 | 1956 | }; |
| ... | ... | @@ -2055,7 +2072,7 @@ const EmitZIR = struct { |
| 2055 | 2072 | try self.emitBody(body, &inst_table, &instructions); |
| 2056 | 2073 | }, |
| 2057 | 2074 | .sema_failure => { |
| 2058 | const err_msg = self.old_module.failed_decls.get(module_fn.owner_decl).?; | |
| 2075 | const err_msg = self.old_module.failed_decls.get(module_fn.owner_decl).?.items[0]; | |
| 2059 | 2076 | const fail_inst = try self.arena.allocator.create(Inst.CompileError); |
| 2060 | 2077 | fail_inst.* = .{ |
| 2061 | 2078 | .base = .{ |
src/zir_sema.zig+23| ... | ... | @@ -43,6 +43,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError! |
| 43 | 43 | .coerce_result_ptr => return analyzeInstCoerceResultPtr(mod, scope, old_inst.castTag(.coerce_result_ptr).?), |
| 44 | 44 | .coerce_to_ptr_elem => return analyzeInstCoerceToPtrElem(mod, scope, old_inst.castTag(.coerce_to_ptr_elem).?), |
| 45 | 45 | .compileerror => return analyzeInstCompileError(mod, scope, old_inst.castTag(.compileerror).?), |
| 46 | .compilelog => return analyzeInstCompileLog(mod, scope, old_inst.castTag(.compilelog).?), | |
| 46 | 47 | .@"const" => return analyzeInstConst(mod, scope, old_inst.castTag(.@"const").?), |
| 47 | 48 | .dbg_stmt => return analyzeInstDbgStmt(mod, scope, old_inst.castTag(.dbg_stmt).?), |
| 48 | 49 | .declref => return analyzeInstDeclRef(mod, scope, old_inst.castTag(.declref).?), |
| ... | ... | @@ -489,6 +490,28 @@ fn analyzeInstCompileError(mod: *Module, scope: *Scope, inst: *zir.Inst.CompileE |
| 489 | 490 | return mod.fail(scope, inst.base.src, "{}", .{inst.positionals.msg}); |
| 490 | 491 | } |
| 491 | 492 | |
| 493 | fn analyzeInstCompileLog(mod: *Module, scope: *Scope, inst: *zir.Inst.CompileLog) InnerError!*Inst { | |
| 494 | std.debug.print("| ", .{}); | |
| 495 | for (inst.positionals.to_log) |item, i| { | |
| 496 | const to_log = try resolveInst(mod, scope, item); | |
| 497 | if (to_log.value()) |val| { | |
| 498 | std.debug.print("{}", .{val}); | |
| 499 | } else { | |
| 500 | std.debug.print("(runtime value)", .{}); | |
| 501 | } | |
| 502 | if (i != inst.positionals.to_log.len - 1) std.debug.print(", ", .{}); | |
| 503 | } | |
| 504 | std.debug.print("\n", .{}); | |
| 505 | if (!inst.kw_args.seen) { | |
| 506 | inst.kw_args.seen = true; // so that we do not give multiple compile errors if it gets evaled twice | |
| 507 | switch (mod.fail(scope, inst.base.src, "found compile log statement", .{})) { | |
| 508 | error.AnalysisFail => {}, // analysis continues | |
| 509 | else => |e| return e, | |
| 510 | } | |
| 511 | } | |
| 512 | return mod.constVoid(scope, inst.base.src); | |
| 513 | } | |
| 514 | ||
| 492 | 515 | fn analyzeInstArg(mod: *Module, scope: *Scope, inst: *zir.Inst.Arg) InnerError!*Inst { |
| 493 | 516 | const b = try mod.requireRuntimeBlock(scope, inst.base.src); |
| 494 | 517 | const fn_ty = b.func.?.owner_decl.typed_value.most_recent.typed_value.ty; |
test/stage2/test.zig+15| ... | ... | @@ -1171,6 +1171,21 @@ pub fn addCases(ctx: *TestContext) !void { |
| 1171 | 1171 | \\fn entry() void {} |
| 1172 | 1172 | , &[_][]const u8{":2:4: error: redefinition of 'entry'"}); |
| 1173 | 1173 | |
| 1174 | ctx.compileError("compileLog", linux_x64, | |
| 1175 | \\export fn _start() noreturn { | |
| 1176 | \\ const b = true; | |
| 1177 | \\ var f: u32 = 1; | |
| 1178 | \\ @compileLog(b, 20, f, x, .foo); | |
| 1179 | \\ var y: u32 = true; | |
| 1180 | \\ unreachable; | |
| 1181 | \\} | |
| 1182 | \\fn x() void {} | |
| 1183 | , &[_][]const u8{ | |
| 1184 | ":4:3: error: found compile log statement", ":5:16: error: expected u32, found bool", | |
| 1185 | }); | |
| 1186 | ||
| 1187 | // "| true, 20, (runtime value), (function)" // TODO if this is here it invalidates the compile error checker. Need a way to check though. | |
| 1188 | ||
| 1174 | 1189 | { |
| 1175 | 1190 | var case = ctx.obj("variable shadowing", linux_x64); |
| 1176 | 1191 | case.addError( |