authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-09 18:01:34+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-11 17:59:53+02:00
log9b832e7f530833de93857444a86e34c8d99e4755
tree82f844a4f4552d652d5c32ac3d12e718b7d420fe
parent25c850642190bf9939790b872a3657410ec4d19f

Sema: make check for namespace lookup of private declarations more strict

Previously sema only checked that the private declaration was in the same file as the lookup but now it also checks that the namespace where the decl was included from was also in the same file. Closes #13077

5 files changed, 23 insertions(+), 4 deletions(-)

src/Sema.zig+4-4
...@@ -5658,14 +5658,14 @@ fn lookupInNamespace(...@@ -5658,14 +5658,14 @@ fn lookupInNamespace(
5658 const src_file = block.namespace.file_scope;5658 const src_file = block.namespace.file_scope;
56595659
5660 const gpa = sema.gpa;5660 const gpa = sema.gpa;
5661 var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Namespace, void) = .{};5661 var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Namespace, bool) = .{};
5662 defer checked_namespaces.deinit(gpa);5662 defer checked_namespaces.deinit(gpa);
56635663
5664 // Keep track of name conflicts for error notes.5664 // Keep track of name conflicts for error notes.
5665 var candidates: std.ArrayListUnmanaged(Decl.Index) = .{};5665 var candidates: std.ArrayListUnmanaged(Decl.Index) = .{};
5666 defer candidates.deinit(gpa);5666 defer candidates.deinit(gpa);
56675667
5668 try checked_namespaces.put(gpa, namespace, {});5668 try checked_namespaces.put(gpa, namespace, namespace.file_scope == src_file);
5669 var check_i: usize = 0;5669 var check_i: usize = 0;
56705670
5671 while (check_i < checked_namespaces.count()) : (check_i += 1) {5671 while (check_i < checked_namespaces.count()) : (check_i += 1) {
...@@ -5674,7 +5674,7 @@ fn lookupInNamespace(...@@ -5674,7 +5674,7 @@ fn lookupInNamespace(
5674 // Skip decls which are not marked pub, which are in a different5674 // Skip decls which are not marked pub, which are in a different
5675 // file than the `a.b`/`@hasDecl` syntax.5675 // file than the `a.b`/`@hasDecl` syntax.
5676 const decl = mod.declPtr(decl_index);5676 const decl = mod.declPtr(decl_index);
5677 if (decl.is_pub or src_file == decl.getFileScope()) {5677 if (decl.is_pub or (src_file == decl.getFileScope() and checked_namespaces.values()[check_i])) {
5678 try candidates.append(gpa, decl_index);5678 try candidates.append(gpa, decl_index);
5679 }5679 }
5680 }5680 }
...@@ -5693,7 +5693,7 @@ fn lookupInNamespace(...@@ -5693,7 +5693,7 @@ fn lookupInNamespace(
5693 try sema.ensureDeclAnalyzed(sub_usingnamespace_decl_index);5693 try sema.ensureDeclAnalyzed(sub_usingnamespace_decl_index);
5694 const ns_ty = sub_usingnamespace_decl.val.castTag(.ty).?.data;5694 const ns_ty = sub_usingnamespace_decl.val.castTag(.ty).?.data;
5695 const sub_ns = ns_ty.getNamespace().?;5695 const sub_ns = ns_ty.getNamespace().?;
5696 try checked_namespaces.put(gpa, sub_ns, {});5696 try checked_namespaces.put(gpa, sub_ns, src_file == sub_usingnamespace_decl.getFileScope());
5697 }5697 }
5698 }5698 }
56995699
test/behavior/usingnamespace.zig+4
...@@ -75,3 +75,7 @@ test {...@@ -75,3 +75,7 @@ test {
75 const a = AA.b(42);75 const a = AA.b(42);
76 try expect(a.x == AA.c().expected);76 try expect(a.x == AA.c().expected);
77}77}
78
79comptime {
80 _ = @import("usingnamespace/file_1.zig");
81}
test/behavior/usingnamespace/file_0.zig created+1
...@@ -0,0 +1 @@
1pub const A = 123;
test/behavior/usingnamespace/file_1.zig created+9
...@@ -0,0 +1,9 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const imports = @import("imports.zig");
4
5const A = 456;
6
7test {
8 try expect(imports.A == 123);
9}
test/behavior/usingnamespace/imports.zig created+5
...@@ -0,0 +1,5 @@
1const file_0 = @import("file_0.zig");
2const file_1 = @import("file_1.zig");
3
4pub usingnamespace file_0;
5pub usingnamespace file_1;