| author | |
| committer | |
| log | ba74ad552592108ccc3e0ad6fb94eff639db2e45 |
| tree | e9d6ed06a1b396cc8654dc1c0dbdd53d2a9e0578 |
| parent | e2c60cf76778cc049d41a9149df8a5fbb172d3c1 |
4 files changed, 17 insertions(+), 21 deletions(-)
doc/langref.html.in+1-1| ... | ... | @@ -5013,7 +5013,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val |
| 5013 | 5013 | |
| 5014 | 5014 | {#header_open|@hasDecl#} |
| 5015 | 5015 | <pre>{#syntax#}@hasDecl(comptime Namespace: type, comptime name: []const u8) bool{#endsyntax#}</pre> |
| 5016 | <p>Returns whether or not a {#link|Namespace#} has a declaration matching {#syntax#}name{#endsyntax#}.</p> | |
| 5016 | <p>Returns whether or not a {#link|Namespace#} has a public declaration matching {#syntax#}name{#endsyntax#}.</p> | |
| 5017 | 5017 | {#code|test_hasDecl_builtin.zig#} |
| 5018 | 5018 | |
| 5019 | 5019 | <p>Caution: using {#syntax#}@hasDecl{#endsyntax#} to implement |
doc/langref/test_hasDecl_builtin.zig+2-4| ... | ... | @@ -11,10 +11,8 @@ const Foo = struct { |
| 11 | 11 | test "@hasDecl" { |
| 12 | 12 | try expect(@hasDecl(Foo, "blah")); |
| 13 | 13 | |
| 14 | // Even though `hi` is private, @hasDecl returns true because this test is | |
| 15 | // in the same file scope as Foo. It would return false if Foo was declared | |
| 16 | // in a different file. | |
| 17 | try expect(@hasDecl(Foo, "hi")); | |
| 14 | // @hasDecl returns false for private declarations. | |
| 15 | try expect(!@hasDecl(Foo, "hi")); | |
| 18 | 16 | |
| 19 | 17 | // @hasDecl is for declarations; not fields. |
| 20 | 18 | try expect(!@hasDecl(Foo, "nope")); |
src/Sema.zig+6-8| ... | ... | @@ -5977,7 +5977,7 @@ fn lookupIdentifier(sema: *Sema, block: *Block, name: InternPool.NullTerminatedS |
| 5977 | 5977 | var namespace = block.namespace; |
| 5978 | 5978 | while (true) { |
| 5979 | 5979 | if (try sema.lookupInNamespace(block, namespace, name)) |lookup| { |
| 5980 | assert(lookup.accessible); | |
| 5980 | assert(lookup.accessible == .public or lookup.accessible == .private_same_file); | |
| 5981 | 5981 | return lookup.nav; |
| 5982 | 5982 | } |
| 5983 | 5983 | namespace = zcu.namespacePtr(namespace).parent.unwrap() orelse break; |
| ... | ... | @@ -5993,9 +5993,7 @@ fn lookupInNamespace( |
| 5993 | 5993 | ident_name: InternPool.NullTerminatedString, |
| 5994 | 5994 | ) CompileError!?struct { |
| 5995 | 5995 | nav: InternPool.Nav.Index, |
| 5996 | /// If `false`, the declaration is in a different file and is not `pub`. | |
| 5997 | /// We still return the declaration for better error reporting. | |
| 5998 | accessible: bool, | |
| 5996 | accessible: enum { public, private_same_file, private }, | |
| 5999 | 5997 | } { |
| 6000 | 5998 | const pt = sema.pt; |
| 6001 | 5999 | const zcu = pt.zcu; |
| ... | ... | @@ -6025,12 +6023,12 @@ fn lookupInNamespace( |
| 6025 | 6023 | if (namespace.pub_decls.getKeyAdapted(ident_name, adapter)) |nav_index| { |
| 6026 | 6024 | return .{ |
| 6027 | 6025 | .nav = nav_index, |
| 6028 | .accessible = true, | |
| 6026 | .accessible = .public, | |
| 6029 | 6027 | }; |
| 6030 | 6028 | } else if (namespace.priv_decls.getKeyAdapted(ident_name, adapter)) |nav_index| { |
| 6031 | 6029 | return .{ |
| 6032 | 6030 | .nav = nav_index, |
| 6033 | .accessible = src_file == namespace.file_scope, | |
| 6031 | .accessible = if (src_file == namespace.file_scope) .private_same_file else .private, | |
| 6034 | 6032 | }; |
| 6035 | 6033 | } |
| 6036 | 6034 | |
| ... | ... | @@ -12877,7 +12875,7 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 12877 | 12875 | |
| 12878 | 12876 | const namespace = container_type.getNamespace(zcu).unwrap() orelse return .bool_false; |
| 12879 | 12877 | if (try sema.lookupInNamespace(block, namespace, decl_name)) |lookup| { |
| 12880 | if (lookup.accessible) { | |
| 12878 | if (lookup.accessible == .public) { | |
| 12881 | 12879 | return .bool_true; |
| 12882 | 12880 | } |
| 12883 | 12881 | } |
| ... | ... | @@ -26925,7 +26923,7 @@ fn namespaceLookup( |
| 26925 | 26923 | const zcu = pt.zcu; |
| 26926 | 26924 | const gpa = sema.gpa; |
| 26927 | 26925 | if (try sema.lookupInNamespace(block, namespace, decl_name)) |lookup| { |
| 26928 | if (!lookup.accessible) { | |
| 26926 | if (lookup.accessible == .private) { | |
| 26929 | 26927 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 26930 | 26928 | const msg = try sema.errMsg(src, "'{f}' is not marked 'pub'", .{ |
| 26931 | 26929 | decl_name.fmt(&zcu.intern_pool), |
test/behavior/hasdecl.zig+8-8| ... | ... | @@ -4,7 +4,7 @@ const expect = std.testing.expect; |
| 4 | 4 | |
| 5 | 5 | const Foo = @import("hasdecl/foo.zig"); |
| 6 | 6 | |
| 7 | const Bar = struct { | |
| 7 | pub const Bar = struct { | |
| 8 | 8 | nope: i32, |
| 9 | 9 | |
| 10 | 10 | const hi = 1; |
| ... | ... | @@ -18,7 +18,7 @@ test "@hasDecl" { |
| 18 | 18 | try expect(!@hasDecl(Foo, "private_thing")); |
| 19 | 19 | try expect(!@hasDecl(Foo, "no_thing")); |
| 20 | 20 | |
| 21 | try expect(@hasDecl(Bar, "hi")); | |
| 21 | try expect(!@hasDecl(Bar, "hi")); | |
| 22 | 22 | try expect(@hasDecl(Bar, "blah")); |
| 23 | 23 | try expect(!@hasDecl(Bar, "nope")); |
| 24 | 24 | } |
| ... | ... | @@ -26,10 +26,10 @@ test "@hasDecl" { |
| 26 | 26 | test "@hasDecl using a sliced string literal" { |
| 27 | 27 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; |
| 28 | 28 | |
| 29 | try expect(@hasDecl(@This(), "std") == true); | |
| 30 | try expect(@hasDecl(@This(), "std"[0..0]) == false); | |
| 31 | try expect(@hasDecl(@This(), "std"[0..1]) == false); | |
| 32 | try expect(@hasDecl(@This(), "std"[0..2]) == false); | |
| 33 | try expect(@hasDecl(@This(), "std"[0..3]) == true); | |
| 34 | try expect(@hasDecl(@This(), "std"[0..]) == true); | |
| 29 | try expect(@hasDecl(@This(), "Bar") == true); | |
| 30 | try expect(@hasDecl(@This(), "Bar"[0..0]) == false); | |
| 31 | try expect(@hasDecl(@This(), "Bar"[0..1]) == false); | |
| 32 | try expect(@hasDecl(@This(), "Bar"[0..2]) == false); | |
| 33 | try expect(@hasDecl(@This(), "Bar"[0..3]) == true); | |
| 34 | try expect(@hasDecl(@This(), "Bar"[0..]) == true); | |
| 35 | 35 | } |