diff --git a/lib/std/build.zig b/lib/std/build.zig index 8a38383e87..a7615292ce 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -284,11 +284,11 @@ pub const Builder = struct { return run_step; } - fn dupe(self: *Builder, bytes: []const u8) []u8 { + pub fn dupe(self: *Builder, bytes: []const u8) []u8 { return mem.dupe(self.allocator, u8, bytes) catch unreachable; } - fn dupePath(self: *Builder, bytes: []const u8) []u8 { + pub fn dupePath(self: *Builder, bytes: []const u8) []u8 { const the_copy = self.dupe(bytes); for (the_copy) |*byte| { switch (byte.*) { @@ -717,7 +717,7 @@ pub const Builder = struct { return self.invalid_user_input; } - fn spawnChild(self: *Builder, argv: []const []const u8) !void { + pub fn spawnChild(self: *Builder, argv: []const []const u8) !void { return self.spawnChildEnvMap(null, self.env_map, argv); } @@ -843,7 +843,7 @@ pub const Builder = struct { }) catch unreachable; } - fn updateFile(self: *Builder, source_path: []const u8, dest_path: []const u8) !void { + pub fn updateFile(self: *Builder, source_path: []const u8, dest_path: []const u8) !void { if (self.verbose) { warn("cp {} {} ", .{ source_path, dest_path }); } @@ -855,7 +855,7 @@ pub const Builder = struct { }; } - fn pathFromRoot(self: *Builder, rel_path: []const u8) []u8 { + pub fn pathFromRoot(self: *Builder, rel_path: []const u8) []u8 { return fs.path.resolve(self.allocator, &[_][]const u8{ self.build_root, rel_path }) catch unreachable; } diff --git a/lib/std/dwarf.zig b/lib/std/dwarf.zig index fe40a04b9d..ebb4c096f8 100644 --- a/lib/std/dwarf.zig +++ b/lib/std/dwarf.zig @@ -121,7 +121,7 @@ const Die = struct { }; } - fn getAttrString(self: *const Die, di: *DwarfInfo, id: u64) ![]const u8 { + pub fn getAttrString(self: *const Die, di: *DwarfInfo, id: u64) ![]const u8 { const form_value = self.getAttr(id) orelse return error.MissingDebugInfo; return switch (form_value.*) { FormValue.String => |value| value, @@ -389,7 +389,7 @@ pub const DwarfInfo = struct { return self.abbrev_table_list.allocator; } - fn getSymbolName(di: *DwarfInfo, address: u64) ?[]const u8 { + pub fn getSymbolName(di: *DwarfInfo, address: u64) ?[]const u8 { for (di.func_list.span()) |*func| { if (func.pc_range) |range| { if (address >= range.start and address < range.end) { @@ -578,7 +578,7 @@ pub const DwarfInfo = struct { } } - fn findCompileUnit(di: *DwarfInfo, target_address: u64) !*const CompileUnit { + pub fn findCompileUnit(di: *DwarfInfo, target_address: u64) !*const CompileUnit { for (di.compile_unit_list.span()) |*compile_unit| { if (compile_unit.pc_range) |range| { if (target_address >= range.start and target_address < range.end) return compile_unit; @@ -690,7 +690,7 @@ pub const DwarfInfo = struct { return result; } - fn getLineNumberInfo(di: *DwarfInfo, compile_unit: CompileUnit, target_address: usize) !debug.LineInfo { + pub fn getLineNumberInfo(di: *DwarfInfo, compile_unit: CompileUnit, target_address: usize) !debug.LineInfo { var stream = io.fixedBufferStream(di.debug_line); const in = &stream.inStream(); const seekable = &stream.seekableStream(); diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig index 70e26cc71c..65c65292bc 100644 --- a/lib/std/dynamic_library.zig +++ b/lib/std/dynamic_library.zig @@ -33,11 +33,11 @@ const LinkMap = extern struct { pub const Iterator = struct { current: ?*LinkMap, - fn end(self: *Iterator) bool { + pub fn end(self: *Iterator) bool { return self.current == null; } - fn next(self: *Iterator) ?*LinkMap { + pub fn next(self: *Iterator) ?*LinkMap { if (self.current) |it| { self.current = it.l_next; return it; diff --git a/lib/std/json.zig b/lib/std/json.zig index b2b2db6493..1e220d6708 100644 --- a/lib/std/json.zig +++ b/lib/std/json.zig @@ -2336,7 +2336,7 @@ pub const StringifyOptions = struct { /// After a colon, should whitespace be inserted? separator: bool = true, - fn outputIndent( + pub fn outputIndent( whitespace: @This(), out_stream: var, ) @TypeOf(out_stream).Error!void { diff --git a/lib/std/net.zig b/lib/std/net.zig index cc3e0d903e..aa38aeae08 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -386,7 +386,7 @@ pub const AddressList = struct { addrs: []Address, canon_name: ?[]u8, - fn deinit(self: *AddressList) void { + pub fn deinit(self: *AddressList) void { // Here we copy the arena allocator into stack memory, because // otherwise it would destroy itself while it was still working. var arena = self.arena; diff --git a/lib/std/pdb.zig b/lib/std/pdb.zig index 75589b71ff..e4180717e9 100644 --- a/lib/std/pdb.zig +++ b/lib/std/pdb.zig @@ -644,7 +644,7 @@ const MsfStream = struct { return stream; } - fn readNullTermString(self: *MsfStream, allocator: *mem.Allocator) ![]u8 { + pub fn readNullTermString(self: *MsfStream, allocator: *mem.Allocator) ![]u8 { var list = ArrayList(u8).init(allocator); while (true) { const byte = try self.inStream().readByte(); @@ -684,13 +684,13 @@ const MsfStream = struct { return buffer.len; } - fn seekBy(self: *MsfStream, len: i64) !void { + pub fn seekBy(self: *MsfStream, len: i64) !void { self.pos = @intCast(u64, @intCast(i64, self.pos) + len); if (self.pos >= self.blocks.len * self.block_size) return error.EOF; } - fn seekTo(self: *MsfStream, len: u64) !void { + pub fn seekTo(self: *MsfStream, len: u64) !void { self.pos = len; if (self.pos >= self.blocks.len * self.block_size) return error.EOF; @@ -708,7 +708,7 @@ const MsfStream = struct { return block * self.block_size + offset; } - fn inStream(self: *MsfStream) std.io.InStream(*MsfStream, Error, read) { + pub fn inStream(self: *MsfStream) std.io.InStream(*MsfStream, Error, read) { return .{ .context = self }; } }; diff --git a/lib/std/zig/cross_target.zig b/lib/std/zig/cross_target.zig index 8783ddcb6d..1909a07df0 100644 --- a/lib/std/zig/cross_target.zig +++ b/lib/std/zig/cross_target.zig @@ -660,7 +660,7 @@ pub const CrossTarget = struct { return Target.getObjectFormatSimple(self.getOsTag(), self.getCpuArch()); } - fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void { + pub fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void { set.removeFeatureSet(self.cpu_features_sub); set.addFeatureSet(self.cpu_features_add); set.populateDependencies(self.getCpuArch().allFeaturesList()); diff --git a/src-self-hosted/ir/text.zig b/src-self-hosted/ir/text.zig index e1efb40fe5..1efcd6f599 100644 --- a/src-self-hosted/ir/text.zig +++ b/src-self-hosted/ir/text.zig @@ -236,7 +236,7 @@ pub const Inst = struct { @"comptime_int", @"comptime_float", - fn toType(self: BuiltinType) Type { + pub fn toType(self: BuiltinType) Type { return switch (self) { .@"isize" => Type.initTag(.@"isize"), .@"usize" => Type.initTag(.@"usize"), diff --git a/src/ir.cpp b/src/ir.cpp index bcd05553ed..b5c4212ca5 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -21624,6 +21624,15 @@ static IrInstGen *ir_analyze_container_member_access_inner(IrAnalyze *ira, if (tld->resolution == TldResolutionResolving) return ir_error_dependency_loop(ira, source_instr); + if (tld->visib_mod == VisibModPrivate && + tld->import != get_scope_import(source_instr->scope)) + { + ErrorMsg *msg = ir_add_error(ira, source_instr, + buf_sprintf("'%s' is private", buf_ptr(field_name))); + add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here")); + return ira->codegen->invalid_inst_gen; + } + TldFn *tld_fn = (TldFn *)tld; ZigFn *fn_entry = tld_fn->fn_entry; assert(fn_entry != nullptr); diff --git a/test/compile_errors.zig b/test/compile_errors.zig index e85538e0ba..5eb009dafa 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -5375,6 +5375,50 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { break :x tc; }); + cases.addCase(x: { + const tc = cases.create("multiple files with private member instance function (canonical invocation) error", + \\const Foo = @import("foo.zig",).Foo; + \\ + \\export fn callPrivFunction() void { + \\ var foo = Foo{}; + \\ Foo.privateFunction(foo); + \\} + , &[_][]const u8{ + "tmp.zig:5:8: error: 'privateFunction' is private", + "foo.zig:2:5: note: declared here", + }); + + tc.addSourceFile("foo.zig", + \\pub const Foo = struct { + \\ fn privateFunction(self: *Foo) void { } + \\}; + ); + + break :x tc; + }); + + cases.addCase(x: { + const tc = cases.create("multiple files with private member instance function error", + \\const Foo = @import("foo.zig",).Foo; + \\ + \\export fn callPrivFunction() void { + \\ var foo = Foo{}; + \\ foo.privateFunction(); + \\} + , &[_][]const u8{ + "tmp.zig:5:8: error: 'privateFunction' is private", + "foo.zig:2:5: note: declared here", + }); + + tc.addSourceFile("foo.zig", + \\pub const Foo = struct { + \\ fn privateFunction(self: *Foo) void { } + \\}; + ); + + break :x tc; + }); + cases.add("container init with non-type", \\const zero: i32 = 0; \\const a = zero{1};