aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-07-23 22:23:03 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-07-23 22:42:31 -0700
commit7b8cb881df7e034a8626caabf355055ee81a0fef (patch)
treee56858cd22ccf90217a49c51c7d8ff7df49ab0f3 /src/Module.zig
parentf9798108f8434f277de6089502446f2544ee98b3 (diff)
downloadzig-7b8cb881df7e034a8626caabf355055ee81a0fef.tar.gz
zig-7b8cb881df7e034a8626caabf355055ee81a0fef.zip
stage2: improvements towards `zig test`
* There is now a main_pkg in addition to root_pkg. They are usually the same. When using `zig test`, main_pkg is the user's source file and root_pkg has the test runner. * scanDecl no longer looks for test decls outside the package being tested. honoring `--test-filter` is still TODO. * test runner main function has a void return value rather than `anyerror!void` * Sema is improved to generate better AIR for for loops on slices. * Sema: fix incorrect capacity calculation in zirBoolBr * Sema: add compile errors for trying to use slice fields as an lvalue. * Sema: fix type coercion for error unions * Sema: fix analyzeVarRef generating garbage AIR * C codegen: fix renderValue for error unions with 0 bit payload * C codegen: implement function pointer calls * CLI: fix usage text Adds 4 new AIR instructions: * slice_len, slice_ptr: to get the ptr and len fields of a slice. * slice_elem_val, ptr_slice_elem_val: to get the element value of a slice, and a pointer to a slice. AstGen gains a new functionality: * One of the unused flags of struct decls is now used to indicate structs that are known to have non-zero size based on the AST alone.
Diffstat (limited to 'src/Module.zig')
-rw-r--r--src/Module.zig39
1 files changed, 31 insertions, 8 deletions
diff --git a/src/Module.zig b/src/Module.zig
index 4930e7846c..8ebb1c203c 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -35,8 +35,11 @@ comp: *Compilation,
/// Where our incremental compilation metadata serialization will go.
zig_cache_artifact_directory: Compilation.Directory,
-/// Pointer to externally managed resource. `null` if there is no zig file being compiled.
+/// Pointer to externally managed resource.
root_pkg: *Package,
+/// Normally, `main_pkg` and `root_pkg` are the same. The exception is `zig test`, in which
+/// `root_pkg` is the test runner, and `main_pkg` is the user's source file which has the tests.
+main_pkg: *Package,
/// Used by AstGen worker to load and store ZIR cache.
global_zir_cache: Compilation.Directory,
@@ -598,6 +601,9 @@ pub const Struct = struct {
layout_wip,
have_layout,
},
+ /// If true, definitely nonzero size at runtime. If false, resolving the fields
+ /// is necessary to determine whether it has bits at runtime.
+ known_has_bits: bool,
pub const Field = struct {
/// Uses `noreturn` to indicate `anytype`.
@@ -2048,19 +2054,22 @@ pub fn deinit(mod: *Module) void {
mod.deletion_set.deinit(gpa);
- // The callsite of `Compilation.create` owns the `root_pkg`, however
+ // The callsite of `Compilation.create` owns the `main_pkg`, however
// Module owns the builtin and std packages that it adds.
- if (mod.root_pkg.table.fetchRemove("builtin")) |kv| {
+ if (mod.main_pkg.table.fetchRemove("builtin")) |kv| {
gpa.free(kv.key);
kv.value.destroy(gpa);
}
- if (mod.root_pkg.table.fetchRemove("std")) |kv| {
+ if (mod.main_pkg.table.fetchRemove("std")) |kv| {
gpa.free(kv.key);
kv.value.destroy(gpa);
}
- if (mod.root_pkg.table.fetchRemove("root")) |kv| {
+ if (mod.main_pkg.table.fetchRemove("root")) |kv| {
gpa.free(kv.key);
}
+ if (mod.root_pkg != mod.main_pkg) {
+ mod.root_pkg.destroy(gpa);
+ }
mod.compile_log_text.deinit(gpa);
@@ -2148,7 +2157,7 @@ pub fn astGenFile(mod: *Module, file: *Scope.File) !void {
const stat = try source_file.stat();
- const want_local_cache = file.pkg == mod.root_pkg;
+ const want_local_cache = file.pkg == mod.main_pkg;
const digest = hash: {
var path_hash: Cache.HashHelper = .{};
path_hash.addBytes(build_options.version);
@@ -2792,6 +2801,7 @@ pub fn semaFile(mod: *Module, file: *Scope.File) SemaError!void {
.zir_index = undefined, // set below
.layout = .Auto,
.status = .none,
+ .known_has_bits = undefined,
.namespace = .{
.parent = null,
.ty = struct_ty,
@@ -3301,10 +3311,23 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
gop.value_ptr.* = new_decl;
// Exported decls, comptime decls, usingnamespace decls, and
// test decls if in test mode, get analyzed.
+ const decl_pkg = namespace.file_scope.pkg;
const want_analysis = is_exported or switch (decl_name_index) {
0 => true, // comptime decl
- 1 => mod.comp.bin_file.options.is_test, // test decl
- else => is_named_test and mod.comp.bin_file.options.is_test,
+ 1 => blk: {
+ // test decl with no name. Skip the part where we check against
+ // the test name filter.
+ if (!mod.comp.bin_file.options.is_test) break :blk false;
+ if (decl_pkg != mod.main_pkg) break :blk false;
+ break :blk true;
+ },
+ else => blk: {
+ if (!is_named_test) break :blk false;
+ if (!mod.comp.bin_file.options.is_test) break :blk false;
+ if (decl_pkg != mod.main_pkg) break :blk false;
+ // TODO check the name against --test-filter
+ break :blk true;
+ },
};
if (want_analysis) {
mod.comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl });