From 269e54877051791790f5dffc4d4f1476834e4e43 Mon Sep 17 00:00:00 2001 From: Martin Wickham Date: Thu, 30 Sep 2021 13:34:12 -0500 Subject: [PATCH 01/14] Fix namespace references for deeply nested structs --- src/Module.zig | 19 +++++++------------ src/Sema.zig | 41 ++++++++++++++--------------------------- 2 files changed, 21 insertions(+), 39 deletions(-) diff --git a/src/Module.zig b/src/Module.zig index 6c790d3804..c398081bc3 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1107,7 +1107,7 @@ pub const Scope = struct { /// Asserts the scope has a parent which is a Namespace and returns it. pub fn namespace(scope: *Scope) *Namespace { switch (scope.tag) { - .block => return scope.cast(Block).?.sema.owner_decl.namespace, + .block => return scope.cast(Block).?.src_decl.namespace, .file => return scope.cast(File).?.root_decl.?.namespace, .namespace => return scope.cast(Namespace).?, } @@ -3244,11 +3244,11 @@ pub fn semaFile(mod: *Module, file: *Scope.File) SemaError!void { .file_scope = file, }, }; - const new_decl = try mod.allocateNewDecl(&struct_obj.namespace, 0, null); + const decl_name = try file.fullyQualifiedNameZ(gpa); + const new_decl = try mod.allocateNewDecl(decl_name, &struct_obj.namespace, 0, null); file.root_decl = new_decl; struct_obj.owner_decl = new_decl; new_decl.src_line = 0; - new_decl.name = try file.fullyQualifiedNameZ(gpa); new_decl.is_pub = true; new_decl.is_exported = false; new_decl.has_align = false; @@ -3276,7 +3276,6 @@ pub fn semaFile(mod: *Module, file: *Scope.File) SemaError!void { .perm_arena = &new_decl_arena.allocator, .code = file.zir, .owner_decl = new_decl, - .namespace = &struct_obj.namespace, .func = null, .fn_ret_ty = Type.initTag(.void), .owner_func = null, @@ -3342,7 +3341,6 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { .perm_arena = &decl_arena.allocator, .code = zir, .owner_decl = decl, - .namespace = decl.namespace, .func = null, .fn_ret_ty = Type.initTag(.void), .owner_func = null, @@ -3818,13 +3816,12 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi // We create a Decl for it regardless of analysis status. const gop = try namespace.decls.getOrPut(gpa, decl_name); if (!gop.found_existing) { - const new_decl = try mod.allocateNewDecl(namespace, decl_node, iter.parent_decl.src_scope); + const new_decl = try mod.allocateNewDecl(decl_name, namespace, decl_node, iter.parent_decl.src_scope); if (is_usingnamespace) { namespace.usingnamespace_set.putAssumeCapacity(new_decl, is_pub); } log.debug("scan new {*} ({s}) into {*}", .{ new_decl, decl_name, namespace }); new_decl.src_line = line; - new_decl.name = decl_name; gop.value_ptr.* = new_decl; // Exported decls, comptime decls, usingnamespace decls, and // test decls if in test mode, get analyzed. @@ -4089,7 +4086,6 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: *Allocator) Se .perm_arena = &decl_arena.allocator, .code = decl.namespace.file_scope.zir, .owner_decl = decl, - .namespace = decl.namespace, .func = func, .fn_ret_ty = func.owner_decl.ty.fnReturnType(), .owner_func = func, @@ -4226,7 +4222,7 @@ fn markOutdatedDecl(mod: *Module, decl: *Decl) !void { decl.analysis = .outdated; } -pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: Ast.Node.Index, src_scope: ?*CaptureScope) !*Decl { +pub fn allocateNewDecl(mod: *Module, name: [:0]const u8, namespace: *Scope.Namespace, src_node: Ast.Node.Index, src_scope: ?*CaptureScope) !*Decl { // If we have emit-h then we must allocate a bigger structure to store the emit-h state. const new_decl: *Decl = if (mod.emit_h != null) blk: { const parent_struct = try mod.gpa.create(DeclPlusEmitH); @@ -4238,7 +4234,7 @@ pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: Ast. } else try mod.gpa.create(Decl); new_decl.* = .{ - .name = "", + .name = name, .namespace = namespace, .src_node = src_node, .src_line = undefined, @@ -4414,9 +4410,8 @@ pub fn createAnonymousDeclFromDeclNamed( const namespace = src_decl.namespace; try namespace.anon_decls.ensureUnusedCapacity(mod.gpa, 1); - const new_decl = try mod.allocateNewDecl(namespace, src_decl.src_node, src_scope); + const new_decl = try mod.allocateNewDecl(name, namespace, src_decl.src_node, src_scope); - new_decl.name = name; new_decl.src_line = src_decl.src_line; new_decl.ty = typed_value.ty; new_decl.val = typed_value.val; diff --git a/src/Sema.zig b/src/Sema.zig index 8842a55dcc..218f4258b8 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -24,8 +24,6 @@ inst_map: InstMap = .{}, /// and `src_decl` of `Scope.Block` is the `Decl` of the callee. /// This `Decl` owns the arena memory of this `Sema`. owner_decl: *Decl, -/// How to look up decl names. -namespace: *Scope.Namespace, /// For an inline or comptime function call, this will be the root parent function /// which contains the callsite. Corresponds to `owner_decl`. owner_func: ?*Module.Fn, @@ -1048,6 +1046,8 @@ pub fn analyzeStructDecl( } else 0; _ = try sema.mod.scanNamespace(&struct_obj.namespace, extra_index, decls_len, new_decl); + + new_decl.namespace = &struct_obj.namespace; } fn zirStructDecl( @@ -1084,7 +1084,7 @@ fn zirStructDecl( .status = .none, .known_has_bits = undefined, .namespace = .{ - .parent = sema.owner_decl.namespace, + .parent = block.src_decl.namespace, .ty = struct_ty, .file_scope = block.getFileScope(), }, @@ -1194,7 +1194,7 @@ fn zirEnumDecl( .values = .{}, .node_offset = src.node_offset, .namespace = .{ - .parent = sema.owner_decl.namespace, + .parent = block.src_decl.namespace, .ty = enum_ty, .file_scope = block.getFileScope(), }, @@ -1205,6 +1205,8 @@ fn zirEnumDecl( extra_index = try mod.scanNamespace(&enum_obj.namespace, extra_index, decls_len, new_decl); + new_decl.namespace = &enum_obj.namespace; + const body = sema.code.extra[extra_index..][0..body_len]; if (fields_len == 0) { assert(body.len == 0); @@ -1227,10 +1229,6 @@ fn zirEnumDecl( sema.owner_decl = new_decl; defer sema.owner_decl = prev_owner_decl; - const prev_namespace = sema.namespace; - sema.namespace = &enum_obj.namespace; - defer sema.namespace = prev_namespace; - const prev_owner_func = sema.owner_func; sema.owner_func = null; defer sema.owner_func = prev_owner_func; @@ -1385,7 +1383,7 @@ fn zirUnionDecl( .layout = small.layout, .status = .none, .namespace = .{ - .parent = sema.owner_decl.namespace, + .parent = block.src_decl.namespace, .ty = union_ty, .file_scope = block.getFileScope(), }, @@ -1396,6 +1394,8 @@ fn zirUnionDecl( _ = try sema.mod.scanNamespace(&union_obj.namespace, extra_index, decls_len, new_decl); + new_decl.namespace = &union_obj.namespace; + try sema.types_pending_resolution.ensureUnusedCapacity(sema.gpa, 1); try new_decl.finalizeNewArena(&new_decl_arena); sema.types_pending_resolution.appendAssumeCapacity(union_ty); @@ -2692,7 +2692,7 @@ fn zirDeclVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr } fn lookupIdentifier(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, name: []const u8) !*Decl { - var namespace = sema.namespace; + var namespace = block.src_decl.namespace; while (true) { if (try sema.lookupInNamespace(block, src, namespace, name, false)) |decl| { return decl; @@ -3010,10 +3010,6 @@ fn analyzeCall( sema.inst_map = parent_inst_map; } - const parent_namespace = sema.namespace; - sema.namespace = module_fn.owner_decl.namespace; - defer sema.namespace = parent_namespace; - const parent_func = sema.func; sema.func = module_fn; defer sema.func = parent_func; @@ -3276,12 +3272,12 @@ fn analyzeCall( // Create a Decl for the new function. const src_decl = namespace.getDecl(); - const new_decl = try mod.allocateNewDecl(namespace, module_fn.owner_decl.src_node, src_decl.src_scope); // TODO better names for generic function instantiations const name_index = mod.getNextAnonNameIndex(); - new_decl.name = try std.fmt.allocPrintZ(gpa, "{s}__anon_{d}", .{ + const decl_name = try std.fmt.allocPrintZ(gpa, "{s}__anon_{d}", .{ module_fn.owner_decl.name, name_index, }); + const new_decl = try mod.allocateNewDecl(decl_name, namespace, module_fn.owner_decl.src_node, src_decl.src_scope); new_decl.src_line = module_fn.owner_decl.src_line; new_decl.is_pub = module_fn.owner_decl.is_pub; new_decl.is_exported = module_fn.owner_decl.is_exported; @@ -3311,7 +3307,6 @@ fn analyzeCall( .perm_arena = &new_decl_arena.allocator, .code = fn_zir, .owner_decl = new_decl, - .namespace = namespace, .func = null, .fn_ret_ty = Type.initTag(.void), .owner_func = null, @@ -11809,7 +11804,7 @@ pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: switch (ty.tag()) { .@"struct" => { const struct_obj = ty.castTag(.@"struct").?.data; - if (struct_obj.owner_decl.namespace != sema.owner_decl.namespace) return; + if (struct_obj.owner_decl.namespace.parent != sema.owner_decl.namespace) return; switch (struct_obj.status) { .none => {}, .field_types_wip => { @@ -11817,10 +11812,6 @@ pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: }, .have_field_types, .have_layout, .layout_wip => return, } - const prev_namespace = sema.namespace; - sema.namespace = &struct_obj.namespace; - defer sema.namespace = prev_namespace; - const old_src = block.src_decl; defer block.src_decl = old_src; block.src_decl = struct_obj.owner_decl; @@ -11831,7 +11822,7 @@ pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: }, .@"union", .union_tagged => { const union_obj = ty.cast(Type.Payload.Union).?.data; - if (union_obj.owner_decl.namespace != sema.owner_decl.namespace) return; + if (union_obj.owner_decl.namespace.parent != sema.owner_decl.namespace) return; switch (union_obj.status) { .none => {}, .field_types_wip => { @@ -11839,10 +11830,6 @@ pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: }, .have_field_types, .have_layout, .layout_wip => return, } - const prev_namespace = sema.namespace; - sema.namespace = &union_obj.namespace; - defer sema.namespace = prev_namespace; - const old_src = block.src_decl; defer block.src_decl = old_src; block.src_decl = union_obj.owner_decl; From b1e5081826ba383ebdb298117e5712b8c73fb22a Mon Sep 17 00:00:00 2001 From: Martin Wickham Date: Thu, 30 Sep 2021 15:40:11 -0500 Subject: [PATCH 02/14] Fix rendering of type names --- src/Module.zig | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Module.zig b/src/Module.zig index c398081bc3..026052be84 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -617,12 +617,15 @@ pub const Decl = struct { return tree.tokens.items(.start)[decl.srcToken()]; } - pub fn renderFullyQualifiedName(decl: Decl, writer: anytype) !void { - const unqualified_name = mem.spanZ(decl.name); - return decl.namespace.renderFullyQualifiedName(unqualified_name, writer); + pub fn renderFullyQualifiedName(decl: *const Decl, writer: anytype) @TypeOf(writer).Error!void { + // Namespace decls (struct/enum/union/opaque) use their own namespace, + // which means the decl name and the namespace name are the same. + // In that case we want to omit the decl name, unless this is the root decl. + const unqualified_name = if (decl.namespace.getDecl() != decl or decl.namespace.parent == null) mem.spanZ(decl.name) else ""; + return try decl.namespace.renderFullyQualifiedName(unqualified_name, writer); } - pub fn getFullyQualifiedName(decl: Decl, gpa: *Allocator) ![:0]u8 { + pub fn getFullyQualifiedName(decl: *const Decl, gpa: *Allocator) ![:0]u8 { var buffer = std.ArrayList(u8).init(gpa); defer buffer.deinit(); try decl.renderFullyQualifiedName(buffer.writer()); From 7ef59384500afa5b20bee474d570af55565dfa7f Mon Sep 17 00:00:00 2001 From: Martin Wickham Date: Thu, 30 Sep 2021 21:41:24 -0500 Subject: [PATCH 03/14] Fix decl removal from namespace when destroyed --- src/Module.zig | 16 +++++++++------- src/Sema.zig | 18 +++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/Module.zig b/src/Module.zig index 026052be84..0557a6dcb0 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1695,7 +1695,7 @@ pub const Scope = struct { .ty = ty, .val = val, }); - errdefer wad.block.sema.mod.deleteAnonDecl(&wad.block.base, new_decl); + errdefer wad.block.sema.mod.abortAnonDecl(new_decl); try new_decl.finalizeNewArena(&wad.new_decl_arena); wad.finished = true; return new_decl; @@ -4013,9 +4013,10 @@ pub fn deleteUnusedDecl(mod: *Module, decl: *Decl) void { }, } - const dependants = decl.dependants.keys(); - assert(dependants[0].namespace.anon_decls.swapRemove(decl)); + const owner_namespace = if (decl.namespace.getDecl() == decl and decl.namespace.parent != null) decl.namespace.parent.? else decl.namespace; + assert(owner_namespace.anon_decls.swapRemove(decl)); + const dependants = decl.dependants.keys(); for (dependants) |dep| { dep.removeDependency(decl); } @@ -4026,10 +4027,11 @@ pub fn deleteUnusedDecl(mod: *Module, decl: *Decl) void { decl.destroy(mod); } -pub fn deleteAnonDecl(mod: *Module, scope: *Scope, decl: *Decl) void { - log.debug("deleteAnonDecl {*} ({s})", .{ decl, decl.name }); - const scope_decl = scope.srcDecl().?; - assert(scope_decl.namespace.anon_decls.swapRemove(decl)); +pub fn abortAnonDecl(mod: *Module, decl: *Decl) void { + log.debug("abortAnonDecl {*} ({s})", .{ decl, decl.name }); + assert(decl.namespace.anon_decls.swapRemove(decl)); + assert(decl.dependants.count() == 0); + assert(decl.dependencies.count() == 0); decl.destroy(mod); } diff --git a/src/Sema.zig b/src/Sema.zig index 218f4258b8..995dc84303 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1074,7 +1074,7 @@ fn zirStructDecl( .val = struct_val, }, type_name); new_decl.owns_tv = true; - errdefer sema.mod.deleteAnonDecl(&block.base, new_decl); + errdefer sema.mod.abortAnonDecl(new_decl); struct_obj.* = .{ .owner_decl = new_decl, .fields = .{}, @@ -1185,7 +1185,7 @@ fn zirEnumDecl( .val = enum_val, }, type_name); new_decl.owns_tv = true; - errdefer sema.mod.deleteAnonDecl(&block.base, new_decl); + errdefer sema.mod.abortAnonDecl(new_decl); enum_obj.* = .{ .owner_decl = new_decl, @@ -1373,7 +1373,7 @@ fn zirUnionDecl( .val = union_val, }, type_name); new_decl.owns_tv = true; - errdefer sema.mod.deleteAnonDecl(&block.base, new_decl); + errdefer sema.mod.abortAnonDecl(new_decl); union_obj.* = .{ .owner_decl = new_decl, .tag_ty = Type.initTag(.@"null"), @@ -1443,7 +1443,7 @@ fn zirErrorSetDecl( .val = error_set_val, }, type_name); new_decl.owns_tv = true; - errdefer sema.mod.deleteAnonDecl(&block.base, new_decl); + errdefer sema.mod.abortAnonDecl(new_decl); const names = try new_decl_arena.allocator.alloc([]const u8, fields.len); for (fields) |str_index, i| { names[i] = try new_decl_arena.allocator.dupe(u8, sema.code.nullTerminatedString(str_index)); @@ -2101,7 +2101,7 @@ fn zirStr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A .ty = decl_ty, .val = decl_val, }); - errdefer sema.mod.deleteAnonDecl(&block.base, new_decl); + errdefer sema.mod.abortAnonDecl(new_decl); try new_decl.finalizeNewArena(&new_decl_arena); return sema.analyzeDeclRef(new_decl); } @@ -11804,7 +11804,7 @@ pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: switch (ty.tag()) { .@"struct" => { const struct_obj = ty.castTag(.@"struct").?.data; - if (struct_obj.owner_decl.namespace.parent != sema.owner_decl.namespace) return; + if (struct_obj.owner_decl.namespace.parent != block.src_decl.namespace) return; switch (struct_obj.status) { .none => {}, .field_types_wip => { @@ -11822,7 +11822,7 @@ pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: }, .@"union", .union_tagged => { const union_obj = ty.cast(Type.Payload.Union).?.data; - if (union_obj.owner_decl.namespace.parent != sema.owner_decl.namespace) return; + if (union_obj.owner_decl.namespace.parent != block.src_decl.namespace) return; switch (union_obj.status) { .none => {}, .field_types_wip => { @@ -12210,7 +12210,7 @@ fn generateUnionTagTypeNumbered( .val = enum_val, }); new_decl.owns_tv = true; - errdefer sema.mod.deleteAnonDecl(&block.base, new_decl); + errdefer sema.mod.abortAnonDecl(new_decl); enum_obj.* = .{ .owner_decl = new_decl, @@ -12246,7 +12246,7 @@ fn generateUnionTagTypeSimple(sema: *Sema, block: *Scope.Block, fields_len: u32) .val = enum_val, }); new_decl.owns_tv = true; - errdefer sema.mod.deleteAnonDecl(&block.base, new_decl); + errdefer sema.mod.abortAnonDecl(new_decl); enum_obj.* = .{ .owner_decl = new_decl, From 993dc2ae77514e61235f0920755fdb1ccc77c2f7 Mon Sep 17 00:00:00 2001 From: Martin Wickham Date: Thu, 30 Sep 2021 21:42:34 -0500 Subject: [PATCH 04/14] Fix ownership of array type and elements --- src/Sema.zig | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index 995dc84303..7fb12bf27c 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -8244,10 +8244,13 @@ fn zirArrayInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: var anon_decl = try block.startAnonDecl(); defer anon_decl.deinit(); assert(!(resolved_args.len == 0)); - const final_ty = try Type.Tag.array.create(anon_decl.arena(), .{ .len = resolved_args.len, .elem_type = sema.typeOf(resolved_args[0]) }); + const final_ty = try Type.Tag.array.create(anon_decl.arena(), .{ + .len = resolved_args.len, + .elem_type = try sema.typeOf(resolved_args[0]).copy(anon_decl.arena()), + }); const buf = try anon_decl.arena().alloc(Value, resolved_args.len); for (resolved_args) |arg, i| { - buf[i] = (try sema.resolveMaybeUndefVal(block, src, arg)).?; + buf[i] = try (try sema.resolveMaybeUndefVal(block, src, arg)).?.copy(anon_decl.arena()); } const val = try Value.Tag.array.create(anon_decl.arena(), buf); From 0b8ddb4478ebf14811caf8a083ca493f9ed733b2 Mon Sep 17 00:00:00 2001 From: Martin Wickham Date: Thu, 30 Sep 2021 21:43:30 -0500 Subject: [PATCH 05/14] Improve debug names of decls --- src/Module.zig | 35 +++++++++++++++++++++++++++++++++++ src/crash_report.zig | 2 +- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/Module.zig b/src/Module.zig index 0557a6dcb0..07ebb0823c 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -625,6 +625,14 @@ pub const Decl = struct { return try decl.namespace.renderFullyQualifiedName(unqualified_name, writer); } + pub fn renderFullyQualifiedDebugName(decl: *const Decl, writer: anytype) @TypeOf(writer).Error!void { + // Namespace decls (struct/enum/union/opaque) use their own namespace, + // which means the decl name and the namespace name are the same. + // In that case we want to omit the decl name, unless this is the root decl. + const unqualified_name = if (decl.namespace.getDecl() != decl or decl.namespace.parent == null) mem.spanZ(decl.name) else ""; + return try decl.namespace.renderFullyQualifiedDebugName(unqualified_name, writer); + } + pub fn getFullyQualifiedName(decl: *const Decl, gpa: *Allocator) ![:0]u8 { var buffer = std.ArrayList(u8).init(gpa); defer buffer.deinit(); @@ -1246,6 +1254,26 @@ pub const Scope = struct { } } + // This renders e.g. "std.fs:Dir.OpenOptions" + pub fn renderFullyQualifiedDebugName( + ns: Namespace, + name: []const u8, + writer: anytype, + ) @TypeOf(writer).Error!void { + var separator_char: u8 = '.'; + if (ns.parent) |parent| { + const decl = ns.getDecl(); + try parent.renderFullyQualifiedDebugName(mem.spanZ(decl.name), writer); + } else { + try ns.file_scope.renderFullyQualifiedDebugName(writer); + separator_char = ':'; + } + if (name.len != 0) { + try writer.writeByte(separator_char); + try writer.writeAll(name); + } + } + pub fn getDecl(ns: Namespace) *Decl { return ns.ty.getOwnerDecl(); } @@ -1400,6 +1428,13 @@ pub const Scope = struct { }; } + pub fn renderFullyQualifiedDebugName(file: File, writer: anytype) !void { + for (file.sub_file_path) |byte| switch (byte) { + '/', '\\' => try writer.writeByte('/'), + else => try writer.writeByte(byte), + }; + } + pub fn fullyQualifiedNameZ(file: File, gpa: *Allocator) ![:0]u8 { var buf = std.ArrayList(u8).init(gpa); defer buf.deinit(); diff --git a/src/crash_report.zig b/src/crash_report.zig index 84f4b8db84..4554e324cb 100644 --- a/src/crash_report.zig +++ b/src/crash_report.zig @@ -150,7 +150,7 @@ fn writeFilePath(file: *Scope.File, stream: anytype) !void { fn writeFullyQualifiedDeclWithFile(decl: *Decl, stream: anytype) !void { try writeFilePath(decl.getFileScope(), stream); try stream.writeAll(": "); - try decl.namespace.renderFullyQualifiedName(std.mem.sliceTo(decl.name, 0), stream); + try decl.renderFullyQualifiedDebugName(stream); } fn compilerPanic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn { From 8d42500699939028aaf78e9463326820b6d08353 Mon Sep 17 00:00:00 2001 From: Martin Wickham Date: Thu, 30 Sep 2021 22:57:41 -0500 Subject: [PATCH 06/14] Implement hashing and equals for some pointer values --- src/value.zig | 52 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/src/value.zig b/src/value.zig index ac52654041..72fc46ef4c 100644 --- a/src/value.zig +++ b/src/value.zig @@ -1238,9 +1238,24 @@ pub const Value = extern union { const b_field_index = b.castTag(.enum_field_index).?.data; return a_field_index == b_field_index; }, + .elem_ptr => @panic("TODO: Implement more pointer eql cases"), + .field_ptr => @panic("TODO: Implement more pointer eql cases"), + .eu_payload_ptr => @panic("TODO: Implement more pointer eql cases"), + .opt_payload_ptr => @panic("TODO: Implement more pointer eql cases"), else => {}, } } + + if (a.pointerDecl()) |a_decl| { + if (b.pointerDecl()) |b_decl| { + return a_decl == b_decl; + } else { + return false; + } + } else if (b.pointerDecl()) |_| { + return false; + } + if (ty.zigTypeTag() == .Type) { var buf_a: ToTypeBuffer = undefined; var buf_b: ToTypeBuffer = undefined; @@ -1285,8 +1300,28 @@ pub const Value = extern union { const float = val.toFloat(f128); std.hash.autoHash(hasher, @bitCast(u128, float)); }, - .Pointer => { - @panic("TODO implement hashing pointer values"); + .Pointer => switch (val.tag()) { + .decl_ref_mut, + .extern_fn, + .decl_ref, + .function, + .variable, + => std.hash.autoHash(hasher, val.pointerDecl().?), + + .elem_ptr => @panic("TODO: Implement more pointer hashing cases"), + .field_ptr => @panic("TODO: Implement more pointer hashing cases"), + .eu_payload_ptr => @panic("TODO: Implement more pointer hashing cases"), + .opt_payload_ptr => @panic("TODO: Implement more pointer hashing cases"), + + .zero, + .one, + .int_u64, + .int_i64, + .int_big_positive, + .int_big_negative, + => @panic("TODO: Implement pointer hashing for int pointers"), + + else => unreachable, }, .Array, .Vector => { @panic("TODO implement hashing array/vector values"); @@ -1432,6 +1467,19 @@ pub const Value = extern union { return sub_val; } + /// Gets the decl referenced by this pointer. If the pointer does not point + /// to a decl, or if it points to some part of a decl (like field_ptr or element_ptr), + /// this function returns null. + pub fn pointerDecl(self: Value) ?*Module.Decl { + return switch (self.tag()) { + .decl_ref_mut => self.castTag(.decl_ref_mut).?.data.decl, + .extern_fn, .decl_ref => self.cast(Payload.Decl).?.data, + .function => self.castTag(.function).?.data.owner_decl, + .variable => self.castTag(.variable).?.data.owner_decl, + else => null, + }; + } + pub fn sliceLen(val: Value) u64 { return switch (val.tag()) { .empty_array => 0, From 806eee8e99fbbd86f01b62b4306bd48f1cd3c872 Mon Sep 17 00:00:00 2001 From: Martin Wickham Date: Thu, 30 Sep 2021 23:38:41 -0500 Subject: [PATCH 07/14] Fix abortAnonDecl() --- src/Module.zig | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Module.zig b/src/Module.zig index 07ebb0823c..60dea31d18 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -4064,9 +4064,19 @@ pub fn deleteUnusedDecl(mod: *Module, decl: *Decl) void { pub fn abortAnonDecl(mod: *Module, decl: *Decl) void { log.debug("abortAnonDecl {*} ({s})", .{ decl, decl.name }); - assert(decl.namespace.anon_decls.swapRemove(decl)); - assert(decl.dependants.count() == 0); - assert(decl.dependencies.count() == 0); + + const owner_namespace = if (decl.namespace.getDecl() == decl and decl.namespace.parent != null) decl.namespace.parent.? else decl.namespace; + assert(owner_namespace.anon_decls.swapRemove(decl)); + + const dependants = decl.dependants.keys(); + for (dependants) |dep| { + dep.removeDependency(decl); + } + + for (decl.dependencies.keys()) |dep| { + dep.removeDependant(decl); + } + decl.destroy(mod); } From f7c11acb7f487806b14ada9d13d6afe8d3fe54d5 Mon Sep 17 00:00:00 2001 From: Martin Wickham Date: Fri, 1 Oct 2021 00:42:50 -0500 Subject: [PATCH 08/14] Resolve struct fields in a separate sema context --- src/Module.zig | 6 -- src/Sema.zig | 208 ++++++++++++++++++++++++++----------------------- 2 files changed, 112 insertions(+), 102 deletions(-) diff --git a/src/Module.zig b/src/Module.zig index 60dea31d18..a2b22e4c17 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -3584,12 +3584,6 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl }); } } - // In case this Decl is a struct or union, we need to resolve the fields - // while we still have the `Sema` in scope, so that the field type expressions - // can use the resolved AIR instructions that they possibly reference. - // We do this after the decl is populated and set to `complete` so that a `Decl` - // may reference itself. - try sema.resolvePendingTypes(&block_scope); if (decl.is_exported) { const export_src = src; // TODO point to the export token diff --git a/src/Sema.zig b/src/Sema.zig index 7fb12bf27c..0aa8a28664 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -60,9 +60,6 @@ comptime_args_fn_inst: Zir.Inst.Index = 0, /// extra hash table lookup in the `monomorphed_funcs` set. /// Sema will set this to null when it takes ownership. preallocated_new_func: ?*Module.Fn = null, -/// Collects struct, union, enum, and opaque decls which need to have their -/// fields resolved before this Sema is deinitialized. -types_pending_resolution: std.ArrayListUnmanaged(Type) = .{}, const std = @import("std"); const mem = std.mem; @@ -99,7 +96,6 @@ pub fn deinit(sema: *Sema) void { sema.air_values.deinit(gpa); sema.inst_map.deinit(gpa); sema.decl_val_table.deinit(gpa); - sema.types_pending_resolution.deinit(gpa); sema.* = undefined; } @@ -1093,9 +1089,7 @@ fn zirStructDecl( &struct_obj.namespace, new_decl, new_decl.name, }); try sema.analyzeStructDecl(new_decl, inst, struct_obj); - try sema.types_pending_resolution.ensureUnusedCapacity(sema.gpa, 1); try new_decl.finalizeNewArena(&new_decl_arena); - sema.types_pending_resolution.appendAssumeCapacity(struct_ty); return sema.analyzeDeclVal(block, src, new_decl); } @@ -1396,9 +1390,7 @@ fn zirUnionDecl( new_decl.namespace = &union_obj.namespace; - try sema.types_pending_resolution.ensureUnusedCapacity(sema.gpa, 1); try new_decl.finalizeNewArena(&new_decl_arena); - sema.types_pending_resolution.appendAssumeCapacity(union_ty); return sema.analyzeDeclVal(block, src, new_decl); } @@ -3176,12 +3168,6 @@ fn analyzeCall( }); delete_memoized_call_key = false; } - - // Much like in `Module.semaDecl`, if the result is a struct or union type, - // we need to resolve the field type expressions right here, right now, while - // the child `Sema` is still available, with the AIR instruction map intact, - // because the field type expressions may reference into it. - try sema.resolvePendingTypes(&child_block); } break :res2 result; @@ -11792,70 +11778,23 @@ pub fn resolveTypeLayout( } } -pub fn resolvePendingTypes(sema: *Sema, block: *Scope.Block) !void { - for (sema.types_pending_resolution.items) |ty| { - // If an error happens resolving the fields of a struct, it will be marked - // invalid and a proper compile error set up. But we should still look at the - // other types pending resolution. - const src: LazySrcLoc = .{ .node_offset = 0 }; - sema.resolveDeclFields(block, src, ty) catch continue; - } -} - -/// `sema` and `block` are expected to be the same ones used for the `Decl`. -pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type) !void { - switch (ty.tag()) { - .@"struct" => { - const struct_obj = ty.castTag(.@"struct").?.data; - if (struct_obj.owner_decl.namespace.parent != block.src_decl.namespace) return; - switch (struct_obj.status) { - .none => {}, - .field_types_wip => { - return sema.mod.fail(&block.base, src, "struct {} depends on itself", .{ty}); - }, - .have_field_types, .have_layout, .layout_wip => return, - } - const old_src = block.src_decl; - defer block.src_decl = old_src; - block.src_decl = struct_obj.owner_decl; - - struct_obj.status = .field_types_wip; - try sema.analyzeStructFields(block, struct_obj); - struct_obj.status = .have_field_types; - }, - .@"union", .union_tagged => { - const union_obj = ty.cast(Type.Payload.Union).?.data; - if (union_obj.owner_decl.namespace.parent != block.src_decl.namespace) return; - switch (union_obj.status) { - .none => {}, - .field_types_wip => { - return sema.mod.fail(&block.base, src, "union {} depends on itself", .{ty}); - }, - .have_field_types, .have_layout, .layout_wip => return, - } - const old_src = block.src_decl; - defer block.src_decl = old_src; - block.src_decl = union_obj.owner_decl; - - union_obj.status = .field_types_wip; - try sema.analyzeUnionFields(block, union_obj); - union_obj.status = .have_field_types; - }, - else => return, - } -} - fn resolveTypeFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type) CompileError!Type { switch (ty.tag()) { .@"struct" => { const struct_obj = ty.castTag(.@"struct").?.data; switch (struct_obj.status) { - .none => unreachable, + .none => {}, .field_types_wip => { return sema.mod.fail(&block.base, src, "struct {} depends on itself", .{ty}); }, .have_field_types, .have_layout, .layout_wip => return ty, } + + struct_obj.status = .field_types_wip; + try semaStructFields(sema.mod, struct_obj); + struct_obj.status = .have_field_types; + + return ty; }, .type_info => return sema.resolveBuiltinTypeFields(block, src, "TypeInfo"), .extern_options => return sema.resolveBuiltinTypeFields(block, src, "ExternOptions"), @@ -11871,12 +11810,18 @@ fn resolveTypeFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type .@"union", .union_tagged => { const union_obj = ty.cast(Type.Payload.Union).?.data; switch (union_obj.status) { - .none => unreachable, + .none => {}, .field_types_wip => { return sema.mod.fail(&block.base, src, "union {} depends on itself", .{ty}); }, .have_field_types, .have_layout, .layout_wip => return ty, } + + union_obj.status = .field_types_wip; + try semaUnionFields(sema.mod, union_obj); + union_obj.status = .have_field_types; + + return ty; }, else => return ty, } @@ -11892,16 +11837,16 @@ fn resolveBuiltinTypeFields( return sema.resolveTypeFields(block, src, resolved_ty); } -fn analyzeStructFields( - sema: *Sema, - block: *Scope.Block, +fn semaStructFields( + mod: *Module, struct_obj: *Module.Struct, ) CompileError!void { const tracy = trace(@src()); defer tracy.end(); - const gpa = sema.gpa; - const zir = sema.code; + const gpa = mod.gpa; + const decl = struct_obj.owner_decl; + const zir = struct_obj.namespace.file_scope.zir; const extended = zir.instructions.items(.data)[struct_obj.zir_index].extended; assert(extended.opcode == .struct_decl); const small = @bitCast(Zir.Inst.StructDecl.Small, extended.small); @@ -11940,15 +11885,50 @@ fn analyzeStructFields( } extra_index += body.len; - var decl_arena = struct_obj.owner_decl.value_arena.?.promote(gpa); - defer struct_obj.owner_decl.value_arena.?.* = decl_arena.state; + var decl_arena = decl.value_arena.?.promote(gpa); + defer decl.value_arena.?.* = decl_arena.state; - try struct_obj.fields.ensureTotalCapacity(&decl_arena.allocator, fields_len); + var analysis_arena = std.heap.ArenaAllocator.init(gpa); + defer analysis_arena.deinit(); + + var sema: Sema = .{ + .mod = mod, + .gpa = gpa, + .arena = &analysis_arena.allocator, + .perm_arena = &decl_arena.allocator, + .code = zir, + .owner_decl = decl, + .func = null, + .fn_ret_ty = Type.initTag(.void), + .owner_func = null, + }; + defer sema.deinit(); + + var wip_captures = try WipCaptureScope.init(gpa, &decl_arena.allocator, decl.src_scope); + defer wip_captures.deinit(); + + var block_scope: Scope.Block = .{ + .parent = null, + .sema = &sema, + .src_decl = decl, + .wip_capture_scope = wip_captures.scope, + .instructions = .{}, + .inlining = null, + .is_comptime = true, + }; + defer { + assert(block_scope.instructions.items.len == 0); + block_scope.params.deinit(gpa); + } if (body.len != 0) { - _ = try sema.analyzeBody(block, body); + _ = try sema.analyzeBody(&block_scope, body); } + try wip_captures.finalize(); + + try struct_obj.fields.ensureTotalCapacity(&decl_arena.allocator, fields_len); + const bits_per_field = 4; const fields_per_u32 = 32 / bits_per_field; const bit_bags_count = std.math.divCeil(usize, fields_len, fields_per_u32) catch unreachable; @@ -11985,7 +11965,7 @@ fn analyzeStructFields( // TODO: if we need to report an error here, use a source location // that points to this type expression rather than the struct. // But only resolve the source location if we need to emit a compile error. - try sema.resolveType(block, src, field_type_ref); + try sema.resolveType(&block_scope, src, field_type_ref); const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name); assert(!gop.found_existing); @@ -12003,7 +11983,7 @@ fn analyzeStructFields( // TODO: if we need to report an error here, use a source location // that points to this alignment expression rather than the struct. // But only resolve the source location if we need to emit a compile error. - const abi_align_val = (try sema.resolveInstConst(block, src, align_ref)).val; + const abi_align_val = (try sema.resolveInstConst(&block_scope, src, align_ref)).val; gop.value_ptr.abi_align = try abi_align_val.copy(&decl_arena.allocator); } if (has_default) { @@ -12013,23 +11993,23 @@ fn analyzeStructFields( // TODO: if we need to report an error here, use a source location // that points to this default value expression rather than the struct. // But only resolve the source location if we need to emit a compile error. - const default_val = (try sema.resolveMaybeUndefVal(block, src, default_inst)) orelse - return sema.failWithNeededComptime(block, src); + const default_val = (try sema.resolveMaybeUndefVal(&block_scope, src, default_inst)) orelse + return sema.failWithNeededComptime(&block_scope, src); gop.value_ptr.default_val = try default_val.copy(&decl_arena.allocator); } } } -fn analyzeUnionFields( - sema: *Sema, - block: *Scope.Block, +fn semaUnionFields( + mod: *Module, union_obj: *Module.Union, ) CompileError!void { const tracy = trace(@src()); defer tracy.end(); - const gpa = sema.gpa; - const zir = sema.code; + const gpa = mod.gpa; + const decl = union_obj.owner_decl; + const zir = union_obj.namespace.file_scope.zir; const extended = zir.instructions.items(.data)[union_obj.zir_index].extended; assert(extended.opcode == .union_decl); const small = @bitCast(Zir.Inst.UnionDecl.Small, extended.small); @@ -12077,20 +12057,56 @@ fn analyzeUnionFields( var decl_arena = union_obj.owner_decl.value_arena.?.promote(gpa); defer union_obj.owner_decl.value_arena.?.* = decl_arena.state; - try union_obj.fields.ensureTotalCapacity(&decl_arena.allocator, fields_len); + var analysis_arena = std.heap.ArenaAllocator.init(gpa); + defer analysis_arena.deinit(); + + var sema: Sema = .{ + .mod = mod, + .gpa = gpa, + .arena = &analysis_arena.allocator, + .perm_arena = &decl_arena.allocator, + .code = zir, + .owner_decl = decl, + .func = null, + .fn_ret_ty = Type.initTag(.void), + .owner_func = null, + }; + defer sema.deinit(); + + var wip_captures = try WipCaptureScope.init(gpa, &decl_arena.allocator, decl.src_scope); + defer wip_captures.deinit(); + + var block_scope: Scope.Block = .{ + .parent = null, + .sema = &sema, + .src_decl = decl, + .wip_capture_scope = wip_captures.scope, + .instructions = .{}, + .inlining = null, + .is_comptime = true, + }; + defer { + assert(block_scope.instructions.items.len == 0); + block_scope.params.deinit(gpa); + } if (body.len != 0) { - _ = try sema.analyzeBody(block, body); + _ = try sema.analyzeBody(&block_scope, body); } + + try wip_captures.finalize(); + + try union_obj.fields.ensureTotalCapacity(&decl_arena.allocator, fields_len); + var int_tag_ty: Type = undefined; var enum_field_names: ?*Module.EnumNumbered.NameMap = null; var enum_value_map: ?*Module.EnumNumbered.ValueMap = null; if (tag_type_ref != .none) { - const provided_ty = try sema.resolveType(block, src, tag_type_ref); + const provided_ty = try sema.resolveType(&block_scope, src, tag_type_ref); if (small.auto_enum_tag) { // The provided type is an integer type and we must construct the enum tag type here. int_tag_ty = provided_ty; - union_obj.tag_ty = try sema.generateUnionTagTypeNumbered(block, fields_len, provided_ty); + union_obj.tag_ty = try sema.generateUnionTagTypeNumbered(&block_scope, fields_len, provided_ty); enum_field_names = &union_obj.tag_ty.castTag(.enum_numbered).?.data.fields; enum_value_map = &union_obj.tag_ty.castTag(.enum_numbered).?.data.values; } else { @@ -12101,7 +12117,7 @@ fn analyzeUnionFields( // If auto_enum_tag is false, this is an untagged union. However, for semantic analysis // purposes, we still auto-generate an enum tag type the same way. That the union is // untagged is represented by the Type tag (union vs union_tagged). - union_obj.tag_ty = try sema.generateUnionTagTypeSimple(block, fields_len); + union_obj.tag_ty = try sema.generateUnionTagTypeSimple(&block_scope, fields_len); enum_field_names = &union_obj.tag_ty.castTag(.enum_simple).?.data.fields; } @@ -12150,8 +12166,8 @@ fn analyzeUnionFields( if (enum_value_map) |map| { const tag_src = src; // TODO better source location - const coerced = try sema.coerce(block, int_tag_ty, tag_ref, tag_src); - const val = try sema.resolveConstValue(block, tag_src, coerced); + const coerced = try sema.coerce(&block_scope, int_tag_ty, tag_ref, tag_src); + const val = try sema.resolveConstValue(&block_scope, tag_src, coerced); map.putAssumeCapacityContext(val, {}, .{ .ty = int_tag_ty }); } @@ -12167,7 +12183,7 @@ fn analyzeUnionFields( // TODO: if we need to report an error here, use a source location // that points to this type expression rather than the union. // But only resolve the source location if we need to emit a compile error. - try sema.resolveType(block, src, field_type_ref); + try sema.resolveType(&block_scope, src, field_type_ref); const gop = union_obj.fields.getOrPutAssumeCapacity(field_name); assert(!gop.found_existing); @@ -12180,7 +12196,7 @@ fn analyzeUnionFields( // TODO: if we need to report an error here, use a source location // that points to this alignment expression rather than the struct. // But only resolve the source location if we need to emit a compile error. - const abi_align_val = (try sema.resolveInstConst(block, src, align_ref)).val; + const abi_align_val = (try sema.resolveInstConst(&block_scope, src, align_ref)).val; gop.value_ptr.abi_align = try abi_align_val.copy(&decl_arena.allocator); } else { gop.value_ptr.abi_align = Value.initTag(.abi_align_default); From d1a4bdb1f375b6aa737f1c02c346899336465e00 Mon Sep 17 00:00:00 2001 From: Martin Wickham Date: Fri, 1 Oct 2021 00:43:39 -0500 Subject: [PATCH 09/14] Declare generic fn dependency earlier to keep invariant --- src/Sema.zig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index 0aa8a28664..beeda48fe5 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -3279,6 +3279,11 @@ fn analyzeCall( namespace.anon_decls.putAssumeCapacityNoClobber(new_decl, {}); + // The generic function Decl is guaranteed to be the first dependency + // of each of its instantiations. + assert(new_decl.dependencies.keys().len == 0); + try mod.declareDeclDependency(new_decl, module_fn.owner_decl); + var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa); errdefer new_decl_arena.deinit(); @@ -3411,11 +3416,6 @@ fn analyzeCall( }); assert(!new_decl.ty.fnInfo().is_generic); - // The generic function Decl is guaranteed to be the first dependency - // of each of its instantiations. - assert(new_decl.dependencies.keys().len == 0); - try mod.declareDeclDependency(new_decl, module_fn.owner_decl); - // Queue up a `codegen_func` work item for the new Fn. The `comptime_args` field // will be populated, ensuring it will have `analyzeBody` called with the ZIR // parameters mapped appropriately. From 53a36eacfa145244902e9230243c76892d141b03 Mon Sep 17 00:00:00 2001 From: Martin Wickham Date: Fri, 1 Oct 2021 12:05:12 -0500 Subject: [PATCH 10/14] Remove my dumb "namespace decl" hack --- src/Compilation.zig | 14 +++--- src/Module.zig | 104 ++++++++++++++++++++++-------------------- src/Sema.zig | 43 +++++++++-------- src/codegen.zig | 4 +- src/codegen/c.zig | 2 +- src/codegen/llvm.zig | 2 +- src/codegen/spirv.zig | 2 +- src/crash_report.zig | 6 +-- src/link/Plan9.zig | 6 +-- 9 files changed, 96 insertions(+), 87 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index 95337de1e1..b9ed8e209d 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1770,7 +1770,7 @@ pub fn update(self: *Compilation) !void { assert(decl.deletion_flag); assert(decl.dependants.count() == 0); const is_anon = if (decl.zir_decl_index == 0) blk: { - break :blk decl.namespace.anon_decls.swapRemove(decl); + break :blk decl.src_namespace.anon_decls.swapRemove(decl); } else false; try module.clearDecl(decl, null); @@ -1889,13 +1889,13 @@ pub fn totalErrorCount(self: *Compilation) usize { // the previous parse success, including compile errors, but we cannot // emit them until the file succeeds parsing. for (module.failed_decls.keys()) |key| { - if (key.namespace.file_scope.okToReportErrors()) { + if (key.getFileScope().okToReportErrors()) { total += 1; } } if (module.emit_h) |emit_h| { for (emit_h.failed_decls.keys()) |key| { - if (key.namespace.file_scope.okToReportErrors()) { + if (key.getFileScope().okToReportErrors()) { total += 1; } } @@ -1968,7 +1968,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors { while (it.next()) |entry| { // Skip errors for Decls within files that had a parse failure. // We'll try again once parsing succeeds. - if (entry.key_ptr.*.namespace.file_scope.okToReportErrors()) { + if (entry.key_ptr.*.getFileScope().okToReportErrors()) { try AllErrors.add(module, &arena, &errors, entry.value_ptr.*.*); } } @@ -1978,7 +1978,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors { while (it.next()) |entry| { // Skip errors for Decls within files that had a parse failure. // We'll try again once parsing succeeds. - if (entry.key_ptr.*.namespace.file_scope.okToReportErrors()) { + if (entry.key_ptr.*.getFileScope().okToReportErrors()) { try AllErrors.add(module, &arena, &errors, entry.value_ptr.*.*); } } @@ -2169,12 +2169,12 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor defer air.deinit(gpa); log.debug("analyze liveness of {s}", .{decl.name}); - var liveness = try Liveness.analyze(gpa, air, decl.namespace.file_scope.zir); + var liveness = try Liveness.analyze(gpa, air, decl.getFileScope().zir); defer liveness.deinit(gpa); if (builtin.mode == .Debug and self.verbose_air) { std.debug.print("# Begin Function AIR: {s}:\n", .{decl.name}); - @import("print_air.zig").dump(gpa, air, decl.namespace.file_scope.zir, liveness); + @import("print_air.zig").dump(gpa, air, decl.getFileScope().zir, liveness); std.debug.print("# End Function AIR: {s}\n\n", .{decl.name}); } diff --git a/src/Module.zig b/src/Module.zig index a2b22e4c17..3dd576e3fc 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -264,7 +264,7 @@ pub const Export = struct { pub fn getSrcLoc(exp: Export) SrcLoc { return .{ - .file_scope = exp.src_decl.namespace.file_scope, + .file_scope = exp.src_decl.getFileScope(), .parent_decl_node = exp.src_decl.src_node, .lazy = exp.src, }; @@ -350,7 +350,7 @@ pub const Decl = struct { /// Reference to externally owned memory. /// In the case of the Decl corresponding to a file, this is /// the namespace of the struct, since there is no parent. - namespace: *Scope.Namespace, + src_namespace: *Scope.Namespace, /// The scope which lexically contains this decl. A decl must depend /// on its lexical parent, in order to ensure that this pointer is valid. @@ -516,7 +516,7 @@ pub const Decl = struct { /// This name is relative to the containing namespace of the decl. /// The memory is owned by the containing File ZIR. pub fn getName(decl: Decl) ?[:0]const u8 { - const zir = decl.namespace.file_scope.zir; + const zir = decl.getFileScope().zir; return decl.getNameZir(zir); } @@ -528,7 +528,7 @@ pub const Decl = struct { } pub fn contentsHash(decl: Decl) std.zig.SrcHash { - const zir = decl.namespace.file_scope.zir; + const zir = decl.getFileScope().zir; return decl.contentsHashZir(zir); } @@ -541,21 +541,21 @@ pub const Decl = struct { pub fn zirBlockIndex(decl: *const Decl) Zir.Inst.Index { assert(decl.zir_decl_index != 0); - const zir = decl.namespace.file_scope.zir; + const zir = decl.getFileScope().zir; return zir.extra[decl.zir_decl_index + 6]; } pub fn zirAlignRef(decl: Decl) Zir.Inst.Ref { if (!decl.has_align) return .none; assert(decl.zir_decl_index != 0); - const zir = decl.namespace.file_scope.zir; + const zir = decl.getFileScope().zir; return @intToEnum(Zir.Inst.Ref, zir.extra[decl.zir_decl_index + 7]); } pub fn zirLinksectionRef(decl: Decl) Zir.Inst.Ref { if (!decl.has_linksection_or_addrspace) return .none; assert(decl.zir_decl_index != 0); - const zir = decl.namespace.file_scope.zir; + const zir = decl.getFileScope().zir; const extra_index = decl.zir_decl_index + 7 + @boolToInt(decl.has_align); return @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]); } @@ -563,16 +563,16 @@ pub const Decl = struct { pub fn zirAddrspaceRef(decl: Decl) Zir.Inst.Ref { if (!decl.has_linksection_or_addrspace) return .none; assert(decl.zir_decl_index != 0); - const zir = decl.namespace.file_scope.zir; + const zir = decl.getFileScope().zir; const extra_index = decl.zir_decl_index + 7 + @boolToInt(decl.has_align) + 1; return @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]); } /// Returns true if and only if the Decl is the top level struct associated with a File. pub fn isRoot(decl: *const Decl) bool { - if (decl.namespace.parent != null) + if (decl.src_namespace.parent != null) return false; - return decl == decl.namespace.ty.getOwnerDecl(); + return decl == decl.src_namespace.getDecl(); } pub fn relativeToLine(decl: Decl, offset: u32) u32 { @@ -608,29 +608,21 @@ pub const Decl = struct { } pub fn srcToken(decl: Decl) Ast.TokenIndex { - const tree = &decl.namespace.file_scope.tree; + const tree = &decl.getFileScope().tree; return tree.firstToken(decl.src_node); } pub fn srcByteOffset(decl: Decl) u32 { - const tree = &decl.namespace.file_scope.tree; + const tree = &decl.getFileScope().tree; return tree.tokens.items(.start)[decl.srcToken()]; } pub fn renderFullyQualifiedName(decl: *const Decl, writer: anytype) @TypeOf(writer).Error!void { - // Namespace decls (struct/enum/union/opaque) use their own namespace, - // which means the decl name and the namespace name are the same. - // In that case we want to omit the decl name, unless this is the root decl. - const unqualified_name = if (decl.namespace.getDecl() != decl or decl.namespace.parent == null) mem.spanZ(decl.name) else ""; - return try decl.namespace.renderFullyQualifiedName(unqualified_name, writer); + return try decl.src_namespace.renderFullyQualifiedName(mem.spanZ(decl.name), writer); } pub fn renderFullyQualifiedDebugName(decl: *const Decl, writer: anytype) @TypeOf(writer).Error!void { - // Namespace decls (struct/enum/union/opaque) use their own namespace, - // which means the decl name and the namespace name are the same. - // In that case we want to omit the decl name, unless this is the root decl. - const unqualified_name = if (decl.namespace.getDecl() != decl or decl.namespace.parent == null) mem.spanZ(decl.name) else ""; - return try decl.namespace.renderFullyQualifiedDebugName(unqualified_name, writer); + return try decl.src_namespace.renderFullyQualifiedDebugName(mem.spanZ(decl.name), writer); } pub fn getFullyQualifiedName(decl: *const Decl, gpa: *Allocator) ![:0]u8 { @@ -742,7 +734,7 @@ pub const Decl = struct { } pub fn getFileScope(decl: Decl) *Scope.File { - return decl.namespace.file_scope; + return decl.src_namespace.file_scope; } pub fn getEmitH(decl: *Decl, module: *Module) *EmitH { @@ -1118,8 +1110,8 @@ pub const Scope = struct { /// Asserts the scope has a parent which is a Namespace and returns it. pub fn namespace(scope: *Scope) *Namespace { switch (scope.tag) { - .block => return scope.cast(Block).?.src_decl.namespace, - .file => return scope.cast(File).?.root_decl.?.namespace, + .block => return scope.cast(Block).?.namespace, + .file => return scope.cast(File).?.root_decl.?.src_namespace, .namespace => return scope.cast(Namespace).?, } } @@ -1134,14 +1126,14 @@ pub const Scope = struct { } } - /// When called from inside a Block Scope, chases the src_decl, not the owner_decl. + /// When called from inside a Block Scope, chases the namespace, not the owner_decl. pub fn getFileScope(base: *Scope) *Scope.File { var cur = base; while (true) { cur = switch (cur.tag) { .namespace => return @fieldParentPtr(Namespace, "base", cur).file_scope, .file => return @fieldParentPtr(File, "base", cur), - .block => return @fieldParentPtr(Block, "base", cur).src_decl.namespace.file_scope, + .block => return @fieldParentPtr(Block, "base", cur).namespace.file_scope, }; } } @@ -1475,6 +1467,10 @@ pub const Scope = struct { /// This can vary during inline or comptime function calls. See `Sema.owner_decl` /// for the one that will be the same for all Block instances. src_decl: *Decl, + /// The namespace to use for lookups from this source block + /// When analyzing fields, this is different from src_decl.src_namepsace. + namespace: *Namespace, + /// The AIR instructions generated for this block. instructions: ArrayListUnmanaged(Air.Inst.Index), // `param` instructions are collected here to be used by the `func` instruction. params: std.ArrayListUnmanaged(Param) = .{}, @@ -1541,6 +1537,7 @@ pub const Scope = struct { .parent = parent, .sema = parent.sema, .src_decl = parent.src_decl, + .namespace = parent.namespace, .instructions = .{}, .wip_capture_scope = parent.wip_capture_scope, .label = null, @@ -1564,7 +1561,7 @@ pub const Scope = struct { } pub fn getFileScope(block: *Block) *Scope.File { - return block.src_decl.namespace.file_scope; + return block.namespace.file_scope; } pub fn addTy( @@ -3327,6 +3324,7 @@ pub fn semaFile(mod: *Module, file: *Scope.File) SemaError!void { .parent = null, .sema = &sema, .src_decl = new_decl, + .namespace = &struct_obj.namespace, .wip_capture_scope = wip_captures.scope, .instructions = .{}, .inlining = null, @@ -3355,12 +3353,12 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { const tracy = trace(@src()); defer tracy.end(); - if (decl.namespace.file_scope.status != .success_zir) { + if (decl.getFileScope().status != .success_zir) { return error.AnalysisFail; } const gpa = mod.gpa; - const zir = decl.namespace.file_scope.zir; + const zir = decl.getFileScope().zir; const zir_datas = zir.instructions.items(.data); decl.analysis = .in_progress; @@ -3406,6 +3404,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { .parent = null, .sema = &sema, .src_decl = decl, + .namespace = decl.src_namespace, .wip_capture_scope = wip_captures.scope, .instructions = .{}, .inlining = null, @@ -4042,8 +4041,8 @@ pub fn deleteUnusedDecl(mod: *Module, decl: *Decl) void { }, } - const owner_namespace = if (decl.namespace.getDecl() == decl and decl.namespace.parent != null) decl.namespace.parent.? else decl.namespace; - assert(owner_namespace.anon_decls.swapRemove(decl)); + assert(!decl.isRoot()); + assert(decl.src_namespace.anon_decls.swapRemove(decl)); const dependants = decl.dependants.keys(); for (dependants) |dep| { @@ -4059,8 +4058,8 @@ pub fn deleteUnusedDecl(mod: *Module, decl: *Decl) void { pub fn abortAnonDecl(mod: *Module, decl: *Decl) void { log.debug("abortAnonDecl {*} ({s})", .{ decl, decl.name }); - const owner_namespace = if (decl.namespace.getDecl() == decl and decl.namespace.parent != null) decl.namespace.parent.? else decl.namespace; - assert(owner_namespace.anon_decls.swapRemove(decl)); + assert(!decl.isRoot()); + assert(decl.src_namespace.anon_decls.swapRemove(decl)); const dependants = decl.dependants.keys(); for (dependants) |dep| { @@ -4128,7 +4127,7 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: *Allocator) Se .gpa = gpa, .arena = arena, .perm_arena = &decl_arena.allocator, - .code = decl.namespace.file_scope.zir, + .code = decl.getFileScope().zir, .owner_decl = decl, .func = func, .fn_ret_ty = func.owner_decl.ty.fnReturnType(), @@ -4148,6 +4147,7 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: *Allocator) Se .parent = null, .sema = &sema, .src_decl = decl, + .namespace = decl.src_namespace, .wip_capture_scope = wip_captures.scope, .instructions = .{}, .inlining = null, @@ -4279,7 +4279,7 @@ pub fn allocateNewDecl(mod: *Module, name: [:0]const u8, namespace: *Scope.Names new_decl.* = .{ .name = name, - .namespace = namespace, + .src_namespace = namespace, .src_node = src_node, .src_line = undefined, .has_tv = false, @@ -4426,32 +4426,38 @@ pub fn createAnonymousDeclNamed( typed_value: TypedValue, name: [:0]u8, ) !*Decl { - return mod.createAnonymousDeclFromDeclNamed(scope.srcDecl().?, scope.srcScope(), typed_value, name); + return mod.createAnonymousDeclFromDeclNamed(scope.srcDecl().?, scope.namespace(), scope.srcScope(), typed_value, name); } pub fn createAnonymousDecl(mod: *Module, scope: *Scope, typed_value: TypedValue) !*Decl { - return mod.createAnonymousDeclFromDecl(scope.srcDecl().?, scope.srcScope(), typed_value); + return mod.createAnonymousDeclFromDecl(scope.srcDecl().?, scope.namespace(), scope.srcScope(), typed_value); } -pub fn createAnonymousDeclFromDecl(mod: *Module, src_decl: *Decl, src_scope: ?*CaptureScope, tv: TypedValue) !*Decl { +pub fn createAnonymousDeclFromDecl( + mod: *Module, + src_decl: *Decl, + namespace: *Scope.Namespace, + src_scope: ?*CaptureScope, + tv: TypedValue, +) !*Decl { const name_index = mod.getNextAnonNameIndex(); const name = try std.fmt.allocPrintZ(mod.gpa, "{s}__anon_{d}", .{ src_decl.name, name_index, }); - return mod.createAnonymousDeclFromDeclNamed(src_decl, src_scope, tv, name); + return mod.createAnonymousDeclFromDeclNamed(src_decl, namespace, src_scope, tv, name); } /// Takes ownership of `name` even if it returns an error. pub fn createAnonymousDeclFromDeclNamed( mod: *Module, src_decl: *Decl, + namespace: *Scope.Namespace, src_scope: ?*CaptureScope, typed_value: TypedValue, name: [:0]u8, ) !*Decl { errdefer mod.gpa.free(name); - const namespace = src_decl.namespace; try namespace.anon_decls.ensureUnusedCapacity(mod.gpa, 1); const new_decl = try mod.allocateNewDecl(name, namespace, src_decl.src_node, src_scope); @@ -4705,10 +4711,10 @@ pub const SwitchProngSrc = union(enum) { range_expand: RangeExpand, ) LazySrcLoc { @setCold(true); - const tree = decl.namespace.file_scope.getTree(gpa) catch |err| { + const tree = decl.getFileScope().getTree(gpa) catch |err| { // In this case we emit a warning + a less precise source location. log.warn("unable to load {s}: {s}", .{ - decl.namespace.file_scope.sub_file_path, @errorName(err), + decl.getFileScope().sub_file_path, @errorName(err), }); return LazySrcLoc{ .node_offset = 0 }; }; @@ -4817,10 +4823,10 @@ pub const PeerTypeCandidateSrc = union(enum) { else => {}, } - const tree = decl.namespace.file_scope.getTree(gpa) catch |err| { + const tree = decl.getFileScope().getTree(gpa) catch |err| { // In this case we emit a warning + a less precise source location. log.warn("unable to load {s}: {s}", .{ - decl.namespace.file_scope.sub_file_path, @errorName(err), + decl.getFileScope().sub_file_path, @errorName(err), }); return LazySrcLoc{ .node_offset = 0 }; }; @@ -4863,7 +4869,7 @@ pub fn processOutdatedAndDeletedDecls(mod: *Module) !void { // Remove from the namespace it resides in, preserving declaration order. assert(decl.zir_decl_index != 0); - _ = decl.namespace.decls.orderedRemove(mem.spanZ(decl.name)); + _ = decl.src_namespace.decls.orderedRemove(mem.spanZ(decl.name)); try mod.clearDecl(decl, &outdated_decls); decl.destroy(mod); @@ -4929,7 +4935,7 @@ pub fn populateTestFunctions(mod: *Module) !void { const gpa = mod.gpa; const builtin_pkg = mod.main_pkg.table.get("builtin").?; const builtin_file = (mod.importPkg(builtin_pkg) catch unreachable).file; - const builtin_namespace = builtin_file.root_decl.?.namespace; + const builtin_namespace = builtin_file.root_decl.?.src_namespace; const decl = builtin_namespace.decls.get("test_functions").?; var buf: Type.SlicePtrFieldTypeBuffer = undefined; const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf).elemType(); @@ -4942,7 +4948,7 @@ pub fn populateTestFunctions(mod: *Module) !void { const arena = &new_decl_arena.allocator; const test_fn_vals = try arena.alloc(Value, mod.test_functions.count()); - const array_decl = try mod.createAnonymousDeclFromDecl(decl, null, .{ + const array_decl = try mod.createAnonymousDeclFromDecl(decl, decl.src_namespace, null, .{ .ty = try Type.Tag.array.create(arena, .{ .len = test_fn_vals.len, .elem_type = try tmp_test_fn_ty.copy(arena), @@ -4955,7 +4961,7 @@ pub fn populateTestFunctions(mod: *Module) !void { var name_decl_arena = std.heap.ArenaAllocator.init(gpa); errdefer name_decl_arena.deinit(); const bytes = try name_decl_arena.allocator.dupe(u8, test_name_slice); - const test_name_decl = try mod.createAnonymousDeclFromDecl(array_decl, null, .{ + const test_name_decl = try mod.createAnonymousDeclFromDecl(array_decl, array_decl.src_namespace, null, .{ .ty = try Type.Tag.array_u8.create(&name_decl_arena.allocator, bytes.len), .val = try Value.Tag.bytes.create(&name_decl_arena.allocator, bytes), }); diff --git a/src/Sema.zig b/src/Sema.zig index beeda48fe5..0c24942c4e 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1042,8 +1042,6 @@ pub fn analyzeStructDecl( } else 0; _ = try sema.mod.scanNamespace(&struct_obj.namespace, extra_index, decls_len, new_decl); - - new_decl.namespace = &struct_obj.namespace; } fn zirStructDecl( @@ -1080,7 +1078,7 @@ fn zirStructDecl( .status = .none, .known_has_bits = undefined, .namespace = .{ - .parent = block.src_decl.namespace, + .parent = block.namespace, .ty = struct_ty, .file_scope = block.getFileScope(), }, @@ -1188,7 +1186,7 @@ fn zirEnumDecl( .values = .{}, .node_offset = src.node_offset, .namespace = .{ - .parent = block.src_decl.namespace, + .parent = block.namespace, .ty = enum_ty, .file_scope = block.getFileScope(), }, @@ -1199,8 +1197,6 @@ fn zirEnumDecl( extra_index = try mod.scanNamespace(&enum_obj.namespace, extra_index, decls_len, new_decl); - new_decl.namespace = &enum_obj.namespace; - const body = sema.code.extra[extra_index..][0..body_len]; if (fields_len == 0) { assert(body.len == 0); @@ -1238,6 +1234,7 @@ fn zirEnumDecl( .parent = null, .sema = sema, .src_decl = new_decl, + .namespace = &enum_obj.namespace, .wip_capture_scope = wip_captures.scope, .instructions = .{}, .inlining = null, @@ -1377,7 +1374,7 @@ fn zirUnionDecl( .layout = small.layout, .status = .none, .namespace = .{ - .parent = block.src_decl.namespace, + .parent = block.namespace, .ty = union_ty, .file_scope = block.getFileScope(), }, @@ -1388,8 +1385,6 @@ fn zirUnionDecl( _ = try sema.mod.scanNamespace(&union_obj.namespace, extra_index, decls_len, new_decl); - new_decl.namespace = &union_obj.namespace; - try new_decl.finalizeNewArena(&new_decl_arena); return sema.analyzeDeclVal(block, src, new_decl); } @@ -2283,6 +2278,7 @@ fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Com .parent = parent_block, .sema = sema, .src_decl = parent_block.src_decl, + .namespace = parent_block.namespace, .wip_capture_scope = parent_block.wip_capture_scope, .instructions = .{}, .inlining = parent_block.inlining, @@ -2383,6 +2379,7 @@ fn zirBlock( .parent = parent_block, .sema = sema, .src_decl = parent_block.src_decl, + .namespace = parent_block.namespace, .wip_capture_scope = parent_block.wip_capture_scope, .instructions = .{}, .label = &label, @@ -2684,7 +2681,7 @@ fn zirDeclVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr } fn lookupIdentifier(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, name: []const u8) !*Decl { - var namespace = block.src_decl.namespace; + var namespace = block.namespace; while (true) { if (try sema.lookupInNamespace(block, src, namespace, name, false)) |decl| { return decl; @@ -2713,7 +2710,7 @@ fn lookupInNamespace( } if (observe_usingnamespace and namespace.usingnamespace_set.count() != 0) { - const src_file = block.src_decl.namespace.file_scope; + const src_file = block.namespace.file_scope; const gpa = sema.gpa; var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Scope.Namespace, void) = .{}; @@ -2731,7 +2728,7 @@ fn lookupInNamespace( if (check_ns.decls.get(ident_name)) |decl| { // Skip decls which are not marked pub, which are in a different // file than the `a.b`/`@hasDecl` syntax. - if (decl.is_pub or src_file == decl.namespace.file_scope) { + if (decl.is_pub or src_file == decl.getFileScope()) { try candidates.append(gpa, decl); } } @@ -2739,7 +2736,7 @@ fn lookupInNamespace( while (it.next()) |entry| { const sub_usingnamespace_decl = entry.key_ptr.*; const sub_is_pub = entry.value_ptr.*; - if (!sub_is_pub and src_file != sub_usingnamespace_decl.namespace.file_scope) { + if (!sub_is_pub and src_file != sub_usingnamespace_decl.getFileScope()) { // Skip usingnamespace decls which are not marked pub, which are in // a different file than the `a.b`/`@hasDecl` syntax. continue; @@ -2992,7 +2989,7 @@ fn analyzeCall( // In order to save a bit of stack space, directly modify Sema rather // than create a child one. const parent_zir = sema.code; - sema.code = module_fn.owner_decl.namespace.file_scope.zir; + sema.code = module_fn.owner_decl.getFileScope().zir; defer sema.code = parent_zir; const parent_inst_map = sema.inst_map; @@ -3013,6 +3010,7 @@ fn analyzeCall( .parent = null, .sema = sema, .src_decl = module_fn.owner_decl, + .namespace = module_fn.owner_decl.src_namespace, .wip_capture_scope = wip_captures.scope, .instructions = .{}, .label = null, @@ -3182,7 +3180,7 @@ fn analyzeCall( // Check the Module's generic function map with an adapted context, so that we // can match against `uncasted_args` rather than doing the work below to create a // generic Scope only to junk it if it matches an existing instantiation. - const namespace = module_fn.owner_decl.namespace; + const namespace = module_fn.owner_decl.src_namespace; const fn_zir = namespace.file_scope.zir; const fn_info = fn_zir.getFnInfo(module_fn.zir_body_inst); const zir_tags = fn_zir.instructions.items(.tag); @@ -3314,6 +3312,7 @@ fn analyzeCall( .parent = null, .sema = &child_sema, .src_decl = new_decl, + .namespace = namespace, .wip_capture_scope = wip_captures.scope, .instructions = .{}, .inlining = null, @@ -5338,6 +5337,7 @@ fn analyzeSwitch( .parent = block, .sema = sema, .src_decl = block.src_decl, + .namespace = block.namespace, .wip_capture_scope = block.wip_capture_scope, .instructions = .{}, .label = &label, @@ -5861,7 +5861,7 @@ fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr .{container_type}, ); if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl| { - if (decl.is_pub or decl.namespace.file_scope == block.base.namespace().file_scope) { + if (decl.is_pub or decl.getFileScope() == block.base.namespace().file_scope) { return Air.Inst.Ref.bool_true; } } @@ -9603,8 +9603,9 @@ fn addSafetyCheck( var fail_block: Scope.Block = .{ .parent = parent_block, .sema = sema, - .wip_capture_scope = parent_block.wip_capture_scope, .src_decl = parent_block.src_decl, + .namespace = parent_block.namespace, + .wip_capture_scope = parent_block.wip_capture_scope, .instructions = .{}, .inlining = parent_block.inlining, .is_comptime = parent_block.is_comptime, @@ -10259,7 +10260,7 @@ fn namespaceLookup( const mod = sema.mod; const gpa = sema.gpa; if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl| { - if (!decl.is_pub and decl.namespace.file_scope != block.getFileScope()) { + if (!decl.is_pub and decl.getFileScope() != block.getFileScope()) { const msg = msg: { const msg = try mod.errMsg(&block.base, src, "'{s}' is not marked 'pub'", .{ decl_name, @@ -11911,6 +11912,7 @@ fn semaStructFields( .parent = null, .sema = &sema, .src_decl = decl, + .namespace = &struct_obj.namespace, .wip_capture_scope = wip_captures.scope, .instructions = .{}, .inlining = null, @@ -12080,6 +12082,7 @@ fn semaUnionFields( .parent = null, .sema = &sema, .src_decl = decl, + .namespace = &union_obj.namespace, .wip_capture_scope = wip_captures.scope, .instructions = .{}, .inlining = null, @@ -12290,7 +12293,7 @@ fn getBuiltin( const opt_builtin_inst = try sema.namespaceLookupRef( block, src, - std_file.root_decl.?.namespace, + std_file.root_decl.?.src_namespace, "builtin", ); const builtin_inst = try sema.analyzeLoad(block, src, opt_builtin_inst.?, src); @@ -12484,7 +12487,7 @@ fn typeHasOnePossibleValue( } fn getAstTree(sema: *Sema, block: *Scope.Block) CompileError!*const std.zig.Ast { - return block.src_decl.namespace.file_scope.getTree(sema.gpa) catch |err| { + return block.namespace.file_scope.getTree(sema.gpa) catch |err| { log.err("unable to load AST to report compile error: {s}", .{@errorName(err)}); return error.AnalysisFail; }; diff --git a/src/codegen.zig b/src/codegen.zig index dfaedf041a..33492ad2d5 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -2584,7 +2584,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { fn genArgDbgInfo(self: *Self, inst: Air.Inst.Index, mcv: MCValue) !void { const ty_str = self.air.instructions.items(.data)[inst].ty_str; - const zir = &self.mod_fn.owner_decl.namespace.file_scope.zir; + const zir = &self.mod_fn.owner_decl.getFileScope().zir; const name = zir.nullTerminatedString(ty_str.str); const name_with_null = name.ptr[0 .. name.len + 1]; const ty = self.air.getRefType(ty_str.ty); @@ -3834,7 +3834,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { fn airAsm(self: *Self, inst: Air.Inst.Index) !void { const air_datas = self.air.instructions.items(.data); const air_extra = self.air.extraData(Air.Asm, air_datas[inst].ty_pl.payload); - const zir = self.mod_fn.owner_decl.namespace.file_scope.zir; + const zir = self.mod_fn.owner_decl.getFileScope().zir; const extended = zir.instructions.items(.data)[air_extra.data.zir_index].extended; const zir_extra = zir.extraData(Zir.Inst.Asm, extended.operand); const asm_source = zir.nullTerminatedString(zir_extra.data.asm_source); diff --git a/src/codegen/c.zig b/src/codegen/c.zig index d2ce9cc6de..24ec37bbaa 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -1696,7 +1696,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { const air_datas = f.air.instructions.items(.data); const air_extra = f.air.extraData(Air.Asm, air_datas[inst].ty_pl.payload); - const zir = f.object.dg.decl.namespace.file_scope.zir; + const zir = f.object.dg.decl.getFileScope().zir; const extended = zir.instructions.items(.data)[air_extra.data.zir_index].extended; const zir_extra = zir.extraData(Zir.Inst.Asm, extended.operand); const asm_source = zir.nullTerminatedString(zir_extra.data.asm_source); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 98e12f5430..55bcde59bc 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1819,7 +1819,7 @@ pub const FuncGen = struct { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const air_asm = self.air.extraData(Air.Asm, ty_pl.payload); - const zir = self.dg.decl.namespace.file_scope.zir; + const zir = self.dg.decl.getFileScope().zir; const extended = zir.instructions.items(.data)[air_asm.data.zir_index].extended; const zir_extra = zir.extraData(Zir.Inst.Asm, extended.operand); const asm_source = zir.nullTerminatedString(zir_extra.data.asm_source); diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 5826daa5a5..9f7262f53b 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -139,7 +139,7 @@ pub const SPIRVModule = struct { } fn resolveSourceFileName(self: *SPIRVModule, decl: *Decl) !ResultId { - const path = decl.namespace.file_scope.sub_file_path; + const path = decl.getFileScope().sub_file_path; const result = try self.file_names.getOrPut(path); if (!result.found_existing) { result.value_ptr.* = self.allocResultId(); diff --git a/src/crash_report.zig b/src/crash_report.zig index 4554e324cb..abf483bd3e 100644 --- a/src/crash_report.zig +++ b/src/crash_report.zig @@ -97,7 +97,7 @@ fn dumpStatusReport() !void { allocator, anal.body, anal.body_index, - block.src_decl.getFileScope(), + block.namespace.file_scope, block.src_decl.src_node, 6, // indent stderr, @@ -106,7 +106,7 @@ fn dumpStatusReport() !void { else => |e| return e, }; try stderr.writeAll(" For full context, use the command\n zig ast-check -t "); - try writeFilePath(block.src_decl.getFileScope(), stderr); + try writeFilePath(block.namespace.file_scope, stderr); try stderr.writeAll("\n\n"); var parent = anal.parent; @@ -118,7 +118,7 @@ fn dumpStatusReport() !void { print_zir.renderSingleInstruction( allocator, curr.body[curr.body_index], - curr.block.src_decl.getFileScope(), + curr.block.namespace.file_scope, curr.block.src_decl.src_node, 6, // indent stderr, diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig index 384345ff67..0f99ca31ed 100644 --- a/src/link/Plan9.zig +++ b/src/link/Plan9.zig @@ -163,11 +163,11 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*Plan9 { fn putFn(self: *Plan9, decl: *Module.Decl, out: FnDeclOutput) !void { const gpa = self.base.allocator; - const fn_map_res = try self.fn_decl_table.getOrPut(gpa, decl.namespace.file_scope); + const fn_map_res = try self.fn_decl_table.getOrPut(gpa, decl.getFileScope()); if (fn_map_res.found_existing) { try fn_map_res.value_ptr.functions.put(gpa, decl, out); } else { - const file = decl.namespace.file_scope; + const file = decl.getFileScope(); const arena = &self.path_arena.allocator; // each file gets a symbol fn_map_res.value_ptr.* = .{ @@ -548,7 +548,7 @@ pub fn freeDecl(self: *Plan9, decl: *Module.Decl) void { const is_fn = (decl.val.tag() == .function); if (is_fn) { var symidx_and_submap = - self.fn_decl_table.get(decl.namespace.file_scope).?; + self.fn_decl_table.get(decl.getFileScope()).?; var submap = symidx_and_submap.functions; _ = submap.swapRemove(decl); if (submap.count() == 0) { From 01e08c92b3d1a7895762e7b8f8a7913d08c3fa6c Mon Sep 17 00:00:00 2001 From: Martin Wickham Date: Fri, 1 Oct 2021 12:45:46 -0500 Subject: [PATCH 11/14] Revert collateral changes, clarify abortAnonDecl() --- src/Module.zig | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/Module.zig b/src/Module.zig index 3dd576e3fc..fb6bdad3ac 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -617,15 +617,17 @@ pub const Decl = struct { return tree.tokens.items(.start)[decl.srcToken()]; } - pub fn renderFullyQualifiedName(decl: *const Decl, writer: anytype) @TypeOf(writer).Error!void { - return try decl.src_namespace.renderFullyQualifiedName(mem.spanZ(decl.name), writer); + pub fn renderFullyQualifiedName(decl: Decl, writer: anytype) !void { + const unqualified_name = mem.spanZ(decl.name); + return decl.src_namespace.renderFullyQualifiedName(unqualified_name, writer); } - pub fn renderFullyQualifiedDebugName(decl: *const Decl, writer: anytype) @TypeOf(writer).Error!void { - return try decl.src_namespace.renderFullyQualifiedDebugName(mem.spanZ(decl.name), writer); + pub fn renderFullyQualifiedDebugName(decl: Decl, writer: anytype) !void { + const unqualified_name = mem.spanZ(decl.name); + return decl.src_namespace.renderFullyQualifiedDebugName(unqualified_name, writer); } - pub fn getFullyQualifiedName(decl: *const Decl, gpa: *Allocator) ![:0]u8 { + pub fn getFullyQualifiedName(decl: Decl, gpa: *Allocator) ![:0]u8 { var buffer = std.ArrayList(u8).init(gpa); defer buffer.deinit(); try decl.renderFullyQualifiedName(buffer.writer()); @@ -1246,7 +1248,7 @@ pub const Scope = struct { } } - // This renders e.g. "std.fs:Dir.OpenOptions" + /// This renders e.g. "std/fs.zig:Dir.OpenOptions" pub fn renderFullyQualifiedDebugName( ns: Namespace, name: []const u8, @@ -4055,16 +4057,17 @@ pub fn deleteUnusedDecl(mod: *Module, decl: *Decl) void { decl.destroy(mod); } +/// Cancel the creation of an anon decl and delete any references to it. +/// If other decls depend on this decl, they must be aborted first. pub fn abortAnonDecl(mod: *Module, decl: *Decl) void { log.debug("abortAnonDecl {*} ({s})", .{ decl, decl.name }); assert(!decl.isRoot()); assert(decl.src_namespace.anon_decls.swapRemove(decl)); - const dependants = decl.dependants.keys(); - for (dependants) |dep| { - dep.removeDependency(decl); - } + // An aborted decl must not have dependants -- they must have + // been aborted first and removed from this list. + assert(decl.dependants.count() == 0); for (decl.dependencies.keys()) |dep| { dep.removeDependant(decl); From fd60012c21360202a74b17d87d230a18d56edc88 Mon Sep 17 00:00:00 2001 From: Martin Wickham Date: Fri, 1 Oct 2021 15:02:49 -0500 Subject: [PATCH 12/14] Change *Scope to *Scope.Block, use Sema when required --- src/Module.zig | 181 +-------- src/Sema.zig | 1037 +++++++++++++++++++++++++++--------------------- 2 files changed, 584 insertions(+), 634 deletions(-) diff --git a/src/Module.zig b/src/Module.zig index fb6bdad3ac..27210519b8 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -2372,7 +2372,7 @@ pub const LazySrcLoc = union(enum) { node_offset_lib_name: i32, /// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope. - pub fn toSrcLoc(lazy: LazySrcLoc, scope: *Scope) SrcLoc { + pub fn toSrcLoc(lazy: LazySrcLoc, block: *Scope.Block) SrcLoc { return switch (lazy) { .unneeded, .entire_file, @@ -2380,7 +2380,7 @@ pub const LazySrcLoc = union(enum) { .token_abs, .node_abs, => .{ - .file_scope = scope.getFileScope(), + .file_scope = block.getFileScope(), .parent_decl_node = 0, .lazy = lazy, }, @@ -2416,8 +2416,8 @@ pub const LazySrcLoc = union(enum) { .node_offset_anyframe_type, .node_offset_lib_name, => .{ - .file_scope = scope.getFileScope(), - .parent_decl_node = scope.srcDecl().?.src_node, + .file_scope = block.getFileScope(), + .parent_decl_node = block.src_decl.src_node, .lazy = lazy, }, }; @@ -3464,12 +3464,12 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { if (decl.is_usingnamespace) { const ty_ty = Type.initTag(.type); if (!decl_tv.ty.eql(ty_ty)) { - return mod.fail(&block_scope.base, src, "expected type, found {}", .{decl_tv.ty}); + return sema.fail(&block_scope, src, "expected type, found {}", .{decl_tv.ty}); } var buffer: Value.ToTypeBuffer = undefined; const ty = decl_tv.val.toType(&buffer); if (ty.getNamespace() == null) { - return mod.fail(&block_scope.base, src, "type {} has no namespace", .{ty}); + return sema.fail(&block_scope, src, "type {} has no namespace", .{ty}); } decl.ty = ty_ty; @@ -3532,11 +3532,11 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { if (decl.is_exported) { const export_src = src; // TODO make this point at `export` token if (is_inline) { - return mod.fail(&block_scope.base, export_src, "export of inline function", .{}); + return sema.fail(&block_scope, export_src, "export of inline function", .{}); } // The scope needs to have the decl in it. const options: std.builtin.ExportOptions = .{ .name = mem.spanZ(decl.name) }; - try mod.analyzeExport(&block_scope, export_src, options, decl); + try sema.analyzeExport(&block_scope, export_src, options, decl); } return type_changed or is_inline != prev_is_inline; } @@ -3590,7 +3590,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { const export_src = src; // TODO point to the export token // The scope needs to have the decl in it. const options: std.builtin.ExportOptions = .{ .name = mem.spanZ(decl.name) }; - try mod.analyzeExport(&block_scope, export_src, options, decl); + try sema.analyzeExport(&block_scope, export_src, options, decl); } return type_changed; @@ -4347,81 +4347,6 @@ pub fn getErrorValue(mod: *Module, name: []const u8) !std.StringHashMapUnmanaged }; } -pub fn analyzeExport( - mod: *Module, - block: *Scope.Block, - src: LazySrcLoc, - borrowed_options: std.builtin.ExportOptions, - exported_decl: *Decl, -) !void { - try mod.ensureDeclAnalyzed(exported_decl); - switch (exported_decl.ty.zigTypeTag()) { - .Fn => {}, - else => return mod.fail(&block.base, src, "unable to export type '{}'", .{exported_decl.ty}), - } - - const gpa = mod.gpa; - - try mod.decl_exports.ensureUnusedCapacity(gpa, 1); - try mod.export_owners.ensureUnusedCapacity(gpa, 1); - - const new_export = try gpa.create(Export); - errdefer gpa.destroy(new_export); - - const symbol_name = try gpa.dupe(u8, borrowed_options.name); - errdefer gpa.free(symbol_name); - - const section: ?[]const u8 = if (borrowed_options.section) |s| try gpa.dupe(u8, s) else null; - errdefer if (section) |s| gpa.free(s); - - const src_decl = block.src_decl; - const owner_decl = block.sema.owner_decl; - - log.debug("exporting Decl '{s}' as symbol '{s}' from Decl '{s}'", .{ - exported_decl.name, symbol_name, owner_decl.name, - }); - - new_export.* = .{ - .options = .{ - .name = symbol_name, - .linkage = borrowed_options.linkage, - .section = section, - }, - .src = src, - .link = switch (mod.comp.bin_file.tag) { - .coff => .{ .coff = {} }, - .elf => .{ .elf = link.File.Elf.Export{} }, - .macho => .{ .macho = link.File.MachO.Export{} }, - .plan9 => .{ .plan9 = null }, - .c => .{ .c = {} }, - .wasm => .{ .wasm = {} }, - .spirv => .{ .spirv = {} }, - }, - .owner_decl = owner_decl, - .src_decl = src_decl, - .exported_decl = exported_decl, - .status = .in_progress, - }; - - // Add to export_owners table. - const eo_gop = mod.export_owners.getOrPutAssumeCapacity(owner_decl); - if (!eo_gop.found_existing) { - eo_gop.value_ptr.* = &[0]*Export{}; - } - eo_gop.value_ptr.* = try gpa.realloc(eo_gop.value_ptr.*, eo_gop.value_ptr.len + 1); - eo_gop.value_ptr.*[eo_gop.value_ptr.len - 1] = new_export; - errdefer eo_gop.value_ptr.* = gpa.shrink(eo_gop.value_ptr.*, eo_gop.value_ptr.len - 1); - - // Add to exported_decl table. - const de_gop = mod.decl_exports.getOrPutAssumeCapacity(exported_decl); - if (!de_gop.found_existing) { - de_gop.value_ptr.* = &[0]*Export{}; - } - de_gop.value_ptr.* = try gpa.realloc(de_gop.value_ptr.*, de_gop.value_ptr.len + 1); - de_gop.value_ptr.*[de_gop.value_ptr.len - 1] = new_export; - errdefer de_gop.value_ptr.* = gpa.shrink(de_gop.value_ptr.*, de_gop.value_ptr.len - 1); -} - /// Takes ownership of `name` even if it returns an error. pub fn createAnonymousDeclNamed( mod: *Module, @@ -4506,19 +4431,6 @@ pub fn makeIntType(arena: *Allocator, signedness: std.builtin.Signedness, bits: return Type.initPayload(&int_payload.base); } -/// We don't return a pointer to the new error note because the pointer -/// becomes invalid when you add another one. -pub fn errNote( - mod: *Module, - scope: *Scope, - src: LazySrcLoc, - parent: *ErrorMsg, - comptime format: []const u8, - args: anytype, -) error{OutOfMemory}!void { - return mod.errNoteNonLazy(src.toSrcLoc(scope), parent, format, args); -} - pub fn errNoteNonLazy( mod: *Module, src_loc: SrcLoc, @@ -4536,81 +4448,6 @@ pub fn errNoteNonLazy( }; } -pub fn errMsg( - mod: *Module, - scope: *Scope, - src: LazySrcLoc, - comptime format: []const u8, - args: anytype, -) error{OutOfMemory}!*ErrorMsg { - return ErrorMsg.create(mod.gpa, src.toSrcLoc(scope), format, args); -} - -pub fn fail( - mod: *Module, - scope: *Scope, - src: LazySrcLoc, - comptime format: []const u8, - args: anytype, -) CompileError { - const err_msg = try mod.errMsg(scope, src, format, args); - return mod.failWithOwnedErrorMsg(scope, err_msg); -} - -/// Same as `fail`, except given a token index, and the function sets up the `LazySrcLoc` -/// for pointing at it relatively by subtracting from the containing `Decl`. -pub fn failTok( - mod: *Module, - scope: *Scope, - token_index: Ast.TokenIndex, - comptime format: []const u8, - args: anytype, -) CompileError { - const src = scope.srcDecl().?.tokSrcLoc(token_index); - return mod.fail(scope, src, format, args); -} - -/// Same as `fail`, except given an AST node index, and the function sets up the `LazySrcLoc` -/// for pointing at it relatively by subtracting from the containing `Decl`. -pub fn failNode( - mod: *Module, - scope: *Scope, - node_index: Ast.Node.Index, - comptime format: []const u8, - args: anytype, -) CompileError { - const src = scope.srcDecl().?.nodeSrcLoc(node_index); - return mod.fail(scope, src, format, args); -} - -pub fn failWithOwnedErrorMsg(mod: *Module, scope: *Scope, err_msg: *ErrorMsg) CompileError { - @setCold(true); - - { - errdefer err_msg.destroy(mod.gpa); - if (err_msg.src_loc.lazy == .unneeded) { - return error.NeededSourceLocation; - } - try mod.failed_decls.ensureUnusedCapacity(mod.gpa, 1); - try mod.failed_files.ensureUnusedCapacity(mod.gpa, 1); - } - switch (scope.tag) { - .block => { - const block = scope.cast(Scope.Block).?; - if (block.sema.owner_func) |func| { - func.state = .sema_failure; - } else { - block.sema.owner_decl.analysis = .sema_failure; - block.sema.owner_decl.generation = mod.generation; - } - mod.failed_decls.putAssumeCapacityNoClobber(block.sema.owner_decl, err_msg); - }, - .file => unreachable, - .namespace => unreachable, - } - return error.AnalysisFail; -} - pub fn optionalType(arena: *Allocator, child_type: Type) Allocator.Error!Type { switch (child_type.tag()) { .single_const_pointer => return Type.Tag.optional_single_const_pointer.create( diff --git a/src/Sema.zig b/src/Sema.zig index 0c24942c4e..22acd77aeb 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -880,19 +880,76 @@ fn resolveMaybeUndefValAllowVariables( } fn failWithNeededComptime(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) CompileError { - return sema.mod.fail(&block.base, src, "unable to resolve comptime value", .{}); + return sema.fail(block, src, "unable to resolve comptime value", .{}); } fn failWithUseOfUndef(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) CompileError { - return sema.mod.fail(&block.base, src, "use of undefined value here causes undefined behavior", .{}); + return sema.fail(block, src, "use of undefined value here causes undefined behavior", .{}); } fn failWithDivideByZero(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) CompileError { - return sema.mod.fail(&block.base, src, "division by zero here causes undefined behavior", .{}); + return sema.fail(block, src, "division by zero here causes undefined behavior", .{}); } fn failWithModRemNegative(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, lhs_ty: Type, rhs_ty: Type) CompileError { - return sema.mod.fail(&block.base, src, "remainder division with '{}' and '{}': signed integers and floats must use @rem or @mod", .{ lhs_ty, rhs_ty }); + return sema.fail(block, src, "remainder division with '{}' and '{}': signed integers and floats must use @rem or @mod", .{ lhs_ty, rhs_ty }); +} + +/// We don't return a pointer to the new error note because the pointer +/// becomes invalid when you add another one. +fn errNote( + sema: *Sema, + block: *Scope.Block, + src: LazySrcLoc, + parent: *Module.ErrorMsg, + comptime format: []const u8, + args: anytype, +) error{OutOfMemory}!void { + return sema.mod.errNoteNonLazy(src.toSrcLoc(block), parent, format, args); +} + +fn errMsg( + sema: *Sema, + block: *Scope.Block, + src: LazySrcLoc, + comptime format: []const u8, + args: anytype, +) error{OutOfMemory}!*Module.ErrorMsg { + return Module.ErrorMsg.create(sema.gpa, src.toSrcLoc(block), format, args); +} + +pub fn fail( + sema: *Sema, + block: *Scope.Block, + src: LazySrcLoc, + comptime format: []const u8, + args: anytype, +) CompileError { + const err_msg = try sema.errMsg(block, src, format, args); + return sema.failWithOwnedErrorMsg(err_msg); +} + +fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError { + @setCold(true); + + const mod = sema.mod; + + { + errdefer err_msg.destroy(mod.gpa); + if (err_msg.src_loc.lazy == .unneeded) { + return error.NeededSourceLocation; + } + try mod.failed_decls.ensureUnusedCapacity(mod.gpa, 1); + try mod.failed_files.ensureUnusedCapacity(mod.gpa, 1); + } + if (sema.owner_func) |func| { + func.state = .sema_failure; + } else { + sema.owner_decl.analysis = .sema_failure; + sema.owner_decl.generation = mod.generation; + } + mod.failed_decls.putAssumeCapacityNoClobber(sema.owner_decl, err_msg); + return error.AnalysisFail; } /// Appropriate to call when the coercion has already been done by result @@ -923,9 +980,9 @@ fn resolveAlign( ) !u16 { const alignment_big = try sema.resolveInt(block, src, zir_ref, Type.initTag(.u16)); const alignment = @intCast(u16, alignment_big); // We coerce to u16 in the prev line. - if (alignment == 0) return sema.mod.fail(&block.base, src, "alignment must be >= 1", .{}); + if (alignment == 0) return sema.fail(block, src, "alignment must be >= 1", .{}); if (!std.math.isPowerOfTwo(alignment)) { - return sema.mod.fail(&block.base, src, "alignment value {d} is not a power of two", .{ + return sema.fail(block, src, "alignment value {d} is not a power of two", .{ alignment, }); } @@ -981,7 +1038,7 @@ pub fn resolveInstValue( fn zirBitcastResultPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO implement zir_sema.zirBitcastResultPtr", .{}); + return sema.fail(block, src, "TODO implement zir_sema.zirBitcastResultPtr", .{}); } fn zirCoerceResultPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -1177,7 +1234,7 @@ fn zirEnumDecl( .val = enum_val, }, type_name); new_decl.owns_tv = true; - errdefer sema.mod.abortAnonDecl(new_decl); + errdefer mod.abortAnonDecl(new_decl); enum_obj.* = .{ .owner_decl = new_decl, @@ -1292,12 +1349,12 @@ fn zirEnumDecl( const field_src = enumFieldSrcLoc(block.src_decl, tree.*, src.node_offset, field_i); const other_tag_src = enumFieldSrcLoc(block.src_decl, tree.*, src.node_offset, gop.index); const msg = msg: { - const msg = try mod.errMsg(&block.base, field_src, "duplicate enum tag", .{}); + const msg = try sema.errMsg(block, field_src, "duplicate enum tag", .{}); errdefer msg.destroy(gpa); - try mod.errNote(&block.base, other_tag_src, msg, "other tag here", .{}); + try sema.errNote(block, other_tag_src, msg, "other tag here", .{}); break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } if (has_tag_value) { @@ -1400,7 +1457,7 @@ fn zirOpaqueDecl( _ = extended; _ = inst; - return sema.mod.fail(&block.base, sema.src, "TODO implement zirOpaqueDecl", .{}); + return sema.fail(block, sema.src, "TODO implement zirOpaqueDecl", .{}); } fn zirErrorSetDecl( @@ -1509,7 +1566,7 @@ fn ensureResultUsed( const operand_ty = sema.typeOf(operand); switch (operand_ty.zigTypeTag()) { .Void, .NoReturn => return, - else => return sema.mod.fail(&block.base, src, "expression value is ignored", .{}), + else => return sema.fail(block, src, "expression value is ignored", .{}), } } @@ -1522,7 +1579,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde const src = inst_data.src(); const operand_ty = sema.typeOf(operand); switch (operand_ty.zigTypeTag()) { - .ErrorSet, .ErrorUnion => return sema.mod.fail(&block.base, src, "error is discarded", .{}), + .ErrorSet, .ErrorUnion => return sema.fail(block, src, "error is discarded", .{}), else => return, } } @@ -1548,15 +1605,15 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co } if (!elem_ty.isIndexable()) { const msg = msg: { - const msg = try sema.mod.errMsg( - &block.base, + const msg = try sema.errMsg( + block, src, "type '{}' does not support indexing", .{elem_ty}, ); errdefer msg.destroy(sema.gpa); - try sema.mod.errNote( - &block.base, + try sema.errNote( + block, src, msg, "for loop operand must be an array, slice, tuple, or vector", @@ -1564,13 +1621,13 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co ); break :msg msg; }; - return sema.mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } const result_ptr = try sema.fieldPtr(block, src, array, "len", src); return sema.analyzeLoad(block, src, result_ptr, src); } - return sema.mod.fail(&block.base, src, "TODO implement Sema.zirIndexablePtrLen", .{}); + return sema.fail(block, src, "TODO implement Sema.zirIndexablePtrLen", .{}); } fn zirAllocExtended( @@ -1591,7 +1648,7 @@ fn zirAllocExtended( extra_index += 1; break :blk try sema.resolveType(block, ty_src, type_ref); } else { - return sema.mod.fail(&block.base, src, "TODO implement Sema.zirAllocExtended inferred", .{}); + return sema.fail(block, src, "TODO implement Sema.zirAllocExtended inferred", .{}); }; const alignment: u16 = if (small.has_align) blk: { @@ -1602,11 +1659,11 @@ fn zirAllocExtended( } else 0; if (small.is_comptime) { - return sema.mod.fail(&block.base, src, "TODO implement Sema.zirAllocExtended comptime", .{}); + return sema.fail(block, src, "TODO implement Sema.zirAllocExtended comptime", .{}); } if (!small.is_const) { - return sema.mod.fail(&block.base, src, "TODO implement Sema.zirAllocExtended var", .{}); + return sema.fail(block, src, "TODO implement Sema.zirAllocExtended var", .{}); } const ptr_type = try Type.ptr(sema.arena, .{ @@ -1804,12 +1861,10 @@ fn validateUnionInitPtr( instrs: []const Zir.Inst.Index, union_ptr: Air.Inst.Ref, ) CompileError!void { - const mod = sema.mod; - if (instrs.len != 1) { // TODO add note for other field // TODO add note for union declared here - return mod.fail(&block.base, init_src, "only one union field can be active at once", .{}); + return sema.fail(block, init_src, "only one union field can be active at once", .{}); } const field_ptr = instrs[0]; @@ -1845,7 +1900,6 @@ fn validateStructInitPtr( instrs: []const Zir.Inst.Index, ) CompileError!void { const gpa = sema.gpa; - const mod = sema.mod; // Maps field index to field_ptr index of where it was already initialized. const found_fields = try gpa.alloc(Zir.Inst.Index, struct_obj.fields.count()); @@ -1864,12 +1918,12 @@ fn validateStructInitPtr( const other_field_ptr_data = sema.code.instructions.items(.data)[other_field_ptr].pl_node; const other_field_src: LazySrcLoc = .{ .node_offset_back2tok = other_field_ptr_data.src_node }; const msg = msg: { - const msg = try mod.errMsg(&block.base, field_src, "duplicate field", .{}); + const msg = try sema.errMsg(block, field_src, "duplicate field", .{}); errdefer msg.destroy(gpa); - try mod.errNote(&block.base, other_field_src, msg, "other field here", .{}); + try sema.errNote(block, other_field_src, msg, "other field here", .{}); break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } found_fields[field_index] = field_ptr; } @@ -1884,28 +1938,28 @@ fn validateStructInitPtr( const template = "missing struct field: {s}"; const args = .{field_name}; if (root_msg) |msg| { - try mod.errNote(&block.base, init_src, msg, template, args); + try sema.errNote(block, init_src, msg, template, args); } else { - root_msg = try mod.errMsg(&block.base, init_src, template, args); + root_msg = try sema.errMsg(block, init_src, template, args); } } if (root_msg) |msg| { const fqn = try struct_obj.getFullyQualifiedName(gpa); defer gpa.free(fqn); - try mod.errNoteNonLazy( + try sema.mod.errNoteNonLazy( struct_obj.srcLoc(), msg, "struct '{s}' declared here", .{fqn}, ); - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } } fn zirValidateArrayInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO implement Sema.zirValidateArrayInitPtr", .{}); + return sema.fail(block, src, "TODO implement Sema.zirValidateArrayInitPtr", .{}); } fn failWithBadFieldAccess( @@ -1915,24 +1969,23 @@ fn failWithBadFieldAccess( field_src: LazySrcLoc, field_name: []const u8, ) CompileError { - const mod = sema.mod; const gpa = sema.gpa; const fqn = try struct_obj.getFullyQualifiedName(gpa); defer gpa.free(fqn); const msg = msg: { - const msg = try mod.errMsg( - &block.base, + const msg = try sema.errMsg( + block, field_src, "no field named '{s}' in struct '{s}'", .{ field_name, fqn }, ); errdefer msg.destroy(gpa); - try mod.errNoteNonLazy(struct_obj.srcLoc(), msg, "struct declared here", .{}); + try sema.mod.errNoteNonLazy(struct_obj.srcLoc(), msg, "struct declared here", .{}); break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } fn failWithBadUnionFieldAccess( @@ -1942,24 +1995,23 @@ fn failWithBadUnionFieldAccess( field_src: LazySrcLoc, field_name: []const u8, ) CompileError { - const mod = sema.mod; const gpa = sema.gpa; const fqn = try union_obj.getFullyQualifiedName(gpa); defer gpa.free(fqn); const msg = msg: { - const msg = try mod.errMsg( - &block.base, + const msg = try sema.errMsg( + block, field_src, "no field named '{s}' in union '{s}'", .{ field_name, fqn }, ); errdefer msg.destroy(gpa); - try mod.errNoteNonLazy(union_obj.srcLoc(), msg, "union declared here", .{}); + try sema.mod.errNoteNonLazy(union_obj.srcLoc(), msg, "union declared here", .{}); break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } fn zirStoreToBlockPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { @@ -2150,7 +2202,7 @@ fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compi const src = inst_data.src(); const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const msg = try sema.resolveConstString(block, operand_src, inst_data.operand); - return sema.mod.fail(&block.base, src, "{s}", .{msg}); + return sema.fail(block, src, "{s}", .{msg}); } fn zirCompileLog( @@ -2269,7 +2321,7 @@ fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Com // we check this here to avoid undefined symbols if (!@import("build_options").have_llvm) - return sema.mod.fail(&parent_block.base, src, "cannot do C import on Zig compiler not built with LLVM-extension", .{}); + return sema.fail(&parent_block, src, "cannot do C import on Zig compiler not built with LLVM-extension", .{}); var c_import_buf = std.ArrayList(u8).init(sema.gpa); defer c_import_buf.deinit(); @@ -2290,15 +2342,15 @@ fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Com _ = try sema.analyzeBody(&child_block, body); const c_import_res = sema.mod.comp.cImport(c_import_buf.items) catch |err| - return sema.mod.fail(&child_block.base, src, "C import failed: {s}", .{@errorName(err)}); + return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); if (c_import_res.errors.len != 0) { const msg = msg: { - const msg = try sema.mod.errMsg(&child_block.base, src, "C import failed", .{}); + const msg = try sema.errMsg(&child_block, src, "C import failed", .{}); errdefer msg.destroy(sema.gpa); if (!sema.mod.comp.bin_file.options.link_libc) - try sema.mod.errNote(&child_block.base, src, msg, "libc headers not available; compilation does not link against libc", .{}); + try sema.errNote(&child_block, src, msg, "libc headers not available; compilation does not link against libc", .{}); for (c_import_res.errors) |_| { // TODO integrate with LazySrcLoc @@ -2310,7 +2362,7 @@ fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Com @import("clang.zig").Stage2ErrorMsg.delete(c_import_res.errors.ptr, c_import_res.errors.len); break :msg msg; }; - return sema.mod.failWithOwnedErrorMsg(&child_block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } const c_import_pkg = Package.create( sema.gpa, @@ -2326,10 +2378,10 @@ fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Com try c_import_pkg.add(sema.gpa, "std", std_pkg); const result = sema.mod.importPkg(c_import_pkg) catch |err| - return sema.mod.fail(&child_block.base, src, "C import failed: {s}", .{@errorName(err)}); + return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); sema.mod.astGenFile(result.file) catch |err| - return sema.mod.fail(&child_block.base, src, "C import failed: {s}", .{@errorName(err)}); + return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); try sema.mod.semaFile(result.file); const file_root_decl = result.file.root_decl.?; @@ -2340,7 +2392,7 @@ fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Com fn zirSuspendBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&parent_block.base, src, "TODO: implement Sema.zirSuspendBlock", .{}); + return sema.fail(parent_block, src, "TODO: implement Sema.zirSuspendBlock", .{}); } fn zirBlock( @@ -2527,11 +2579,11 @@ fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro const options_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; const decl_name = sema.code.nullTerminatedString(extra.decl_name); if (extra.namespace != .none) { - return sema.mod.fail(&block.base, src, "TODO: implement exporting with field access", .{}); + return sema.fail(block, src, "TODO: implement exporting with field access", .{}); } const decl = try sema.lookupIdentifier(block, operand_src, decl_name); const options = try sema.resolveExportOptions(block, options_src, extra.options); - try sema.mod.analyzeExport(block, src, options, decl); + try sema.analyzeExport(block, src, options, decl); } fn zirExportValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { @@ -2547,40 +2599,117 @@ fn zirExportValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil const options = try sema.resolveExportOptions(block, options_src, extra.options); const decl = switch (operand.val.tag()) { .function => operand.val.castTag(.function).?.data.owner_decl, - else => return sema.mod.fail(&block.base, operand_src, "TODO implement exporting arbitrary Value objects", .{}), // TODO put this Value into an anonymous Decl and then export it. + else => return sema.fail(block, operand_src, "TODO implement exporting arbitrary Value objects", .{}), // TODO put this Value into an anonymous Decl and then export it. }; - try sema.mod.analyzeExport(block, src, options, decl); + try sema.analyzeExport(block, src, options, decl); +} + +pub fn analyzeExport( + sema: *Sema, + block: *Scope.Block, + src: LazySrcLoc, + borrowed_options: std.builtin.ExportOptions, + exported_decl: *Decl, +) !void { + const Export = Module.Export; + const mod = sema.mod; + + try mod.ensureDeclAnalyzed(exported_decl); + switch (exported_decl.ty.zigTypeTag()) { + .Fn => {}, + else => return sema.fail(block, src, "unable to export type '{}'", .{exported_decl.ty}), + } + + const gpa = mod.gpa; + + try mod.decl_exports.ensureUnusedCapacity(gpa, 1); + try mod.export_owners.ensureUnusedCapacity(gpa, 1); + + const new_export = try gpa.create(Export); + errdefer gpa.destroy(new_export); + + const symbol_name = try gpa.dupe(u8, borrowed_options.name); + errdefer gpa.free(symbol_name); + + const section: ?[]const u8 = if (borrowed_options.section) |s| try gpa.dupe(u8, s) else null; + errdefer if (section) |s| gpa.free(s); + + const src_decl = block.src_decl; + const owner_decl = sema.owner_decl; + + log.debug("exporting Decl '{s}' as symbol '{s}' from Decl '{s}'", .{ + exported_decl.name, symbol_name, owner_decl.name, + }); + + new_export.* = .{ + .options = .{ + .name = symbol_name, + .linkage = borrowed_options.linkage, + .section = section, + }, + .src = src, + .link = switch (mod.comp.bin_file.tag) { + .coff => .{ .coff = {} }, + .elf => .{ .elf = .{} }, + .macho => .{ .macho = .{} }, + .plan9 => .{ .plan9 = null }, + .c => .{ .c = {} }, + .wasm => .{ .wasm = {} }, + .spirv => .{ .spirv = {} }, + }, + .owner_decl = owner_decl, + .src_decl = src_decl, + .exported_decl = exported_decl, + .status = .in_progress, + }; + + // Add to export_owners table. + const eo_gop = mod.export_owners.getOrPutAssumeCapacity(owner_decl); + if (!eo_gop.found_existing) { + eo_gop.value_ptr.* = &[0]*Export{}; + } + eo_gop.value_ptr.* = try gpa.realloc(eo_gop.value_ptr.*, eo_gop.value_ptr.len + 1); + eo_gop.value_ptr.*[eo_gop.value_ptr.len - 1] = new_export; + errdefer eo_gop.value_ptr.* = gpa.shrink(eo_gop.value_ptr.*, eo_gop.value_ptr.len - 1); + + // Add to exported_decl table. + const de_gop = mod.decl_exports.getOrPutAssumeCapacity(exported_decl); + if (!de_gop.found_existing) { + de_gop.value_ptr.* = &[0]*Export{}; + } + de_gop.value_ptr.* = try gpa.realloc(de_gop.value_ptr.*, de_gop.value_ptr.len + 1); + de_gop.value_ptr.*[de_gop.value_ptr.len - 1] = new_export; + errdefer de_gop.value_ptr.* = gpa.shrink(de_gop.value_ptr.*, de_gop.value_ptr.len - 1); } fn zirSetAlignStack(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { - const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[inst].un_node; const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const src: LazySrcLoc = inst_data.src(); const alignment = try sema.resolveAlign(block, operand_src, inst_data.operand); if (alignment > 256) { - return mod.fail(&block.base, src, "attempt to @setAlignStack({d}); maximum is 256", .{ + return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{ alignment, }); } const func = sema.owner_func orelse - return mod.fail(&block.base, src, "@setAlignStack outside function body", .{}); + return sema.fail(block, src, "@setAlignStack outside function body", .{}); switch (func.owner_decl.ty.fnCallingConvention()) { - .Naked => return mod.fail(&block.base, src, "@setAlignStack in naked function", .{}), - .Inline => return mod.fail(&block.base, src, "@setAlignStack in inline function", .{}), + .Naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}), + .Inline => return sema.fail(block, src, "@setAlignStack in inline function", .{}), else => {}, } - const gop = try mod.align_stack_fns.getOrPut(mod.gpa, func); + const gop = try sema.mod.align_stack_fns.getOrPut(sema.mod.gpa, func); if (gop.found_existing) { const msg = msg: { - const msg = try mod.errMsg(&block.base, src, "multiple @setAlignStack in the same function body", .{}); - errdefer msg.destroy(mod.gpa); - try mod.errNote(&block.base, src, msg, "other instance here", .{}); + const msg = try sema.errMsg(block, src, "multiple @setAlignStack in the same function body", .{}); + errdefer msg.destroy(sema.gpa); + try sema.errNote(block, src, msg, "other instance here", .{}); break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } gop.value_ptr.* = .{ .alignment = alignment, .src = src }; } @@ -2596,7 +2725,7 @@ fn zirSetCold(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr fn zirSetFloatMode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src: LazySrcLoc = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirSetFloatMode", .{}); + return sema.fail(block, src, "TODO: implement Sema.zirSetFloatMode", .{}); } fn zirSetRuntimeSafety(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { @@ -2613,7 +2742,7 @@ fn zirFence(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError const order = try sema.resolveAtomicOrder(block, order_src, inst_data.operand); if (@enumToInt(order) < @enumToInt(std.builtin.AtomicOrder.Acquire)) { - return sema.mod.fail(&block.base, order_src, "atomic ordering must be Acquire or stricter", .{}); + return sema.fail(block, order_src, "atomic ordering must be Acquire or stricter", .{}); } _ = try block.addInst(.{ @@ -2757,7 +2886,7 @@ fn lookupInNamespace( }, else => { const msg = msg: { - const msg = try mod.errMsg(&block.base, src, "ambiguous reference", .{}); + const msg = try sema.errMsg(block, src, "ambiguous reference", .{}); errdefer msg.destroy(gpa); for (candidates.items) |candidate| { const src_loc = candidate.srcLoc(); @@ -2765,7 +2894,7 @@ fn lookupInNamespace( } break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); }, } } else if (namespace.decls.get(ident_name)) |decl| { @@ -2899,14 +3028,14 @@ fn analyzeCall( const func_ty = sema.typeOf(func); if (func_ty.zigTypeTag() != .Fn) - return mod.fail(&block.base, func_src, "type '{}' not a function", .{func_ty}); + return sema.fail(block, func_src, "type '{}' not a function", .{func_ty}); const func_ty_info = func_ty.fnInfo(); const cc = func_ty_info.cc; if (cc == .Naked) { // TODO add error note: declared here - return mod.fail( - &block.base, + return sema.fail( + block, func_src, "unable to call function with naked calling convention", .{}, @@ -2917,8 +3046,8 @@ fn analyzeCall( assert(cc == .C); if (uncasted_args.len < fn_params_len) { // TODO add error note: declared here - return mod.fail( - &block.base, + return sema.fail( + block, func_src, "expected at least {d} argument(s), found {d}", .{ fn_params_len, uncasted_args.len }, @@ -2926,8 +3055,8 @@ fn analyzeCall( } } else if (fn_params_len != uncasted_args.len) { // TODO add error note: declared here - return mod.fail( - &block.base, + return sema.fail( + block, func_src, "expected {d} argument(s), found {d}", .{ fn_params_len, uncasted_args.len }, @@ -2945,7 +3074,7 @@ fn analyzeCall( .never_inline, .no_async, .always_tail, - => return mod.fail(&block.base, call_src, "TODO implement call with modifier {}", .{ + => return sema.fail(block, call_src, "TODO implement call with modifier {}", .{ modifier, }), } @@ -2960,7 +3089,7 @@ fn analyzeCall( const func_val = try sema.resolveConstValue(block, func_src, func); const module_fn = switch (func_val.tag()) { .function => func_val.castTag(.function).?.data, - .extern_fn => return mod.fail(&block.base, call_src, "{s} call of extern function", .{ + .extern_fn => return sema.fail(block, call_src, "{s} call of extern function", .{ @as([]const u8, if (is_comptime_call) "comptime" else "inline"), }), else => unreachable, @@ -3633,7 +3762,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Com const payload = try sema.resolveType(block, rhs_src, extra.rhs); if (error_union.zigTypeTag() != .ErrorSet) { - return sema.mod.fail(&block.base, lhs_src, "expected error set type, found {}", .{ + return sema.fail(block, lhs_src, "expected error set type, found {}", .{ error_union.elemType(), }); } @@ -3699,7 +3828,7 @@ fn zirIntToError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile if (try sema.resolveDefinedValue(block, operand_src, op)) |value| { const int = value.toUnsignedInt(); if (int > sema.mod.global_error_set.count() or int == 0) - return sema.mod.fail(&block.base, operand_src, "integer value {d} represents no error", .{int}); + return sema.fail(block, operand_src, "integer value {d} represents no error", .{int}); const payload = try sema.arena.create(Value.Payload.Error); payload.* = .{ .base = .{ .tag = .@"error" }, @@ -3709,7 +3838,7 @@ fn zirIntToError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile } try sema.requireRuntimeBlock(block, src); if (block.wantSafety()) { - return sema.mod.fail(&block.base, src, "TODO: get max errors in compilation", .{}); + return sema.fail(block, src, "TODO: get max errors in compilation", .{}); // const is_gt_max = @panic("TODO get max errors in compilation"); // try sema.addSafetyCheck(block, is_gt_max, .invalid_error_code); } @@ -3729,19 +3858,19 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Com const rhs = sema.resolveInst(extra.rhs); if (sema.typeOf(lhs).zigTypeTag() == .Bool and sema.typeOf(rhs).zigTypeTag() == .Bool) { const msg = msg: { - const msg = try sema.mod.errMsg(&block.base, lhs_src, "expected error set type, found 'bool'", .{}); + const msg = try sema.errMsg(block, lhs_src, "expected error set type, found 'bool'", .{}); errdefer msg.destroy(sema.gpa); - try sema.mod.errNote(&block.base, src, msg, "'||' merges error sets; 'or' performs boolean OR", .{}); + try sema.errNote(block, src, msg, "'||' merges error sets; 'or' performs boolean OR", .{}); break :msg msg; }; - return sema.mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } const lhs_ty = try sema.analyzeAsType(block, lhs_src, lhs); const rhs_ty = try sema.analyzeAsType(block, rhs_src, rhs); if (lhs_ty.zigTypeTag() != .ErrorSet) - return sema.mod.fail(&block.base, lhs_src, "expected error set type, found {}", .{lhs_ty}); + return sema.fail(block, lhs_src, "expected error set type, found {}", .{lhs_ty}); if (rhs_ty.zigTypeTag() != .ErrorSet) - return sema.mod.fail(&block.base, rhs_src, "expected error set type, found {}", .{rhs_ty}); + return sema.fail(block, rhs_src, "expected error set type, found {}", .{rhs_ty}); // Anything merged with anyerror is anyerror. if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) { @@ -3814,7 +3943,6 @@ fn zirEnumLiteral(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil } fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { - const mod = sema.mod; const arena = sema.arena; const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); @@ -3826,17 +3954,17 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE .Enum => operand, .Union => { //if (!operand_ty.unionHasTag()) { - // return mod.fail( - // &block.base, + // return sema.fail( + // block, // operand_src, // "untagged union '{}' cannot be converted to integer", // .{dest_ty_src}, // ); //} - return mod.fail(&block.base, operand_src, "TODO zirEnumToInt for tagged unions", .{}); + return sema.fail(block, operand_src, "TODO zirEnumToInt for tagged unions", .{}); }, else => { - return mod.fail(&block.base, operand_src, "expected enum or tagged union, found {}", .{ + return sema.fail(block, operand_src, "expected enum or tagged union, found {}", .{ operand_ty, }); }, @@ -3861,8 +3989,7 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE } fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { - const mod = sema.mod; - const target = mod.getTarget(); + const target = sema.mod.getTarget(); const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; const src = inst_data.src(); @@ -3872,7 +3999,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE const operand = sema.resolveInst(extra.rhs); if (dest_ty.zigTypeTag() != .Enum) { - return mod.fail(&block.base, dest_ty_src, "expected enum, found {}", .{dest_ty}); + return sema.fail(block, dest_ty_src, "expected enum, found {}", .{dest_ty}); } if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |int_val| { @@ -3884,14 +4011,14 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE } if (!dest_ty.enumHasInt(int_val, target)) { const msg = msg: { - const msg = try mod.errMsg( - &block.base, + const msg = try sema.errMsg( + block, src, "enum '{}' has no tag with value {}", .{ dest_ty, int_val }, ); errdefer msg.destroy(sema.gpa); - try mod.errNoteNonLazy( + try sema.mod.errNoteNonLazy( dest_ty.declSrcLoc(), msg, "enum declared here", @@ -3899,7 +4026,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE ); break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } return sema.addConstant(dest_ty, int_val); } @@ -3926,7 +4053,7 @@ fn zirOptionalPayloadPtr( const opt_type = optional_ptr_ty.elemType(); if (opt_type.zigTypeTag() != .Optional) { - return sema.mod.fail(&block.base, src, "expected optional type, found {}", .{opt_type}); + return sema.fail(block, src, "expected optional type, found {}", .{opt_type}); } const child_type = try opt_type.optionalChildAlloc(sema.arena); @@ -3939,7 +4066,7 @@ fn zirOptionalPayloadPtr( if (try sema.resolveDefinedValue(block, src, optional_ptr)) |pointer_val| { if (try pointer_val.pointerDeref(sema.arena)) |val| { if (val.isNull()) { - return sema.mod.fail(&block.base, src, "unable to unwrap null", .{}); + return sema.fail(block, src, "unable to unwrap null", .{}); } // The same Value represents the pointer to the optional and the payload. return sema.addConstant( @@ -3973,14 +4100,14 @@ fn zirOptionalPayload( const operand_ty = sema.typeOf(operand); const opt_type = operand_ty; if (opt_type.zigTypeTag() != .Optional) { - return sema.mod.fail(&block.base, src, "expected optional type, found {}", .{opt_type}); + return sema.fail(block, src, "expected optional type, found {}", .{opt_type}); } const child_type = try opt_type.optionalChildAlloc(sema.arena); if (try sema.resolveDefinedValue(block, src, operand)) |val| { if (val.isNull()) { - return sema.mod.fail(&block.base, src, "unable to unwrap null", .{}); + return sema.fail(block, src, "unable to unwrap null", .{}); } const sub_val = val.castTag(.opt_payload).?.data; return sema.addConstant(child_type, sub_val); @@ -4010,11 +4137,11 @@ fn zirErrUnionPayload( const operand_src = src; const operand_ty = sema.typeOf(operand); if (operand_ty.zigTypeTag() != .ErrorUnion) - return sema.mod.fail(&block.base, operand_src, "expected error union type, found '{}'", .{operand_ty}); + return sema.fail(block, operand_src, "expected error union type, found '{}'", .{operand_ty}); if (try sema.resolveDefinedValue(block, src, operand)) |val| { if (val.getError()) |name| { - return sema.mod.fail(&block.base, src, "caught unexpected error '{s}'", .{name}); + return sema.fail(block, src, "caught unexpected error '{s}'", .{name}); } const data = val.castTag(.eu_payload).?.data; const result_ty = operand_ty.errorUnionPayload(); @@ -4046,7 +4173,7 @@ fn zirErrUnionPayloadPtr( assert(operand_ty.zigTypeTag() == .Pointer); if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) - return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand_ty.elemType()}); + return sema.fail(block, src, "expected error union type, found {}", .{operand_ty.elemType()}); const payload_ty = operand_ty.elemType().errorUnionPayload(); const operand_pointer_ty = try Type.ptr(sema.arena, .{ @@ -4058,7 +4185,7 @@ fn zirErrUnionPayloadPtr( if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| { if (try pointer_val.pointerDeref(sema.arena)) |val| { if (val.getError()) |name| { - return sema.mod.fail(&block.base, src, "caught unexpected error '{s}'", .{name}); + return sema.fail(block, src, "caught unexpected error '{s}'", .{name}); } return sema.addConstant( operand_pointer_ty, @@ -4085,7 +4212,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compi const operand = sema.resolveInst(inst_data.operand); const operand_ty = sema.typeOf(operand); if (operand_ty.zigTypeTag() != .ErrorUnion) - return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand_ty}); + return sema.fail(block, src, "expected error union type, found '{}'", .{operand_ty}); const result_ty = operand_ty.errorUnionSet(); @@ -4110,7 +4237,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co assert(operand_ty.zigTypeTag() == .Pointer); if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) - return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand_ty.elemType()}); + return sema.fail(block, src, "expected error union type, found {}", .{operand_ty.elemType()}); const result_ty = operand_ty.elemType().errorUnionSet(); @@ -4134,9 +4261,9 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde const operand = sema.resolveInst(inst_data.operand); const operand_ty = sema.typeOf(operand); if (operand_ty.zigTypeTag() != .ErrorUnion) - return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand_ty}); + return sema.fail(block, src, "expected error union type, found '{}'", .{operand_ty}); if (operand_ty.errorUnionPayload().zigTypeTag() != .Void) { - return sema.mod.fail(&block.base, src, "expression value is ignored", .{}); + return sema.fail(block, src, "expression value is ignored", .{}); } } @@ -4277,7 +4404,7 @@ fn funcCommon( } if (align_val.tag() != .null_value) { - return mod.fail(&block.base, src, "TODO implement support for function prototypes to have alignment specified", .{}); + return sema.fail(block, src, "TODO implement support for function prototypes to have alignment specified", .{}); } is_generic = is_generic or bare_return_type.requiresComptime(); @@ -4309,15 +4436,15 @@ fn funcCommon( const lib_name_src: LazySrcLoc = .{ .node_offset_lib_name = src_node_offset }; log.debug("extern fn symbol expected in lib '{s}'", .{lib_name}); mod.comp.stage1AddLinkLib(lib_name) catch |err| { - return mod.fail(&block.base, lib_name_src, "unable to add link lib '{s}': {s}", .{ + return sema.fail(block, lib_name_src, "unable to add link lib '{s}': {s}", .{ lib_name, @errorName(err), }); }; const target = mod.getTarget(); if (target_util.is_libc_lib_name(target, lib_name)) { if (!mod.comp.bin_file.options.link_libc) { - return mod.fail( - &block.base, + return sema.fail( + block, lib_name_src, "dependency on libc must be explicitly specified in the build command", .{}, @@ -4327,8 +4454,8 @@ fn funcCommon( } if (target_util.is_libcpp_lib_name(target, lib_name)) { if (!mod.comp.bin_file.options.link_libcpp) { - return mod.fail( - &block.base, + return sema.fail( + block, lib_name_src, "dependency on libc++ must be explicitly specified in the build command", .{}, @@ -4337,8 +4464,8 @@ fn funcCommon( break :blk; } if (!target.isWasm() and !mod.comp.bin_file.options.pic) { - return mod.fail( - &block.base, + return sema.fail( + block, lib_name_src, "dependency on dynamic library '{s}' requires enabling Position Independent Code. Fixed by `-l{s}` or `-fPIC`.", .{ lib_name, lib_name }, @@ -4528,7 +4655,7 @@ fn zirPtrToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr const ptr_ty = sema.typeOf(ptr); if (ptr_ty.zigTypeTag() != .Pointer) { const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; - return sema.mod.fail(&block.base, ptr_src, "expected pointer, found '{}'", .{ptr_ty}); + return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty}); } // TODO handle known-pointer-address const src = inst_data.src(); @@ -4639,7 +4766,7 @@ fn zirIntCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr if (try sema.isComptimeKnown(block, operand_src, operand)) { return sema.coerce(block, dest_type, operand, operand_src); } else if (dest_is_comptime_int) { - return sema.mod.fail(&block.base, src, "unable to cast runtime value to 'comptime_int'", .{}); + return sema.fail(block, src, "unable to cast runtime value to 'comptime_int'", .{}); } try sema.requireRuntimeBlock(block, operand_src); @@ -4676,8 +4803,8 @@ fn zirFloatCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE const dest_is_comptime_float = switch (dest_type.zigTypeTag()) { .ComptimeFloat => true, .Float => false, - else => return sema.mod.fail( - &block.base, + else => return sema.fail( + block, dest_ty_src, "expected float type, found '{}'", .{dest_type}, @@ -4687,8 +4814,8 @@ fn zirFloatCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE const operand_ty = sema.typeOf(operand); switch (operand_ty.zigTypeTag()) { .ComptimeFloat, .Float, .ComptimeInt => {}, - else => return sema.mod.fail( - &block.base, + else => return sema.fail( + block, operand_src, "expected float type, found '{}'", .{operand_ty}, @@ -4699,7 +4826,7 @@ fn zirFloatCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE return sema.coerce(block, dest_type, operand, operand_src); } if (dest_is_comptime_float) { - return sema.mod.fail(&block.base, src, "unable to cast runtime value to 'comptime_float'", .{}); + return sema.fail(block, src, "unable to cast runtime value to 'comptime_float'", .{}); } const target = sema.mod.getTarget(); const src_bits = operand_ty.floatBits(target); @@ -4817,7 +4944,7 @@ fn zirSwitchCapture( _ = is_ref; _ = is_multi; - return sema.mod.fail(&block.base, src, "TODO implement Sema for zirSwitchCapture", .{}); + return sema.fail(block, src, "TODO implement Sema for zirSwitchCapture", .{}); } fn zirSwitchCaptureElse( @@ -4835,7 +4962,7 @@ fn zirSwitchCaptureElse( const src = switch_info.src(); _ = is_ref; - return sema.mod.fail(&block.base, src, "TODO implement Sema for zirSwitchCaptureElse", .{}); + return sema.fail(block, src, "TODO implement Sema for zirSwitchCaptureElse", .{}); } fn zirSwitchBlock( @@ -4916,7 +5043,6 @@ fn analyzeSwitch( src_node_offset: i32, ) CompileError!Air.Inst.Ref { const gpa = sema.gpa; - const mod = sema.mod; const special: struct { body: []const Zir.Inst.Index, end: usize } = switch (special_prong) { .none => .{ .body = &.{}, .end = extra_end }, @@ -4938,15 +5064,15 @@ fn analyzeSwitch( // Validate usage of '_' prongs. if (special_prong == .under and !operand_ty.isNonexhaustiveEnum()) { const msg = msg: { - const msg = try mod.errMsg( - &block.base, + const msg = try sema.errMsg( + block, src, "'_' prong only allowed when switching on non-exhaustive enums", .{}, ); errdefer msg.destroy(gpa); - try mod.errNote( - &block.base, + try sema.errNote( + block, special_prong_src, msg, "'_' prong here", @@ -4954,7 +5080,7 @@ fn analyzeSwitch( ); break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } // Validate for duplicate items, missing else prong, and invalid range. @@ -5017,8 +5143,8 @@ fn analyzeSwitch( .none => { if (!all_tags_handled) { const msg = msg: { - const msg = try mod.errMsg( - &block.base, + const msg = try sema.errMsg( + block, src, "switch must handle all possibilities", .{}, @@ -5030,15 +5156,15 @@ fn analyzeSwitch( const field_name = operand_ty.enumFieldName(i); // TODO have this point to the tag decl instead of here - try mod.errNote( - &block.base, + try sema.errNote( + block, src, msg, "unhandled enumeration value: '{s}'", .{field_name}, ); } - try mod.errNoteNonLazy( + try sema.mod.errNoteNonLazy( operand_ty.declSrcLoc(), msg, "enum '{}' declared here", @@ -5046,20 +5172,20 @@ fn analyzeSwitch( ); break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } }, .under => { - if (all_tags_handled) return mod.fail( - &block.base, + if (all_tags_handled) return sema.fail( + block, special_prong_src, "unreachable '_' prong; all cases already handled", .{}, ); }, .@"else" => { - if (all_tags_handled) return mod.fail( - &block.base, + if (all_tags_handled) return sema.fail( + block, special_prong_src, "unreachable else prong; all cases already handled", .{}, @@ -5068,8 +5194,8 @@ fn analyzeSwitch( } }, - .ErrorSet => return mod.fail(&block.base, src, "TODO validate switch .ErrorSet", .{}), - .Union => return mod.fail(&block.base, src, "TODO validate switch .Union", .{}), + .ErrorSet => return sema.fail(block, src, "TODO validate switch .ErrorSet", .{}), + .Union => return sema.fail(block, src, "TODO validate switch .Union", .{}), .Int, .ComptimeInt => { var range_set = RangeSet.init(gpa); defer range_set.deinit(); @@ -5144,12 +5270,13 @@ fn analyzeSwitch( var arena = std.heap.ArenaAllocator.init(gpa); defer arena.deinit(); - const min_int = try operand_ty.minInt(&arena.allocator, mod.getTarget()); - const max_int = try operand_ty.maxInt(&arena.allocator, mod.getTarget()); + const target = sema.mod.getTarget(); + const min_int = try operand_ty.minInt(&arena.allocator, target); + const max_int = try operand_ty.maxInt(&arena.allocator, target); if (try range_set.spans(min_int, max_int, operand_ty)) { if (special_prong == .@"else") { - return mod.fail( - &block.base, + return sema.fail( + block, special_prong_src, "unreachable else prong; all cases already handled", .{}, @@ -5159,8 +5286,8 @@ fn analyzeSwitch( } } if (special_prong != .@"else") { - return mod.fail( - &block.base, + return sema.fail( + block, src, "switch must handle all possibilities", .{}, @@ -5221,8 +5348,8 @@ fn analyzeSwitch( switch (special_prong) { .@"else" => { if (true_count + false_count == 2) { - return mod.fail( - &block.base, + return sema.fail( + block, src, "unreachable else prong; all cases already handled", .{}, @@ -5231,8 +5358,8 @@ fn analyzeSwitch( }, .under, .none => { if (true_count + false_count < 2) { - return mod.fail( - &block.base, + return sema.fail( + block, src, "switch must handle all possibilities", .{}, @@ -5243,8 +5370,8 @@ fn analyzeSwitch( }, .EnumLiteral, .Void, .Fn, .Pointer, .Type => { if (special_prong != .@"else") { - return mod.fail( - &block.base, + return sema.fail( + block, src, "else prong required when switching on type '{}'", .{operand_ty}, @@ -5314,7 +5441,7 @@ fn analyzeSwitch( .AnyFrame, .ComptimeFloat, .Float, - => return mod.fail(&block.base, operand_src, "invalid switch operand type '{}'", .{ + => return sema.fail(block, operand_src, "invalid switch operand type '{}'", .{ operand_ty, }), } @@ -5707,19 +5834,18 @@ fn validateSwitchItemEnum( src_node_offset: i32, switch_prong_src: Module.SwitchProngSrc, ) CompileError!void { - const mod = sema.mod; const item_tv = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none); const field_index = item_tv.ty.enumTagFieldIndex(item_tv.val) orelse { const msg = msg: { const src = switch_prong_src.resolve(sema.gpa, block.src_decl, src_node_offset, .none); - const msg = try mod.errMsg( - &block.base, + const msg = try sema.errMsg( + block, src, "enum '{}' has no tag with value '{}'", .{ item_tv.ty, item_tv.val }, ); errdefer msg.destroy(sema.gpa); - try mod.errNoteNonLazy( + try sema.mod.errNoteNonLazy( item_tv.ty.declSrcLoc(), msg, "enum declared here", @@ -5727,7 +5853,7 @@ fn validateSwitchItemEnum( ); break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); }; const maybe_prev_src = seen_fields[field_index]; seen_fields[field_index] = switch_prong_src; @@ -5742,20 +5868,19 @@ fn validateSwitchDupe( src_node_offset: i32, ) CompileError!void { const prev_prong_src = maybe_prev_src orelse return; - const mod = sema.mod; const gpa = sema.gpa; const src = switch_prong_src.resolve(gpa, block.src_decl, src_node_offset, .none); const prev_src = prev_prong_src.resolve(gpa, block.src_decl, src_node_offset, .none); const msg = msg: { - const msg = try mod.errMsg( - &block.base, + const msg = try sema.errMsg( + block, src, "duplicate switch value", .{}, ); errdefer msg.destroy(sema.gpa); - try mod.errNote( - &block.base, + try sema.errNote( + block, prev_src, msg, "previous value here", @@ -5763,7 +5888,7 @@ fn validateSwitchDupe( ); break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } fn validateSwitchItemBool( @@ -5783,7 +5908,7 @@ fn validateSwitchItemBool( } if (true_count.* + false_count.* > 2) { const src = switch_prong_src.resolve(sema.gpa, block.src_decl, src_node_offset, .none); - return sema.mod.fail(&block.base, src, "duplicate switch value", .{}); + return sema.fail(block, src, "duplicate switch value", .{}); } } @@ -5816,15 +5941,15 @@ fn validateSwitchNoRange( const range_src: LazySrcLoc = .{ .node_offset_switch_range = src_node_offset }; const msg = msg: { - const msg = try sema.mod.errMsg( - &block.base, + const msg = try sema.errMsg( + block, operand_src, "ranges not allowed when switching on type '{}'", .{operand_ty}, ); errdefer msg.destroy(sema.gpa); - try sema.mod.errNote( - &block.base, + try sema.errNote( + block, range_src, msg, "range here", @@ -5832,7 +5957,7 @@ fn validateSwitchNoRange( ); break :msg msg; }; - return sema.mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } fn zirHasField(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -5841,7 +5966,7 @@ fn zirHasField(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr _ = extra; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO implement zirHasField", .{}); + return sema.fail(block, src, "TODO implement zirHasField", .{}); } fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -5852,10 +5977,9 @@ fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; const container_type = try sema.resolveType(block, lhs_src, extra.lhs); const decl_name = try sema.resolveConstString(block, rhs_src, extra.rhs); - const mod = sema.mod; - const namespace = container_type.getNamespace() orelse return mod.fail( - &block.base, + const namespace = container_type.getNamespace() orelse return sema.fail( + block, lhs_src, "expected struct, enum, union, or opaque, found '{}'", .{container_type}, @@ -5879,24 +6003,24 @@ fn zirImport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro const result = mod.importFile(block.getFileScope(), operand) catch |err| switch (err) { error.ImportOutsidePkgPath => { - return mod.fail(&block.base, src, "import of file outside package path: '{s}'", .{operand}); + return sema.fail(block, src, "import of file outside package path: '{s}'", .{operand}); }, else => { // TODO: these errors are file system errors; make sure an update() will // retry this and not cache the file system error, which may be transient. - return mod.fail(&block.base, src, "unable to open '{s}': {s}", .{ operand, @errorName(err) }); + return sema.fail(block, src, "unable to open '{s}': {s}", .{ operand, @errorName(err) }); }, }; try mod.semaFile(result.file); const file_root_decl = result.file.root_decl.?; - try sema.mod.declareDeclDependency(sema.owner_decl, file_root_decl); + try mod.declareDeclDependency(sema.owner_decl, file_root_decl); return sema.addConstant(file_root_decl.ty, file_root_decl.val); } fn zirRetErrValueCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { _ = block; _ = inst; - return sema.mod.fail(&block.base, sema.src, "TODO implement zirRetErrValueCode", .{}); + return sema.fail(block, sema.src, "TODO implement zirRetErrValueCode", .{}); } fn zirShl( @@ -5933,8 +6057,8 @@ fn zirShl( } const val = try lhs_val.shl(rhs_val, sema.arena); switch (air_tag) { - .shl_exact => return sema.mod.fail(&block.base, lhs_src, "TODO implement Sema for comptime shl_exact", .{}), - .shl_sat => return sema.mod.fail(&block.base, lhs_src, "TODO implement Sema for comptime shl_sat", .{}), + .shl_exact => return sema.fail(block, lhs_src, "TODO implement Sema for comptime shl_exact", .{}), + .shl_sat => return sema.fail(block, lhs_src, "TODO implement Sema for comptime shl_sat", .{}), .shl => {}, else => unreachable, } @@ -6016,14 +6140,14 @@ fn zirBitwise( if (lhs_ty.zigTypeTag() == .Vector and rhs_ty.zigTypeTag() == .Vector) { if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) { - return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{ + return sema.fail(block, src, "vector length mismatch: {d} and {d}", .{ lhs_ty.arrayLen(), rhs_ty.arrayLen(), }); } - return sema.mod.fail(&block.base, src, "TODO implement support for vectors in zirBitwise", .{}); + return sema.fail(block, src, "TODO implement support for vectors in zirBitwise", .{}); } else if (lhs_ty.zigTypeTag() == .Vector or rhs_ty.zigTypeTag() == .Vector) { - return sema.mod.fail(&block.base, src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{ + return sema.fail(block, src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{ lhs_ty, rhs_ty, }); @@ -6032,7 +6156,7 @@ fn zirBitwise( const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; if (!is_int) { - return sema.mod.fail(&block.base, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) }); + return sema.fail(block, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) }); } if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| { @@ -6056,7 +6180,7 @@ fn zirBitNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro defer tracy.end(); _ = inst; - return sema.mod.fail(&block.base, sema.src, "TODO implement zirBitNot", .{}); + return sema.fail(block, sema.src, "TODO implement zirBitNot", .{}); } fn zirArrayCat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -6073,11 +6197,11 @@ fn zirArrayCat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; const lhs_info = getArrayCatInfo(lhs_ty) orelse - return sema.mod.fail(&block.base, lhs_src, "expected array, found '{}'", .{lhs_ty}); + return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty}); const rhs_info = getArrayCatInfo(rhs_ty) orelse - return sema.mod.fail(&block.base, rhs_src, "expected array, found '{}'", .{rhs_ty}); + return sema.fail(block, rhs_src, "expected array, found '{}'", .{rhs_ty}); if (!lhs_info.elem_type.eql(rhs_info.elem_type)) { - return sema.mod.fail(&block.base, rhs_src, "expected array of type '{}', found '{}'", .{ lhs_info.elem_type, rhs_ty }); + return sema.fail(block, rhs_src, "expected array of type '{}', found '{}'", .{ lhs_info.elem_type, rhs_ty }); } // When there is a sentinel mismatch, no sentinel on the result. The type system @@ -6123,10 +6247,10 @@ fn zirArrayCat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr else sema.analyzeDeclVal(block, .unneeded, try anon_decl.finish(ty, val)); } else { - return sema.mod.fail(&block.base, lhs_src, "TODO runtime array_cat", .{}); + return sema.fail(block, lhs_src, "TODO runtime array_cat", .{}); } } else { - return sema.mod.fail(&block.base, lhs_src, "TODO runtime array_cat", .{}); + return sema.fail(block, lhs_src, "TODO runtime array_cat", .{}); } } @@ -6157,9 +6281,9 @@ fn zirArrayMul(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr // In `**` rhs has to be comptime-known, but lhs can be runtime-known const tomulby = try sema.resolveInt(block, rhs_src, extra.rhs, Type.initTag(.usize)); const mulinfo = getArrayCatInfo(lhs_ty) orelse - return sema.mod.fail(&block.base, lhs_src, "expected array, found '{}'", .{lhs_ty}); + return sema.fail(block, lhs_src, "expected array, found '{}'", .{lhs_ty}); - const final_len = std.math.mul(u64, mulinfo.len, tomulby) catch return sema.mod.fail(&block.base, rhs_src, "operation results in overflow", .{}); + const final_len = std.math.mul(u64, mulinfo.len, tomulby) catch return sema.fail(block, rhs_src, "operation results in overflow", .{}); if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| { var anon_decl = try block.startAnonDecl(); defer anon_decl.deinit(); @@ -6192,7 +6316,7 @@ fn zirArrayMul(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr return sema.analyzeDeclVal(block, .unneeded, try anon_decl.finish(final_ty, val)); } } - return sema.mod.fail(&block.base, lhs_src, "TODO runtime array_mul", .{}); + return sema.fail(block, lhs_src, "TODO runtime array_mul", .{}); } fn zirNegate( @@ -6245,7 +6369,7 @@ fn zirOverflowArithmetic( const extra = sema.code.extraData(Zir.Inst.OverflowArithmetic, extended.operand).data; const src: LazySrcLoc = .{ .node_offset = extra.node }; - return sema.mod.fail(&block.base, src, "TODO implement Sema.zirOverflowArithmetic", .{}); + return sema.fail(block, src, "TODO implement Sema.zirOverflowArithmetic", .{}); } fn analyzeArithmetic( @@ -6265,13 +6389,13 @@ fn analyzeArithmetic( const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(); if (lhs_zig_ty_tag == .Vector and rhs_zig_ty_tag == .Vector) { if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) { - return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{ + return sema.fail(block, src, "vector length mismatch: {d} and {d}", .{ lhs_ty.arrayLen(), rhs_ty.arrayLen(), }); } - return sema.mod.fail(&block.base, src, "TODO implement support for vectors in Sema.analyzeArithmetic", .{}); + return sema.fail(block, src, "TODO implement support for vectors in Sema.analyzeArithmetic", .{}); } else if (lhs_zig_ty_tag == .Vector or rhs_zig_ty_tag == .Vector) { - return sema.mod.fail(&block.base, src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{ + return sema.fail(block, src, "mixed scalar and vector operands to binary expression: '{}' and '{}'", .{ lhs_ty, rhs_ty, }); } @@ -6283,8 +6407,8 @@ fn analyzeArithmetic( const air_tag: Air.Inst.Tag = switch (zir_tag) { .add => .ptr_add, .sub => .ptr_sub, - else => return sema.mod.fail( - &block.base, + else => return sema.fail( + block, op_src, "invalid pointer arithmetic operand: '{s}''", .{@tagName(zir_tag)}, @@ -6298,7 +6422,7 @@ fn analyzeArithmetic( if (try sema.resolveDefinedValue(block, rhs_src, casted_rhs)) |rhs_val| { _ = lhs_val; _ = rhs_val; - return sema.mod.fail(&block.base, src, "TODO implement Sema for comptime pointer arithmetic", .{}); + return sema.fail(block, src, "TODO implement Sema for comptime pointer arithmetic", .{}); } else { break :runtime_src rhs_src; } @@ -6329,7 +6453,7 @@ fn analyzeArithmetic( const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat; if (!is_int and !(is_float and floatOpAllowed(zir_tag))) { - return sema.mod.fail(&block.base, src, "invalid operands to binary expression: '{s}' and '{s}'", .{ + return sema.fail(block, src, "invalid operands to binary expression: '{s}' and '{s}'", .{ @tagName(lhs_zig_ty_tag), @tagName(rhs_zig_ty_tag), }); } @@ -6939,7 +7063,7 @@ fn zirAsm( const clobbers_len = @truncate(u5, extended.small >> 10); if (outputs_len > 1) { - return sema.mod.fail(&block.base, src, "TODO implement Sema for asm with more than 1 output", .{}); + return sema.fail(block, src, "TODO implement Sema for asm with more than 1 output", .{}); } var extra_i = extra.end; @@ -6954,7 +7078,7 @@ fn zirAsm( output_type_bits >>= 1; if (!is_type) { - return sema.mod.fail(&block.base, src, "TODO implement Sema for asm with non `->` output", .{}); + return sema.fail(block, src, "TODO implement Sema for asm with non `->` output", .{}); } const constraint = sema.code.nullTerminatedString(output.data.constraint); @@ -7011,7 +7135,6 @@ fn zirCmpEq( const tracy = trace(@src()); defer tracy.end(); - const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; const src: LazySrcLoc = inst_data.src(); @@ -7040,11 +7163,11 @@ fn zirCmpEq( return sema.analyzeIsNull(block, src, opt_operand, op == .neq); } if (((lhs_ty_tag == .Null and rhs_ty.isCPtr()) or (rhs_ty_tag == .Null and lhs_ty.isCPtr()))) { - return mod.fail(&block.base, src, "TODO implement C pointer cmp", .{}); + return sema.fail(block, src, "TODO implement C pointer cmp", .{}); } if (lhs_ty_tag == .Null or rhs_ty_tag == .Null) { const non_null_type = if (lhs_ty_tag == .Null) rhs_ty else lhs_ty; - return mod.fail(&block.base, src, "comparison of '{}' with null", .{non_null_type}); + return sema.fail(block, src, "comparison of '{}' with null", .{non_null_type}); } if (lhs_ty_tag == .EnumLiteral and rhs_ty_tag == .Union) { return sema.analyzeCmpUnionTag(block, rhs, rhs_src, lhs, lhs_src, op); @@ -7103,7 +7226,7 @@ fn analyzeCmpUnionTag( const union_ty = sema.typeOf(un); const union_tag_ty = union_ty.unionTagType() orelse { // TODO note at declaration site that says "union foo is not tagged" - return sema.mod.fail(&block.base, un_src, "comparison of union and enum literal is only valid for tagged union types", .{}); + return sema.fail(block, un_src, "comparison of union and enum literal is only valid for tagged union types", .{}); }; // Coerce both the union and the tag to the union's tag type, and then execute the // enum comparison codepath. @@ -7155,7 +7278,7 @@ fn analyzeCmp( const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; const resolved_type = try sema.resolvePeerTypes(block, src, instructions, .{ .override = &[_]LazySrcLoc{ lhs_src, rhs_src } }); if (!resolved_type.isSelfComparable(is_equality_cmp)) { - return sema.mod.fail(&block.base, src, "{s} operator not allowed for type '{}'", .{ + return sema.fail(block, src, "{s} operator not allowed for type '{}'", .{ @tagName(op), resolved_type, }); } @@ -7252,7 +7375,7 @@ fn zirSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro .Null, .BoundFn, .Opaque, - => return sema.mod.fail(&block.base, src, "no size available for type '{}'", .{operand_ty}), + => return sema.fail(block, src, "no size available for type '{}'", .{operand_ty}), .Type, .EnumLiteral, .ComptimeFloat, @@ -7340,7 +7463,7 @@ fn zirRetAddr( extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; - return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirRetAddr", .{}); + return sema.fail(block, src, "TODO: implement Sema.zirRetAddr", .{}); } fn zirBuiltinSrc( @@ -7349,7 +7472,7 @@ fn zirBuiltinSrc( extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; - return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirBuiltinSrc", .{}); + return sema.fail(block, src, "TODO: implement Sema.zirBuiltinSrc", .{}); } fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -7551,7 +7674,7 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr }), ); }, - else => |t| return sema.mod.fail(&block.base, src, "TODO: implement zirTypeInfo for {s}", .{ + else => |t| return sema.fail(block, src, "TODO: implement zirTypeInfo for {s}", .{ @tagName(t), }), } @@ -7601,8 +7724,8 @@ fn log2IntType(sema: *Sema, block: *Scope.Block, operand: Type, src: LazySrcLoc) const res = try Module.makeIntType(sema.arena, .unsigned, count); return sema.addType(res); }, - else => return sema.mod.fail( - &block.base, + else => return sema.fail( + block, src, "bit shifting operation expected integer type, found '{}'", .{operand}, @@ -8026,7 +8149,7 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr } else 0; if (bit_end != 0 and bit_start >= bit_end * 8) - return sema.mod.fail(&block.base, src, "bit offset starts after end of host integer", .{}); + return sema.fail(block, src, "bit offset starts after end of host integer", .{}); const elem_type = try sema.resolveType(block, .unneeded, extra.data.elem_type); @@ -8059,11 +8182,10 @@ fn zirStructInitEmpty(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co fn zirUnionInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirUnionInitPtr", .{}); + return sema.fail(block, src, "TODO: Sema.zirUnionInitPtr", .{}); } fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) CompileError!Air.Inst.Ref { - const mod = sema.mod; const gpa = sema.gpa; const zir_datas = sema.code.instructions.items(.data); const inst_data = zir_datas[inst].pl_node; @@ -8107,12 +8229,12 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: const other_field_type_data = zir_datas[other_field_type].pl_node; const other_field_src: LazySrcLoc = .{ .node_offset_back2tok = other_field_type_data.src_node }; const msg = msg: { - const msg = try mod.errMsg(&block.base, field_src, "duplicate field", .{}); + const msg = try sema.errMsg(block, field_src, "duplicate field", .{}); errdefer msg.destroy(gpa); - try mod.errNote(&block.base, other_field_src, msg, "other field here", .{}); + try sema.errNote(block, other_field_src, msg, "other field here", .{}); break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } found_fields[field_index] = item.data.field_type; field_inits[field_index] = sema.resolveInst(item.data.init); @@ -8130,9 +8252,9 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: const template = "missing struct field: {s}"; const args = .{field_name}; if (root_msg) |msg| { - try mod.errNote(&block.base, src, msg, template, args); + try sema.errNote(block, src, msg, template, args); } else { - root_msg = try mod.errMsg(&block.base, src, template, args); + root_msg = try sema.errMsg(block, src, template, args); } } else { field_inits[i] = try sema.addConstant(field.ty, field.default_val); @@ -8141,17 +8263,17 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: if (root_msg) |msg| { const fqn = try struct_obj.getFullyQualifiedName(gpa); defer gpa.free(fqn); - try mod.errNoteNonLazy( + try sema.mod.errNoteNonLazy( struct_obj.srcLoc(), msg, "struct '{s}' declared here", .{fqn}, ); - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } if (is_ref) { - return mod.fail(&block.base, src, "TODO: Sema.zirStructInit is_ref=true", .{}); + return sema.fail(block, src, "TODO: Sema.zirStructInit is_ref=true", .{}); } const is_comptime = for (field_inits) |field_init| { @@ -8168,12 +8290,12 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: return sema.addConstant(resolved_ty, try Value.Tag.@"struct".create(sema.arena, values)); } - return mod.fail(&block.base, src, "TODO: Sema.zirStructInit for runtime-known struct values", .{}); + return sema.fail(block, src, "TODO: Sema.zirStructInit for runtime-known struct values", .{}); } else if (resolved_ty.cast(Type.Payload.Union)) |union_payload| { const union_obj = union_payload.data; if (extra.data.fields_len != 1) { - return sema.mod.fail(&block.base, src, "union initialization expects exactly one field", .{}); + return sema.fail(block, src, "union initialization expects exactly one field", .{}); } const item = sema.code.extraData(Zir.Inst.StructInit.Item, extra.end); @@ -8186,7 +8308,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name); if (is_ref) { - return mod.fail(&block.base, src, "TODO: Sema.zirStructInit is_ref=true union", .{}); + return sema.fail(block, src, "TODO: Sema.zirStructInit is_ref=true union", .{}); } const init_inst = sema.resolveInst(item.data.init); @@ -8199,7 +8321,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: }), ); } - return mod.fail(&block.base, src, "TODO: Sema.zirStructInit for runtime-known union values", .{}); + return sema.fail(block, src, "TODO: Sema.zirStructInit for runtime-known union values", .{}); } unreachable; } @@ -8209,7 +8331,7 @@ fn zirStructInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ const src = inst_data.src(); _ = is_ref; - return sema.mod.fail(&block.base, src, "TODO: Sema.zirStructInitAnon", .{}); + return sema.fail(block, src, "TODO: Sema.zirStructInitAnon", .{}); } fn zirArrayInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) CompileError!Air.Inst.Ref { @@ -8269,13 +8391,13 @@ fn zirArrayInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_r const src = inst_data.src(); _ = is_ref; - return sema.mod.fail(&block.base, src, "TODO: Sema.zirArrayInitAnon", .{}); + return sema.fail(block, src, "TODO: Sema.zirArrayInitAnon", .{}); } fn zirFieldTypeRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirFieldTypeRef", .{}); + return sema.fail(block, src, "TODO: Sema.zirFieldTypeRef", .{}); } fn zirFieldType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -8298,7 +8420,7 @@ fn zirFieldType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE return sema.failWithBadUnionFieldAccess(block, union_obj, src, field_name); return sema.addType(field.ty); }, - else => return sema.mod.fail(&block.base, src, "expected struct or union; found '{}'", .{ + else => return sema.fail(block, src, "expected struct or union; found '{}'", .{ resolved_ty, }), } @@ -8310,7 +8432,7 @@ fn zirErrorReturnTrace( extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; - return sema.mod.fail(&block.base, src, "TODO: Sema.zirErrorReturnTrace", .{}); + return sema.fail(block, src, "TODO: Sema.zirErrorReturnTrace", .{}); } fn zirFrame( @@ -8319,7 +8441,7 @@ fn zirFrame( extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; - return sema.mod.fail(&block.base, src, "TODO: Sema.zirFrame", .{}); + return sema.fail(block, src, "TODO: Sema.zirFrame", .{}); } fn zirFrameAddress( @@ -8328,7 +8450,7 @@ fn zirFrameAddress( extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; - return sema.mod.fail(&block.base, src, "TODO: Sema.zirFrameAddress", .{}); + return sema.fail(block, src, "TODO: Sema.zirFrameAddress", .{}); } fn zirAlignOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -8355,25 +8477,25 @@ fn zirBoolToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE fn zirEmbedFile(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirEmbedFile", .{}); + return sema.fail(block, src, "TODO: Sema.zirEmbedFile", .{}); } fn zirErrorName(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirErrorName", .{}); + return sema.fail(block, src, "TODO: Sema.zirErrorName", .{}); } fn zirUnaryMath(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirUnaryMath", .{}); + return sema.fail(block, src, "TODO: Sema.zirUnaryMath", .{}); } fn zirTagName(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirTagName", .{}); + return sema.fail(block, src, "TODO: Sema.zirTagName", .{}); } fn zirReify(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -8406,25 +8528,25 @@ fn zirReify(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError }; return sema.addType(ty); }, - .Float => return sema.mod.fail(&block.base, src, "TODO: Sema.zirReify for Float", .{}), - .Pointer => return sema.mod.fail(&block.base, src, "TODO: Sema.zirReify for Pointer", .{}), - .Array => return sema.mod.fail(&block.base, src, "TODO: Sema.zirReify for Array", .{}), - .Struct => return sema.mod.fail(&block.base, src, "TODO: Sema.zirReify for Struct", .{}), + .Float => return sema.fail(block, src, "TODO: Sema.zirReify for Float", .{}), + .Pointer => return sema.fail(block, src, "TODO: Sema.zirReify for Pointer", .{}), + .Array => return sema.fail(block, src, "TODO: Sema.zirReify for Array", .{}), + .Struct => return sema.fail(block, src, "TODO: Sema.zirReify for Struct", .{}), .ComptimeFloat => return Air.Inst.Ref.comptime_float_type, .ComptimeInt => return Air.Inst.Ref.comptime_int_type, .Undefined => return Air.Inst.Ref.undefined_type, .Null => return Air.Inst.Ref.null_type, - .Optional => return sema.mod.fail(&block.base, src, "TODO: Sema.zirReify for Optional", .{}), - .ErrorUnion => return sema.mod.fail(&block.base, src, "TODO: Sema.zirReify for ErrorUnion", .{}), - .ErrorSet => return sema.mod.fail(&block.base, src, "TODO: Sema.zirReify for ErrorSet", .{}), - .Enum => return sema.mod.fail(&block.base, src, "TODO: Sema.zirReify for Enum", .{}), - .Union => return sema.mod.fail(&block.base, src, "TODO: Sema.zirReify for Union", .{}), - .Fn => return sema.mod.fail(&block.base, src, "TODO: Sema.zirReify for Fn", .{}), + .Optional => return sema.fail(block, src, "TODO: Sema.zirReify for Optional", .{}), + .ErrorUnion => return sema.fail(block, src, "TODO: Sema.zirReify for ErrorUnion", .{}), + .ErrorSet => return sema.fail(block, src, "TODO: Sema.zirReify for ErrorSet", .{}), + .Enum => return sema.fail(block, src, "TODO: Sema.zirReify for Enum", .{}), + .Union => return sema.fail(block, src, "TODO: Sema.zirReify for Union", .{}), + .Fn => return sema.fail(block, src, "TODO: Sema.zirReify for Fn", .{}), .BoundFn => @panic("TODO delete BoundFn from the language"), - .Opaque => return sema.mod.fail(&block.base, src, "TODO: Sema.zirReify for Opaque", .{}), - .Frame => return sema.mod.fail(&block.base, src, "TODO: Sema.zirReify for Frame", .{}), + .Opaque => return sema.fail(block, src, "TODO: Sema.zirReify for Opaque", .{}), + .Frame => return sema.fail(block, src, "TODO: Sema.zirReify for Frame", .{}), .AnyFrame => return Air.Inst.Ref.anyframe_type, - .Vector => return sema.mod.fail(&block.base, src, "TODO: Sema.zirReify for Vector", .{}), + .Vector => return sema.fail(block, src, "TODO: Sema.zirReify for Vector", .{}), .EnumLiteral => return Air.Inst.Ref.enum_literal_type, } } @@ -8432,26 +8554,26 @@ fn zirReify(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError fn zirTypeName(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirTypeName", .{}); + return sema.fail(block, src, "TODO: Sema.zirTypeName", .{}); } fn zirFrameType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirFrameType", .{}); + return sema.fail(block, src, "TODO: Sema.zirFrameType", .{}); } fn zirFrameSize(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirFrameSize", .{}); + return sema.fail(block, src, "TODO: Sema.zirFrameSize", .{}); } fn zirFloatToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); // TODO don't forget the safety check! - return sema.mod.fail(&block.base, src, "TODO: Sema.zirFloatToInt", .{}); + return sema.fail(block, src, "TODO: Sema.zirFloatToInt", .{}); } fn zirIntToFloat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -8489,15 +8611,15 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr const type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const type_res = try sema.resolveType(block, src, extra.lhs); if (type_res.zigTypeTag() != .Pointer) - return sema.mod.fail(&block.base, type_src, "expected pointer, found '{}'", .{type_res}); + return sema.fail(block, type_src, "expected pointer, found '{}'", .{type_res}); const ptr_align = type_res.ptrAlignment(sema.mod.getTarget()); if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| { const addr = val.toUnsignedInt(); if (!type_res.isAllowzeroPtr() and addr == 0) - return sema.mod.fail(&block.base, operand_src, "pointer type '{}' does not allow address zero", .{type_res}); + return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{type_res}); if (addr != 0 and addr % ptr_align != 0) - return sema.mod.fail(&block.base, operand_src, "pointer type '{}' requires aligned address", .{type_res}); + return sema.fail(block, operand_src, "pointer type '{}' requires aligned address", .{type_res}); const val_payload = try sema.arena.create(Value.Payload.U64); val_payload.* = .{ @@ -8535,7 +8657,7 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr fn zirErrSetCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirErrSetCast", .{}); + return sema.fail(block, src, "TODO: Sema.zirErrSetCast", .{}); } fn zirPtrCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -8547,12 +8669,12 @@ fn zirPtrCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr const operand = sema.resolveInst(extra.rhs); const operand_ty = sema.typeOf(operand); if (operand_ty.zigTypeTag() != .Pointer) { - return sema.mod.fail(&block.base, operand_src, "expected pointer, found {s} type '{}'", .{ + return sema.fail(block, operand_src, "expected pointer, found {s} type '{}'", .{ @tagName(operand_ty.zigTypeTag()), operand_ty, }); } if (dest_ty.zigTypeTag() != .Pointer) { - return sema.mod.fail(&block.base, dest_ty_src, "expected pointer, found {s} type '{}'", .{ + return sema.fail(block, dest_ty_src, "expected pointer, found {s} type '{}'", .{ @tagName(dest_ty.zigTypeTag()), dest_ty, }); } @@ -8571,7 +8693,6 @@ fn zirTruncate(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs); const operand = sema.resolveInst(extra.rhs); const operand_ty = sema.typeOf(operand); - const mod = sema.mod; const dest_is_comptime_int = try sema.checkIntType(block, dest_ty_src, dest_ty); const src_is_comptime_int = try sema.checkIntType(block, operand_src, operand_ty); @@ -8579,7 +8700,7 @@ fn zirTruncate(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr return sema.coerce(block, dest_ty, operand, operand_src); } - const target = mod.getTarget(); + const target = sema.mod.getTarget(); const src_info = operand_ty.intInfo(target); const dest_info = dest_ty.intInfo(target); @@ -8589,28 +8710,28 @@ fn zirTruncate(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr if (!src_is_comptime_int) { if (src_info.signedness != dest_info.signedness) { - return mod.fail(&block.base, operand_src, "expected {s} integer type, found '{}'", .{ + return sema.fail(block, operand_src, "expected {s} integer type, found '{}'", .{ @tagName(dest_info.signedness), operand_ty, }); } if (src_info.bits > 0 and src_info.bits < dest_info.bits) { const msg = msg: { - const msg = try mod.errMsg( - &block.base, + const msg = try sema.errMsg( + block, src, "destination type '{}' has more bits than source type '{}'", .{ dest_ty, operand_ty }, ); - errdefer msg.destroy(mod.gpa); - try mod.errNote(&block.base, dest_ty_src, msg, "destination type has {d} bits", .{ + errdefer msg.destroy(sema.gpa); + try sema.errNote(block, dest_ty_src, msg, "destination type has {d} bits", .{ dest_info.bits, }); - try mod.errNote(&block.base, operand_src, msg, "source type has {d} bits", .{ + try sema.errNote(block, operand_src, msg, "source type has {d} bits", .{ src_info.bits, }); break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } } @@ -8626,7 +8747,7 @@ fn zirTruncate(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr fn zirAlignCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirAlignCast", .{}); + return sema.fail(block, src, "TODO: Sema.zirAlignCast", .{}); } fn zirClz(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -8637,7 +8758,7 @@ fn zirClz(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A const operand_ty = sema.typeOf(operand); // TODO implement support for vectors if (operand_ty.zigTypeTag() != .Int) { - return sema.mod.fail(&block.base, ty_src, "expected integer type, found '{}'", .{ + return sema.fail(block, ty_src, "expected integer type, found '{}'", .{ operand_ty, }); } @@ -8664,7 +8785,7 @@ fn zirCtz(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A const operand_ty = sema.typeOf(operand); // TODO implement support for vectors if (operand_ty.zigTypeTag() != .Int) { - return sema.mod.fail(&block.base, ty_src, "expected integer type, found '{}'", .{ + return sema.fail(block, ty_src, "expected integer type, found '{}'", .{ operand_ty, }); } @@ -8676,7 +8797,7 @@ fn zirCtz(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A const runtime_src = if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { if (val.isUndef()) return sema.addConstUndef(result_ty); - return sema.mod.fail(&block.base, operand_src, "TODO: implement comptime @ctz", .{}); + return sema.fail(block, operand_src, "TODO: implement comptime @ctz", .{}); } else operand_src; try sema.requireRuntimeBlock(block, runtime_src); @@ -8686,55 +8807,55 @@ fn zirCtz(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A fn zirPopCount(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirPopCount", .{}); + return sema.fail(block, src, "TODO: Sema.zirPopCount", .{}); } fn zirByteSwap(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirByteSwap", .{}); + return sema.fail(block, src, "TODO: Sema.zirByteSwap", .{}); } fn zirBitReverse(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirBitReverse", .{}); + return sema.fail(block, src, "TODO: Sema.zirBitReverse", .{}); } fn zirDivExact(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirDivExact", .{}); + return sema.fail(block, src, "TODO: Sema.zirDivExact", .{}); } fn zirDivFloor(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirDivFloor", .{}); + return sema.fail(block, src, "TODO: Sema.zirDivFloor", .{}); } fn zirDivTrunc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirDivTrunc", .{}); + return sema.fail(block, src, "TODO: Sema.zirDivTrunc", .{}); } fn zirShrExact(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirShrExact", .{}); + return sema.fail(block, src, "TODO: Sema.zirShrExact", .{}); } fn zirBitOffsetOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirBitOffsetOf", .{}); + return sema.fail(block, src, "TODO: Sema.zirBitOffsetOf", .{}); } fn zirOffsetOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirOffsetOf", .{}); + return sema.fail(block, src, "TODO: Sema.zirOffsetOf", .{}); } /// Returns `true` if the type was a comptime_int. @@ -8742,7 +8863,7 @@ fn checkIntType(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type) Com switch (ty.zigTypeTag()) { .ComptimeInt => return true, .Int => return false, - else => return sema.mod.fail(&block.base, src, "expected integer type, found '{}'", .{ty}), + else => return sema.fail(block, src, "expected integer type, found '{}'", .{ty}), } } @@ -8754,7 +8875,7 @@ fn checkFloatType( ) CompileError!void { switch (ty.zigTypeTag()) { .ComptimeFloat, .Float => {}, - else => return sema.mod.fail(&block.base, ty_src, "expected float type, found '{}'", .{ + else => return sema.fail(block, ty_src, "expected float type, found '{}'", .{ ty, }), } @@ -8775,8 +8896,8 @@ fn checkAtomicOperandType( .Float => { const bit_count = ty.floatBits(target); if (bit_count > max_atomic_bits) { - return sema.mod.fail( - &block.base, + return sema.fail( + block, ty_src, "expected {d}-bit float type or smaller; found {d}-bit float type", .{ max_atomic_bits, bit_count }, @@ -8788,8 +8909,8 @@ fn checkAtomicOperandType( else => { if (ty.isPtrAtRuntime()) return; - return sema.mod.fail( - &block.base, + return sema.fail( + block, ty_src, "expected bool, integer, float, enum, or pointer type; found {}", .{ty}, @@ -8798,8 +8919,8 @@ fn checkAtomicOperandType( }; const bit_count = int_ty.intInfo(target).bits; if (bit_count > max_atomic_bits) { - return sema.mod.fail( - &block.base, + return sema.fail( + block, ty_src, "expected {d}-bit integer type or smaller; found {d}-bit integer type", .{ max_atomic_bits, bit_count }, @@ -8823,7 +8944,7 @@ fn resolveExportOptions( const linkage_index = struct_obj.fields.getIndex("linkage").?; const section_index = struct_obj.fields.getIndex("section").?; if (!fields[section_index].isNull()) { - return sema.mod.fail(&block.base, src, "TODO: implement exporting with linksection", .{}); + return sema.fail(block, src, "TODO: implement exporting with linksection", .{}); } return std.builtin.ExportOptions{ .name = try fields[name_index].toAllocatedBytes(sema.arena), @@ -8864,7 +8985,6 @@ fn zirCmpxchg( inst: Zir.Inst.Index, air_tag: Air.Inst.Tag, ) CompileError!Air.Inst.Ref { - const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const extra = sema.code.extraData(Zir.Inst.Cmpxchg, inst_data.payload_index).data; const src = inst_data.src(); @@ -8880,8 +9000,8 @@ fn zirCmpxchg( const elem_ty = sema.typeOf(ptr).elemType(); try sema.checkAtomicOperandType(block, elem_ty_src, elem_ty); if (elem_ty.zigTypeTag() == .Float) { - return mod.fail( - &block.base, + return sema.fail( + block, elem_ty_src, "expected bool, integer, enum, or pointer type; found '{}'", .{elem_ty}, @@ -8893,16 +9013,16 @@ fn zirCmpxchg( const failure_order = try sema.resolveAtomicOrder(block, failure_order_src, extra.failure_order); if (@enumToInt(success_order) < @enumToInt(std.builtin.AtomicOrder.Monotonic)) { - return mod.fail(&block.base, success_order_src, "success atomic ordering must be Monotonic or stricter", .{}); + return sema.fail(block, success_order_src, "success atomic ordering must be Monotonic or stricter", .{}); } if (@enumToInt(failure_order) < @enumToInt(std.builtin.AtomicOrder.Monotonic)) { - return mod.fail(&block.base, failure_order_src, "failure atomic ordering must be Monotonic or stricter", .{}); + return sema.fail(block, failure_order_src, "failure atomic ordering must be Monotonic or stricter", .{}); } if (@enumToInt(failure_order) > @enumToInt(success_order)) { - return mod.fail(&block.base, failure_order_src, "failure atomic ordering must be no stricter than success", .{}); + return sema.fail(block, failure_order_src, "failure atomic ordering must be no stricter than success", .{}); } if (failure_order == .Release or failure_order == .AcqRel) { - return mod.fail(&block.base, failure_order_src, "failure atomic ordering must not be Release or AcqRel", .{}); + return sema.fail(block, failure_order_src, "failure atomic ordering must not be Release or AcqRel", .{}); } const result_ty = try Module.optionalType(sema.arena, elem_ty); @@ -8952,25 +9072,25 @@ fn zirCmpxchg( fn zirSplat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirSplat", .{}); + return sema.fail(block, src, "TODO: Sema.zirSplat", .{}); } fn zirReduce(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirReduce", .{}); + return sema.fail(block, src, "TODO: Sema.zirReduce", .{}); } fn zirShuffle(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirShuffle", .{}); + return sema.fail(block, src, "TODO: Sema.zirShuffle", .{}); } fn zirSelect(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirSelect", .{}); + return sema.fail(block, src, "TODO: Sema.zirSelect", .{}); } fn zirAtomicLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -8988,8 +9108,8 @@ fn zirAtomicLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile switch (order) { .Release, .AcqRel => { - return sema.mod.fail( - &block.base, + return sema.fail( + block, order_src, "@atomicLoad atomic ordering must not be Release or AcqRel", .{}, @@ -9019,7 +9139,6 @@ fn zirAtomicLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile } fn zirAtomicRmw(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { - const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const extra = sema.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data; const src = inst_data.src(); @@ -9037,14 +9156,14 @@ fn zirAtomicRmw(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE switch (operand_ty.zigTypeTag()) { .Enum => if (op != .Xchg) { - return mod.fail(&block.base, op_src, "@atomicRmw with enum only allowed with .Xchg", .{}); + return sema.fail(block, op_src, "@atomicRmw with enum only allowed with .Xchg", .{}); }, .Bool => if (op != .Xchg) { - return mod.fail(&block.base, op_src, "@atomicRmw with bool only allowed with .Xchg", .{}); + return sema.fail(block, op_src, "@atomicRmw with bool only allowed with .Xchg", .{}); }, .Float => switch (op) { .Xchg, .Add, .Sub => {}, - else => return mod.fail(&block.base, op_src, "@atomicRmw with float only allowed with .Xchg, .Add, and .Sub", .{}), + else => return sema.fail(block, op_src, "@atomicRmw with float only allowed with .Xchg, .Add, and .Sub", .{}), }, else => {}, } @@ -9052,7 +9171,7 @@ fn zirAtomicRmw(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE const order = try sema.resolveAtomicOrder(block, order_src, extra.ordering); if (order == .Unordered) { - return mod.fail(&block.base, order_src, "@atomicRmw atomic ordering must not be Unordered", .{}); + return sema.fail(block, order_src, "@atomicRmw atomic ordering must not be Unordered", .{}); } // special case zero bit types @@ -9115,8 +9234,8 @@ fn zirAtomicStore(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil const air_tag: Air.Inst.Tag = switch (order) { .Acquire, .AcqRel => { - return sema.mod.fail( - &block.base, + return sema.fail( + block, order_src, "@atomicStore atomic ordering must not be Acquire or AcqRel", .{}, @@ -9134,31 +9253,31 @@ fn zirAtomicStore(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil fn zirMulAdd(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirMulAdd", .{}); + return sema.fail(block, src, "TODO: Sema.zirMulAdd", .{}); } fn zirBuiltinCall(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirBuiltinCall", .{}); + return sema.fail(block, src, "TODO: Sema.zirBuiltinCall", .{}); } fn zirFieldPtrType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirFieldPtrType", .{}); + return sema.fail(block, src, "TODO: Sema.zirFieldPtrType", .{}); } fn zirFieldParentPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirFieldParentPtr", .{}); + return sema.fail(block, src, "TODO: Sema.zirFieldParentPtr", .{}); } fn zirMaximum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirMaximum", .{}); + return sema.fail(block, src, "TODO: Sema.zirMaximum", .{}); } fn zirMemcpy(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { @@ -9172,16 +9291,16 @@ fn zirMemcpy(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro const dest_ptr_ty = sema.typeOf(dest_ptr); if (dest_ptr_ty.zigTypeTag() != .Pointer) { - return sema.mod.fail(&block.base, dest_src, "expected pointer, found '{}'", .{dest_ptr_ty}); + return sema.fail(block, dest_src, "expected pointer, found '{}'", .{dest_ptr_ty}); } if (dest_ptr_ty.isConstPtr()) { - return sema.mod.fail(&block.base, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty}); + return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty}); } const uncasted_src_ptr = sema.resolveInst(extra.source); const uncasted_src_ptr_ty = sema.typeOf(uncasted_src_ptr); if (uncasted_src_ptr_ty.zigTypeTag() != .Pointer) { - return sema.mod.fail(&block.base, src_src, "expected pointer, found '{}'", .{ + return sema.fail(block, src_src, "expected pointer, found '{}'", .{ uncasted_src_ptr_ty, }); } @@ -9208,7 +9327,7 @@ fn zirMemcpy(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro _ = dest_ptr_val; _ = src_ptr_val; _ = len_val; - return sema.mod.fail(&block.base, src, "TODO: Sema.zirMemcpy at comptime", .{}); + return sema.fail(block, src, "TODO: Sema.zirMemcpy at comptime", .{}); } else break :rs len_src; } else break :rs src_src; } else dest_src; @@ -9236,10 +9355,10 @@ fn zirMemset(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro const dest_ptr = sema.resolveInst(extra.dest); const dest_ptr_ty = sema.typeOf(dest_ptr); if (dest_ptr_ty.zigTypeTag() != .Pointer) { - return sema.mod.fail(&block.base, dest_src, "expected pointer, found '{}'", .{dest_ptr_ty}); + return sema.fail(block, dest_src, "expected pointer, found '{}'", .{dest_ptr_ty}); } if (dest_ptr_ty.isConstPtr()) { - return sema.mod.fail(&block.base, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty}); + return sema.fail(block, dest_src, "cannot store through const pointer '{}'", .{dest_ptr_ty}); } const elem_ty = dest_ptr_ty.elemType2(); const value = try sema.coerce(block, elem_ty, sema.resolveInst(extra.byte), value_src); @@ -9254,7 +9373,7 @@ fn zirMemset(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro _ = ptr_val; _ = len_val; _ = val; - return sema.mod.fail(&block.base, src, "TODO: Sema.zirMemset at comptime", .{}); + return sema.fail(block, src, "TODO: Sema.zirMemset at comptime", .{}); } else break :rs value_src; } else break :rs len_src; } else dest_src; @@ -9275,19 +9394,19 @@ fn zirMemset(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro fn zirMinimum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirMinimum", .{}); + return sema.fail(block, src, "TODO: Sema.zirMinimum", .{}); } fn zirBuiltinAsyncCall(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirBuiltinAsyncCall", .{}); + return sema.fail(block, src, "TODO: Sema.zirBuiltinAsyncCall", .{}); } fn zirResume(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirResume", .{}); + return sema.fail(block, src, "TODO: Sema.zirResume", .{}); } fn zirAwait( @@ -9300,7 +9419,7 @@ fn zirAwait( const src = inst_data.src(); _ = is_nosuspend; - return sema.mod.fail(&block.base, src, "TODO: Sema.zirAwait", .{}); + return sema.fail(block, src, "TODO: Sema.zirAwait", .{}); } fn zirVarExtended( @@ -9360,7 +9479,7 @@ fn zirVarExtended( if (lib_name != null) { // Look at the sema code for functions which has this logic, it just needs to // be extracted and shared by both var and func - return sema.mod.fail(&block.base, src, "TODO: handle var with lib_name in Sema", .{}); + return sema.fail(block, src, "TODO: handle var with lib_name in Sema", .{}); } const new_var = try sema.gpa.create(Module.Var); @@ -9496,7 +9615,7 @@ fn zirWasmMemorySize( ) CompileError!Air.Inst.Ref { const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; const src: LazySrcLoc = .{ .node_offset = extra.node }; - return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirWasmMemorySize", .{}); + return sema.fail(block, src, "TODO: implement Sema.zirWasmMemorySize", .{}); } fn zirWasmMemoryGrow( @@ -9506,7 +9625,7 @@ fn zirWasmMemoryGrow( ) CompileError!Air.Inst.Ref { const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; const src: LazySrcLoc = .{ .node_offset = extra.node }; - return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirWasmMemoryGrow", .{}); + return sema.fail(block, src, "TODO: implement Sema.zirWasmMemoryGrow", .{}); } fn zirBuiltinExtern( @@ -9516,12 +9635,12 @@ fn zirBuiltinExtern( ) CompileError!Air.Inst.Ref { const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; const src: LazySrcLoc = .{ .node_offset = extra.node }; - return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirBuiltinExtern", .{}); + return sema.fail(block, src, "TODO: implement Sema.zirBuiltinExtern", .{}); } fn requireFunctionBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void { if (sema.func == null) { - return sema.mod.fail(&block.base, src, "instruction illegal outside function body", .{}); + return sema.fail(block, src, "instruction illegal outside function body", .{}); } } @@ -9579,7 +9698,7 @@ fn validateVarType( }, } else unreachable; // TODO should not need else unreachable if (!ok) { - return sema.mod.fail(&block.base, src, "variable of type '{}' must be const or comptime", .{var_ty}); + return sema.fail(block, src, "variable of type '{}' must be const or comptime", .{var_ty}); } } @@ -9684,7 +9803,7 @@ fn panicWithMsg( const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty); const ptr_stack_trace_ty = try Type.ptr(arena, .{ .pointee_type = stack_trace_ty, - .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant), // TODO might need a place that is more dynamic + .@"addrspace" = target_util.defaultAddressSpace(mod.getTarget(), .global_constant), // TODO might need a place that is more dynamic }); const null_stack_trace = try sema.addConstant( try Module.optionalType(arena, ptr_stack_trace_ty), @@ -9730,7 +9849,7 @@ fn emitBackwardBranch(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void { sema.branch_count += 1; if (sema.branch_count > sema.branch_quota) { // TODO show the "called from here" stack - return sema.mod.fail(&block.base, src, "evaluation exceeded {d} backwards branches", .{sema.branch_quota}); + return sema.fail(block, src, "evaluation exceeded {d} backwards branches", .{sema.branch_quota}); } } @@ -9745,7 +9864,6 @@ fn fieldVal( // When editing this function, note that there is corresponding logic to be edited // in `fieldPtr`. This function takes a value and returns a value. - const mod = sema.mod; const arena = sema.arena; const object_src = src; // TODO better source location const object_ty = sema.typeOf(object); @@ -9758,8 +9876,8 @@ fn fieldVal( try Value.Tag.int_u64.create(arena, object_ty.arrayLen()), ); } else { - return mod.fail( - &block.base, + return sema.fail( + block, field_name_src, "no member named '{s}' in '{}'", .{ field_name, object_ty }, @@ -9773,8 +9891,8 @@ fn fieldVal( const result_ty = object_ty.slicePtrFieldType(buf); if (try sema.resolveMaybeUndefVal(block, object_src, object)) |val| { if (val.isUndef()) return sema.addConstUndef(result_ty); - return mod.fail( - &block.base, + return sema.fail( + block, field_name_src, "TODO implement comptime slice ptr", .{}, @@ -9794,8 +9912,8 @@ fn fieldVal( try sema.requireRuntimeBlock(block, src); return block.addTyOp(.slice_len, result_ty, object); } else { - return mod.fail( - &block.base, + return sema.fail( + block, field_name_src, "no member named '{s}' in '{}'", .{ field_name, object_ty }, @@ -9812,8 +9930,8 @@ fn fieldVal( try Value.Tag.int_u64.create(arena, ptr_child.arrayLen()), ); } else { - return mod.fail( - &block.base, + return sema.fail( + block, field_name_src, "no member named '{s}' in '{}'", .{ field_name, object_ty }, @@ -9850,10 +9968,10 @@ fn fieldVal( break :blk name; } } - return mod.fail(&block.base, src, "no error named '{s}' in '{}'", .{ + return sema.fail(block, src, "no error named '{s}' in '{}'", .{ field_name, child_type, }); - } else (try mod.getErrorValue(field_name)).key; + } else (try sema.mod.getErrorValue(field_name)).key; return sema.addConstant( try child_type.copy(arena), @@ -9873,7 +9991,7 @@ fn fieldVal( .Union => "union", else => unreachable, }; - return mod.fail(&block.base, src, "{s} '{}' has no member named '{s}'", .{ + return sema.fail(block, src, "{s} '{}' has no member named '{s}'", .{ kw_name, child_type, field_name, }); }, @@ -9885,14 +10003,14 @@ fn fieldVal( } const field_index = child_type.enumFieldIndex(field_name) orelse { const msg = msg: { - const msg = try mod.errMsg( - &block.base, + const msg = try sema.errMsg( + block, src, "enum '{}' has no member named '{s}'", .{ child_type, field_name }, ); errdefer msg.destroy(sema.gpa); - try mod.errNoteNonLazy( + try sema.mod.errNoteNonLazy( child_type.declSrcLoc(), msg, "enum declared here", @@ -9900,20 +10018,20 @@ fn fieldVal( ); break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); }; const field_index_u32 = @intCast(u32, field_index); const enum_val = try Value.Tag.enum_field_index.create(arena, field_index_u32); return sema.addConstant(try child_type.copy(arena), enum_val); }, - else => return mod.fail(&block.base, src, "type '{}' has no members", .{child_type}), + else => return sema.fail(block, src, "type '{}' has no members", .{child_type}), } }, .Struct => return sema.structFieldVal(block, src, object, field_name, field_name_src, object_ty), .Union => return sema.unionFieldVal(block, src, object, field_name, field_name_src, object_ty), else => {}, } - return mod.fail(&block.base, src, "type '{}' does not support field access", .{object_ty}); + return sema.fail(block, src, "type '{}' does not support field access", .{object_ty}); } fn fieldPtr( @@ -9927,12 +10045,11 @@ fn fieldPtr( // When editing this function, note that there is corresponding logic to be edited // in `fieldVal`. This function takes a pointer and returns a pointer. - const mod = sema.mod; const object_ptr_src = src; // TODO better source location const object_ptr_ty = sema.typeOf(object_ptr); const object_ty = switch (object_ptr_ty.zigTypeTag()) { .Pointer => object_ptr_ty.elemType(), - else => return mod.fail(&block.base, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty}), + else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty}), }; switch (object_ty.zigTypeTag()) { .Array => { @@ -9944,8 +10061,8 @@ fn fieldPtr( try Value.Tag.int_u64.create(anon_decl.arena(), object_ty.arrayLen()), )); } else { - return mod.fail( - &block.base, + return sema.fail( + block, field_name_src, "no member named '{s}' in '{}'", .{ field_name, object_ty }, @@ -9962,22 +10079,22 @@ fn fieldPtr( // the runtime value to it, and then return the `alloc`. // In both cases the pointer should be const. if (mem.eql(u8, field_name, "ptr")) { - return mod.fail( - &block.base, + return sema.fail( + block, field_name_src, "TODO: implement reference to 'ptr' field of slice '{}'", .{object_ty}, ); } else if (mem.eql(u8, field_name, "len")) { - return mod.fail( - &block.base, + return sema.fail( + block, field_name_src, "TODO: implement reference to 'len' field of slice '{}'", .{object_ty}, ); } else { - return mod.fail( - &block.base, + return sema.fail( + block, field_name_src, "no member named '{s}' in '{}'", .{ field_name, object_ty }, @@ -9996,8 +10113,8 @@ fn fieldPtr( try Value.Tag.int_u64.create(anon_decl.arena(), ptr_child.arrayLen()), )); } else { - return mod.fail( - &block.base, + return sema.fail( + block, field_name_src, "no member named '{s}' in '{}'", .{ field_name, object_ty }, @@ -10036,10 +10153,10 @@ fn fieldPtr( break :blk name; } } - return mod.fail(&block.base, src, "no error named '{s}' in '{}'", .{ + return sema.fail(block, src, "no error named '{s}' in '{}'", .{ field_name, child_type, }); - } else (try mod.getErrorValue(field_name)).key; + } else (try sema.mod.getErrorValue(field_name)).key; var anon_decl = try block.startAnonDecl(); defer anon_decl.deinit(); @@ -10061,7 +10178,7 @@ fn fieldPtr( .Union => "union", else => unreachable, }; - return mod.fail(&block.base, src, "{s} '{}' has no member named '{s}'", .{ + return sema.fail(block, src, "{s} '{}' has no member named '{s}'", .{ kw_name, child_type, field_name, }); }, @@ -10073,14 +10190,14 @@ fn fieldPtr( } const field_index = child_type.enumFieldIndex(field_name) orelse { const msg = msg: { - const msg = try mod.errMsg( - &block.base, + const msg = try sema.errMsg( + block, src, "enum '{}' has no member named '{s}'", .{ child_type, field_name }, ); errdefer msg.destroy(sema.gpa); - try mod.errNoteNonLazy( + try sema.mod.errNoteNonLazy( child_type.declSrcLoc(), msg, "enum declared here", @@ -10088,7 +10205,7 @@ fn fieldPtr( ); break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); }; const field_index_u32 = @intCast(u32, field_index); var anon_decl = try block.startAnonDecl(); @@ -10098,14 +10215,14 @@ fn fieldPtr( try Value.Tag.enum_field_index.create(anon_decl.arena(), field_index_u32), )); }, - else => return mod.fail(&block.base, src, "type '{}' has no members", .{child_type}), + else => return sema.fail(block, src, "type '{}' has no members", .{child_type}), } }, .Struct => return sema.structFieldPtr(block, src, object_ptr, field_name, field_name_src, object_ty), .Union => return sema.unionFieldPtr(block, src, object_ptr, field_name, field_name_src, object_ty), else => {}, } - return mod.fail(&block.base, src, "type '{}' does not support field access", .{object_ty}); + return sema.fail(block, src, "type '{}' does not support field access", .{object_ty}); } fn fieldCallBind( @@ -10119,13 +10236,12 @@ fn fieldCallBind( // When editing this function, note that there is corresponding logic to be edited // in `fieldVal`. This function takes a pointer and returns a pointer. - const mod = sema.mod; const raw_ptr_src = src; // TODO better source location const raw_ptr_ty = sema.typeOf(raw_ptr); const inner_ty = if (raw_ptr_ty.zigTypeTag() == .Pointer and raw_ptr_ty.ptrSize() == .One) raw_ptr_ty.childType() else - return mod.fail(&block.base, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty}); + return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty}); // Optionally dereference a second pointer to get the concrete type. const is_double_ptr = inner_ty.zigTypeTag() == .Pointer and inner_ty.ptrSize() == .One; @@ -10194,7 +10310,7 @@ fn fieldCallBind( }; return sema.analyzeLoad(block, src, ptr_inst, src); }, - .Union => return sema.mod.fail(&block.base, src, "TODO implement field calls on unions", .{}), + .Union => return sema.fail(block, src, "TODO implement field calls on unions", .{}), .Type => { const namespace = try sema.analyzeLoad(block, src, object_ptr, src); return sema.fieldVal(block, src, namespace, field_name, field_name_src); @@ -10247,7 +10363,7 @@ fn fieldCallBind( else => {}, } - return mod.fail(&block.base, src, "type '{}' has no field or member function named '{s}'", .{ concrete_ty, field_name }); + return sema.fail(block, src, "type '{}' has no field or member function named '{s}'", .{ concrete_ty, field_name }); } fn namespaceLookup( @@ -10257,19 +10373,18 @@ fn namespaceLookup( namespace: *Scope.Namespace, decl_name: []const u8, ) CompileError!?*Decl { - const mod = sema.mod; const gpa = sema.gpa; if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl| { if (!decl.is_pub and decl.getFileScope() != block.getFileScope()) { const msg = msg: { - const msg = try mod.errMsg(&block.base, src, "'{s}' is not marked 'pub'", .{ + const msg = try sema.errMsg(block, src, "'{s}' is not marked 'pub'", .{ decl_name, }); errdefer msg.destroy(gpa); - try mod.errNoteNonLazy(decl.srcLoc(), msg, "declared here", .{}); + try sema.mod.errNoteNonLazy(decl.srcLoc(), msg, "declared here", .{}); break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } return decl; } @@ -10435,7 +10550,7 @@ fn unionFieldVal( } try sema.requireRuntimeBlock(block, src); - return sema.mod.fail(&block.base, src, "TODO implement runtime union field access", .{}); + return sema.fail(block, src, "TODO implement runtime union field access", .{}); } fn elemPtr( @@ -10450,10 +10565,10 @@ fn elemPtr( const array_ptr_ty = sema.typeOf(array_ptr); const array_ty = switch (array_ptr_ty.zigTypeTag()) { .Pointer => array_ptr_ty.elemType(), - else => return sema.mod.fail(&block.base, array_ptr_src, "expected pointer, found '{}'", .{array_ptr_ty}), + else => return sema.fail(block, array_ptr_src, "expected pointer, found '{}'", .{array_ptr_ty}), }; if (!array_ty.isIndexable()) { - return sema.mod.fail(&block.base, src, "array access of non-array type '{}'", .{array_ty}); + return sema.fail(block, src, "array access of non-array type '{}'", .{array_ty}); } if (array_ty.isSinglePointer() and array_ty.elemType().zigTypeTag() == .Array) { // we have to deref the ptr operand to get the actual array pointer @@ -10464,7 +10579,7 @@ fn elemPtr( return sema.elemPtrArray(block, src, array_ptr, elem_index, elem_index_src); } - return sema.mod.fail(&block.base, src, "TODO implement more analyze elemptr", .{}); + return sema.fail(block, src, "TODO implement more analyze elemptr", .{}); } fn elemVal( @@ -10482,7 +10597,7 @@ fn elemVal( .Slice => { if (try sema.resolveDefinedValue(block, src, array_maybe_ptr)) |slice_val| { _ = slice_val; - return sema.mod.fail(&block.base, src, "TODO implement Sema for elemVal for comptime known slice", .{}); + return sema.fail(block, src, "TODO implement Sema for elemVal for comptime known slice", .{}); } try sema.requireRuntimeBlock(block, src); return block.addBinOp(.slice_elem_val, array_maybe_ptr, elem_index); @@ -10490,7 +10605,7 @@ fn elemVal( .Many, .C => { if (try sema.resolveDefinedValue(block, src, array_maybe_ptr)) |ptr_val| { _ = ptr_val; - return sema.mod.fail(&block.base, src, "TODO implement Sema for elemVal for comptime known pointer", .{}); + return sema.fail(block, src, "TODO implement Sema for elemVal for comptime known pointer", .{}); } try sema.requireRuntimeBlock(block, src); return block.addBinOp(.ptr_elem_val, array_maybe_ptr, elem_index); @@ -10505,7 +10620,7 @@ fn elemVal( const slice = try sema.analyzeLoad(block, src, array_maybe_ptr, array_ptr_src); if (try sema.resolveDefinedValue(block, src, slice)) |slice_val| { _ = slice_val; - return sema.mod.fail(&block.base, src, "TODO implement Sema for elemVal for comptime known slice", .{}); + return sema.fail(block, src, "TODO implement Sema for elemVal for comptime known slice", .{}); } try sema.requireRuntimeBlock(block, src); return block.addBinOp(.slice_elem_val, slice, elem_index); @@ -10519,7 +10634,7 @@ fn elemVal( const ptr = try sema.analyzeLoad(block, src, array_maybe_ptr, array_ptr_src); if (try sema.resolveDefinedValue(block, src, ptr)) |ptr_val| { _ = ptr_val; - return sema.mod.fail(&block.base, src, "TODO implement Sema for elemVal for comptime known pointer", .{}); + return sema.fail(block, src, "TODO implement Sema for elemVal for comptime known pointer", .{}); } try sema.requireRuntimeBlock(block, src); return block.addBinOp(.ptr_elem_val, ptr, elem_index); @@ -10527,8 +10642,8 @@ fn elemVal( try sema.requireRuntimeBlock(block, src); return block.addBinOp(.ptr_ptr_elem_val, array_maybe_ptr, elem_index); }, - .One => return sema.mod.fail( - &block.base, + .One => return sema.fail( + block, array_ptr_src, "expected pointer, found '{}'", .{indexable_ty.elemType()}, @@ -10538,8 +10653,8 @@ fn elemVal( const ptr = try sema.elemPtr(block, src, array_maybe_ptr, elem_index, elem_index_src); return sema.analyzeLoad(block, src, ptr, elem_index_src); }, - else => return sema.mod.fail( - &block.base, + else => return sema.fail( + block, array_ptr_src, "expected pointer, found '{}'", .{indexable_ty}, @@ -10547,8 +10662,8 @@ fn elemVal( } }, }, - else => return sema.mod.fail( - &block.base, + else => return sema.fail( + block, array_ptr_src, "expected pointer, found '{}'", .{maybe_ptr_ty}, @@ -10616,10 +10731,10 @@ fn coerce( if (dest_type.eql(inst_ty)) return inst; - const mod = sema.mod; const arena = sema.arena; + const target = sema.mod.getTarget(); - const in_memory_result = coerceInMemoryAllowed(dest_type, inst_ty, false, mod.getTarget()); + const in_memory_result = coerceInMemoryAllowed(dest_type, inst_ty, false, target); if (in_memory_result == .ok) { return sema.bitcast(block, dest_type, inst, inst_src); } @@ -10636,8 +10751,6 @@ fn coerce( if (try sema.coerceNum(block, dest_type, inst, inst_src)) |some| return some; - const target = mod.getTarget(); - switch (dest_type.zigTypeTag()) { .Optional => { // null to ?T @@ -10664,7 +10777,7 @@ fn coerce( if (inst_ty.ptrAddressSpace() != dest_type.ptrAddressSpace()) break :src_array_ptr; const dst_elem_type = dest_type.elemType(); - switch (coerceInMemoryAllowed(dst_elem_type, array_elem_type, dest_is_mut, mod.getTarget())) { + switch (coerceInMemoryAllowed(dst_elem_type, array_elem_type, dest_is_mut, target)) { .ok => {}, .no_match => break :src_array_ptr, } @@ -10733,14 +10846,14 @@ fn coerce( const resolved_dest_type = try sema.resolveTypeFields(block, inst_src, dest_type); const field_index = resolved_dest_type.enumFieldIndex(bytes) orelse { const msg = msg: { - const msg = try mod.errMsg( - &block.base, + const msg = try sema.errMsg( + block, inst_src, "enum '{}' has no field named '{s}'", .{ resolved_dest_type, bytes }, ); errdefer msg.destroy(sema.gpa); - try mod.errNoteNonLazy( + try sema.mod.errNoteNonLazy( resolved_dest_type.declSrcLoc(), msg, "enum declared here", @@ -10748,7 +10861,7 @@ fn coerce( ); break :msg msg; }; - return mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); }; return sema.addConstant( resolved_dest_type, @@ -10771,7 +10884,7 @@ fn coerce( else => {}, } - return mod.fail(&block.base, inst_src, "expected {}, found {}", .{ dest_type, inst_ty }); + return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_type, inst_ty }); } const InMemoryCoercionResult = enum { @@ -10888,13 +11001,13 @@ fn coerceNum( .ComptimeInt, .Int => switch (src_zig_tag) { .Float, .ComptimeFloat => { if (val.floatHasFraction()) { - return sema.mod.fail(&block.base, inst_src, "fractional component prevents float value {} from coercion to type '{}'", .{ val, dest_type }); + return sema.fail(block, inst_src, "fractional component prevents float value {} from coercion to type '{}'", .{ val, dest_type }); } - return sema.mod.fail(&block.base, inst_src, "TODO float to int", .{}); + return sema.fail(block, inst_src, "TODO float to int", .{}); }, .Int, .ComptimeInt => { if (!val.intFitsInType(dest_type, target)) { - return sema.mod.fail(&block.base, inst_src, "type {} cannot represent integer value {}", .{ dest_type, val }); + return sema.fail(block, inst_src, "type {} cannot represent integer value {}", .{ dest_type, val }); } return try sema.addConstant(dest_type, val); }, @@ -10908,8 +11021,8 @@ fn coerceNum( .Float => { const result_val = try val.floatCast(sema.arena, dest_type); if (!val.eql(result_val, dest_type)) { - return sema.mod.fail( - &block.base, + return sema.fail( + block, inst_src, "type {} cannot represent float value {}", .{ dest_type, val }, @@ -10922,8 +11035,8 @@ fn coerceNum( // TODO implement this compile error //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty); //if (!int_again_val.eql(val, inst_ty)) { - // return sema.mod.fail( - // &block.base, + // return sema.fail( + // block, // inst_src, // "type {} cannot represent integer value {}", // .{ dest_type, val }, @@ -10946,7 +11059,7 @@ fn coerceVarArgParam( ) !Air.Inst.Ref { const inst_ty = sema.typeOf(inst); switch (inst_ty.zigTypeTag()) { - .ComptimeInt, .ComptimeFloat => return sema.mod.fail(&block.base, inst_src, "integer and float literals in var args function must be casted", .{}), + .ComptimeInt, .ComptimeFloat => return sema.fail(block, inst_src, "integer and float literals in var args function must be casted", .{}), else => {}, } // TODO implement more of this function. @@ -10960,7 +11073,7 @@ fn storePtr( src: LazySrcLoc, ptr: Air.Inst.Ref, uncasted_operand: Air.Inst.Ref, -) !void { +) CompileError!void { return sema.storePtr2(block, src, ptr, src, uncasted_operand, src, .store); } @@ -10976,7 +11089,7 @@ fn storePtr2( ) !void { const ptr_ty = sema.typeOf(ptr); if (ptr_ty.isConstPtr()) - return sema.mod.fail(&block.base, src, "cannot assign to constant", .{}); + return sema.fail(block, src, "cannot assign to constant", .{}); const elem_ty = ptr_ty.elemType(); const operand = try sema.coerce(block, elem_ty, uncasted_operand, operand_src); @@ -10985,7 +11098,7 @@ fn storePtr2( const runtime_src = if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| rs: { const operand_val = (try sema.resolveMaybeUndefVal(block, operand_src, operand)) orelse - return sema.mod.fail(&block.base, src, "cannot store runtime value in compile time variable", .{}); + return sema.fail(block, src, "cannot store runtime value in compile time variable", .{}); if (ptr_val.tag() == .decl_ref_mut) { try sema.storePtrVal(block, src, ptr_val, operand_val, elem_ty); return; @@ -11013,21 +11126,21 @@ fn storePtrVal( if (decl_ref_mut.data.runtime_index < block.runtime_index) { if (block.runtime_cond) |cond_src| { const msg = msg: { - const msg = try sema.mod.errMsg(&block.base, src, "store to comptime variable depends on runtime condition", .{}); + const msg = try sema.errMsg(block, src, "store to comptime variable depends on runtime condition", .{}); errdefer msg.destroy(sema.gpa); - try sema.mod.errNote(&block.base, cond_src, msg, "runtime condition here", .{}); + try sema.errNote(block, cond_src, msg, "runtime condition here", .{}); break :msg msg; }; - return sema.mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } if (block.runtime_loop) |loop_src| { const msg = msg: { - const msg = try sema.mod.errMsg(&block.base, src, "cannot store to comptime variable in non-inline loop", .{}); + const msg = try sema.errMsg(block, src, "cannot store to comptime variable in non-inline loop", .{}); errdefer msg.destroy(sema.gpa); - try sema.mod.errNote(&block.base, loop_src, msg, "non-inline loop here", .{}); + try sema.errNote(block, loop_src, msg, "non-inline loop here", .{}); break :msg msg; }; - return sema.mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } unreachable; } @@ -11191,7 +11304,7 @@ fn analyzeLoad( const ptr_ty = sema.typeOf(ptr); const elem_ty = switch (ptr_ty.zigTypeTag()) { .Pointer => ptr_ty.elemType(), - else => return sema.mod.fail(&block.base, ptr_src, "expected pointer, found '{}'", .{ptr_ty}), + else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty}), }; if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| { if (try ptr_val.pointerDeref(sema.arena)) |elem_val| { @@ -11213,7 +11326,7 @@ fn analyzeSliceLen( if (slice_val.isUndef()) { return sema.addConstUndef(Type.initTag(.usize)); } - return sema.mod.fail(&block.base, src, "TODO implement Sema analyzeSliceLen on comptime slice", .{}); + return sema.fail(block, src, "TODO implement Sema analyzeSliceLen on comptime slice", .{}); } try sema.requireRuntimeBlock(block, src); return block.addTyOp(.slice_len, Type.initTag(.usize), slice_inst); @@ -11283,7 +11396,7 @@ fn analyzeSlice( const array_ptr_ty = sema.typeOf(array_ptr); const ptr_child = switch (array_ptr_ty.zigTypeTag()) { .Pointer => array_ptr_ty.elemType(), - else => return sema.mod.fail(&block.base, src, "expected pointer, found '{}'", .{array_ptr_ty}), + else => return sema.fail(block, src, "expected pointer, found '{}'", .{array_ptr_ty}), }; var array_type = ptr_child; @@ -11296,11 +11409,11 @@ fn analyzeSlice( break :blk ptr_child.elemType().elemType(); } - return sema.mod.fail(&block.base, src, "slice of single-item pointer", .{}); + return sema.fail(block, src, "slice of single-item pointer", .{}); } break :blk ptr_child.elemType(); }, - else => return sema.mod.fail(&block.base, src, "slice of non-array type '{}'", .{ptr_child}), + else => return sema.fail(block, src, "slice of non-array type '{}'", .{ptr_child}), }; const slice_sentinel = if (sentinel_opt != .none) blk: { @@ -11316,7 +11429,7 @@ fn analyzeSlice( const start_u64 = start_val.toUnsignedInt(); const end_u64 = end_val.toUnsignedInt(); if (start_u64 > end_u64) { - return sema.mod.fail(&block.base, src, "out of bounds slice", .{}); + return sema.fail(block, src, "out of bounds slice", .{}); } const len = end_u64 - start_u64; @@ -11341,7 +11454,7 @@ fn analyzeSlice( }); _ = return_type; - return sema.mod.fail(&block.base, src, "TODO implement analysis of slice", .{}); + return sema.fail(block, src, "TODO implement analysis of slice", .{}); } /// Asserts that lhs and rhs types are both numeric. @@ -11366,13 +11479,13 @@ fn cmpNumeric( if (lhs_ty_tag == .Vector and rhs_ty_tag == .Vector) { if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) { - return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{ + return sema.fail(block, src, "vector length mismatch: {d} and {d}", .{ lhs_ty.arrayLen(), rhs_ty.arrayLen(), }); } - return sema.mod.fail(&block.base, src, "TODO implement support for vectors in cmpNumeric", .{}); + return sema.fail(block, src, "TODO implement support for vectors in cmpNumeric", .{}); } else if (lhs_ty_tag == .Vector or rhs_ty_tag == .Vector) { - return sema.mod.fail(&block.base, src, "mixed scalar and vector operands to comparison operator: '{}' and '{}'", .{ + return sema.fail(block, src, "mixed scalar and vector operands to comparison operator: '{}' and '{}'", .{ lhs_ty, rhs_ty, }); } @@ -11522,7 +11635,7 @@ fn cmpNumeric( const dest_type = if (dest_float_type) |ft| ft else blk: { const max_bits = std.math.max(lhs_bits, rhs_bits); const casted_bits = std.math.cast(u16, max_bits) catch |err| switch (err) { - error.Overflow => return sema.mod.fail(&block.base, src, "{d} exceeds maximum integer bit count", .{max_bits}), + error.Overflow => return sema.fail(block, src, "{d} exceeds maximum integer bit count", .{max_bits}), }; const signedness: std.builtin.Signedness = if (dest_int_is_signed) .signed else .unsigned; break :blk try Module.makeIntType(sema.arena, signedness, casted_bits); @@ -11569,8 +11682,8 @@ fn wrapErrorUnion( const expected_name = val.castTag(.@"error").?.data.name; const n = dest_err_set_ty.castTag(.error_set_single).?.data; if (!mem.eql(u8, expected_name, n)) { - return sema.mod.fail( - &block.base, + return sema.fail( + block, inst_src, "expected type '{}', found type '{}'", .{ dest_err_set_ty, inst_ty }, @@ -11587,8 +11700,8 @@ fn wrapErrorUnion( if (mem.eql(u8, expected_name, name)) break true; } else false; if (!found) { - return sema.mod.fail( - &block.base, + return sema.fail( + block, inst_src, "expected type '{}', found type '{}'", .{ dest_err_set_ty, inst_ty }, @@ -11599,8 +11712,8 @@ fn wrapErrorUnion( const expected_name = val.castTag(.@"error").?.data.name; const map = &dest_err_set_ty.castTag(.error_set_inferred).?.data.map; if (!map.contains(expected_name)) { - return sema.mod.fail( - &block.base, + return sema.fail( + block, inst_src, "expected type '{}', found type '{}'", .{ dest_err_set_ty, inst_ty }, @@ -11735,18 +11848,18 @@ fn resolvePeerTypes( ); const msg = msg: { - const msg = try sema.mod.errMsg(&block.base, src, "incompatible types: '{}' and '{}'", .{ chosen_ty, candidate_ty }); + const msg = try sema.errMsg(block, src, "incompatible types: '{}' and '{}'", .{ chosen_ty, candidate_ty }); errdefer msg.destroy(sema.gpa); if (chosen_src) |src_loc| - try sema.mod.errNote(&block.base, src_loc, msg, "type '{}' here", .{chosen_ty}); + try sema.errNote(block, src_loc, msg, "type '{}' here", .{chosen_ty}); if (candidate_src) |src_loc| - try sema.mod.errNote(&block.base, src_loc, msg, "type '{}' here", .{candidate_ty}); + try sema.errNote(block, src_loc, msg, "type '{}' here", .{candidate_ty}); break :msg msg; }; - return sema.mod.failWithOwnedErrorMsg(&block.base, msg); + return sema.failWithOwnedErrorMsg(msg); } return sema.typeOf(chosen); @@ -11765,7 +11878,7 @@ pub fn resolveTypeLayout( switch (struct_obj.status) { .none, .have_field_types => {}, .field_types_wip, .layout_wip => { - return sema.mod.fail(&block.base, src, "struct {} depends on itself", .{ty}); + return sema.fail(block, src, "struct {} depends on itself", .{ty}); }, .have_layout => return, } @@ -11786,7 +11899,7 @@ fn resolveTypeFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type switch (struct_obj.status) { .none => {}, .field_types_wip => { - return sema.mod.fail(&block.base, src, "struct {} depends on itself", .{ty}); + return sema.fail(block, src, "struct {} depends on itself", .{ty}); }, .have_field_types, .have_layout, .layout_wip => return ty, } @@ -11813,7 +11926,7 @@ fn resolveTypeFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type switch (union_obj.status) { .none => {}, .field_types_wip => { - return sema.mod.fail(&block.base, src, "union {} depends on itself", .{ty}); + return sema.fail(block, src, "union {} depends on itself", .{ty}); }, .have_field_types, .have_layout, .layout_wip => return ty, } @@ -12232,7 +12345,7 @@ fn generateUnionTagTypeNumbered( .val = enum_val, }); new_decl.owns_tv = true; - errdefer sema.mod.abortAnonDecl(new_decl); + errdefer mod.abortAnonDecl(new_decl); enum_obj.* = .{ .owner_decl = new_decl, @@ -12268,7 +12381,7 @@ fn generateUnionTagTypeSimple(sema: *Sema, block: *Scope.Block, fields_len: u32) .val = enum_val, }); new_decl.owns_tv = true; - errdefer sema.mod.abortAnonDecl(new_decl); + errdefer mod.abortAnonDecl(new_decl); enum_obj.* = .{ .owner_decl = new_decl, @@ -12752,8 +12865,8 @@ pub fn analyzeAddrspace( .pointer => "pointers", }; - return sema.mod.fail( - &block.base, + return sema.fail( + block, src, "{s} with address space '{s}' are not supported on {s}", .{ entity, @tagName(address_space), arch.genericName() }, From 272bad3f12a43e3613498080b6b656de5e28e2cf Mon Sep 17 00:00:00 2001 From: Martin Wickham Date: Fri, 1 Oct 2021 17:45:13 -0500 Subject: [PATCH 13/14] Delete Module.Scope, move Block into Sema --- src/Compilation.zig | 12 +- src/Module.zig | 992 ++++++++++++---------------------------- src/Sema.zig | 1000 ++++++++++++++++++++++++++--------------- src/codegen/c.zig | 2 +- src/codegen/llvm.zig | 2 +- src/codegen/spirv.zig | 2 +- src/codegen/wasm.zig | 2 +- src/crash_report.zig | 12 +- src/link/Plan9.zig | 2 +- src/main.zig | 8 +- src/print_zir.zig | 8 +- src/type.zig | 6 +- 12 files changed, 959 insertions(+), 1089 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index b9ed8e209d..8b44d6d51b 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -54,7 +54,7 @@ c_object_work_queue: std.fifo.LinearFifo(*CObject, .Dynamic), /// These jobs are to tokenize, parse, and astgen files, which may be outdated /// since the last compilation, as well as scan for `@import` and queue up /// additional jobs corresponding to those new files. -astgen_work_queue: std.fifo.LinearFifo(*Module.Scope.File, .Dynamic), +astgen_work_queue: std.fifo.LinearFifo(*Module.File, .Dynamic), /// The ErrorMsg memory is owned by the `CObject`, using Compilation's general purpose allocator. /// This data is accessed by multiple threads and is protected by `mutex`. @@ -446,7 +446,7 @@ pub const AllErrors = struct { pub fn addZir( arena: *Allocator, errors: *std.ArrayList(Message), - file: *Module.Scope.File, + file: *Module.File, ) !void { assert(file.zir_loaded); assert(file.tree_loaded); @@ -1444,7 +1444,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .emit_docs = options.emit_docs, .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa), .c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa), - .astgen_work_queue = std.fifo.LinearFifo(*Module.Scope.File, .Dynamic).init(gpa), + .astgen_work_queue = std.fifo.LinearFifo(*Module.File, .Dynamic).init(gpa), .keep_source_files_loaded = options.keep_source_files_loaded, .use_clang = use_clang, .clang_argv = options.clang_argv, @@ -2465,14 +2465,14 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor const AstGenSrc = union(enum) { root, import: struct { - importing_file: *Module.Scope.File, + importing_file: *Module.File, import_tok: std.zig.Ast.TokenIndex, }, }; fn workerAstGenFile( comp: *Compilation, - file: *Module.Scope.File, + file: *Module.File, prog_node: *std.Progress.Node, wg: *WaitGroup, src: AstGenSrc, @@ -2742,7 +2742,7 @@ fn reportRetryableCObjectError( fn reportRetryableAstGenError( comp: *Compilation, src: AstGenSrc, - file: *Module.Scope.File, + file: *Module.File, err: anyerror, ) error{OutOfMemory}!void { const mod = comp.bin_file.options.module.?; diff --git a/src/Module.zig b/src/Module.zig index 27210519b8..828e9b9226 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -59,7 +59,7 @@ export_owners: std.AutoArrayHashMapUnmanaged(*Decl, []*Export) = .{}, /// over it and check which source files have been modified on the file system when /// an update is requested, as well as to cache `@import` results. /// Keys are fully resolved file paths. This table owns the keys and values. -import_table: std.StringArrayHashMapUnmanaged(*Scope.File) = .{}, +import_table: std.StringArrayHashMapUnmanaged(*File) = .{}, /// The set of all the generic function instantiations. This is used so that when a generic /// function is called twice with the same comptime parameter arguments, both calls dispatch @@ -85,8 +85,8 @@ failed_decls: std.AutoArrayHashMapUnmanaged(*Decl, *ErrorMsg) = .{}, /// The value is the AST node index offset from the Decl. compile_log_decls: std.AutoArrayHashMapUnmanaged(*Decl, i32) = .{}, /// Using a map here for consistency with the other fields here. -/// The ErrorMsg memory is owned by the `Scope.File`, using Module's general purpose allocator. -failed_files: std.AutoArrayHashMapUnmanaged(*Scope.File, ?*ErrorMsg) = .{}, +/// The ErrorMsg memory is owned by the `File`, using Module's general purpose allocator. +failed_files: std.AutoArrayHashMapUnmanaged(*File, ?*ErrorMsg) = .{}, /// Using a map here for consistency with the other fields here. /// The ErrorMsg memory is owned by the `Export`, using Module's general purpose allocator. failed_exports: std.AutoArrayHashMapUnmanaged(*Export, *ErrorMsg) = .{}, @@ -350,7 +350,7 @@ pub const Decl = struct { /// Reference to externally owned memory. /// In the case of the Decl corresponding to a file, this is /// the namespace of the struct, since there is no parent. - src_namespace: *Scope.Namespace, + src_namespace: *Namespace, /// The scope which lexically contains this decl. A decl must depend /// on its lexical parent, in order to ensure that this pointer is valid. @@ -690,7 +690,7 @@ pub const Decl = struct { /// Gets the namespace that this Decl creates by being a struct, union, /// enum, or opaque. /// Only returns it if the Decl is the owner. - pub fn getInnerNamespace(decl: *Decl) ?*Scope.Namespace { + pub fn getInnerNamespace(decl: *Decl) ?*Namespace { if (!decl.owns_tv) return null; const ty = (decl.val.castTag(.ty) orelse return null).data; switch (ty.tag()) { @@ -735,7 +735,7 @@ pub const Decl = struct { std.debug.print("\n", .{}); } - pub fn getFileScope(decl: Decl) *Scope.File { + pub fn getFileScope(decl: Decl) *File { return decl.src_namespace.file_scope; } @@ -787,7 +787,7 @@ pub const Struct = struct { /// Set of field names in declaration order. fields: std.StringArrayHashMapUnmanaged(Field), /// Represents the declarations inside this struct. - namespace: Scope.Namespace, + namespace: Namespace, /// Offset from `owner_decl`, points to the struct AST node. node_offset: i32, /// Index of the struct_decl ZIR instruction. @@ -909,7 +909,7 @@ pub const EnumFull = struct { /// If this hash map is empty, it means the enum tags are auto-numbered. values: ValueMap, /// Represents the declarations inside this enum. - namespace: Scope.Namespace, + namespace: Namespace, /// Offset from `owner_decl`, points to the enum decl AST node. node_offset: i32, @@ -937,7 +937,7 @@ pub const Union = struct { /// Set of field names in declaration order. fields: std.StringArrayHashMapUnmanaged(Field), /// Represents the declarations inside this union. - namespace: Scope.Namespace, + namespace: Namespace, /// Offset from `owner_decl`, points to the union decl AST node. node_offset: i32, /// Index of the union_decl ZIR instruction. @@ -1081,668 +1081,312 @@ pub const Var = struct { is_threadlocal: bool, }; -pub const Scope = struct { - tag: Tag, +/// The container that structs, enums, unions, and opaques have. +pub const Namespace = struct { + parent: ?*Namespace, + file_scope: *File, + /// Will be a struct, enum, union, or opaque. + ty: Type, + /// Direct children of the namespace. Used during an update to detect + /// which decls have been added/removed from source. + /// Declaration order is preserved via entry order. + /// Key memory is owned by `decl.name`. + /// TODO save memory with https://github.com/ziglang/zig/issues/8619. + /// Anonymous decls are not stored here; they are kept in `anon_decls` instead. + decls: std.StringArrayHashMapUnmanaged(*Decl) = .{}, - pub fn cast(base: *Scope, comptime T: type) ?*T { - if (base.tag != T.base_tag) - return null; + anon_decls: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{}, - return @fieldParentPtr(T, "base", base); + /// Key is usingnamespace Decl itself. To find the namespace being included, + /// the Decl Value has to be resolved as a Type which has a Namespace. + /// Value is whether the usingnamespace decl is marked `pub`. + usingnamespace_set: std.AutoHashMapUnmanaged(*Decl, bool) = .{}, + + pub fn deinit(ns: *Namespace, mod: *Module) void { + ns.destroyDecls(mod); + ns.* = undefined; } - /// Get the decl which contains this decl, for the purposes of source reporting - pub fn srcDecl(scope: *Scope) ?*Decl { - return switch (scope.tag) { - .block => scope.cast(Block).?.src_decl, - .file => null, - .namespace => scope.cast(Namespace).?.getDecl(), - }; + pub fn destroyDecls(ns: *Namespace, mod: *Module) void { + const gpa = mod.gpa; + + log.debug("destroyDecls {*}", .{ns}); + + var decls = ns.decls; + ns.decls = .{}; + + var anon_decls = ns.anon_decls; + ns.anon_decls = .{}; + + for (decls.values()) |value| { + value.destroy(mod); + } + decls.deinit(gpa); + + for (anon_decls.keys()) |key| { + key.destroy(mod); + } + anon_decls.deinit(gpa); } - /// Get the scope which contains this decl, for resolving closure_get instructions. - pub fn srcScope(scope: *Scope) ?*CaptureScope { - return switch (scope.tag) { - .block => scope.cast(Block).?.wip_capture_scope, - .file => null, - .namespace => scope.cast(Namespace).?.getDecl().src_scope, - }; + pub fn deleteAllDecls( + ns: *Namespace, + mod: *Module, + outdated_decls: ?*std.AutoArrayHashMap(*Decl, void), + ) !void { + const gpa = mod.gpa; + + log.debug("deleteAllDecls {*}", .{ns}); + + var decls = ns.decls; + ns.decls = .{}; + + var anon_decls = ns.anon_decls; + ns.anon_decls = .{}; + + // TODO rework this code to not panic on OOM. + // (might want to coordinate with the clearDecl function) + + for (decls.values()) |child_decl| { + mod.clearDecl(child_decl, outdated_decls) catch @panic("out of memory"); + child_decl.destroy(mod); + } + decls.deinit(gpa); + + for (anon_decls.keys()) |child_decl| { + mod.clearDecl(child_decl, outdated_decls) catch @panic("out of memory"); + child_decl.destroy(mod); + } + anon_decls.deinit(gpa); } - /// Asserts the scope has a parent which is a Namespace and returns it. - pub fn namespace(scope: *Scope) *Namespace { - switch (scope.tag) { - .block => return scope.cast(Block).?.namespace, - .file => return scope.cast(File).?.root_decl.?.src_namespace, - .namespace => return scope.cast(Namespace).?, + // This renders e.g. "std.fs.Dir.OpenOptions" + pub fn renderFullyQualifiedName( + ns: Namespace, + name: []const u8, + writer: anytype, + ) @TypeOf(writer).Error!void { + if (ns.parent) |parent| { + const decl = ns.getDecl(); + try parent.renderFullyQualifiedName(mem.spanZ(decl.name), writer); + } else { + try ns.file_scope.renderFullyQualifiedName(writer); + } + if (name.len != 0) { + try writer.writeAll("."); + try writer.writeAll(name); } } - /// Asserts the scope has a parent which is a Namespace or File and - /// returns the sub_file_path field. - pub fn subFilePath(base: *Scope) []const u8 { - switch (base.tag) { - .namespace => return @fieldParentPtr(Namespace, "base", base).file_scope.sub_file_path, - .file => return @fieldParentPtr(File, "base", base).sub_file_path, - .block => unreachable, + /// This renders e.g. "std/fs.zig:Dir.OpenOptions" + pub fn renderFullyQualifiedDebugName( + ns: Namespace, + name: []const u8, + writer: anytype, + ) @TypeOf(writer).Error!void { + var separator_char: u8 = '.'; + if (ns.parent) |parent| { + const decl = ns.getDecl(); + try parent.renderFullyQualifiedDebugName(mem.spanZ(decl.name), writer); + } else { + try ns.file_scope.renderFullyQualifiedDebugName(writer); + separator_char = ':'; + } + if (name.len != 0) { + try writer.writeByte(separator_char); + try writer.writeAll(name); } } - /// When called from inside a Block Scope, chases the namespace, not the owner_decl. - pub fn getFileScope(base: *Scope) *Scope.File { - var cur = base; - while (true) { - cur = switch (cur.tag) { - .namespace => return @fieldParentPtr(Namespace, "base", cur).file_scope, - .file => return @fieldParentPtr(File, "base", cur), - .block => return @fieldParentPtr(Block, "base", cur).namespace.file_scope, - }; + pub fn getDecl(ns: Namespace) *Decl { + return ns.ty.getOwnerDecl(); + } +}; + +pub const File = struct { + status: enum { + never_loaded, + retryable_failure, + parse_failure, + astgen_failure, + success_zir, + }, + source_loaded: bool, + tree_loaded: bool, + zir_loaded: bool, + /// Relative to the owning package's root_src_dir. + /// Memory is stored in gpa, owned by File. + sub_file_path: []const u8, + /// Whether this is populated depends on `source_loaded`. + source: [:0]const u8, + /// Whether this is populated depends on `status`. + stat_size: u64, + /// Whether this is populated depends on `status`. + stat_inode: std.fs.File.INode, + /// Whether this is populated depends on `status`. + stat_mtime: i128, + /// Whether this is populated or not depends on `tree_loaded`. + tree: Ast, + /// Whether this is populated or not depends on `zir_loaded`. + zir: Zir, + /// Package that this file is a part of, managed externally. + pkg: *Package, + /// The Decl of the struct that represents this File. + root_decl: ?*Decl, + + /// Used by change detection algorithm, after astgen, contains the + /// set of decls that existed in the previous ZIR but not in the new one. + deleted_decls: std.ArrayListUnmanaged(*Decl) = .{}, + /// Used by change detection algorithm, after astgen, contains the + /// set of decls that existed both in the previous ZIR and in the new one, + /// but their source code has been modified. + outdated_decls: std.ArrayListUnmanaged(*Decl) = .{}, + + /// The most recent successful ZIR for this file, with no errors. + /// This is only populated when a previously successful ZIR + /// newly introduces compile errors during an update. When ZIR is + /// successful, this field is unloaded. + prev_zir: ?*Zir = null, + + pub fn unload(file: *File, gpa: *Allocator) void { + file.unloadTree(gpa); + file.unloadSource(gpa); + file.unloadZir(gpa); + } + + pub fn unloadTree(file: *File, gpa: *Allocator) void { + if (file.tree_loaded) { + file.tree_loaded = false; + file.tree.deinit(gpa); } } - pub const Tag = enum { - /// .zig source code. - file, - /// Namespace owned by structs, enums, unions, and opaques for decls. - namespace, - block, - }; - - /// The container that structs, enums, unions, and opaques have. - pub const Namespace = struct { - pub const base_tag: Tag = .namespace; - base: Scope = Scope{ .tag = base_tag }, - - parent: ?*Namespace, - file_scope: *Scope.File, - /// Will be a struct, enum, union, or opaque. - ty: Type, - /// Direct children of the namespace. Used during an update to detect - /// which decls have been added/removed from source. - /// Declaration order is preserved via entry order. - /// Key memory is owned by `decl.name`. - /// TODO save memory with https://github.com/ziglang/zig/issues/8619. - /// Anonymous decls are not stored here; they are kept in `anon_decls` instead. - decls: std.StringArrayHashMapUnmanaged(*Decl) = .{}, - - anon_decls: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{}, - - /// Key is usingnamespace Decl itself. To find the namespace being included, - /// the Decl Value has to be resolved as a Type which has a Namespace. - /// Value is whether the usingnamespace decl is marked `pub`. - usingnamespace_set: std.AutoHashMapUnmanaged(*Decl, bool) = .{}, - - pub fn deinit(ns: *Namespace, mod: *Module) void { - ns.destroyDecls(mod); - ns.* = undefined; + pub fn unloadSource(file: *File, gpa: *Allocator) void { + if (file.source_loaded) { + file.source_loaded = false; + gpa.free(file.source); } + } - pub fn destroyDecls(ns: *Namespace, mod: *Module) void { - const gpa = mod.gpa; - - log.debug("destroyDecls {*}", .{ns}); - - var decls = ns.decls; - ns.decls = .{}; - - var anon_decls = ns.anon_decls; - ns.anon_decls = .{}; - - for (decls.values()) |value| { - value.destroy(mod); - } - decls.deinit(gpa); - - for (anon_decls.keys()) |key| { - key.destroy(mod); - } - anon_decls.deinit(gpa); + pub fn unloadZir(file: *File, gpa: *Allocator) void { + if (file.zir_loaded) { + file.zir_loaded = false; + file.zir.deinit(gpa); } + } - pub fn deleteAllDecls( - ns: *Namespace, - mod: *Module, - outdated_decls: ?*std.AutoArrayHashMap(*Decl, void), - ) !void { - const gpa = mod.gpa; - - log.debug("deleteAllDecls {*}", .{ns}); - - var decls = ns.decls; - ns.decls = .{}; - - var anon_decls = ns.anon_decls; - ns.anon_decls = .{}; - - // TODO rework this code to not panic on OOM. - // (might want to coordinate with the clearDecl function) - - for (decls.values()) |child_decl| { - mod.clearDecl(child_decl, outdated_decls) catch @panic("out of memory"); - child_decl.destroy(mod); - } - decls.deinit(gpa); - - for (anon_decls.keys()) |child_decl| { - mod.clearDecl(child_decl, outdated_decls) catch @panic("out of memory"); - child_decl.destroy(mod); - } - anon_decls.deinit(gpa); + pub fn deinit(file: *File, mod: *Module) void { + const gpa = mod.gpa; + log.debug("deinit File {s}", .{file.sub_file_path}); + file.deleted_decls.deinit(gpa); + file.outdated_decls.deinit(gpa); + if (file.root_decl) |root_decl| { + root_decl.destroy(mod); } - - // This renders e.g. "std.fs.Dir.OpenOptions" - pub fn renderFullyQualifiedName( - ns: Namespace, - name: []const u8, - writer: anytype, - ) @TypeOf(writer).Error!void { - if (ns.parent) |parent| { - const decl = ns.getDecl(); - try parent.renderFullyQualifiedName(mem.spanZ(decl.name), writer); - } else { - try ns.file_scope.renderFullyQualifiedName(writer); - } - if (name.len != 0) { - try writer.writeAll("."); - try writer.writeAll(name); - } + gpa.free(file.sub_file_path); + file.unload(gpa); + if (file.prev_zir) |prev_zir| { + prev_zir.deinit(gpa); + gpa.destroy(prev_zir); } + file.* = undefined; + } - /// This renders e.g. "std/fs.zig:Dir.OpenOptions" - pub fn renderFullyQualifiedDebugName( - ns: Namespace, - name: []const u8, - writer: anytype, - ) @TypeOf(writer).Error!void { - var separator_char: u8 = '.'; - if (ns.parent) |parent| { - const decl = ns.getDecl(); - try parent.renderFullyQualifiedDebugName(mem.spanZ(decl.name), writer); - } else { - try ns.file_scope.renderFullyQualifiedDebugName(writer); - separator_char = ':'; - } - if (name.len != 0) { - try writer.writeByte(separator_char); - try writer.writeAll(name); - } - } + pub fn getSource(file: *File, gpa: *Allocator) ![:0]const u8 { + if (file.source_loaded) return file.source; - pub fn getDecl(ns: Namespace) *Decl { - return ns.ty.getOwnerDecl(); - } - }; + const root_dir_path = file.pkg.root_src_directory.path orelse "."; + log.debug("File.getSource, not cached. pkgdir={s} sub_file_path={s}", .{ + root_dir_path, file.sub_file_path, + }); - pub const File = struct { - pub const base_tag: Tag = .file; - base: Scope = Scope{ .tag = base_tag }, - status: enum { - never_loaded, - retryable_failure, - parse_failure, - astgen_failure, - success_zir, - }, - source_loaded: bool, - tree_loaded: bool, - zir_loaded: bool, - /// Relative to the owning package's root_src_dir. - /// Memory is stored in gpa, owned by File. - sub_file_path: []const u8, - /// Whether this is populated depends on `source_loaded`. - source: [:0]const u8, - /// Whether this is populated depends on `status`. - stat_size: u64, - /// Whether this is populated depends on `status`. - stat_inode: std.fs.File.INode, - /// Whether this is populated depends on `status`. - stat_mtime: i128, - /// Whether this is populated or not depends on `tree_loaded`. - tree: Ast, - /// Whether this is populated or not depends on `zir_loaded`. - zir: Zir, - /// Package that this file is a part of, managed externally. - pkg: *Package, - /// The Decl of the struct that represents this File. - root_decl: ?*Decl, + // Keep track of inode, file size, mtime, hash so we can detect which files + // have been modified when an incremental update is requested. + var f = try file.pkg.root_src_directory.handle.openFile(file.sub_file_path, .{}); + defer f.close(); - /// Used by change detection algorithm, after astgen, contains the - /// set of decls that existed in the previous ZIR but not in the new one. - deleted_decls: std.ArrayListUnmanaged(*Decl) = .{}, - /// Used by change detection algorithm, after astgen, contains the - /// set of decls that existed both in the previous ZIR and in the new one, - /// but their source code has been modified. - outdated_decls: std.ArrayListUnmanaged(*Decl) = .{}, + const stat = try f.stat(); - /// The most recent successful ZIR for this file, with no errors. - /// This is only populated when a previously successful ZIR - /// newly introduces compile errors during an update. When ZIR is - /// successful, this field is unloaded. - prev_zir: ?*Zir = null, + if (stat.size > std.math.maxInt(u32)) + return error.FileTooBig; - pub fn unload(file: *File, gpa: *Allocator) void { - file.unloadTree(gpa); - file.unloadSource(gpa); - file.unloadZir(gpa); - } + const source = try gpa.allocSentinel(u8, @intCast(usize, stat.size), 0); + defer if (!file.source_loaded) gpa.free(source); + const amt = try f.readAll(source); + if (amt != stat.size) + return error.UnexpectedEndOfFile; - pub fn unloadTree(file: *File, gpa: *Allocator) void { - if (file.tree_loaded) { - file.tree_loaded = false; - file.tree.deinit(gpa); - } - } + // Here we do not modify stat fields because this function is the one + // used for error reporting. We need to keep the stat fields stale so that + // astGenFile can know to regenerate ZIR. - pub fn unloadSource(file: *File, gpa: *Allocator) void { - if (file.source_loaded) { - file.source_loaded = false; - gpa.free(file.source); - } - } + file.source = source; + file.source_loaded = true; + return source; + } - pub fn unloadZir(file: *File, gpa: *Allocator) void { - if (file.zir_loaded) { - file.zir_loaded = false; - file.zir.deinit(gpa); - } - } + pub fn getTree(file: *File, gpa: *Allocator) !*const Ast { + if (file.tree_loaded) return &file.tree; - pub fn deinit(file: *File, mod: *Module) void { - const gpa = mod.gpa; - log.debug("deinit File {s}", .{file.sub_file_path}); - file.deleted_decls.deinit(gpa); - file.outdated_decls.deinit(gpa); - if (file.root_decl) |root_decl| { - root_decl.destroy(mod); - } - gpa.free(file.sub_file_path); - file.unload(gpa); - if (file.prev_zir) |prev_zir| { - prev_zir.deinit(gpa); - gpa.destroy(prev_zir); - } - file.* = undefined; - } + const source = try file.getSource(gpa); + file.tree = try std.zig.parse(gpa, source); + file.tree_loaded = true; + return &file.tree; + } - pub fn getSource(file: *File, gpa: *Allocator) ![:0]const u8 { - if (file.source_loaded) return file.source; + pub fn destroy(file: *File, mod: *Module) void { + const gpa = mod.gpa; + file.deinit(mod); + gpa.destroy(file); + } - const root_dir_path = file.pkg.root_src_directory.path orelse "."; - log.debug("File.getSource, not cached. pkgdir={s} sub_file_path={s}", .{ - root_dir_path, file.sub_file_path, - }); - - // Keep track of inode, file size, mtime, hash so we can detect which files - // have been modified when an incremental update is requested. - var f = try file.pkg.root_src_directory.handle.openFile(file.sub_file_path, .{}); - defer f.close(); - - const stat = try f.stat(); - - if (stat.size > std.math.maxInt(u32)) - return error.FileTooBig; - - const source = try gpa.allocSentinel(u8, @intCast(usize, stat.size), 0); - defer if (!file.source_loaded) gpa.free(source); - const amt = try f.readAll(source); - if (amt != stat.size) - return error.UnexpectedEndOfFile; - - // Here we do not modify stat fields because this function is the one - // used for error reporting. We need to keep the stat fields stale so that - // astGenFile can know to regenerate ZIR. - - file.source = source; - file.source_loaded = true; - return source; - } - - pub fn getTree(file: *File, gpa: *Allocator) !*const Ast { - if (file.tree_loaded) return &file.tree; - - const source = try file.getSource(gpa); - file.tree = try std.zig.parse(gpa, source); - file.tree_loaded = true; - return &file.tree; - } - - pub fn destroy(file: *File, mod: *Module) void { - const gpa = mod.gpa; - file.deinit(mod); - gpa.destroy(file); - } - - pub fn renderFullyQualifiedName(file: File, writer: anytype) !void { - // Convert all the slashes into dots and truncate the extension. - const ext = std.fs.path.extension(file.sub_file_path); - const noext = file.sub_file_path[0 .. file.sub_file_path.len - ext.len]; - for (noext) |byte| switch (byte) { - '/', '\\' => try writer.writeByte('.'), - else => try writer.writeByte(byte), - }; - } - - pub fn renderFullyQualifiedDebugName(file: File, writer: anytype) !void { - for (file.sub_file_path) |byte| switch (byte) { - '/', '\\' => try writer.writeByte('/'), - else => try writer.writeByte(byte), - }; - } - - pub fn fullyQualifiedNameZ(file: File, gpa: *Allocator) ![:0]u8 { - var buf = std.ArrayList(u8).init(gpa); - defer buf.deinit(); - try file.renderFullyQualifiedName(buf.writer()); - return buf.toOwnedSliceSentinel(0); - } - - /// Returns the full path to this file relative to its package. - pub fn fullPath(file: File, ally: *Allocator) ![]u8 { - return file.pkg.root_src_directory.join(ally, &[_][]const u8{file.sub_file_path}); - } - - pub fn dumpSrc(file: *File, src: LazySrcLoc) void { - const loc = std.zig.findLineColumn(file.source.bytes, src); - std.debug.print("{s}:{d}:{d}\n", .{ file.sub_file_path, loc.line + 1, loc.column + 1 }); - } - - pub fn okToReportErrors(file: File) bool { - return switch (file.status) { - .parse_failure, .astgen_failure => false, - else => true, - }; - } - }; - - /// This is the context needed to semantically analyze ZIR instructions and - /// produce AIR instructions. - /// This is a temporary structure stored on the stack; references to it are valid only - /// during semantic analysis of the block. - pub const Block = struct { - pub const base_tag: Tag = .block; - - base: Scope = Scope{ .tag = base_tag }, - parent: ?*Block, - /// Shared among all child blocks. - sema: *Sema, - /// This Decl is the Decl according to the Zig source code corresponding to this Block. - /// This can vary during inline or comptime function calls. See `Sema.owner_decl` - /// for the one that will be the same for all Block instances. - src_decl: *Decl, - /// The namespace to use for lookups from this source block - /// When analyzing fields, this is different from src_decl.src_namepsace. - namespace: *Namespace, - /// The AIR instructions generated for this block. - instructions: ArrayListUnmanaged(Air.Inst.Index), - // `param` instructions are collected here to be used by the `func` instruction. - params: std.ArrayListUnmanaged(Param) = .{}, - - wip_capture_scope: *CaptureScope, - - label: ?*Label = null, - inlining: ?*Inlining, - /// If runtime_index is not 0 then one of these is guaranteed to be non null. - runtime_cond: ?LazySrcLoc = null, - runtime_loop: ?LazySrcLoc = null, - /// Non zero if a non-inline loop or a runtime conditional have been encountered. - /// Stores to to comptime variables are only allowed when var.runtime_index <= runtime_index. - runtime_index: u32 = 0, - - is_comptime: bool, - - /// when null, it is determined by build mode, changed by @setRuntimeSafety - want_safety: ?bool = null, - - c_import_buf: ?*std.ArrayList(u8) = null, - - const Param = struct { - /// `noreturn` means `anytype`. - ty: Type, - is_comptime: bool, + pub fn renderFullyQualifiedName(file: File, writer: anytype) !void { + // Convert all the slashes into dots and truncate the extension. + const ext = std.fs.path.extension(file.sub_file_path); + const noext = file.sub_file_path[0 .. file.sub_file_path.len - ext.len]; + for (noext) |byte| switch (byte) { + '/', '\\' => try writer.writeByte('.'), + else => try writer.writeByte(byte), }; + } - /// This `Block` maps a block ZIR instruction to the corresponding - /// AIR instruction for break instruction analysis. - pub const Label = struct { - zir_block: Zir.Inst.Index, - merges: Merges, + pub fn renderFullyQualifiedDebugName(file: File, writer: anytype) !void { + for (file.sub_file_path) |byte| switch (byte) { + '/', '\\' => try writer.writeByte('/'), + else => try writer.writeByte(byte), }; + } - /// This `Block` indicates that an inline function call is happening - /// and return instructions should be analyzed as a break instruction - /// to this AIR block instruction. - /// It is shared among all the blocks in an inline or comptime called - /// function. - pub const Inlining = struct { - comptime_result: Air.Inst.Ref, - merges: Merges, + pub fn fullyQualifiedNameZ(file: File, gpa: *Allocator) ![:0]u8 { + var buf = std.ArrayList(u8).init(gpa); + defer buf.deinit(); + try file.renderFullyQualifiedName(buf.writer()); + return buf.toOwnedSliceSentinel(0); + } + + /// Returns the full path to this file relative to its package. + pub fn fullPath(file: File, ally: *Allocator) ![]u8 { + return file.pkg.root_src_directory.join(ally, &[_][]const u8{file.sub_file_path}); + } + + pub fn dumpSrc(file: *File, src: LazySrcLoc) void { + const loc = std.zig.findLineColumn(file.source.bytes, src); + std.debug.print("{s}:{d}:{d}\n", .{ file.sub_file_path, loc.line + 1, loc.column + 1 }); + } + + pub fn okToReportErrors(file: File) bool { + return switch (file.status) { + .parse_failure, .astgen_failure => false, + else => true, }; - - pub const Merges = struct { - block_inst: Air.Inst.Index, - /// Separate array list from break_inst_list so that it can be passed directly - /// to resolvePeerTypes. - results: ArrayListUnmanaged(Air.Inst.Ref), - /// Keeps track of the break instructions so that the operand can be replaced - /// if we need to add type coercion at the end of block analysis. - /// Same indexes, capacity, length as `results`. - br_list: ArrayListUnmanaged(Air.Inst.Index), - }; - - /// For debugging purposes. - pub fn dump(block: *Block, mod: Module) void { - Zir.dumpBlock(mod, block); - } - - pub fn makeSubBlock(parent: *Block) Block { - return .{ - .parent = parent, - .sema = parent.sema, - .src_decl = parent.src_decl, - .namespace = parent.namespace, - .instructions = .{}, - .wip_capture_scope = parent.wip_capture_scope, - .label = null, - .inlining = parent.inlining, - .is_comptime = parent.is_comptime, - .runtime_cond = parent.runtime_cond, - .runtime_loop = parent.runtime_loop, - .runtime_index = parent.runtime_index, - .want_safety = parent.want_safety, - .c_import_buf = parent.c_import_buf, - }; - } - - pub fn wantSafety(block: *const Block) bool { - return block.want_safety orelse switch (block.sema.mod.optimizeMode()) { - .Debug => true, - .ReleaseSafe => true, - .ReleaseFast => false, - .ReleaseSmall => false, - }; - } - - pub fn getFileScope(block: *Block) *Scope.File { - return block.namespace.file_scope; - } - - pub fn addTy( - block: *Block, - tag: Air.Inst.Tag, - ty: Type, - ) error{OutOfMemory}!Air.Inst.Ref { - return block.addInst(.{ - .tag = tag, - .data = .{ .ty = ty }, - }); - } - - pub fn addTyOp( - block: *Block, - tag: Air.Inst.Tag, - ty: Type, - operand: Air.Inst.Ref, - ) error{OutOfMemory}!Air.Inst.Ref { - return block.addInst(.{ - .tag = tag, - .data = .{ .ty_op = .{ - .ty = try block.sema.addType(ty), - .operand = operand, - } }, - }); - } - - pub fn addNoOp(block: *Block, tag: Air.Inst.Tag) error{OutOfMemory}!Air.Inst.Ref { - return block.addInst(.{ - .tag = tag, - .data = .{ .no_op = {} }, - }); - } - - pub fn addUnOp( - block: *Block, - tag: Air.Inst.Tag, - operand: Air.Inst.Ref, - ) error{OutOfMemory}!Air.Inst.Ref { - return block.addInst(.{ - .tag = tag, - .data = .{ .un_op = operand }, - }); - } - - pub fn addBr( - block: *Block, - target_block: Air.Inst.Index, - operand: Air.Inst.Ref, - ) error{OutOfMemory}!Air.Inst.Ref { - return block.addInst(.{ - .tag = .br, - .data = .{ .br = .{ - .block_inst = target_block, - .operand = operand, - } }, - }); - } - - pub fn addBinOp( - block: *Block, - tag: Air.Inst.Tag, - lhs: Air.Inst.Ref, - rhs: Air.Inst.Ref, - ) error{OutOfMemory}!Air.Inst.Ref { - return block.addInst(.{ - .tag = tag, - .data = .{ .bin_op = .{ - .lhs = lhs, - .rhs = rhs, - } }, - }); - } - - pub fn addArg(block: *Block, ty: Type, name: u32) error{OutOfMemory}!Air.Inst.Ref { - return block.addInst(.{ - .tag = .arg, - .data = .{ .ty_str = .{ - .ty = try block.sema.addType(ty), - .str = name, - } }, - }); - } - - pub fn addStructFieldPtr( - block: *Block, - struct_ptr: Air.Inst.Ref, - field_index: u32, - ptr_field_ty: Type, - ) !Air.Inst.Ref { - const ty = try block.sema.addType(ptr_field_ty); - const tag: Air.Inst.Tag = switch (field_index) { - 0 => .struct_field_ptr_index_0, - 1 => .struct_field_ptr_index_1, - 2 => .struct_field_ptr_index_2, - 3 => .struct_field_ptr_index_3, - else => { - return block.addInst(.{ - .tag = .struct_field_ptr, - .data = .{ .ty_pl = .{ - .ty = ty, - .payload = try block.sema.addExtra(Air.StructField{ - .struct_operand = struct_ptr, - .field_index = @intCast(u32, field_index), - }), - } }, - }); - }, - }; - return block.addInst(.{ - .tag = tag, - .data = .{ .ty_op = .{ - .ty = ty, - .operand = struct_ptr, - } }, - }); - } - - pub fn addInst(block: *Block, inst: Air.Inst) error{OutOfMemory}!Air.Inst.Ref { - return Air.indexToRef(try block.addInstAsIndex(inst)); - } - - pub fn addInstAsIndex(block: *Block, inst: Air.Inst) error{OutOfMemory}!Air.Inst.Index { - const sema = block.sema; - const gpa = sema.gpa; - - try sema.air_instructions.ensureUnusedCapacity(gpa, 1); - try block.instructions.ensureUnusedCapacity(gpa, 1); - - const result_index = @intCast(Air.Inst.Index, sema.air_instructions.len); - sema.air_instructions.appendAssumeCapacity(inst); - block.instructions.appendAssumeCapacity(result_index); - return result_index; - } - - pub fn startAnonDecl(block: *Block) !WipAnonDecl { - return WipAnonDecl{ - .block = block, - .new_decl_arena = std.heap.ArenaAllocator.init(block.sema.gpa), - .finished = false, - }; - } - - pub const WipAnonDecl = struct { - block: *Scope.Block, - new_decl_arena: std.heap.ArenaAllocator, - finished: bool, - - pub fn arena(wad: *WipAnonDecl) *Allocator { - return &wad.new_decl_arena.allocator; - } - - pub fn deinit(wad: *WipAnonDecl) void { - if (!wad.finished) { - wad.new_decl_arena.deinit(); - } - wad.* = undefined; - } - - pub fn finish(wad: *WipAnonDecl, ty: Type, val: Value) !*Decl { - const new_decl = try wad.block.sema.mod.createAnonymousDecl(&wad.block.base, .{ - .ty = ty, - .val = val, - }); - errdefer wad.block.sema.mod.abortAnonDecl(new_decl); - try new_decl.finalizeNewArena(&wad.new_decl_arena); - wad.finished = true; - return new_decl; - } - }; - }; + } }; /// This struct holds data necessary to construct API-facing `AllErrors.Message`. /// Its memory is managed with the general purpose allocator so that they /// can be created and destroyed in response to incremental updates. -/// In some cases, the Scope.File could have been inferred from where the ErrorMsg -/// is stored. For example, if it is stored in Module.failed_decls, then the Scope.File +/// In some cases, the File could have been inferred from where the ErrorMsg +/// is stored. For example, if it is stored in Module.failed_decls, then the File /// would be determined by the Decl Scope. However, the data structure contains the field /// anyway so that `ErrorMsg` can be reused for error notes, which may be in a different /// file than the parent error message. It also simplifies processing of error messages. @@ -1794,7 +1438,7 @@ pub const ErrorMsg = struct { /// Canonical reference to a position within a source file. pub const SrcLoc = struct { - file_scope: *Scope.File, + file_scope: *File, /// Might be 0 depending on tag of `lazy`. parent_decl_node: Ast.Node.Index, /// Relative to `parent_decl_node`. @@ -2371,60 +2015,8 @@ pub const LazySrcLoc = union(enum) { /// The Decl is determined contextually. node_offset_lib_name: i32, - /// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope. - pub fn toSrcLoc(lazy: LazySrcLoc, block: *Scope.Block) SrcLoc { - return switch (lazy) { - .unneeded, - .entire_file, - .byte_abs, - .token_abs, - .node_abs, - => .{ - .file_scope = block.getFileScope(), - .parent_decl_node = 0, - .lazy = lazy, - }, - - .byte_offset, - .token_offset, - .node_offset, - .node_offset_back2tok, - .node_offset_var_decl_ty, - .node_offset_for_cond, - .node_offset_builtin_call_arg0, - .node_offset_builtin_call_arg1, - .node_offset_builtin_call_arg2, - .node_offset_builtin_call_arg3, - .node_offset_builtin_call_arg4, - .node_offset_builtin_call_arg5, - .node_offset_array_access_index, - .node_offset_slice_sentinel, - .node_offset_call_func, - .node_offset_field_name, - .node_offset_deref_ptr, - .node_offset_asm_source, - .node_offset_asm_ret_ty, - .node_offset_if_cond, - .node_offset_bin_op, - .node_offset_bin_lhs, - .node_offset_bin_rhs, - .node_offset_switch_operand, - .node_offset_switch_special_prong, - .node_offset_switch_range, - .node_offset_fn_type_cc, - .node_offset_fn_type_ret_ty, - .node_offset_anyframe_type, - .node_offset_lib_name, - => .{ - .file_scope = block.getFileScope(), - .parent_decl_node = block.src_decl.src_node, - .lazy = lazy, - }, - }; - } - /// Upgrade to a `SrcLoc` based on the `Decl` provided. - pub fn toSrcLocWithDecl(lazy: LazySrcLoc, decl: *Decl) SrcLoc { + pub fn toSrcLoc(lazy: LazySrcLoc, decl: *Decl) SrcLoc { return switch (lazy) { .unneeded, .entire_file, @@ -2613,7 +2205,7 @@ comptime { } } -pub fn astGenFile(mod: *Module, file: *Scope.File) !void { +pub fn astGenFile(mod: *Module, file: *File) !void { const tracy = trace(@src()); defer tracy.end(); @@ -2997,7 +2589,7 @@ pub fn astGenFile(mod: *Module, file: *Scope.File) !void { /// * Decl.zir_index /// * Fn.zir_body_inst /// * Decl.zir_decl_index -fn updateZirRefs(gpa: *Allocator, file: *Scope.File, old_zir: Zir) !void { +fn updateZirRefs(gpa: *Allocator, file: *File, old_zir: Zir) !void { const new_zir = file.zir; // Maps from old ZIR to new ZIR, struct_decl, enum_decl, etc. Any instruction which @@ -3253,7 +2845,7 @@ pub fn semaPkg(mod: *Module, pkg: *Package) !void { /// Regardless of the file status, will create a `Decl` so that we /// can track dependencies and re-analyze when the file becomes outdated. -pub fn semaFile(mod: *Module, file: *Scope.File) SemaError!void { +pub fn semaFile(mod: *Module, file: *File) SemaError!void { const tracy = trace(@src()); defer tracy.end(); @@ -3322,7 +2914,7 @@ pub fn semaFile(mod: *Module, file: *Scope.File) SemaError!void { var wip_captures = try WipCaptureScope.init(gpa, &new_decl_arena.allocator, null); defer wip_captures.deinit(); - var block_scope: Scope.Block = .{ + var block_scope: Sema.Block = .{ .parent = null, .sema = &sema, .src_decl = new_decl, @@ -3402,7 +2994,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { var wip_captures = try WipCaptureScope.init(gpa, &decl_arena.allocator, decl.src_scope); defer wip_captures.deinit(); - var block_scope: Scope.Block = .{ + var block_scope: Sema.Block = .{ .parent = null, .sema = &sema, .src_decl = decl, @@ -3617,7 +3209,7 @@ pub fn declareDeclDependency(mod: *Module, depender: *Decl, dependee: *Decl) !vo } pub const ImportFileResult = struct { - file: *Scope.File, + file: *File, is_new: bool, }; @@ -3643,7 +3235,7 @@ pub fn importPkg(mod: *Module, pkg: *Package) !ImportFileResult { const sub_file_path = try gpa.dupe(u8, pkg.root_src_path); errdefer gpa.free(sub_file_path); - const new_file = try gpa.create(Scope.File); + const new_file = try gpa.create(File); errdefer gpa.destroy(new_file); gop.value_ptr.* = new_file; @@ -3670,7 +3262,7 @@ pub fn importPkg(mod: *Module, pkg: *Package) !ImportFileResult { pub fn importFile( mod: *Module, - cur_file: *Scope.File, + cur_file: *File, import_string: []const u8, ) !ImportFileResult { if (cur_file.pkg.table.get(import_string)) |pkg| { @@ -3698,7 +3290,7 @@ pub fn importFile( }; keep_resolved_path = true; // It's now owned by import_table. - const new_file = try gpa.create(Scope.File); + const new_file = try gpa.create(File); errdefer gpa.destroy(new_file); const resolved_root_path = try std.fs.path.resolve(gpa, &[_][]const u8{cur_pkg_dir_path}); @@ -3739,7 +3331,7 @@ pub fn importFile( pub fn scanNamespace( mod: *Module, - namespace: *Scope.Namespace, + namespace: *Namespace, extra_start: usize, decls_len: u32, parent_decl: *Decl, @@ -3783,7 +3375,7 @@ pub fn scanNamespace( const ScanDeclIter = struct { module: *Module, - namespace: *Scope.Namespace, + namespace: *Namespace, parent_decl: *Decl, usingnamespace_index: usize = 0, comptime_index: usize = 0, @@ -4146,7 +3738,7 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn, arena: *Allocator) Se var wip_captures = try WipCaptureScope.init(gpa, &decl_arena.allocator, decl.src_scope); defer wip_captures.deinit(); - var inner_block: Scope.Block = .{ + var inner_block: Sema.Block = .{ .parent = null, .sema = &sema, .src_decl = decl, @@ -4269,7 +3861,7 @@ fn markOutdatedDecl(mod: *Module, decl: *Decl) !void { decl.analysis = .outdated; } -pub fn allocateNewDecl(mod: *Module, name: [:0]const u8, namespace: *Scope.Namespace, src_node: Ast.Node.Index, src_scope: ?*CaptureScope) !*Decl { +pub fn allocateNewDecl(mod: *Module, name: [:0]const u8, namespace: *Namespace, src_node: Ast.Node.Index, src_scope: ?*CaptureScope) !*Decl { // If we have emit-h then we must allocate a bigger structure to store the emit-h state. const new_decl: *Decl = if (mod.emit_h != null) blk: { const parent_struct = try mod.gpa.create(DeclPlusEmitH); @@ -4350,21 +3942,21 @@ pub fn getErrorValue(mod: *Module, name: []const u8) !std.StringHashMapUnmanaged /// Takes ownership of `name` even if it returns an error. pub fn createAnonymousDeclNamed( mod: *Module, - scope: *Scope, + block: *Sema.Block, typed_value: TypedValue, name: [:0]u8, ) !*Decl { - return mod.createAnonymousDeclFromDeclNamed(scope.srcDecl().?, scope.namespace(), scope.srcScope(), typed_value, name); + return mod.createAnonymousDeclFromDeclNamed(block.src_decl, block.namespace, block.wip_capture_scope, typed_value, name); } -pub fn createAnonymousDecl(mod: *Module, scope: *Scope, typed_value: TypedValue) !*Decl { - return mod.createAnonymousDeclFromDecl(scope.srcDecl().?, scope.namespace(), scope.srcScope(), typed_value); +pub fn createAnonymousDecl(mod: *Module, block: *Sema.Block, typed_value: TypedValue) !*Decl { + return mod.createAnonymousDeclFromDecl(block.src_decl, block.namespace, block.wip_capture_scope, typed_value); } pub fn createAnonymousDeclFromDecl( mod: *Module, src_decl: *Decl, - namespace: *Scope.Namespace, + namespace: *Namespace, src_scope: ?*CaptureScope, tv: TypedValue, ) !*Decl { @@ -4379,7 +3971,7 @@ pub fn createAnonymousDeclFromDecl( pub fn createAnonymousDeclFromDeclNamed( mod: *Module, src_decl: *Decl, - namespace: *Scope.Namespace, + namespace: *Namespace, src_scope: ?*CaptureScope, typed_value: TypedValue, name: [:0]u8, @@ -4516,7 +4108,7 @@ pub fn optimizeMode(mod: Module) std.builtin.Mode { return mod.comp.bin_file.options.optimize_mode; } -fn lockAndClearFileCompileError(mod: *Module, file: *Scope.File) void { +fn lockAndClearFileCompileError(mod: *Module, file: *File) void { switch (file.status) { .success_zir, .retryable_failure => {}, .never_loaded, .parse_failure, .astgen_failure => { diff --git a/src/Sema.zig b/src/Sema.zig index 22acd77aeb..6bc7cecac7 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -21,7 +21,7 @@ air_values: std.ArrayListUnmanaged(Value) = .{}, /// Maps ZIR to AIR. inst_map: InstMap = .{}, /// When analyzing an inline function call, owner_decl is the Decl of the caller -/// and `src_decl` of `Scope.Block` is the `Decl` of the callee. +/// and `src_decl` of `Block` is the `Decl` of the callee. /// This `Decl` owns the arena memory of this `Sema`. owner_decl: *Decl, /// For an inline or comptime function call, this will be the root parent function @@ -75,7 +75,7 @@ const Air = @import("Air.zig"); const Zir = @import("Zir.zig"); const Module = @import("Module.zig"); const trace = @import("tracy.zig").trace; -const Scope = Module.Scope; +const Namespace = Module.Namespace; const CompileError = Module.CompileError; const SemaError = Module.SemaError; const Decl = Module.Decl; @@ -89,6 +89,286 @@ const crash_report = @import("crash_report.zig"); pub const InstMap = std.AutoHashMapUnmanaged(Zir.Inst.Index, Air.Inst.Ref); +/// This is the context needed to semantically analyze ZIR instructions and +/// produce AIR instructions. +/// This is a temporary structure stored on the stack; references to it are valid only +/// during semantic analysis of the block. +pub const Block = struct { + parent: ?*Block, + /// Shared among all child blocks. + sema: *Sema, + /// This Decl is the Decl according to the Zig source code corresponding to this Block. + /// This can vary during inline or comptime function calls. See `Sema.owner_decl` + /// for the one that will be the same for all Block instances. + src_decl: *Decl, + /// The namespace to use for lookups from this source block + /// When analyzing fields, this is different from src_decl.src_namepsace. + namespace: *Namespace, + /// The AIR instructions generated for this block. + instructions: std.ArrayListUnmanaged(Air.Inst.Index), + // `param` instructions are collected here to be used by the `func` instruction. + params: std.ArrayListUnmanaged(Param) = .{}, + + wip_capture_scope: *CaptureScope, + + label: ?*Label = null, + inlining: ?*Inlining, + /// If runtime_index is not 0 then one of these is guaranteed to be non null. + runtime_cond: ?LazySrcLoc = null, + runtime_loop: ?LazySrcLoc = null, + /// Non zero if a non-inline loop or a runtime conditional have been encountered. + /// Stores to to comptime variables are only allowed when var.runtime_index <= runtime_index. + runtime_index: u32 = 0, + + is_comptime: bool, + + /// when null, it is determined by build mode, changed by @setRuntimeSafety + want_safety: ?bool = null, + + c_import_buf: ?*std.ArrayList(u8) = null, + + const Param = struct { + /// `noreturn` means `anytype`. + ty: Type, + is_comptime: bool, + }; + + /// This `Block` maps a block ZIR instruction to the corresponding + /// AIR instruction for break instruction analysis. + pub const Label = struct { + zir_block: Zir.Inst.Index, + merges: Merges, + }; + + /// This `Block` indicates that an inline function call is happening + /// and return instructions should be analyzed as a break instruction + /// to this AIR block instruction. + /// It is shared among all the blocks in an inline or comptime called + /// function. + pub const Inlining = struct { + comptime_result: Air.Inst.Ref, + merges: Merges, + }; + + pub const Merges = struct { + block_inst: Air.Inst.Index, + /// Separate array list from break_inst_list so that it can be passed directly + /// to resolvePeerTypes. + results: std.ArrayListUnmanaged(Air.Inst.Ref), + /// Keeps track of the break instructions so that the operand can be replaced + /// if we need to add type coercion at the end of block analysis. + /// Same indexes, capacity, length as `results`. + br_list: std.ArrayListUnmanaged(Air.Inst.Index), + }; + + /// For debugging purposes. + pub fn dump(block: *Block, mod: Module) void { + Zir.dumpBlock(mod, block); + } + + pub fn makeSubBlock(parent: *Block) Block { + return .{ + .parent = parent, + .sema = parent.sema, + .src_decl = parent.src_decl, + .namespace = parent.namespace, + .instructions = .{}, + .wip_capture_scope = parent.wip_capture_scope, + .label = null, + .inlining = parent.inlining, + .is_comptime = parent.is_comptime, + .runtime_cond = parent.runtime_cond, + .runtime_loop = parent.runtime_loop, + .runtime_index = parent.runtime_index, + .want_safety = parent.want_safety, + .c_import_buf = parent.c_import_buf, + }; + } + + pub fn wantSafety(block: *const Block) bool { + return block.want_safety orelse switch (block.sema.mod.optimizeMode()) { + .Debug => true, + .ReleaseSafe => true, + .ReleaseFast => false, + .ReleaseSmall => false, + }; + } + + pub fn getFileScope(block: *Block) *Module.File { + return block.namespace.file_scope; + } + + pub fn addTy( + block: *Block, + tag: Air.Inst.Tag, + ty: Type, + ) error{OutOfMemory}!Air.Inst.Ref { + return block.addInst(.{ + .tag = tag, + .data = .{ .ty = ty }, + }); + } + + pub fn addTyOp( + block: *Block, + tag: Air.Inst.Tag, + ty: Type, + operand: Air.Inst.Ref, + ) error{OutOfMemory}!Air.Inst.Ref { + return block.addInst(.{ + .tag = tag, + .data = .{ .ty_op = .{ + .ty = try block.sema.addType(ty), + .operand = operand, + } }, + }); + } + + pub fn addNoOp(block: *Block, tag: Air.Inst.Tag) error{OutOfMemory}!Air.Inst.Ref { + return block.addInst(.{ + .tag = tag, + .data = .{ .no_op = {} }, + }); + } + + pub fn addUnOp( + block: *Block, + tag: Air.Inst.Tag, + operand: Air.Inst.Ref, + ) error{OutOfMemory}!Air.Inst.Ref { + return block.addInst(.{ + .tag = tag, + .data = .{ .un_op = operand }, + }); + } + + pub fn addBr( + block: *Block, + target_block: Air.Inst.Index, + operand: Air.Inst.Ref, + ) error{OutOfMemory}!Air.Inst.Ref { + return block.addInst(.{ + .tag = .br, + .data = .{ .br = .{ + .block_inst = target_block, + .operand = operand, + } }, + }); + } + + pub fn addBinOp( + block: *Block, + tag: Air.Inst.Tag, + lhs: Air.Inst.Ref, + rhs: Air.Inst.Ref, + ) error{OutOfMemory}!Air.Inst.Ref { + return block.addInst(.{ + .tag = tag, + .data = .{ .bin_op = .{ + .lhs = lhs, + .rhs = rhs, + } }, + }); + } + + pub fn addArg(block: *Block, ty: Type, name: u32) error{OutOfMemory}!Air.Inst.Ref { + return block.addInst(.{ + .tag = .arg, + .data = .{ .ty_str = .{ + .ty = try block.sema.addType(ty), + .str = name, + } }, + }); + } + + pub fn addStructFieldPtr( + block: *Block, + struct_ptr: Air.Inst.Ref, + field_index: u32, + ptr_field_ty: Type, + ) !Air.Inst.Ref { + const ty = try block.sema.addType(ptr_field_ty); + const tag: Air.Inst.Tag = switch (field_index) { + 0 => .struct_field_ptr_index_0, + 1 => .struct_field_ptr_index_1, + 2 => .struct_field_ptr_index_2, + 3 => .struct_field_ptr_index_3, + else => { + return block.addInst(.{ + .tag = .struct_field_ptr, + .data = .{ .ty_pl = .{ + .ty = ty, + .payload = try block.sema.addExtra(Air.StructField{ + .struct_operand = struct_ptr, + .field_index = @intCast(u32, field_index), + }), + } }, + }); + }, + }; + return block.addInst(.{ + .tag = tag, + .data = .{ .ty_op = .{ + .ty = ty, + .operand = struct_ptr, + } }, + }); + } + + pub fn addInst(block: *Block, inst: Air.Inst) error{OutOfMemory}!Air.Inst.Ref { + return Air.indexToRef(try block.addInstAsIndex(inst)); + } + + pub fn addInstAsIndex(block: *Block, inst: Air.Inst) error{OutOfMemory}!Air.Inst.Index { + const sema = block.sema; + const gpa = sema.gpa; + + try sema.air_instructions.ensureUnusedCapacity(gpa, 1); + try block.instructions.ensureUnusedCapacity(gpa, 1); + + const result_index = @intCast(Air.Inst.Index, sema.air_instructions.len); + sema.air_instructions.appendAssumeCapacity(inst); + block.instructions.appendAssumeCapacity(result_index); + return result_index; + } + + pub fn startAnonDecl(block: *Block) !WipAnonDecl { + return WipAnonDecl{ + .block = block, + .new_decl_arena = std.heap.ArenaAllocator.init(block.sema.gpa), + .finished = false, + }; + } + + pub const WipAnonDecl = struct { + block: *Block, + new_decl_arena: std.heap.ArenaAllocator, + finished: bool, + + pub fn arena(wad: *WipAnonDecl) *Allocator { + return &wad.new_decl_arena.allocator; + } + + pub fn deinit(wad: *WipAnonDecl) void { + if (!wad.finished) { + wad.new_decl_arena.deinit(); + } + wad.* = undefined; + } + + pub fn finish(wad: *WipAnonDecl, ty: Type, val: Value) !*Decl { + const new_decl = try wad.block.sema.mod.createAnonymousDecl(wad.block, .{ + .ty = ty, + .val = val, + }); + errdefer wad.block.sema.mod.abortAnonDecl(new_decl); + try new_decl.finalizeNewArena(&wad.new_decl_arena); + wad.finished = true; + return new_decl; + } + }; +}; + pub fn deinit(sema: *Sema) void { const gpa = sema.gpa; sema.air_instructions.deinit(gpa); @@ -102,7 +382,7 @@ pub fn deinit(sema: *Sema) void { /// Returns only the result from the body that is specified. /// Only appropriate to call when it is determined at comptime that this body /// has no peers. -fn resolveBody(sema: *Sema, block: *Scope.Block, body: []const Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn resolveBody(sema: *Sema, block: *Block, body: []const Zir.Inst.Index) CompileError!Air.Inst.Ref { const break_inst = try sema.analyzeBody(block, body); const operand_ref = sema.code.instructions.items(.data)[break_inst].@"break".operand; return sema.resolveInst(operand_ref); @@ -125,7 +405,7 @@ const always_noreturn: CompileError!Zir.Inst.Index = @as(Zir.Inst.Index, undefin /// well as the operand. No block scope needs to be created for this strategy. pub fn analyzeBody( sema: *Sema, - block: *Scope.Block, + block: *Block, body: []const Zir.Inst.Index, ) CompileError!Zir.Inst.Index { // No tracy calls here, to avoid interfering with the tail call mechanism. @@ -142,9 +422,9 @@ pub fn analyzeBody( wip_captures.deinit(); }; - const map = &block.sema.inst_map; - const tags = block.sema.code.instructions.items(.tag); - const datas = block.sema.code.instructions.items(.data); + const map = &sema.inst_map; + const tags = sema.code.instructions.items(.tag); + const datas = sema.code.instructions.items(.data); var orig_captures: usize = parent_capture_scope.captures.count(); @@ -667,7 +947,7 @@ pub fn analyzeBody( return result; } -fn zirExtended(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirExtended(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const extended = sema.code.instructions.items(.data)[inst].extended; switch (extended.opcode) { // zig fmt: off @@ -719,7 +999,7 @@ pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) Air.Inst.Ref { fn resolveConstBool( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref, ) !bool { @@ -732,7 +1012,7 @@ fn resolveConstBool( fn resolveConstString( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref, ) ![]u8 { @@ -743,14 +1023,14 @@ fn resolveConstString( return val.toAllocatedBytes(sema.arena); } -pub fn resolveType(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type { +pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) !Type { const air_inst = sema.resolveInst(zir_ref); return sema.analyzeAsType(block, src, air_inst); } fn analyzeAsType( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, air_inst: Air.Inst.Ref, ) !Type { @@ -767,7 +1047,7 @@ fn analyzeAsType( /// Value Tag `generic_poison` causes `error.GenericPoison` to be returned. fn resolveValue( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, air_ref: Air.Inst.Ref, ) CompileError!Value { @@ -782,7 +1062,7 @@ fn resolveValue( /// Value Tag `undef` may be returned. fn resolveConstMaybeUndefVal( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, inst: Air.Inst.Ref, ) CompileError!Value { @@ -800,7 +1080,7 @@ fn resolveConstMaybeUndefVal( /// See `resolveValue` for an alternative. fn resolveConstValue( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, air_ref: Air.Inst.Ref, ) CompileError!Value { @@ -819,7 +1099,7 @@ fn resolveConstValue( /// Value Tag `undef` causes this function to return a compile error. fn resolveDefinedValue( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, air_ref: Air.Inst.Ref, ) CompileError!?Value { @@ -837,7 +1117,7 @@ fn resolveDefinedValue( /// Value Tag `generic_poison` causes `error.GenericPoison` to be returned. fn resolveMaybeUndefVal( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, inst: Air.Inst.Ref, ) CompileError!?Value { @@ -852,7 +1132,7 @@ fn resolveMaybeUndefVal( /// Returns all Value tags including `variable` and `undef`. fn resolveMaybeUndefValAllowVariables( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, inst: Air.Inst.Ref, ) CompileError!?Value { @@ -879,19 +1159,19 @@ fn resolveMaybeUndefValAllowVariables( } } -fn failWithNeededComptime(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) CompileError { +fn failWithNeededComptime(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError { return sema.fail(block, src, "unable to resolve comptime value", .{}); } -fn failWithUseOfUndef(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) CompileError { +fn failWithUseOfUndef(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError { return sema.fail(block, src, "use of undefined value here causes undefined behavior", .{}); } -fn failWithDivideByZero(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) CompileError { +fn failWithDivideByZero(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError { return sema.fail(block, src, "division by zero here causes undefined behavior", .{}); } -fn failWithModRemNegative(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, lhs_ty: Type, rhs_ty: Type) CompileError { +fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: Type, rhs_ty: Type) CompileError { return sema.fail(block, src, "remainder division with '{}' and '{}': signed integers and floats must use @rem or @mod", .{ lhs_ty, rhs_ty }); } @@ -899,28 +1179,28 @@ fn failWithModRemNegative(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, lhs /// becomes invalid when you add another one. fn errNote( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, parent: *Module.ErrorMsg, comptime format: []const u8, args: anytype, ) error{OutOfMemory}!void { - return sema.mod.errNoteNonLazy(src.toSrcLoc(block), parent, format, args); + return sema.mod.errNoteNonLazy(src.toSrcLoc(block.src_decl), parent, format, args); } fn errMsg( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, comptime format: []const u8, args: anytype, ) error{OutOfMemory}!*Module.ErrorMsg { - return Module.ErrorMsg.create(sema.gpa, src.toSrcLoc(block), format, args); + return Module.ErrorMsg.create(sema.gpa, src.toSrcLoc(block.src_decl), format, args); } pub fn fail( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, comptime format: []const u8, args: anytype, @@ -958,7 +1238,7 @@ fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError { /// TODO don't ever call this since we're migrating towards ResultLoc.coerced_ty. fn resolveAlreadyCoercedInt( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref, comptime Int: type, @@ -974,7 +1254,7 @@ fn resolveAlreadyCoercedInt( fn resolveAlign( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref, ) !u16 { @@ -991,7 +1271,7 @@ fn resolveAlign( fn resolveInt( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref, dest_type: Type, @@ -1007,7 +1287,7 @@ fn resolveInt( // a function that does not. pub fn resolveInstConst( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref, ) CompileError!TypedValue { @@ -1023,7 +1303,7 @@ pub fn resolveInstConst( // See `resolveInstConst` for an alternative. pub fn resolveInstValue( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref, ) CompileError!TypedValue { @@ -1035,13 +1315,13 @@ pub fn resolveInstValue( }; } -fn zirBitcastResultPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirBitcastResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO implement zir_sema.zirBitcastResultPtr", .{}); } -fn zirCoerceResultPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -1103,7 +1383,7 @@ pub fn analyzeStructDecl( fn zirStructDecl( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, inst: Zir.Inst.Index, ) CompileError!Air.Inst.Ref { @@ -1120,7 +1400,7 @@ fn zirStructDecl( const struct_ty = try Type.Tag.@"struct".create(&new_decl_arena.allocator, struct_obj); const struct_val = try Value.Tag.ty.create(&new_decl_arena.allocator, struct_ty); const type_name = try sema.createTypeName(block, small.name_strategy); - const new_decl = try sema.mod.createAnonymousDeclNamed(&block.base, .{ + const new_decl = try sema.mod.createAnonymousDeclNamed(block, .{ .ty = Type.initTag(.type), .val = struct_val, }, type_name); @@ -1148,7 +1428,7 @@ fn zirStructDecl( return sema.analyzeDeclVal(block, src, new_decl); } -fn createTypeName(sema: *Sema, block: *Scope.Block, name_strategy: Zir.Inst.NameStrategy) ![:0]u8 { +fn createTypeName(sema: *Sema, block: *Block, name_strategy: Zir.Inst.NameStrategy) ![:0]u8 { switch (name_strategy) { .anon => { // It would be neat to have "struct:line:column" but this name has @@ -1176,7 +1456,7 @@ fn createTypeName(sema: *Sema, block: *Scope.Block, name_strategy: Zir.Inst.Name fn zirEnumDecl( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const tracy = trace(@src()); @@ -1229,7 +1509,7 @@ fn zirEnumDecl( const enum_ty = Type.initPayload(&enum_ty_payload.base); const enum_val = try Value.Tag.ty.create(&new_decl_arena.allocator, enum_ty); const type_name = try sema.createTypeName(block, small.name_strategy); - const new_decl = try mod.createAnonymousDeclNamed(&block.base, .{ + const new_decl = try mod.createAnonymousDeclNamed(block, .{ .ty = Type.initTag(.type), .val = enum_val, }, type_name); @@ -1287,7 +1567,7 @@ fn zirEnumDecl( var wip_captures = try WipCaptureScope.init(gpa, sema.perm_arena, new_decl.src_scope); defer wip_captures.deinit(); - var enum_block: Scope.Block = .{ + var enum_block: Block = .{ .parent = null, .sema = sema, .src_decl = new_decl, @@ -1377,7 +1657,7 @@ fn zirEnumDecl( fn zirUnionDecl( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, inst: Zir.Inst.Index, ) CompileError!Air.Inst.Ref { @@ -1416,7 +1696,7 @@ fn zirUnionDecl( const union_ty = Type.initPayload(&union_payload.base); const union_val = try Value.Tag.ty.create(&new_decl_arena.allocator, union_ty); const type_name = try sema.createTypeName(block, small.name_strategy); - const new_decl = try sema.mod.createAnonymousDeclNamed(&block.base, .{ + const new_decl = try sema.mod.createAnonymousDeclNamed(block, .{ .ty = Type.initTag(.type), .val = union_val, }, type_name); @@ -1448,7 +1728,7 @@ fn zirUnionDecl( fn zirOpaqueDecl( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, inst: Zir.Inst.Index, ) CompileError!Air.Inst.Ref { @@ -1462,7 +1742,7 @@ fn zirOpaqueDecl( fn zirErrorSetDecl( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, name_strategy: Zir.Inst.NameStrategy, ) CompileError!Air.Inst.Ref { @@ -1482,7 +1762,7 @@ fn zirErrorSetDecl( const error_set_ty = try Type.Tag.error_set.create(&new_decl_arena.allocator, error_set); const error_set_val = try Value.Tag.ty.create(&new_decl_arena.allocator, error_set_ty); const type_name = try sema.createTypeName(block, name_strategy); - const new_decl = try sema.mod.createAnonymousDeclNamed(&block.base, .{ + const new_decl = try sema.mod.createAnonymousDeclNamed(block, .{ .ty = Type.initTag(.type), .val = error_set_val, }, type_name); @@ -1504,7 +1784,7 @@ fn zirErrorSetDecl( fn zirRetPtr( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const tracy = trace(@src()); @@ -1524,7 +1804,7 @@ fn zirRetPtr( return block.addTy(.alloc, ptr_type); } -fn zirRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -1535,7 +1815,7 @@ fn zirRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A fn zirRetType( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const tracy = trace(@src()); @@ -1546,7 +1826,7 @@ fn zirRetType( return sema.addType(sema.fn_ret_ty); } -fn zirEnsureResultUsed(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirEnsureResultUsed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const tracy = trace(@src()); defer tracy.end(); @@ -1559,7 +1839,7 @@ fn zirEnsureResultUsed(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) C fn ensureResultUsed( sema: *Sema, - block: *Scope.Block, + block: *Block, operand: Air.Inst.Ref, src: LazySrcLoc, ) CompileError!void { @@ -1570,7 +1850,7 @@ fn ensureResultUsed( } } -fn zirEnsureResultNonError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const tracy = trace(@src()); defer tracy.end(); @@ -1584,7 +1864,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde } } -fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirIndexablePtrLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -1632,7 +1912,7 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co fn zirAllocExtended( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand); @@ -1675,7 +1955,7 @@ fn zirAllocExtended( return block.addTy(.alloc, ptr_type); } -fn zirAllocComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -1695,7 +1975,7 @@ fn zirAllocInferredComptime(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air. ); } -fn zirAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -1711,7 +1991,7 @@ fn zirAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError return block.addTy(.alloc, ptr_type); } -fn zirAllocMut(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -1733,7 +2013,7 @@ fn zirAllocMut(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr fn zirAllocInferred( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, inferred_alloc_ty: Type, ) CompileError!Air.Inst.Ref { @@ -1764,7 +2044,7 @@ fn zirAllocInferred( return result; } -fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const tracy = trace(@src()); defer tracy.end(); @@ -1823,7 +2103,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde } } -fn zirValidateStructInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirValidateStructInitPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const tracy = trace(@src()); defer tracy.end(); @@ -1855,7 +2135,7 @@ fn zirValidateStructInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Ind fn validateUnionInitPtr( sema: *Sema, - block: *Scope.Block, + block: *Block, union_obj: *Module.Union, init_src: LazySrcLoc, instrs: []const Zir.Inst.Index, @@ -1894,7 +2174,7 @@ fn validateUnionInitPtr( fn validateStructInitPtr( sema: *Sema, - block: *Scope.Block, + block: *Block, struct_obj: *Module.Struct, init_src: LazySrcLoc, instrs: []const Zir.Inst.Index, @@ -1956,7 +2236,7 @@ fn validateStructInitPtr( } } -fn zirValidateArrayInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirValidateArrayInitPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO implement Sema.zirValidateArrayInitPtr", .{}); @@ -1964,7 +2244,7 @@ fn zirValidateArrayInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde fn failWithBadFieldAccess( sema: *Sema, - block: *Scope.Block, + block: *Block, struct_obj: *Module.Struct, field_src: LazySrcLoc, field_name: []const u8, @@ -1990,7 +2270,7 @@ fn failWithBadFieldAccess( fn failWithBadUnionFieldAccess( sema: *Sema, - block: *Scope.Block, + block: *Block, union_obj: *Module.Union, field_src: LazySrcLoc, field_name: []const u8, @@ -2014,7 +2294,7 @@ fn failWithBadUnionFieldAccess( return sema.failWithOwnedErrorMsg(msg); } -fn zirStoreToBlockPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirStoreToBlockPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const tracy = trace(@src()); defer tracy.end(); @@ -2039,7 +2319,7 @@ fn zirStoreToBlockPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co return sema.storePtr(block, src, bitcasted_ptr, value); } -fn zirStoreToInferredPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const tracy = trace(@src()); defer tracy.end(); @@ -2087,7 +2367,7 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) unreachable; } -fn zirSetEvalBranchQuota(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirSetEvalBranchQuota(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); const quota = try sema.resolveAlreadyCoercedInt(block, src, inst_data.operand, u32); @@ -2095,7 +2375,7 @@ fn zirSetEvalBranchQuota(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) sema.branch_quota = quota; } -fn zirStore(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const tracy = trace(@src()); defer tracy.end(); @@ -2105,7 +2385,7 @@ fn zirStore(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError return sema.storePtr(block, sema.src, ptr, value); } -fn zirStoreNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const tracy = trace(@src()); defer tracy.end(); @@ -2117,7 +2397,7 @@ fn zirStoreNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE return sema.storePtr(block, src, ptr, value); } -fn zirStr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirStr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -2136,7 +2416,7 @@ fn zirStr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A const decl_ty = try Type.Tag.array_u8_sentinel_0.create(&new_decl_arena.allocator, bytes.len); const decl_val = try Value.Tag.bytes.create(&new_decl_arena.allocator, bytes); - const new_decl = try sema.mod.createAnonymousDecl(&block.base, .{ + const new_decl = try sema.mod.createAnonymousDecl(block, .{ .ty = decl_ty, .val = decl_val, }); @@ -2145,7 +2425,7 @@ fn zirStr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A return sema.analyzeDeclRef(new_decl); } -fn zirInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { _ = block; const tracy = trace(@src()); defer tracy.end(); @@ -2154,7 +2434,7 @@ fn zirInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A return sema.addIntUnsigned(Type.initTag(.comptime_int), int); } -fn zirIntBig(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirIntBig(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { _ = block; const tracy = trace(@src()); defer tracy.end(); @@ -2172,7 +2452,7 @@ fn zirIntBig(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro ); } -fn zirFloat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { _ = block; const arena = sema.arena; const number = sema.code.instructions.items(.data)[inst].float; @@ -2182,7 +2462,7 @@ fn zirFloat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError ); } -fn zirFloat128(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirFloat128(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { _ = block; const arena = sema.arena; const inst_data = sema.code.instructions.items(.data)[inst].pl_node; @@ -2194,7 +2474,7 @@ fn zirFloat128(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr ); } -fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { +fn zirCompileError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { const tracy = trace(@src()); defer tracy.end(); @@ -2207,7 +2487,7 @@ fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compi fn zirCompileLog( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { var managed = sema.mod.compile_log_text.toManaged(sema.gpa); @@ -2239,7 +2519,7 @@ fn zirCompileLog( return Air.Inst.Ref.void_value; } -fn zirPanic(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { +fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src: LazySrcLoc = inst_data.src(); const msg_inst = sema.resolveInst(inst_data.operand); @@ -2247,7 +2527,7 @@ fn zirPanic(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError return sema.panicWithMsg(block, src, msg_inst); } -fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -2275,7 +2555,7 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compil .payload = undefined, } }, }); - var label: Scope.Block.Label = .{ + var label: Block.Label = .{ .zir_block = inst, .merges = .{ .results = .{}, @@ -2310,7 +2590,7 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compil return sema.analyzeBlockBody(parent_block, src, &child_block, merges); } -fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -2326,7 +2606,7 @@ fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Com var c_import_buf = std.ArrayList(u8).init(sema.gpa); defer c_import_buf.deinit(); - var child_block: Scope.Block = .{ + var child_block: Block = .{ .parent = parent_block, .sema = sema, .src_decl = parent_block.src_decl, @@ -2389,7 +2669,7 @@ fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Com return sema.addConstant(file_root_decl.ty, file_root_decl.val); } -fn zirSuspendBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirSuspendBlock(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(parent_block, src, "TODO: implement Sema.zirSuspendBlock", .{}); @@ -2397,7 +2677,7 @@ fn zirSuspendBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index fn zirBlock( sema: *Sema, - parent_block: *Scope.Block, + parent_block: *Block, inst: Zir.Inst.Index, ) CompileError!Air.Inst.Ref { const tracy = trace(@src()); @@ -2418,7 +2698,7 @@ fn zirBlock( .data = undefined, }); - var label: Scope.Block.Label = .{ + var label: Block.Label = .{ .zir_block = inst, .merges = .{ .results = .{}, @@ -2427,7 +2707,7 @@ fn zirBlock( }, }; - var child_block: Scope.Block = .{ + var child_block: Block = .{ .parent = parent_block, .sema = sema, .src_decl = parent_block.src_decl, @@ -2451,11 +2731,11 @@ fn zirBlock( fn resolveBlockBody( sema: *Sema, - parent_block: *Scope.Block, + parent_block: *Block, src: LazySrcLoc, - child_block: *Scope.Block, + child_block: *Block, body: []const Zir.Inst.Index, - merges: *Scope.Block.Merges, + merges: *Block.Merges, ) CompileError!Air.Inst.Ref { if (child_block.is_comptime) { return sema.resolveBody(child_block, body); @@ -2467,10 +2747,10 @@ fn resolveBlockBody( fn analyzeBlockBody( sema: *Sema, - parent_block: *Scope.Block, + parent_block: *Block, src: LazySrcLoc, - child_block: *Scope.Block, - merges: *Scope.Block.Merges, + child_block: *Block, + merges: *Block.Merges, ) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -2568,7 +2848,7 @@ fn analyzeBlockBody( return Air.indexToRef(merges.block_inst); } -fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const tracy = trace(@src()); defer tracy.end(); @@ -2586,7 +2866,7 @@ fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro try sema.analyzeExport(block, src, options, decl); } -fn zirExportValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirExportValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const tracy = trace(@src()); defer tracy.end(); @@ -2606,7 +2886,7 @@ fn zirExportValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil pub fn analyzeExport( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, borrowed_options: std.builtin.ExportOptions, exported_decl: *Decl, @@ -2682,7 +2962,7 @@ pub fn analyzeExport( errdefer de_gop.value_ptr.* = gpa.shrink(de_gop.value_ptr.*, de_gop.value_ptr.len - 1); } -fn zirSetAlignStack(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirSetAlignStack(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const src: LazySrcLoc = inst_data.src(); @@ -2714,7 +2994,7 @@ fn zirSetAlignStack(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp gop.value_ptr.* = .{ .alignment = alignment, .src = src }; } -fn zirSetCold(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirSetCold(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const is_cold = try sema.resolveConstBool(block, operand_src, inst_data.operand); @@ -2722,19 +3002,19 @@ fn zirSetCold(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr func.is_cold = is_cold; } -fn zirSetFloatMode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirSetFloatMode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src: LazySrcLoc = inst_data.src(); return sema.fail(block, src, "TODO: implement Sema.zirSetFloatMode", .{}); } -fn zirSetRuntimeSafety(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirSetRuntimeSafety(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; block.want_safety = try sema.resolveConstBool(block, operand_src, inst_data.operand); } -fn zirFence(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirFence(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { if (block.is_comptime) return; const inst_data = sema.code.instructions.items(.data)[inst].un_node; @@ -2751,7 +3031,7 @@ fn zirFence(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError }); } -fn zirBreak(sema: *Sema, start_block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { +fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { const tracy = trace(@src()); defer tracy.end(); @@ -2773,7 +3053,7 @@ fn zirBreak(sema: *Sema, start_block: *Scope.Block, inst: Zir.Inst.Index) Compil } } -fn zirDbgStmt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const tracy = trace(@src()); defer tracy.end(); @@ -2793,7 +3073,7 @@ fn zirDbgStmt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr }); } -fn zirDeclRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].str_tok; const src = inst_data.src(); const decl_name = inst_data.get(sema.code); @@ -2801,7 +3081,7 @@ fn zirDeclRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr return sema.analyzeDeclRef(decl); } -fn zirDeclVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].str_tok; const src = inst_data.src(); const decl_name = inst_data.get(sema.code); @@ -2809,7 +3089,7 @@ fn zirDeclVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr return sema.analyzeDeclVal(block, src, decl); } -fn lookupIdentifier(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, name: []const u8) !*Decl { +fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: []const u8) !*Decl { var namespace = block.namespace; while (true) { if (try sema.lookupInNamespace(block, src, namespace, name, false)) |decl| { @@ -2824,9 +3104,9 @@ fn lookupIdentifier(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, name: []c /// only for ones in the specified namespace. fn lookupInNamespace( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, - namespace: *Scope.Namespace, + namespace: *Namespace, ident_name: []const u8, observe_usingnamespace: bool, ) CompileError!?*Decl { @@ -2842,7 +3122,7 @@ fn lookupInNamespace( const src_file = block.namespace.file_scope; const gpa = sema.gpa; - var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Scope.Namespace, void) = .{}; + var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Namespace, void) = .{}; defer checked_namespaces.deinit(gpa); // Keep track of name conflicts for error notes. @@ -2914,7 +3194,7 @@ fn lookupInNamespace( fn zirCall( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, ) CompileError!Air.Inst.Ref { const tracy = trace(@src()); @@ -3016,7 +3296,7 @@ const GenericRemoveAdapter = struct { fn analyzeCall( sema: *Sema, - block: *Scope.Block, + block: *Block, func: Air.Inst.Ref, func_src: LazySrcLoc, call_src: LazySrcLoc, @@ -3097,7 +3377,7 @@ fn analyzeCall( // Analyze the ZIR. The same ZIR gets analyzed into a runtime function // or an inlined call depending on what union tag the `label` field is - // set to in the `Scope.Block`. + // set to in the `Block`. // This block instruction will be used to capture the return value from the // inlined function. const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len); @@ -3107,7 +3387,7 @@ fn analyzeCall( }); // This one is shared among sub-blocks within the same callee, but not // shared among the entire inline/comptime call stack. - var inlining: Scope.Block.Inlining = .{ + var inlining: Block.Inlining = .{ .comptime_result = undefined, .merges = .{ .results = .{}, @@ -3135,7 +3415,7 @@ fn analyzeCall( var wip_captures = try WipCaptureScope.init(gpa, sema.perm_arena, module_fn.owner_decl.src_scope); defer wip_captures.deinit(); - var child_block: Scope.Block = .{ + var child_block: Block = .{ .parent = null, .sema = sema, .src_decl = module_fn.owner_decl, @@ -3437,7 +3717,7 @@ fn analyzeCall( var wip_captures = try WipCaptureScope.init(gpa, sema.perm_arena, new_decl.src_scope); defer wip_captures.deinit(); - var child_block: Scope.Block = .{ + var child_block: Block = .{ .parent = null, .sema = &child_sema, .src_decl = new_decl, @@ -3598,7 +3878,7 @@ fn analyzeCall( fn finishGenericCall( sema: *Sema, - block: *Scope.Block, + block: *Block, call_src: LazySrcLoc, callee: *Module.Fn, func_src: LazySrcLoc, @@ -3665,7 +3945,7 @@ fn finishGenericCall( return func_inst; } -fn zirIntType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirIntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { _ = block; const tracy = trace(@src()); defer tracy.end(); @@ -3676,7 +3956,7 @@ fn zirIntType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr return sema.addType(ty); } -fn zirOptionalType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -3688,7 +3968,7 @@ fn zirOptionalType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compi return sema.addType(opt_type); } -fn zirElemType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); const array_type = try sema.resolveType(block, src, inst_data.operand); @@ -3696,7 +3976,7 @@ fn zirElemType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr return sema.addType(elem_type); } -fn zirVectorType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const elem_type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; @@ -3710,7 +3990,7 @@ fn zirVectorType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile return sema.addType(vector_type); } -fn zirArrayType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -3722,7 +4002,7 @@ fn zirArrayType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE return sema.addType(array_ty); } -fn zirArrayTypeSentinel(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirArrayTypeSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -3738,7 +4018,7 @@ fn zirArrayTypeSentinel(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) return sema.addType(array_ty); } -fn zirAnyframeType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirAnyframeType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -3750,7 +4030,7 @@ fn zirAnyframeType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compi return sema.addType(anyframe_type); } -fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -3770,7 +4050,7 @@ fn zirErrorUnionType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Com return sema.addType(err_union_ty); } -fn zirErrorValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { _ = block; const tracy = trace(@src()); defer tracy.end(); @@ -3788,7 +4068,7 @@ fn zirErrorValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile ); } -fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirErrorToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -3815,7 +4095,7 @@ fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile return block.addTyOp(.bitcast, result_ty, op_coerced); } -fn zirIntToError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirIntToError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -3845,7 +4125,7 @@ fn zirIntToError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile return block.addTyOp(.bitcast, Type.initTag(.anyerror), op); } -fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -3929,7 +4209,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Com return sema.addConstant(Type.initTag(.type), try Value.Tag.ty.create(sema.arena, error_set_ty)); } -fn zirEnumLiteral(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { _ = block; const tracy = trace(@src()); defer tracy.end(); @@ -3942,7 +4222,7 @@ fn zirEnumLiteral(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil ); } -fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirEnumToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const arena = sema.arena; const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); @@ -3988,7 +4268,7 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE return block.addTyOp(.bitcast, int_tag_ty, enum_tag); } -fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const target = sema.mod.getTarget(); const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; @@ -4038,7 +4318,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE /// Pointer in, pointer out. fn zirOptionalPayloadPtr( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, safety_check: bool, ) CompileError!Air.Inst.Ref { @@ -4087,7 +4367,7 @@ fn zirOptionalPayloadPtr( /// Value in, value out. fn zirOptionalPayload( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, safety_check: bool, ) CompileError!Air.Inst.Ref { @@ -4124,7 +4404,7 @@ fn zirOptionalPayload( /// Value in, value out fn zirErrUnionPayload( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, safety_check: bool, ) CompileError!Air.Inst.Ref { @@ -4159,7 +4439,7 @@ fn zirErrUnionPayload( /// Pointer in, pointer out. fn zirErrUnionPayloadPtr( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, safety_check: bool, ) CompileError!Air.Inst.Ref { @@ -4203,7 +4483,7 @@ fn zirErrUnionPayloadPtr( } /// Value in, value out -fn zirErrUnionCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4226,7 +4506,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compi } /// Pointer in, value out -fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4252,7 +4532,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co return block.addTyOp(.unwrap_errunion_err_ptr, result_ty, operand); } -fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const tracy = trace(@src()); defer tracy.end(); @@ -4269,7 +4549,7 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde fn zirFunc( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, inferred_error_set: bool, ) CompileError!Air.Inst.Ref { @@ -4312,7 +4592,7 @@ fn zirFunc( fn funcCommon( sema: *Sema, - block: *Scope.Block, + block: *Block, src_node_offset: i32, body_inst: Zir.Inst.Index, ret_ty_body: []const Zir.Inst.Index, @@ -4511,7 +4791,7 @@ fn funcCommon( fn zirParam( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, is_comptime: bool, ) CompileError!void { @@ -4581,7 +4861,7 @@ fn zirParam( fn zirParamAnytype( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, is_comptime: bool, ) CompileError!void { @@ -4616,7 +4896,7 @@ fn zirParamAnytype( try sema.inst_map.put(sema.gpa, inst, .generic_poison); } -fn zirAs(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirAs(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4624,7 +4904,7 @@ fn zirAs(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Ai return sema.analyzeAs(block, .unneeded, bin_inst.lhs, bin_inst.rhs); } -fn zirAsNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirAsNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4636,7 +4916,7 @@ fn zirAsNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro fn analyzeAs( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, zir_dest_type: Zir.Inst.Ref, zir_operand: Zir.Inst.Ref, @@ -4646,7 +4926,7 @@ fn analyzeAs( return sema.coerce(block, dest_type, operand, src); } -fn zirPtrToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4663,7 +4943,7 @@ fn zirPtrToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr return block.addUnOp(.ptrtoint, ptr); } -fn zirFieldVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirFieldVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4682,7 +4962,7 @@ fn zirFieldVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr } } -fn zirFieldPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirFieldPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4695,7 +4975,7 @@ fn zirFieldPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src); } -fn zirFieldCallBind(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirFieldCallBind(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4708,7 +4988,7 @@ fn zirFieldCallBind(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp return sema.fieldCallBind(block, src, object_ptr, field_name, field_name_src); } -fn zirFieldValNamed(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirFieldValNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4721,7 +5001,7 @@ fn zirFieldValNamed(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp return sema.fieldVal(block, src, object, field_name, field_name_src); } -fn zirFieldPtrNamed(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirFieldPtrNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4734,7 +5014,7 @@ fn zirFieldPtrNamed(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp return sema.fieldPtr(block, src, object_ptr, field_name, field_name_src); } -fn zirFieldCallBindNamed(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirFieldCallBindNamed(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4747,7 +5027,7 @@ fn zirFieldCallBindNamed(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) return sema.fieldCallBind(block, src, object_ptr, field_name, field_name_src); } -fn zirIntCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4773,7 +5053,7 @@ fn zirIntCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr return block.addTyOp(.intcast, dest_type, operand); } -fn zirBitcast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4787,7 +5067,7 @@ fn zirBitcast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr return sema.bitcast(block, dest_type, operand, operand_src); } -fn zirFloatCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4838,7 +5118,7 @@ fn zirFloatCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE return block.addTyOp(.fptrunc, dest_type, operand); } -fn zirElemVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirElemVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4848,7 +5128,7 @@ fn zirElemVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr return sema.elemVal(block, sema.src, array, elem_index, sema.src); } -fn zirElemValNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirElemValNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4861,7 +5141,7 @@ fn zirElemValNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil return sema.elemVal(block, src, array, elem_index, elem_index_src); } -fn zirElemPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4871,7 +5151,7 @@ fn zirElemPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr return sema.elemPtr(block, sema.src, array_ptr, elem_index, sema.src); } -fn zirElemPtrNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4884,7 +5164,7 @@ fn zirElemPtrNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src); } -fn zirSliceStart(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirSliceStart(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4897,7 +5177,7 @@ fn zirSliceStart(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile return sema.analyzeSlice(block, src, array_ptr, start, .none, .none, .unneeded); } -fn zirSliceEnd(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirSliceEnd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4911,7 +5191,7 @@ fn zirSliceEnd(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr return sema.analyzeSlice(block, src, array_ptr, start, end, .none, .unneeded); } -fn zirSliceSentinel(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -4929,7 +5209,7 @@ fn zirSliceSentinel(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp fn zirSwitchCapture( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, is_multi: bool, is_ref: bool, @@ -4949,7 +5229,7 @@ fn zirSwitchCapture( fn zirSwitchCaptureElse( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, is_ref: bool, ) CompileError!Air.Inst.Ref { @@ -4967,7 +5247,7 @@ fn zirSwitchCaptureElse( fn zirSwitchBlock( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, is_ref: bool, special_prong: Zir.SpecialProng, @@ -5000,7 +5280,7 @@ fn zirSwitchBlock( fn zirSwitchBlockMulti( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, is_ref: bool, special_prong: Zir.SpecialProng, @@ -5033,7 +5313,7 @@ fn zirSwitchBlockMulti( fn analyzeSwitch( sema: *Sema, - block: *Scope.Block, + block: *Block, operand: Air.Inst.Ref, extra_end: usize, special_prong: Zir.SpecialProng, @@ -5451,7 +5731,7 @@ fn analyzeSwitch( .tag = .block, .data = undefined, }); - var label: Scope.Block.Label = .{ + var label: Block.Label = .{ .zir_block = switch_inst, .merges = .{ .results = .{}, @@ -5460,7 +5740,7 @@ fn analyzeSwitch( }, }; - var child_block: Scope.Block = .{ + var child_block: Block = .{ .parent = block, .sema = sema, .src_decl = block.src_decl, @@ -5771,7 +6051,7 @@ fn analyzeSwitch( fn resolveSwitchItemVal( sema: *Sema, - block: *Scope.Block, + block: *Block, item_ref: Zir.Inst.Ref, switch_node_offset: i32, switch_prong_src: Module.SwitchProngSrc, @@ -5798,7 +6078,7 @@ fn resolveSwitchItemVal( fn validateSwitchRange( sema: *Sema, - block: *Scope.Block, + block: *Block, range_set: *RangeSet, first_ref: Zir.Inst.Ref, last_ref: Zir.Inst.Ref, @@ -5814,7 +6094,7 @@ fn validateSwitchRange( fn validateSwitchItem( sema: *Sema, - block: *Scope.Block, + block: *Block, range_set: *RangeSet, item_ref: Zir.Inst.Ref, operand_ty: Type, @@ -5828,7 +6108,7 @@ fn validateSwitchItem( fn validateSwitchItemEnum( sema: *Sema, - block: *Scope.Block, + block: *Block, seen_fields: []?Module.SwitchProngSrc, item_ref: Zir.Inst.Ref, src_node_offset: i32, @@ -5862,7 +6142,7 @@ fn validateSwitchItemEnum( fn validateSwitchDupe( sema: *Sema, - block: *Scope.Block, + block: *Block, maybe_prev_src: ?Module.SwitchProngSrc, switch_prong_src: Module.SwitchProngSrc, src_node_offset: i32, @@ -5893,7 +6173,7 @@ fn validateSwitchDupe( fn validateSwitchItemBool( sema: *Sema, - block: *Scope.Block, + block: *Block, true_count: *u8, false_count: *u8, item_ref: Zir.Inst.Ref, @@ -5916,7 +6196,7 @@ const ValueSrcMap = std.HashMap(Value, Module.SwitchProngSrc, Value.HashContext, fn validateSwitchItemSparse( sema: *Sema, - block: *Scope.Block, + block: *Block, seen_values: *ValueSrcMap, item_ref: Zir.Inst.Ref, src_node_offset: i32, @@ -5929,7 +6209,7 @@ fn validateSwitchItemSparse( fn validateSwitchNoRange( sema: *Sema, - block: *Scope.Block, + block: *Block, ranges_len: u32, operand_ty: Type, src_node_offset: i32, @@ -5960,7 +6240,7 @@ fn validateSwitchNoRange( return sema.failWithOwnedErrorMsg(msg); } -fn zirHasField(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; _ = extra; @@ -5969,7 +6249,7 @@ fn zirHasField(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr return sema.fail(block, src, "TODO implement zirHasField", .{}); } -fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; const src = inst_data.src(); @@ -5985,14 +6265,14 @@ fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr .{container_type}, ); if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl| { - if (decl.is_pub or decl.getFileScope() == block.base.namespace().file_scope) { + if (decl.is_pub or decl.getFileScope() == block.getFileScope()) { return Air.Inst.Ref.bool_true; } } return Air.Inst.Ref.bool_false; } -fn zirImport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -6017,7 +6297,7 @@ fn zirImport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro return sema.addConstant(file_root_decl.ty, file_root_decl.val); } -fn zirRetErrValueCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirRetErrValueCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { _ = block; _ = inst; return sema.fail(block, sema.src, "TODO implement zirRetErrValueCode", .{}); @@ -6025,7 +6305,7 @@ fn zirRetErrValueCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co fn zirShl( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, air_tag: Air.Inst.Tag, ) CompileError!Air.Inst.Ref { @@ -6076,7 +6356,7 @@ fn zirShl( return block.addBinOp(air_tag, lhs, rhs); } -fn zirShr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirShr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -6109,7 +6389,7 @@ fn zirShr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A fn zirBitwise( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, air_tag: Air.Inst.Tag, ) CompileError!Air.Inst.Ref { @@ -6175,7 +6455,7 @@ fn zirBitwise( return block.addBinOp(air_tag, casted_lhs, casted_rhs); } -fn zirBitNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -6183,7 +6463,7 @@ fn zirBitNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro return sema.fail(block, sema.src, "TODO implement zirBitNot", .{}); } -fn zirArrayCat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -6267,7 +6547,7 @@ fn getArrayCatInfo(t: Type) ?Type.ArrayInfo { }; } -fn zirArrayMul(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -6321,7 +6601,7 @@ fn zirArrayMul(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr fn zirNegate( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, tag_override: Zir.Inst.Tag, ) CompileError!Air.Inst.Ref { @@ -6340,7 +6620,7 @@ fn zirNegate( fn zirArithmetic( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, zir_tag: Zir.Inst.Tag, ) CompileError!Air.Inst.Ref { @@ -6360,7 +6640,7 @@ fn zirArithmetic( fn zirOverflowArithmetic( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const tracy = trace(@src()); @@ -6374,7 +6654,7 @@ fn zirOverflowArithmetic( fn analyzeArithmetic( sema: *Sema, - block: *Scope.Block, + block: *Block, /// TODO performance investigation: make this comptime? zir_tag: Zir.Inst.Tag, lhs: Air.Inst.Ref, @@ -7035,7 +7315,7 @@ fn analyzeArithmetic( return block.addBinOp(rs.air_tag, casted_lhs, casted_rhs); } -fn zirLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -7048,7 +7328,7 @@ fn zirLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError! fn zirAsm( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, inst: Zir.Inst.Index, ) CompileError!Air.Inst.Ref { @@ -7127,7 +7407,7 @@ fn zirAsm( /// Only called for equality operators. See also `zirCmp`. fn zirCmpEq( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, op: std.math.CompareOperator, air_tag: Air.Inst.Tag, @@ -7216,7 +7496,7 @@ fn zirCmpEq( fn analyzeCmpUnionTag( sema: *Sema, - block: *Scope.Block, + block: *Block, un: Air.Inst.Ref, un_src: LazySrcLoc, tag: Air.Inst.Ref, @@ -7239,7 +7519,7 @@ fn analyzeCmpUnionTag( /// Only called for non-equality operators. See also `zirCmpEq`. fn zirCmp( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, op: std.math.CompareOperator, ) CompileError!Air.Inst.Ref { @@ -7258,7 +7538,7 @@ fn zirCmp( fn analyzeCmp( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref, @@ -7289,7 +7569,7 @@ fn analyzeCmp( fn cmpSelf( sema: *Sema, - block: *Scope.Block, + block: *Block, casted_lhs: Air.Inst.Ref, casted_rhs: Air.Inst.Ref, op: std.math.CompareOperator, @@ -7347,7 +7627,7 @@ fn cmpSelf( /// cmp_neq(x, true ) => not(x) fn runtimeBoolCmp( sema: *Sema, - block: *Scope.Block, + block: *Block, op: std.math.CompareOperator, lhs: Air.Inst.Ref, rhs: bool, @@ -7361,7 +7641,7 @@ fn runtimeBoolCmp( } } -fn zirSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; @@ -7402,7 +7682,7 @@ fn zirSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro return sema.addIntUnsigned(Type.initTag(.comptime_int), abi_size); } -fn zirBitSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand); @@ -7413,17 +7693,17 @@ fn zirBitSizeOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE fn zirThis( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { - const this_decl = block.base.namespace().getDecl(); + const this_decl = block.namespace.getDecl(); const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; return sema.analyzeDeclVal(block, src, this_decl); } fn zirClosureCapture( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, ) CompileError!void { // TODO: Compile error when closed over values are modified @@ -7437,7 +7717,7 @@ fn zirClosureCapture( fn zirClosureGet( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, ) CompileError!Air.Inst.Ref { // TODO CLOSURE: Test this with inline functions @@ -7459,7 +7739,7 @@ fn zirClosureGet( fn zirRetAddr( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; @@ -7468,14 +7748,14 @@ fn zirRetAddr( fn zirBuiltinSrc( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; return sema.fail(block, src, "TODO: implement Sema.zirBuiltinSrc", .{}); } -fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); const ty = try sema.resolveType(block, src, inst_data.operand); @@ -7680,7 +7960,7 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr } } -fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { _ = block; const zir_datas = sema.code.instructions.items(.data); const inst_data = zir_datas[inst].un_node; @@ -7689,7 +7969,7 @@ fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro return sema.addType(operand_ty); } -fn zirTypeofElem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirTypeofElem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { _ = block; const inst_data = sema.code.instructions.items(.data)[inst].un_node; const operand_ptr = sema.resolveInst(inst_data.operand); @@ -7697,7 +7977,7 @@ fn zirTypeofElem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile return sema.addType(elem_ty); } -fn zirTypeofLog2IntType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirTypeofLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); const operand = sema.resolveInst(inst_data.operand); @@ -7705,14 +7985,14 @@ fn zirTypeofLog2IntType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) return sema.log2IntType(block, operand_ty, src); } -fn zirLog2IntType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirLog2IntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); const operand = try sema.resolveType(block, src, inst_data.operand); return sema.log2IntType(block, operand, src); } -fn log2IntType(sema: *Sema, block: *Scope.Block, operand: Type, src: LazySrcLoc) CompileError!Air.Inst.Ref { +fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) CompileError!Air.Inst.Ref { switch (operand.zigTypeTag()) { .ComptimeInt => return Air.Inst.Ref.comptime_int_type, .Int => { @@ -7735,7 +8015,7 @@ fn log2IntType(sema: *Sema, block: *Scope.Block, operand: Type, src: LazySrcLoc) fn zirTypeofPeer( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const tracy = trace(@src()); @@ -7756,7 +8036,7 @@ fn zirTypeofPeer( return sema.addType(result_type); } -fn zirBoolNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -7780,7 +8060,7 @@ fn zirBoolNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr fn zirBoolBr( sema: *Sema, - parent_block: *Scope.Block, + parent_block: *Block, inst: Zir.Inst.Index, is_bool_or: bool, ) CompileError!Air.Inst.Ref { @@ -7866,7 +8146,7 @@ fn zirBoolBr( fn zirIsNonNull( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, ) CompileError!Air.Inst.Ref { const tracy = trace(@src()); @@ -7880,7 +8160,7 @@ fn zirIsNonNull( fn zirIsNonNullPtr( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, ) CompileError!Air.Inst.Ref { const tracy = trace(@src()); @@ -7893,7 +8173,7 @@ fn zirIsNonNullPtr( return sema.analyzeIsNull(block, src, loaded, true); } -fn zirIsNonErr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirIsNonErr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -7902,7 +8182,7 @@ fn zirIsNonErr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr return sema.analyzeIsNonErr(block, inst_data.src(), operand); } -fn zirIsNonErrPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -7915,7 +8195,7 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil fn zirCondbr( sema: *Sema, - parent_block: *Scope.Block, + parent_block: *Block, inst: Zir.Inst.Index, ) CompileError!Zir.Inst.Index { const tracy = trace(@src()); @@ -7970,7 +8250,7 @@ fn zirCondbr( return always_noreturn; } -fn zirUnreachable(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { +fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { const tracy = trace(@src()); defer tracy.end(); @@ -7989,7 +8269,7 @@ fn zirUnreachable(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil fn zirRetErrValue( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, ) CompileError!Zir.Inst.Index { const inst_data = sema.code.instructions.items(.data)[inst].str_tok; @@ -8013,7 +8293,7 @@ fn zirRetErrValue( fn zirRetCoerce( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, ) CompileError!Zir.Inst.Index { const tracy = trace(@src()); @@ -8026,7 +8306,7 @@ fn zirRetCoerce( return sema.analyzeRet(block, operand, src, true); } -fn zirRetNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { +fn zirRetNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { const tracy = trace(@src()); defer tracy.end(); @@ -8041,7 +8321,7 @@ fn zirRetNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr return sema.analyzeRet(block, operand, src, false); } -fn zirRetLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { +fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { const tracy = trace(@src()); defer tracy.end(); @@ -8058,7 +8338,7 @@ fn zirRetLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr fn analyzeRet( sema: *Sema, - block: *Scope.Block, + block: *Block, uncasted_operand: Air.Inst.Ref, src: LazySrcLoc, need_coercion: bool, @@ -8091,7 +8371,7 @@ fn floatOpAllowed(tag: Zir.Inst.Tag) bool { }; } -fn zirPtrTypeSimple(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -8108,7 +8388,7 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp return sema.addType(ty); } -fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -8168,7 +8448,7 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr return sema.addType(ty); } -fn zirStructInitEmpty(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -8179,13 +8459,13 @@ fn zirStructInitEmpty(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co return sema.addConstant(struct_type, Value.initTag(.empty_struct_value)); } -fn zirUnionInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirUnionInitPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirUnionInitPtr", .{}); } -fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) CompileError!Air.Inst.Ref { +fn zirStructInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: bool) CompileError!Air.Inst.Ref { const gpa = sema.gpa; const zir_datas = sema.code.instructions.items(.data); const inst_data = zir_datas[inst].pl_node; @@ -8326,7 +8606,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: unreachable; } -fn zirStructInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) CompileError!Air.Inst.Ref { +fn zirStructInitAnon(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: bool) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); @@ -8334,7 +8614,7 @@ fn zirStructInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ return sema.fail(block, src, "TODO: Sema.zirStructInitAnon", .{}); } -fn zirArrayInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) CompileError!Air.Inst.Ref { +fn zirArrayInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: bool) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); @@ -8386,7 +8666,7 @@ fn zirArrayInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: try sema.analyzeLoad(block, .unneeded, alloc, .unneeded); } -fn zirArrayInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) CompileError!Air.Inst.Ref { +fn zirArrayInitAnon(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: bool) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); @@ -8394,13 +8674,13 @@ fn zirArrayInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_r return sema.fail(block, src, "TODO: Sema.zirArrayInitAnon", .{}); } -fn zirFieldTypeRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirFieldTypeRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirFieldTypeRef", .{}); } -fn zirFieldType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirFieldType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const extra = sema.code.extraData(Zir.Inst.FieldType, inst_data.payload_index).data; const src = inst_data.src(); @@ -8428,7 +8708,7 @@ fn zirFieldType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE fn zirErrorReturnTrace( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; @@ -8437,7 +8717,7 @@ fn zirErrorReturnTrace( fn zirFrame( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; @@ -8446,14 +8726,14 @@ fn zirFrame( fn zirFrameAddress( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; return sema.fail(block, src, "TODO: Sema.zirFrameAddress", .{}); } -fn zirAlignOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const ty = try sema.resolveType(block, operand_src, inst_data.operand); @@ -8462,7 +8742,7 @@ fn zirAlignOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr return sema.addIntUnsigned(Type.comptime_int, abi_align); } -fn zirBoolToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const operand = sema.resolveInst(inst_data.operand); @@ -8474,31 +8754,31 @@ fn zirBoolToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE return block.addUnOp(.bool_to_int, operand); } -fn zirEmbedFile(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirEmbedFile", .{}); } -fn zirErrorName(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirErrorName", .{}); } -fn zirUnaryMath(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirUnaryMath(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirUnaryMath", .{}); } -fn zirTagName(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirTagName", .{}); } -fn zirReify(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); const type_info_ty = try sema.getBuiltinType(block, src, "TypeInfo"); @@ -8551,32 +8831,32 @@ fn zirReify(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError } } -fn zirTypeName(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirTypeName", .{}); } -fn zirFrameType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirFrameType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirFrameType", .{}); } -fn zirFrameSize(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirFrameSize(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirFrameSize", .{}); } -fn zirFloatToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); // TODO don't forget the safety check! return sema.fail(block, src, "TODO: Sema.zirFloatToInt", .{}); } -fn zirIntToFloat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; @@ -8598,7 +8878,7 @@ fn zirIntToFloat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile return block.addTyOp(.int_to_float, dest_ty, operand); } -fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); @@ -8654,13 +8934,13 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr return block.addTyOp(.bitcast, type_res, operand_coerced); } -fn zirErrSetCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirErrSetCast", .{}); } -fn zirPtrCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; @@ -8684,7 +8964,7 @@ fn zirPtrCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr return block.addTyOp(.bitcast, dest_ty, operand); } -fn zirTruncate(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; @@ -8744,13 +9024,13 @@ fn zirTruncate(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr return block.addTyOp(.trunc, dest_ty, operand); } -fn zirAlignCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirAlignCast", .{}); } -fn zirClz(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirClz(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; @@ -8777,7 +9057,7 @@ fn zirClz(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A return block.addTyOp(.clz, result_ty, operand); } -fn zirCtz(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirCtz(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; @@ -8804,62 +9084,62 @@ fn zirCtz(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!A return block.addTyOp(.ctz, result_ty, operand); } -fn zirPopCount(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirPopCount(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirPopCount", .{}); } -fn zirByteSwap(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirByteSwap", .{}); } -fn zirBitReverse(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirBitReverse", .{}); } -fn zirDivExact(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirDivExact", .{}); } -fn zirDivFloor(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirDivFloor", .{}); } -fn zirDivTrunc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirDivTrunc", .{}); } -fn zirShrExact(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirShrExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirShrExact", .{}); } -fn zirBitOffsetOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirBitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirBitOffsetOf", .{}); } -fn zirOffsetOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirOffsetOf", .{}); } /// Returns `true` if the type was a comptime_int. -fn checkIntType(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type) CompileError!bool { +fn checkIntType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!bool { switch (ty.zigTypeTag()) { .ComptimeInt => return true, .Int => return false, @@ -8869,7 +9149,7 @@ fn checkIntType(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type) Com fn checkFloatType( sema: *Sema, - block: *Scope.Block, + block: *Block, ty_src: LazySrcLoc, ty: Type, ) CompileError!void { @@ -8883,7 +9163,7 @@ fn checkFloatType( fn checkAtomicOperandType( sema: *Sema, - block: *Scope.Block, + block: *Block, ty_src: LazySrcLoc, ty: Type, ) CompileError!void { @@ -8930,7 +9210,7 @@ fn checkAtomicOperandType( fn resolveExportOptions( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref, ) CompileError!std.builtin.ExportOptions { @@ -8955,7 +9235,7 @@ fn resolveExportOptions( fn resolveAtomicOrder( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref, ) CompileError!std.builtin.AtomicOrder { @@ -8968,7 +9248,7 @@ fn resolveAtomicOrder( fn resolveAtomicRmwOp( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref, ) CompileError!std.builtin.AtomicRmwOp { @@ -8981,7 +9261,7 @@ fn resolveAtomicRmwOp( fn zirCmpxchg( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, air_tag: Air.Inst.Tag, ) CompileError!Air.Inst.Ref { @@ -9069,31 +9349,31 @@ fn zirCmpxchg( }); } -fn zirSplat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirSplat", .{}); } -fn zirReduce(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirReduce", .{}); } -fn zirShuffle(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirShuffle", .{}); } -fn zirSelect(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirSelect(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirSelect", .{}); } -fn zirAtomicLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirAtomicLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; // zig fmt: off @@ -9138,7 +9418,7 @@ fn zirAtomicLoad(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile }); } -fn zirAtomicRmw(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirAtomicRmw(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const extra = sema.code.extraData(Zir.Inst.AtomicRmw, inst_data.payload_index).data; const src = inst_data.src(); @@ -9216,7 +9496,7 @@ fn zirAtomicRmw(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE }); } -fn zirAtomicStore(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirAtomicStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const extra = sema.code.extraData(Zir.Inst.AtomicStore, inst_data.payload_index).data; const src = inst_data.src(); @@ -9250,37 +9530,37 @@ fn zirAtomicStore(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil return sema.storePtr2(block, src, ptr, ptr_src, operand, operand_src, air_tag); } -fn zirMulAdd(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirMulAdd(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirMulAdd", .{}); } -fn zirBuiltinCall(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirBuiltinCall", .{}); } -fn zirFieldPtrType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirFieldPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirFieldPtrType", .{}); } -fn zirFieldParentPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirFieldParentPtr", .{}); } -fn zirMaximum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirMaximum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirMaximum", .{}); } -fn zirMemcpy(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const extra = sema.code.extraData(Zir.Inst.Memcpy, inst_data.payload_index).data; const src = inst_data.src(); @@ -9345,7 +9625,7 @@ fn zirMemcpy(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro }); } -fn zirMemset(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { +fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const extra = sema.code.extraData(Zir.Inst.Memset, inst_data.payload_index).data; const src = inst_data.src(); @@ -9391,19 +9671,19 @@ fn zirMemset(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro }); } -fn zirMinimum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirMinimum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirMinimum", .{}); } -fn zirBuiltinAsyncCall(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirBuiltinAsyncCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirBuiltinAsyncCall", .{}); } -fn zirResume(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirResume(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); return sema.fail(block, src, "TODO: Sema.zirResume", .{}); @@ -9411,7 +9691,7 @@ fn zirResume(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro fn zirAwait( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Zir.Inst.Index, is_nosuspend: bool, ) CompileError!Air.Inst.Ref { @@ -9424,7 +9704,7 @@ fn zirAwait( fn zirVarExtended( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand); @@ -9499,7 +9779,7 @@ fn zirVarExtended( fn zirFuncExtended( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, inst: Zir.Inst.Index, ) CompileError!Air.Inst.Ref { @@ -9566,7 +9846,7 @@ fn zirFuncExtended( fn zirCUndef( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; @@ -9579,7 +9859,7 @@ fn zirCUndef( fn zirCInclude( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; @@ -9592,7 +9872,7 @@ fn zirCInclude( fn zirCDefine( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; @@ -9610,7 +9890,7 @@ fn zirCDefine( fn zirWasmMemorySize( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; @@ -9620,7 +9900,7 @@ fn zirWasmMemorySize( fn zirWasmMemoryGrow( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; @@ -9630,7 +9910,7 @@ fn zirWasmMemoryGrow( fn zirBuiltinExtern( sema: *Sema, - block: *Scope.Block, + block: *Block, extended: Zir.Inst.Extended.InstData, ) CompileError!Air.Inst.Ref { const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; @@ -9638,13 +9918,13 @@ fn zirBuiltinExtern( return sema.fail(block, src, "TODO: implement Sema.zirBuiltinExtern", .{}); } -fn requireFunctionBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void { +fn requireFunctionBlock(sema: *Sema, block: *Block, src: LazySrcLoc) !void { if (sema.func == null) { return sema.fail(block, src, "instruction illegal outside function body", .{}); } } -fn requireRuntimeBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void { +fn requireRuntimeBlock(sema: *Sema, block: *Block, src: LazySrcLoc) !void { if (block.is_comptime) { return sema.failWithNeededComptime(block, src); } @@ -9654,7 +9934,7 @@ fn requireRuntimeBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void /// Emit a compile error if type cannot be used for a runtime variable. fn validateVarType( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, var_ty: Type, is_extern: bool, @@ -9713,13 +9993,13 @@ pub const PanicId = enum { fn addSafetyCheck( sema: *Sema, - parent_block: *Scope.Block, + parent_block: *Block, ok: Air.Inst.Ref, panic_id: PanicId, ) !void { const gpa = sema.gpa; - var fail_block: Scope.Block = .{ + var fail_block: Block = .{ .parent = parent_block, .sema = sema, .src_decl = parent_block.src_decl, @@ -9783,7 +10063,7 @@ fn addSafetyCheck( fn panicWithMsg( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.Ref, ) !Zir.Inst.Index { @@ -9817,7 +10097,7 @@ fn panicWithMsg( fn safetyPanic( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, panic_id: PanicId, ) CompileError!Zir.Inst.Index { @@ -9845,7 +10125,7 @@ fn safetyPanic( return sema.panicWithMsg(block, src, casted_msg_inst); } -fn emitBackwardBranch(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void { +fn emitBackwardBranch(sema: *Sema, block: *Block, src: LazySrcLoc) !void { sema.branch_count += 1; if (sema.branch_count > sema.branch_quota) { // TODO show the "called from here" stack @@ -9855,7 +10135,7 @@ fn emitBackwardBranch(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void { fn fieldVal( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, object: Air.Inst.Ref, field_name: []const u8, @@ -10036,7 +10316,7 @@ fn fieldVal( fn fieldPtr( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, object_ptr: Air.Inst.Ref, field_name: []const u8, @@ -10227,7 +10507,7 @@ fn fieldPtr( fn fieldCallBind( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, raw_ptr: Air.Inst.Ref, field_name: []const u8, @@ -10368,9 +10648,9 @@ fn fieldCallBind( fn namespaceLookup( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, - namespace: *Scope.Namespace, + namespace: *Namespace, decl_name: []const u8, ) CompileError!?*Decl { const gpa = sema.gpa; @@ -10393,9 +10673,9 @@ fn namespaceLookup( fn namespaceLookupRef( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, - namespace: *Scope.Namespace, + namespace: *Namespace, decl_name: []const u8, ) CompileError!?Air.Inst.Ref { const decl = (try sema.namespaceLookup(block, src, namespace, decl_name)) orelse return null; @@ -10404,7 +10684,7 @@ fn namespaceLookupRef( fn structFieldPtr( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, struct_ptr: Air.Inst.Ref, field_name: []const u8, @@ -10444,7 +10724,7 @@ fn structFieldPtr( fn structFieldVal( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, struct_byval: Air.Inst.Ref, field_name: []const u8, @@ -10482,7 +10762,7 @@ fn structFieldVal( fn unionFieldPtr( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, union_ptr: Air.Inst.Ref, field_name: []const u8, @@ -10524,7 +10804,7 @@ fn unionFieldPtr( fn unionFieldVal( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, union_byval: Air.Inst.Ref, field_name: []const u8, @@ -10555,7 +10835,7 @@ fn unionFieldVal( fn elemPtr( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, array_ptr: Air.Inst.Ref, elem_index: Air.Inst.Ref, @@ -10584,7 +10864,7 @@ fn elemPtr( fn elemVal( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, array_maybe_ptr: Air.Inst.Ref, elem_index: Air.Inst.Ref, @@ -10673,7 +10953,7 @@ fn elemVal( fn elemPtrArray( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, array_ptr: Air.Inst.Ref, elem_index: Air.Inst.Ref, @@ -10713,7 +10993,7 @@ fn elemPtrArray( fn coerce( sema: *Sema, - block: *Scope.Block, + block: *Block, dest_type_unresolved: Type, inst: Air.Inst.Ref, inst_src: LazySrcLoc, @@ -10985,7 +11265,7 @@ fn coerceInMemoryAllowed(dest_type: Type, src_type: Type, dest_is_mut: bool, tar fn coerceNum( sema: *Sema, - block: *Scope.Block, + block: *Block, dest_type: Type, inst: Air.Inst.Ref, inst_src: LazySrcLoc, @@ -11053,7 +11333,7 @@ fn coerceNum( fn coerceVarArgParam( sema: *Sema, - block: *Scope.Block, + block: *Block, inst: Air.Inst.Ref, inst_src: LazySrcLoc, ) !Air.Inst.Ref { @@ -11069,7 +11349,7 @@ fn coerceVarArgParam( // TODO migrate callsites to use storePtr2 instead. fn storePtr( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, ptr: Air.Inst.Ref, uncasted_operand: Air.Inst.Ref, @@ -11079,7 +11359,7 @@ fn storePtr( fn storePtr2( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, ptr: Air.Inst.Ref, ptr_src: LazySrcLoc, @@ -11116,7 +11396,7 @@ fn storePtr2( /// assert the store must be done at comptime. fn storePtrVal( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, ptr_val: Value, operand_val: Value, @@ -11161,7 +11441,7 @@ fn storePtrVal( fn bitcast( sema: *Sema, - block: *Scope.Block, + block: *Block, dest_type: Type, inst: Air.Inst.Ref, inst_src: LazySrcLoc, @@ -11177,7 +11457,7 @@ fn bitcast( fn coerceArrayPtrToSlice( sema: *Sema, - block: *Scope.Block, + block: *Block, dest_type: Type, inst: Air.Inst.Ref, inst_src: LazySrcLoc, @@ -11192,7 +11472,7 @@ fn coerceArrayPtrToSlice( fn coerceArrayPtrToMany( sema: *Sema, - block: *Scope.Block, + block: *Block, dest_type: Type, inst: Air.Inst.Ref, inst_src: LazySrcLoc, @@ -11207,7 +11487,7 @@ fn coerceArrayPtrToMany( fn analyzeDeclVal( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, decl: *Decl, ) CompileError!Air.Inst.Ref { @@ -11261,7 +11541,7 @@ fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref { fn analyzeRef( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref, ) CompileError!Air.Inst.Ref { @@ -11296,7 +11576,7 @@ fn analyzeRef( fn analyzeLoad( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, ptr: Air.Inst.Ref, ptr_src: LazySrcLoc, @@ -11318,7 +11598,7 @@ fn analyzeLoad( fn analyzeSliceLen( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, slice_inst: Air.Inst.Ref, ) CompileError!Air.Inst.Ref { @@ -11334,7 +11614,7 @@ fn analyzeSliceLen( fn analyzeIsNull( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref, invert_logic: bool, @@ -11359,7 +11639,7 @@ fn analyzeIsNull( fn analyzeIsNonErr( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref, ) CompileError!Air.Inst.Ref { @@ -11385,7 +11665,7 @@ fn analyzeIsNonErr( fn analyzeSlice( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, array_ptr: Air.Inst.Ref, start: Air.Inst.Ref, @@ -11460,7 +11740,7 @@ fn analyzeSlice( /// Asserts that lhs and rhs types are both numeric. fn cmpNumeric( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref, @@ -11648,7 +11928,7 @@ fn cmpNumeric( fn wrapOptional( sema: *Sema, - block: *Scope.Block, + block: *Block, dest_type: Type, inst: Air.Inst.Ref, inst_src: LazySrcLoc, @@ -11663,7 +11943,7 @@ fn wrapOptional( fn wrapErrorUnion( sema: *Sema, - block: *Scope.Block, + block: *Block, dest_type: Type, inst: Air.Inst.Ref, inst_src: LazySrcLoc, @@ -11739,7 +12019,7 @@ fn wrapErrorUnion( fn unionToTag( sema: *Sema, - block: *Scope.Block, + block: *Block, dest_type: Type, un: Air.Inst.Ref, un_src: LazySrcLoc, @@ -11753,7 +12033,7 @@ fn unionToTag( fn resolvePeerTypes( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, instructions: []Air.Inst.Ref, candidate_srcs: Module.PeerTypeCandidateSrc, @@ -11867,7 +12147,7 @@ fn resolvePeerTypes( pub fn resolveTypeLayout( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, ty: Type, ) CompileError!void { @@ -11892,7 +12172,7 @@ pub fn resolveTypeLayout( } } -fn resolveTypeFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type) CompileError!Type { +fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!Type { switch (ty.tag()) { .@"struct" => { const struct_obj = ty.castTag(.@"struct").?.data; @@ -11943,7 +12223,7 @@ fn resolveTypeFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type fn resolveBuiltinTypeFields( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, name: []const u8, ) CompileError!Type { @@ -12021,7 +12301,7 @@ fn semaStructFields( var wip_captures = try WipCaptureScope.init(gpa, &decl_arena.allocator, decl.src_scope); defer wip_captures.deinit(); - var block_scope: Scope.Block = .{ + var block_scope: Block = .{ .parent = null, .sema = &sema, .src_decl = decl, @@ -12191,7 +12471,7 @@ fn semaUnionFields( var wip_captures = try WipCaptureScope.init(gpa, &decl_arena.allocator, decl.src_scope); defer wip_captures.deinit(); - var block_scope: Scope.Block = .{ + var block_scope: Block = .{ .parent = null, .sema = &sema, .src_decl = decl, @@ -12322,7 +12602,7 @@ fn semaUnionFields( fn generateUnionTagTypeNumbered( sema: *Sema, - block: *Scope.Block, + block: *Block, fields_len: u32, int_ty: Type, ) !Type { @@ -12340,7 +12620,7 @@ fn generateUnionTagTypeNumbered( const enum_ty = Type.initPayload(&enum_ty_payload.base); const enum_val = try Value.Tag.ty.create(&new_decl_arena.allocator, enum_ty); // TODO better type name - const new_decl = try mod.createAnonymousDecl(&block.base, .{ + const new_decl = try mod.createAnonymousDecl(block, .{ .ty = Type.initTag(.type), .val = enum_val, }); @@ -12361,7 +12641,7 @@ fn generateUnionTagTypeNumbered( return enum_ty; } -fn generateUnionTagTypeSimple(sema: *Sema, block: *Scope.Block, fields_len: u32) !Type { +fn generateUnionTagTypeSimple(sema: *Sema, block: *Block, fields_len: u32) !Type { const mod = sema.mod; var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa); @@ -12376,7 +12656,7 @@ fn generateUnionTagTypeSimple(sema: *Sema, block: *Scope.Block, fields_len: u32) const enum_ty = Type.initPayload(&enum_ty_payload.base); const enum_val = try Value.Tag.ty.create(&new_decl_arena.allocator, enum_ty); // TODO better type name - const new_decl = try mod.createAnonymousDecl(&block.base, .{ + const new_decl = try mod.createAnonymousDecl(block, .{ .ty = Type.initTag(.type), .val = enum_val, }); @@ -12396,7 +12676,7 @@ fn generateUnionTagTypeSimple(sema: *Sema, block: *Scope.Block, fields_len: u32) fn getBuiltin( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, name: []const u8, ) CompileError!Air.Inst.Ref { @@ -12422,7 +12702,7 @@ fn getBuiltin( fn getBuiltinType( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, name: []const u8, ) CompileError!Type { @@ -12436,7 +12716,7 @@ fn getBuiltinType( /// that the types are already resolved. fn typeHasOnePossibleValue( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, starting_type: Type, ) CompileError!?Value { @@ -12599,7 +12879,7 @@ fn typeHasOnePossibleValue( }; } -fn getAstTree(sema: *Sema, block: *Scope.Block) CompileError!*const std.zig.Ast { +fn getAstTree(sema: *Sema, block: *Block) CompileError!*const std.zig.Ast { return block.namespace.file_scope.getTree(sema.gpa) catch |err| { log.err("unable to load AST to report compile error: {s}", .{@errorName(err)}); return error.AnalysisFail; @@ -12789,7 +13069,7 @@ fn getBreakBlock(sema: *Sema, inst_index: Air.Inst.Index) ?Air.Inst.Index { fn isComptimeKnown( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, inst: Air.Inst.Ref, ) !bool { @@ -12798,7 +13078,7 @@ fn isComptimeKnown( fn analyzeComptimeAlloc( sema: *Sema, - block: *Scope.Block, + block: *Block, var_type: Type, ) CompileError!Air.Inst.Ref { const ptr_type = try Type.ptr(sema.arena, .{ @@ -12841,7 +13121,7 @@ pub const AddressSpaceContext = enum { pub fn analyzeAddrspace( sema: *Sema, - block: *Scope.Block, + block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref, ctx: AddressSpaceContext, diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 24ec37bbaa..8ba43b3125 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -246,7 +246,7 @@ pub const DeclGen = struct { fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } { @setCold(true); const src: LazySrcLoc = .{ .node_offset = 0 }; - const src_loc = src.toSrcLocWithDecl(dg.decl); + const src_loc = src.toSrcLoc(dg.decl); dg.error_msg = try Module.ErrorMsg.create(dg.module.gpa, src_loc, format, args); return error.AnalysisFail; } diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 55bcde59bc..761dd2a8bc 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -557,7 +557,7 @@ pub const DeclGen = struct { fn todo(self: *DeclGen, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { @setCold(true); assert(self.err_msg == null); - const src_loc = @as(LazySrcLoc, .{ .node_offset = 0 }).toSrcLocWithDecl(self.decl); + const src_loc = @as(LazySrcLoc, .{ .node_offset = 0 }).toSrcLoc(self.decl); self.err_msg = try Module.ErrorMsg.create(self.gpa, src_loc, "TODO (LLVM): " ++ format, args); return error.CodegenFail; } diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 9f7262f53b..25a1d228e0 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -295,7 +295,7 @@ pub const DeclGen = struct { fn fail(self: *DeclGen, comptime format: []const u8, args: anytype) Error { @setCold(true); const src: LazySrcLoc = .{ .node_offset = 0 }; - const src_loc = src.toSrcLocWithDecl(self.decl); + const src_loc = src.toSrcLoc(self.decl); self.error_msg = try Module.ErrorMsg.create(self.spv.module.gpa, src_loc, format, args); return error.AnalysisFail; } diff --git a/src/codegen/wasm.zig b/src/codegen/wasm.zig index 9bd80f7d84..6902553257 100644 --- a/src/codegen/wasm.zig +++ b/src/codegen/wasm.zig @@ -540,7 +540,7 @@ pub const Context = struct { /// Sets `err_msg` on `Context` and returns `error.CodegemFail` which is caught in link/Wasm.zig fn fail(self: *Context, comptime fmt: []const u8, args: anytype) InnerError { const src: LazySrcLoc = .{ .node_offset = 0 }; - const src_loc = src.toSrcLocWithDecl(self.decl); + const src_loc = src.toSrcLoc(self.decl); self.err_msg = try Module.ErrorMsg.create(self.gpa, src_loc, fmt, args); return error.CodegenFail; } diff --git a/src/crash_report.zig b/src/crash_report.zig index abf483bd3e..88c5f704c1 100644 --- a/src/crash_report.zig +++ b/src/crash_report.zig @@ -8,6 +8,7 @@ const print_zir = @import("print_zir.zig"); const Module = @import("Module.zig"); const Sema = @import("Sema.zig"); const Zir = @import("Zir.zig"); +const Decl = Module.Decl; pub const is_enabled = builtin.mode == .Debug; @@ -36,7 +37,7 @@ fn en(val: anytype) En(@TypeOf(val)) { pub const AnalyzeBody = struct { parent: if (is_enabled) ?*AnalyzeBody else void, sema: En(*Sema), - block: En(*Module.Scope.Block), + block: En(*Sema.Block), body: En([]const Zir.Inst.Index), body_index: En(usize), @@ -64,7 +65,7 @@ pub const AnalyzeBody = struct { threadlocal var zir_state: ?*AnalyzeBody = if (is_enabled) null else @compileError("Cannot use zir_state if crash_report is disabled."); -pub fn prepAnalyzeBody(sema: *Sema, block: *Module.Scope.Block, body: []const Zir.Inst.Index) AnalyzeBody { +pub fn prepAnalyzeBody(sema: *Sema, block: *Sema.Block, body: []const Zir.Inst.Index) AnalyzeBody { if (is_enabled) { return .{ .parent = null, @@ -87,7 +88,7 @@ fn dumpStatusReport() !void { const allocator = &fba.allocator; const stderr = io.getStdErr().writer(); - const block: *Scope.Block = anal.block; + const block: *Sema.Block = anal.block; try stderr.writeAll("Analyzing "); try writeFullyQualifiedDeclWithFile(block.src_decl, stderr); @@ -134,12 +135,9 @@ fn dumpStatusReport() !void { try stderr.writeAll("\n"); } -const Scope = Module.Scope; -const Decl = Module.Decl; - var crash_heap: [16 * 4096]u8 = undefined; -fn writeFilePath(file: *Scope.File, stream: anytype) !void { +fn writeFilePath(file: *Module.File, stream: anytype) !void { if (file.pkg.root_src_directory.path) |path| { try stream.writeAll(path); try stream.writeAll(std.fs.path.sep_str); diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig index 0f99ca31ed..51c5abb048 100644 --- a/src/link/Plan9.zig +++ b/src/link/Plan9.zig @@ -57,7 +57,7 @@ path_arena: std.heap.ArenaAllocator, /// of the function to know what file it came from. /// If we group the decls by file, it makes it really easy to do this (put the symbol in the correct place) fn_decl_table: std.AutoArrayHashMapUnmanaged( - *Module.Scope.File, + *Module.File, struct { sym_index: u32, functions: std.AutoArrayHashMapUnmanaged(*Module.Decl, FnDeclOutput) = .{} }, ) = .{}, data_decl_table: std.AutoArrayHashMapUnmanaged(*Module.Decl, []const u8) = .{}, diff --git a/src/main.zig b/src/main.zig index e0be4b6021..e56f1ba07e 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3233,7 +3233,7 @@ pub fn cmdFmt(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !voi const Module = @import("Module.zig"); const AstGen = @import("AstGen.zig"); - var file: Module.Scope.File = .{ + var file: Module.File = .{ .status = .never_loaded, .source_loaded = true, .zir_loaded = false, @@ -3429,7 +3429,7 @@ fn fmtPathFile( const Module = @import("Module.zig"); const AstGen = @import("AstGen.zig"); - var file: Module.Scope.File = .{ + var file: Module.File = .{ .status = .never_loaded, .source_loaded = true, .zir_loaded = false, @@ -4019,7 +4019,7 @@ pub fn cmdAstCheck( } } - var file: Module.Scope.File = .{ + var file: Module.File = .{ .status = .never_loaded, .source_loaded = false, .tree_loaded = false, @@ -4170,7 +4170,7 @@ pub fn cmdChangelist( if (stat.size > max_src_size) return error.FileTooBig; - var file: Module.Scope.File = .{ + var file: Module.File = .{ .status = .never_loaded, .source_loaded = false, .tree_loaded = false, diff --git a/src/print_zir.zig b/src/print_zir.zig index c53c92f6bf..15ab00464b 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -11,7 +11,7 @@ const LazySrcLoc = Module.LazySrcLoc; /// Write human-readable, debug formatted ZIR code to a file. pub fn renderAsTextToFile( gpa: *Allocator, - scope_file: *Module.Scope.File, + scope_file: *Module.File, fs_file: std.fs.File, ) !void { var arena = std.heap.ArenaAllocator.init(gpa); @@ -64,7 +64,7 @@ pub fn renderInstructionContext( gpa: *Allocator, block: []const Zir.Inst.Index, block_index: usize, - scope_file: *Module.Scope.File, + scope_file: *Module.File, parent_decl_node: Ast.Node.Index, indent: u32, stream: anytype, @@ -96,7 +96,7 @@ pub fn renderInstructionContext( pub fn renderSingleInstruction( gpa: *Allocator, inst: Zir.Inst.Index, - scope_file: *Module.Scope.File, + scope_file: *Module.File, parent_decl_node: Ast.Node.Index, indent: u32, stream: anytype, @@ -122,7 +122,7 @@ pub fn renderSingleInstruction( const Writer = struct { gpa: *Allocator, arena: *Allocator, - file: *Module.Scope.File, + file: *Module.File, code: Zir, indent: u32, parent_decl_node: Ast.Node.Index, diff --git a/src/type.zig b/src/type.zig index dacde84167..8f200c0f35 100644 --- a/src/type.zig +++ b/src/type.zig @@ -3067,7 +3067,7 @@ pub const Type = extern union { } /// Returns null if the type has no namespace. - pub fn getNamespace(self: Type) ?*Module.Scope.Namespace { + pub fn getNamespace(self: Type) ?*Module.Namespace { return switch (self.tag()) { .@"struct" => &self.castTag(.@"struct").?.data.namespace, .enum_full => &self.castTag(.enum_full).?.data.namespace, @@ -3833,12 +3833,12 @@ pub const Type = extern union { /// Most commonly used for files. pub const ContainerScope = struct { base: Payload, - data: *Module.Scope.Namespace, + data: *Module.Namespace, }; pub const Opaque = struct { base: Payload = .{ .tag = .@"opaque" }, - data: Module.Scope.Namespace, + data: Module.Namespace, }; pub const Struct = struct { From 1d2c3af90627fd2b5ffdd3a9c5f96fd73dddb2d5 Mon Sep 17 00:00:00 2001 From: Martin Wickham Date: Fri, 1 Oct 2021 20:30:02 -0500 Subject: [PATCH 14/14] Remove address of pointer --- src/Sema.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Sema.zig b/src/Sema.zig index 6bc7cecac7..731a5a8a8a 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2601,7 +2601,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr // we check this here to avoid undefined symbols if (!@import("build_options").have_llvm) - return sema.fail(&parent_block, src, "cannot do C import on Zig compiler not built with LLVM-extension", .{}); + return sema.fail(parent_block, src, "cannot do C import on Zig compiler not built with LLVM-extension", .{}); var c_import_buf = std.ArrayList(u8).init(sema.gpa); defer c_import_buf.deinit();