diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-10-04 18:00:21 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-04 18:00:21 -0400 |
| commit | 302a69f127ae8542f49d9cd07c7cc49f3bbd6181 (patch) | |
| tree | 063f062e7701e4679a0e97ad1a25021294663640 /src | |
| parent | 0e2d858d69ee1595bb58d936f83f0e0248d54d68 (diff) | |
| parent | 6d3858dc8a5e5d510a6c9cc972357dda551628b3 (diff) | |
| download | zig-302a69f127ae8542f49d9cd07c7cc49f3bbd6181.tar.gz zig-302a69f127ae8542f49d9cd07c7cc49f3bbd6181.zip | |
Merge pull request #6295 from Vexu/stage2
Stage2: basic imports
Diffstat (limited to 'src')
| -rw-r--r-- | src/Compilation.zig | 18 | ||||
| -rw-r--r-- | src/Module.zig | 56 | ||||
| -rw-r--r-- | src/astgen.zig | 11 | ||||
| -rw-r--r-- | src/main.zig | 5 | ||||
| -rw-r--r-- | src/test.zig | 15 | ||||
| -rw-r--r-- | src/type.zig | 112 | ||||
| -rw-r--r-- | src/value.zig | 15 | ||||
| -rw-r--r-- | src/zir.zig | 4 | ||||
| -rw-r--r-- | src/zir_sema.zig | 32 |
9 files changed, 263 insertions, 5 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index 5288dad0d0..16a475b2fc 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -8,6 +8,7 @@ const log = std.log.scoped(.compilation); const Target = std.Target; const Value = @import("value.zig").Value; +const Type = @import("type.zig").Type; const target_util = @import("target.zig"); const Package = @import("Package.zig"); const link = @import("link.zig"); @@ -640,15 +641,19 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { const root_scope = rs: { if (mem.endsWith(u8, root_pkg.root_src_path, ".zig")) { + const struct_payload = try gpa.create(Type.Payload.EmptyStruct); const root_scope = try gpa.create(Module.Scope.File); + struct_payload.* = .{ .scope = &root_scope.root_container }; root_scope.* = .{ - .sub_file_path = root_pkg.root_src_path, + // TODO this is duped so it can be freed in Container.deinit + .sub_file_path = try gpa.dupe(u8, root_pkg.root_src_path), .source = .{ .unloaded = {} }, .contents = .{ .not_available = {} }, .status = .never_loaded, .root_container = .{ .file_scope = root_scope, .decls = .{}, + .ty = Type.initPayload(&struct_payload.base), }, }; break :rs &root_scope.base; @@ -1025,6 +1030,17 @@ pub fn update(self: *Compilation) !void { else => |e| return e, }; } + + // TODO only analyze imports if they are still referenced + for (module.import_table.items()) |entry| { + entry.value.unload(module.gpa); + module.analyzeContainer(&entry.value.root_container) catch |err| switch (err) { + error.AnalysisFail => { + assert(self.totalErrorCount() != 0); + }, + else => |e| return e, + }; + } } } diff --git a/src/Module.zig b/src/Module.zig index 4fcf72f4ff..75b6afffcd 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -70,6 +70,9 @@ deletion_set: ArrayListUnmanaged(*Decl) = .{}, /// Error tags and their values, tag names are duped with mod.gpa. global_error_set: std.StringHashMapUnmanaged(u16) = .{}, +/// Keys are fully qualified paths +import_table: std.StringArrayHashMapUnmanaged(*Scope.File) = .{}, + /// Incrementing integer used to compare against the corresponding Decl /// field to determine whether a Decl's status applies to an ongoing update, or a /// previous analysis. @@ -208,7 +211,7 @@ pub const Decl = struct { .container => { const container = @fieldParentPtr(Scope.Container, "base", self.scope); const tree = container.file_scope.contents.tree; - // TODO Container should have it's own decls() + // TODO Container should have its own decls() const decl_node = tree.root_node.decls()[self.src_index]; return tree.token_locs[decl_node.firstToken()].start; }, @@ -532,12 +535,13 @@ pub const Scope = struct { /// Direct children of the file. decls: std.AutoArrayHashMapUnmanaged(*Decl, void), - - // TODO implement container types and put this in a status union - // ty: Type + ty: Type, pub fn deinit(self: *Container, gpa: *Allocator) void { self.decls.deinit(gpa); + // TODO either Container of File should have an arena for sub_file_path and ty + gpa.destroy(self.ty.cast(Type.Payload.EmptyStruct).?); + gpa.free(self.file_scope.sub_file_path); self.* = undefined; } @@ -854,6 +858,11 @@ pub fn deinit(self: *Module) void { gpa.free(entry.key); } self.global_error_set.deinit(gpa); + + for (self.import_table.items()) |entry| { + entry.value.base.destroy(gpa); + } + self.import_table.deinit(gpa); } fn freeExportList(gpa: *Allocator, export_list: []*Export) void { @@ -2381,6 +2390,45 @@ pub fn analyzeSlice(self: *Module, scope: *Scope, src: usize, array_ptr: *Inst, return self.fail(scope, src, "TODO implement analysis of slice", .{}); } +pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []const u8) !*Scope.File { + // TODO if (package_table.get(target_string)) |pkg| + if (self.import_table.get(target_string)) |some| { + return some; + } + + // TODO check for imports outside of pkg path + if (false) return error.ImportOutsidePkgPath; + + // TODO Scope.Container arena for ty and sub_file_path + const struct_payload = try self.gpa.create(Type.Payload.EmptyStruct); + errdefer self.gpa.destroy(struct_payload); + const file_scope = try self.gpa.create(Scope.File); + errdefer self.gpa.destroy(file_scope); + const file_path = try self.gpa.dupe(u8, target_string); + errdefer self.gpa.free(file_path); + + struct_payload.* = .{ .scope = &file_scope.root_container }; + file_scope.* = .{ + .sub_file_path = file_path, + .source = .{ .unloaded = {} }, + .contents = .{ .not_available = {} }, + .status = .never_loaded, + .root_container = .{ + .file_scope = file_scope, + .decls = .{}, + .ty = Type.initPayload(&struct_payload.base), + }, + }; + self.analyzeContainer(&file_scope.root_container) catch |err| switch (err) { + error.AnalysisFail => { + assert(self.comp.totalErrorCount() != 0); + }, + else => |e| return e, + }; + try self.import_table.put(self.gpa, file_scope.sub_file_path, file_scope); + return file_scope; +} + /// Asserts that lhs and rhs types are both numeric. pub fn cmpNumeric( self: *Module, diff --git a/src/astgen.zig b/src/astgen.zig index 2c091a86ec..19b522b9c6 100644 --- a/src/astgen.zig +++ b/src/astgen.zig @@ -1973,6 +1973,15 @@ fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCa } } +fn import(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst { + try ensureBuiltinParamCount(mod, scope, call, 1); + const tree = scope.tree(); + const src = tree.token_locs[call.builtin_token].start; + const params = call.params(); + const target = try expr(mod, scope, .none, params[0]); + return addZIRUnOp(mod, scope, src, .import, target); +} + fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst { const tree = scope.tree(); const builtin_name = tree.tokenSlice(call.builtin_token); @@ -1995,6 +2004,8 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.Built } else if (mem.eql(u8, builtin_name, "@breakpoint")) { const src = tree.token_locs[call.builtin_token].start; return rlWrap(mod, scope, rl, try addZIRNoOp(mod, scope, src, .breakpoint)); + } else if (mem.eql(u8, builtin_name, "@import")) { + return rlWrap(mod, scope, rl, try import(mod, scope, call)); } else { return mod.failTok(scope, call.builtin_token, "invalid builtin function: '{}'", .{builtin_name}); } diff --git a/src/main.zig b/src/main.zig index 0868839257..4fddf9ed21 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1454,6 +1454,11 @@ fn buildOutputType( cleanup_root_dir = dir; root_pkg_memory.root_src_directory = .{ .path = p, .handle = dir }; root_pkg_memory.root_src_path = try fs.path.relative(arena, p, src_path); + } else if (fs.path.dirname(src_path)) |p| { + const dir = try fs.cwd().openDir(p, .{}); + cleanup_root_dir = dir; + root_pkg_memory.root_src_directory = .{ .path = p, .handle = dir }; + root_pkg_memory.root_src_path = fs.path.basename(src_path); } else { root_pkg_memory.root_src_directory = .{ .path = null, .handle = fs.cwd() }; root_pkg_memory.root_src_path = src_path; diff --git a/src/test.zig b/src/test.zig index 8ad11efa9c..c0ac56aa2d 100644 --- a/src/test.zig +++ b/src/test.zig @@ -56,6 +56,12 @@ pub const TestContext = struct { }, }; + pub const File = struct { + /// Contents of the importable file. Doesn't yet support incremental updates. + src: [:0]const u8, + path: []const u8, + }; + pub const TestType = enum { Zig, ZIR, @@ -78,6 +84,8 @@ pub const TestContext = struct { extension: TestType, cbe: bool = false, + files: std.ArrayList(File), + /// Adds a subcase in which the module is updated with `src`, and the /// resulting ZIR is validated against `result`. pub fn addTransform(self: *Case, src: [:0]const u8, result: [:0]const u8) void { @@ -156,6 +164,7 @@ pub const TestContext = struct { .updates = std.ArrayList(Update).init(ctx.cases.allocator), .output_mode = .Exe, .extension = T, + .files = std.ArrayList(File).init(ctx.cases.allocator), }) catch unreachable; return &ctx.cases.items[ctx.cases.items.len - 1]; } @@ -182,6 +191,7 @@ pub const TestContext = struct { .updates = std.ArrayList(Update).init(ctx.cases.allocator), .output_mode = .Obj, .extension = T, + .files = std.ArrayList(File).init(ctx.cases.allocator), }) catch unreachable; return &ctx.cases.items[ctx.cases.items.len - 1]; } @@ -204,6 +214,7 @@ pub const TestContext = struct { .output_mode = .Obj, .extension = T, .cbe = true, + .files = std.ArrayList(File).init(ctx.cases.allocator), }) catch unreachable; return &ctx.cases.items[ctx.cases.items.len - 1]; } @@ -505,6 +516,10 @@ pub const TestContext = struct { }); defer comp.destroy(); + for (case.files.items) |file| { + try tmp.dir.writeFile(file.path, file.src); + } + for (case.updates.items) |update, update_index| { var update_node = root_node.start("update", 3); update_node.activate(); diff --git a/src/type.zig b/src/type.zig index 4966395512..c22edaa561 100644 --- a/src/type.zig +++ b/src/type.zig @@ -89,6 +89,8 @@ pub const Type = extern union { .anyerror_void_error_union, .error_union => return .ErrorUnion, .anyframe_T, .@"anyframe" => return .AnyFrame, + + .empty_struct => return .Struct, } } @@ -439,6 +441,7 @@ pub const Type = extern union { }, .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet), .error_set_single => return self.copyPayloadShallow(allocator, Payload.ErrorSetSingle), + .empty_struct => return self.copyPayloadShallow(allocator, Payload.EmptyStruct), } } @@ -505,6 +508,8 @@ pub const Type = extern union { .@"null" => return out_stream.writeAll("@Type(.Null)"), .@"undefined" => return out_stream.writeAll("@Type(.Undefined)"), + // TODO this should print the structs name + .empty_struct => return out_stream.writeAll("struct {}"), .@"anyframe" => return out_stream.writeAll("anyframe"), .anyerror_void_error_union => return out_stream.writeAll("anyerror!void"), .const_slice_u8 => return out_stream.writeAll("[]const u8"), @@ -788,6 +793,7 @@ pub const Type = extern union { .@"null", .@"undefined", .enum_literal, + .empty_struct, => false, }; } @@ -910,6 +916,7 @@ pub const Type = extern union { .@"null", .@"undefined", .enum_literal, + .empty_struct, => unreachable, }; } @@ -932,6 +939,7 @@ pub const Type = extern union { .@"undefined" => unreachable, .enum_literal => unreachable, .single_const_pointer_to_comptime_int => unreachable, + .empty_struct => unreachable, .u8, .i8, @@ -1107,6 +1115,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => false, .single_const_pointer, @@ -1181,6 +1190,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => false, .const_slice, @@ -1252,6 +1262,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => false, .single_const_pointer, @@ -1332,6 +1343,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => false, .pointer => { @@ -1407,6 +1419,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => false, .pointer => { @@ -1524,6 +1537,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => unreachable, .array => self.cast(Payload.Array).?.elem_type, @@ -1651,6 +1665,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => unreachable, .array => self.cast(Payload.Array).?.len, @@ -1716,6 +1731,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => unreachable, .single_const_pointer, @@ -1798,6 +1814,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => false, .int_signed, @@ -1872,6 +1889,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => false, .int_unsigned, @@ -1936,6 +1954,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => unreachable, .int_unsigned => .{ .signed = false, .bits = self.cast(Payload.IntUnsigned).?.bits }, @@ -2018,6 +2037,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => false, .usize, @@ -2129,6 +2149,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => unreachable, }; } @@ -2206,6 +2227,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => unreachable, } } @@ -2282,6 +2304,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => unreachable, } } @@ -2358,6 +2381,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => unreachable, }; } @@ -2431,6 +2455,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => unreachable, }; } @@ -2504,6 +2529,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => unreachable, }; } @@ -2577,6 +2603,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => false, }; } @@ -2636,6 +2663,7 @@ pub const Type = extern union { .error_set_single, => return null, + .empty_struct => return Value.initTag(.empty_struct_value), .void => return Value.initTag(.void_value), .noreturn => return Value.initTag(.unreachable_value), .@"null" => return Value.initTag(.null_value), @@ -2743,6 +2771,7 @@ pub const Type = extern union { .anyerror_void_error_union, .error_set, .error_set_single, + .empty_struct, => return false, .c_const_pointer, @@ -2760,6 +2789,80 @@ pub const Type = extern union { (self.isSinglePointer() and self.elemType().zigTypeTag() == .Array); } + /// Asserts that the type is a container. (note: ErrorSet is not a container). + pub fn getContainerScope(self: Type) *Module.Scope.Container { + return switch (self.tag()) { + .f16, + .f32, + .f64, + .f128, + .c_longdouble, + .comptime_int, + .comptime_float, + .u8, + .i8, + .u16, + .i16, + .u32, + .i32, + .u64, + .i64, + .usize, + .isize, + .c_short, + .c_ushort, + .c_int, + .c_uint, + .c_long, + .c_ulong, + .c_longlong, + .c_ulonglong, + .bool, + .type, + .anyerror, + .fn_noreturn_no_args, + .fn_void_no_args, + .fn_naked_noreturn_no_args, + .fn_ccc_void_no_args, + .function, + .single_const_pointer_to_comptime_int, + .const_slice_u8, + .c_void, + .void, + .noreturn, + .@"null", + .@"undefined", + .int_unsigned, + .int_signed, + .array, + .array_sentinel, + .array_u8, + .array_u8_sentinel_0, + .single_const_pointer, + .single_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .const_slice, + .mut_slice, + .optional, + .optional_single_mut_pointer, + .optional_single_const_pointer, + .enum_literal, + .error_union, + .@"anyframe", + .anyframe_T, + .anyerror_void_error_union, + .error_set, + .error_set_single, + .c_const_pointer, + .c_mut_pointer, + .pointer, + => unreachable, + + .empty_struct => self.cast(Type.Payload.EmptyStruct).?.scope, + }; + } + /// This enum does not directly correspond to `std.builtin.TypeId` because /// it has extra enum tags in it, as a way of using less memory. For example, /// even though Zig recognizes `*align(10) i32` and `*i32` both as Pointer types @@ -2835,6 +2938,7 @@ pub const Type = extern union { anyframe_T, error_set, error_set_single, + empty_struct, pub const last_no_payload_tag = Tag.const_slice_u8; pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1; @@ -2942,6 +3046,14 @@ pub const Type = extern union { /// memory is owned by `Module` name: []const u8, }; + + /// Mostly used for namespace like structs with zero fields. + /// Most commonly used for files. + pub const EmptyStruct = struct { + base: Payload = .{ .tag = .empty_struct }, + + scope: *Module.Scope.Container, + }; }; }; diff --git a/src/value.zig b/src/value.zig index b65aa06bea..6e38b1bed4 100644 --- a/src/value.zig +++ b/src/value.zig @@ -68,6 +68,7 @@ pub const Value = extern union { one, void_value, unreachable_value, + empty_struct_value, empty_array, null_value, bool_true, @@ -182,6 +183,7 @@ pub const Value = extern union { .null_value, .bool_true, .bool_false, + .empty_struct_value, => unreachable, .ty => { @@ -312,6 +314,8 @@ pub const Value = extern union { .enum_literal_type => return out_stream.writeAll("@Type(.EnumLiteral)"), .anyframe_type => return out_stream.writeAll("anyframe"), + // TODO this should print `NAME{}` + .empty_struct_value => return out_stream.writeAll("struct {}{}"), .null_value => return out_stream.writeAll("null"), .undef => return out_stream.writeAll("undefined"), .zero => return out_stream.writeAll("0"), @@ -475,6 +479,7 @@ pub const Value = extern union { .float_128, .enum_literal, .@"error", + .empty_struct_value, => unreachable, }; } @@ -543,6 +548,7 @@ pub const Value = extern union { .enum_literal, .error_set, .@"error", + .empty_struct_value, => unreachable, .undef => unreachable, @@ -626,6 +632,7 @@ pub const Value = extern union { .enum_literal, .error_set, .@"error", + .empty_struct_value, => unreachable, .undef => unreachable, @@ -709,6 +716,7 @@ pub const Value = extern union { .enum_literal, .error_set, .@"error", + .empty_struct_value, => unreachable, .undef => unreachable, @@ -820,6 +828,7 @@ pub const Value = extern union { .enum_literal, .error_set, .@"error", + .empty_struct_value, => unreachable, .zero, @@ -907,6 +916,7 @@ pub const Value = extern union { .enum_literal, .error_set, .@"error", + .empty_struct_value, => unreachable, .zero, @@ -1078,6 +1088,7 @@ pub const Value = extern union { .enum_literal, .error_set, .@"error", + .empty_struct_value, => unreachable, .zero, @@ -1152,6 +1163,7 @@ pub const Value = extern union { .enum_literal, .error_set, .@"error", + .empty_struct_value, => unreachable, .zero, @@ -1300,6 +1312,7 @@ pub const Value = extern union { .enum_literal, .error_set, .@"error", + .empty_struct_value, => unreachable, .ref_val => self.cast(Payload.RefVal).?.val, @@ -1383,6 +1396,7 @@ pub const Value = extern union { .enum_literal, .error_set, .@"error", + .empty_struct_value, => unreachable, .empty_array => unreachable, // out of bounds array index @@ -1483,6 +1497,7 @@ pub const Value = extern union { .enum_literal, .error_set, .@"error", + .empty_struct_value, => false, .undef => unreachable, diff --git a/src/zir.zig b/src/zir.zig index 7e723fc674..96081afc55 100644 --- a/src/zir.zig +++ b/src/zir.zig @@ -161,6 +161,8 @@ pub const Inst = struct { @"fn", /// Returns a function type. fntype, + /// @import(operand) + import, /// Integer literal. int, /// Convert an integer value to another integer type, asserting that the destination type @@ -315,6 +317,7 @@ pub const Inst = struct { .ensure_err_payload_void, .anyframe_type, .bitnot, + .import, => UnOp, .add, @@ -489,6 +492,7 @@ pub const Inst = struct { .error_set, .slice, .slice_start, + .import, => false, .@"break", diff --git a/src/zir_sema.zig b/src/zir_sema.zig index 10543d2ee6..d02c21ec47 100644 --- a/src/zir_sema.zig +++ b/src/zir_sema.zig @@ -134,6 +134,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError! .error_set => return analyzeInstErrorSet(mod, scope, old_inst.castTag(.error_set).?), .slice => return analyzeInstSlice(mod, scope, old_inst.castTag(.slice).?), .slice_start => return analyzeInstSliceStart(mod, scope, old_inst.castTag(.slice_start).?), + .import => return analyzeInstImport(mod, scope, old_inst.castTag(.import).?), } } @@ -1047,6 +1048,19 @@ fn analyzeInstFieldPtr(mod: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPtr .val = Value.initPayload(&ref_payload.base), }); }, + .Struct => { + const container_scope = child_type.getContainerScope(); + if (mod.lookupDeclName(&container_scope.base, field_name)) |decl| { + // TODO if !decl.is_pub and inDifferentFiles() "{} is private" + return mod.analyzeDeclRef(scope, fieldptr.base.src, decl); + } + + if (&container_scope.file_scope.base == mod.root_scope) { + return mod.fail(scope, fieldptr.base.src, "root source file has no member called '{}'", .{field_name}); + } else { + return mod.fail(scope, fieldptr.base.src, "container '{}' has no member called '{}'", .{ child_type, field_name }); + } + }, else => return mod.fail(scope, fieldptr.base.src, "type '{}' does not support field access", .{child_type}), } }, @@ -1190,6 +1204,24 @@ fn analyzeInstSliceStart(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) Inn return mod.analyzeSlice(scope, inst.base.src, array_ptr, start, null, null); } +fn analyzeInstImport(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { + const operand = try resolveConstString(mod, scope, inst.positionals.operand); + + const file_scope = mod.analyzeImport(scope, inst.base.src, operand) catch |err| switch (err) { + // error.ImportOutsidePkgPath => { + // return mod.fail(scope, inst.base.src, "import of file outside package path: '{}'", .{operand}); + // }, + error.FileNotFound => { + return mod.fail(scope, inst.base.src, "unable to find '{}'", .{operand}); + }, + else => { + // TODO user friendly error to string + return mod.fail(scope, inst.base.src, "unable to open '{}': {}", .{ operand, @errorName(err) }); + }, + }; + return mod.constType(scope, inst.base.src, file_scope.root_container.ty); +} + fn analyzeInstShl(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst { return mod.fail(scope, inst.base.src, "TODO implement analyzeInstShl", .{}); } |
