From 9b832e7f530833de93857444a86e34c8d99e4755 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Wed, 9 Nov 2022 18:01:34 +0200 Subject: [PATCH] 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 --- src/Sema.zig | 8 ++++---- test/behavior/usingnamespace.zig | 4 ++++ test/behavior/usingnamespace/file_0.zig | 1 + test/behavior/usingnamespace/file_1.zig | 9 +++++++++ test/behavior/usingnamespace/imports.zig | 5 +++++ 5 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 test/behavior/usingnamespace/file_0.zig create mode 100644 test/behavior/usingnamespace/file_1.zig create mode 100644 test/behavior/usingnamespace/imports.zig diff --git a/src/Sema.zig b/src/Sema.zig index 0ca92fb6498a06589833f2752d8cbece5497edcf..b93a892dcce43e0b87954bda67d8ee40940c926f 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -5658,14 +5658,14 @@ fn lookupInNamespace( const src_file = block.namespace.file_scope; const gpa = sema.gpa; - var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Namespace, void) = .{}; + var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Namespace, bool) = .{}; defer checked_namespaces.deinit(gpa); // Keep track of name conflicts for error notes. var candidates: std.ArrayListUnmanaged(Decl.Index) = .{}; defer candidates.deinit(gpa); - try checked_namespaces.put(gpa, namespace, {}); + try checked_namespaces.put(gpa, namespace, namespace.file_scope == src_file); var check_i: usize = 0; while (check_i < checked_namespaces.count()) : (check_i += 1) { @@ -5674,7 +5674,7 @@ fn lookupInNamespace( // Skip decls which are not marked pub, which are in a different // file than the `a.b`/`@hasDecl` syntax. const decl = mod.declPtr(decl_index); - if (decl.is_pub or src_file == decl.getFileScope()) { + if (decl.is_pub or (src_file == decl.getFileScope() and checked_namespaces.values()[check_i])) { try candidates.append(gpa, decl_index); } } @@ -5693,7 +5693,7 @@ fn lookupInNamespace( try sema.ensureDeclAnalyzed(sub_usingnamespace_decl_index); const ns_ty = sub_usingnamespace_decl.val.castTag(.ty).?.data; const sub_ns = ns_ty.getNamespace().?; - try checked_namespaces.put(gpa, sub_ns, {}); + try checked_namespaces.put(gpa, sub_ns, src_file == sub_usingnamespace_decl.getFileScope()); } } diff --git a/test/behavior/usingnamespace.zig b/test/behavior/usingnamespace.zig index 83f720ff85697ae550adc8c66f920a2e9a42604c..97ab86b1729c8caa9a1a2997bf6f4470e4d61c09 100644 --- a/test/behavior/usingnamespace.zig +++ b/test/behavior/usingnamespace.zig @@ -75,3 +75,7 @@ test { const a = AA.b(42); try expect(a.x == AA.c().expected); } + +comptime { + _ = @import("usingnamespace/file_1.zig"); +} diff --git a/test/behavior/usingnamespace/file_0.zig b/test/behavior/usingnamespace/file_0.zig new file mode 100644 index 0000000000000000000000000000000000000000..584f583c56d1d0039e3a5819cc48b388b3dc8c69 --- /dev/null +++ b/test/behavior/usingnamespace/file_0.zig @@ -0,0 +1 @@ +pub const A = 123; diff --git a/test/behavior/usingnamespace/file_1.zig b/test/behavior/usingnamespace/file_1.zig new file mode 100644 index 0000000000000000000000000000000000000000..971fb8958d59dbf733ae3abd56c15cd9fb15b8bf --- /dev/null +++ b/test/behavior/usingnamespace/file_1.zig @@ -0,0 +1,9 @@ +const std = @import("std"); +const expect = std.testing.expect; +const imports = @import("imports.zig"); + +const A = 456; + +test { + try expect(imports.A == 123); +} diff --git a/test/behavior/usingnamespace/imports.zig b/test/behavior/usingnamespace/imports.zig new file mode 100644 index 0000000000000000000000000000000000000000..bbbc7dd8ca87f25abcbef88a4463deeddf70ec52 --- /dev/null +++ b/test/behavior/usingnamespace/imports.zig @@ -0,0 +1,5 @@ +const file_0 = @import("file_0.zig"); +const file_1 = @import("file_1.zig"); + +pub usingnamespace file_0; +pub usingnamespace file_1; -- 2.54.0