Skip to content

Commit b660134

Browse files
LemonBoyandrewrk
authored andcommitted
Use the correct scope for use
use expressions outside the top-level scope now work as intended.
1 parent 860684c commit b660134

File tree

3 files changed

+31
-19
lines changed

3 files changed

+31
-19
lines changed

src/analyze.cpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3313,8 +3313,8 @@ Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name) {
33133313
for (size_t i = 0; i < decls_scope->use_decls.length; i += 1) {
33143314
AstNode *use_decl_node = decls_scope->use_decls.at(i);
33153315
if (use_decl_node->data.use.resolution == TldResolutionUnresolved) {
3316-
preview_use_decl(g, use_decl_node);
3317-
resolve_use_decl(g, use_decl_node);
3316+
preview_use_decl(g, use_decl_node, decls_scope);
3317+
resolve_use_decl(g, use_decl_node, decls_scope);
33183318
}
33193319
}
33203320

@@ -3754,14 +3754,14 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
37543754
analyze_fn_ir(g, fn_table_entry, return_type_node);
37553755
}
37563756

3757-
static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node) {
3757+
static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node, ScopeDecls* decls_scope) {
37583758
if (src_use_node->data.use.resolution == TldResolutionUnresolved) {
3759-
preview_use_decl(g, src_use_node);
3759+
preview_use_decl(g, src_use_node, decls_scope);
37603760
}
37613761

37623762
ConstExprValue *use_target_value = src_use_node->data.use.using_namespace_value;
37633763
if (type_is_invalid(use_target_value->type)) {
3764-
get_container_scope(dst_use_node->owner)->any_imports_failed = true;
3764+
decls_scope->any_imports_failed = true;
37653765
return;
37663766
}
37673767

@@ -3775,12 +3775,12 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
37753775
if (target_import->id != ZigTypeIdStruct) {
37763776
add_node_error(g, dst_use_node,
37773777
buf_sprintf("expected struct, found '%s'", buf_ptr(&target_import->name)));
3778-
get_container_scope(dst_use_node->owner)->any_imports_failed = true;
3778+
decls_scope->any_imports_failed = true;
37793779
return;
37803780
}
37813781

37823782
if (get_container_scope(target_import)->any_imports_failed) {
3783-
get_container_scope(dst_use_node->owner)->any_imports_failed = true;
3783+
decls_scope->any_imports_failed = true;
37843784
}
37853785

37863786
auto it = get_container_scope(target_import)->decl_table.entry_iterator();
@@ -3798,7 +3798,7 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
37983798

37993799
Buf *target_tld_name = entry->key;
38003800

3801-
auto existing_entry = get_container_scope(dst_use_node->owner)->decl_table.put_unique(target_tld_name, target_tld);
3801+
auto existing_entry = decls_scope->decl_table.put_unique(target_tld_name, target_tld);
38023802
if (existing_entry) {
38033803
Tld *existing_decl = existing_entry->value;
38043804
if (existing_decl != target_tld) {
@@ -3814,22 +3814,22 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
38143814
for (size_t i = 0; i < get_container_scope(target_import)->use_decls.length; i += 1) {
38153815
AstNode *use_decl_node = get_container_scope(target_import)->use_decls.at(i);
38163816
if (use_decl_node->data.use.visib_mod != VisibModPrivate)
3817-
add_symbols_from_import(g, use_decl_node, dst_use_node);
3817+
add_symbols_from_import(g, use_decl_node, dst_use_node, decls_scope);
38183818
}
38193819
}
38203820

3821-
void resolve_use_decl(CodeGen *g, AstNode *node) {
3821+
void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
38223822
assert(node->type == NodeTypeUse);
38233823

38243824
if (node->data.use.resolution == TldResolutionOk ||
38253825
node->data.use.resolution == TldResolutionInvalid)
38263826
{
38273827
return;
38283828
}
3829-
add_symbols_from_import(g, node, node);
3829+
add_symbols_from_import(g, node, node, decls_scope);
38303830
}
38313831

3832-
void preview_use_decl(CodeGen *g, AstNode *node) {
3832+
void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
38333833
assert(node->type == NodeTypeUse);
38343834

38353835
if (node->data.use.resolution == TldResolutionOk ||
@@ -3839,11 +3839,11 @@ void preview_use_decl(CodeGen *g, AstNode *node) {
38393839
}
38403840

38413841
node->data.use.resolution = TldResolutionResolving;
3842-
ConstExprValue *result = analyze_const_value(g, &get_container_scope(node->owner)->base,
3842+
ConstExprValue *result = analyze_const_value(g, &decls_scope->base,
38433843
node->data.use.expr, g->builtin_types.entry_type, nullptr);
38443844

38453845
if (type_is_invalid(result->type))
3846-
get_container_scope(node->owner)->any_imports_failed = true;
3846+
decls_scope->any_imports_failed = true;
38473847

38483848
node->data.use.using_namespace_value = result;
38493849
}
@@ -3967,8 +3967,12 @@ void semantic_analyze(CodeGen *g) {
39673967
{
39683968
for (; g->use_queue_index < g->use_queue.length; g->use_queue_index += 1) {
39693969
AstNode *use_decl_node = g->use_queue.at(g->use_queue_index);
3970-
preview_use_decl(g, use_decl_node);
3971-
resolve_use_decl(g, use_decl_node);
3970+
// Get the top-level scope where `use` is used
3971+
ScopeDecls *decls_scope = get_container_scope(use_decl_node->owner);
3972+
if (use_decl_node->data.use.resolution == TldResolutionUnresolved) {
3973+
preview_use_decl(g, use_decl_node, decls_scope);
3974+
resolve_use_decl(g, use_decl_node, decls_scope);
3975+
}
39723976
}
39733977
for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) {
39743978
Tld *tld = g->resolve_queue.at(g->resolve_queue_index);

src/analyze.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ bool is_array_ref(ZigType *type_entry);
8686
bool is_container_ref(ZigType *type_entry);
8787
bool is_valid_vector_elem_type(ZigType *elem_type);
8888
void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node);
89-
void preview_use_decl(CodeGen *g, AstNode *node);
90-
void resolve_use_decl(CodeGen *g, AstNode *node);
89+
void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls* decls_scope);
90+
void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls* decls_scope);
9191
ZigFn *scope_fn_entry(Scope *scope);
9292
ZigPackage *scope_package(Scope *scope);
9393
ZigType *get_scope_import(Scope *scope);

test/stage1/behavior/import.zig

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
const expect = @import("std").testing.expect;
2+
const expectEqual = @import("std").testing.expectEqual;
23
const a_namespace = @import("import/a_namespace.zig");
34

45
test "call fn via namespace lookup" {
5-
expect(a_namespace.foo() == 1234);
6+
expectEqual(i32(1234), a_namespace.foo());
67
}
78

89
test "importing the same thing gives the same import" {
910
expect(@import("std") == @import("std"));
1011
}
12+
13+
test "import in non-toplevel scope" {
14+
const S = struct {
15+
use @import("import/a_namespace.zig");
16+
};
17+
expectEqual(i32(1234), S.foo());
18+
}

0 commit comments

Comments
 (0)