authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-05-18 23:48:38+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-19 00:32:49-04:00
logb660134a18a308a3a4378c98b78b84595da34e7e
tree94dd218222c1a14256aa4a64d3e7dead7e9598f0
parent860684cc2f867b568137319930981904968c9577

Use the correct scope for `use`

use expressions outside the top-level scope now work as intended.

3 files changed, 31 insertions(+), 19 deletions(-)

src/analyze.cpp+20-16
......@@ -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
3757static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node) {
3757static 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,11 +3814,11 @@ 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
3821void resolve_use_decl(CodeGen *g, AstNode *node) {
3821void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
38223822 assert(node->type == NodeTypeUse);
38233823
38243824 if (node->data.use.resolution == TldResolutionOk ||
......@@ -3826,10 +3826,10 @@ void resolve_use_decl(CodeGen *g, AstNode *node) {
38263826 {
38273827 return;
38283828 }
3829 add_symbols_from_import(g, node, node);
3829 add_symbols_from_import(g, node, node, decls_scope);
38303830}
38313831
3832void preview_use_decl(CodeGen *g, AstNode *node) {
3832void 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+2-2
......@@ -86,8 +86,8 @@ bool is_array_ref(ZigType *type_entry);
8686bool is_container_ref(ZigType *type_entry);
8787bool is_valid_vector_elem_type(ZigType *elem_type);
8888void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node);
89void preview_use_decl(CodeGen *g, AstNode *node);
90void resolve_use_decl(CodeGen *g, AstNode *node);
89void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls* decls_scope);
90void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls* decls_scope);
9191ZigFn *scope_fn_entry(Scope *scope);
9292ZigPackage *scope_package(Scope *scope);
9393ZigType *get_scope_import(Scope *scope);
test/stage1/behavior/import.zig+9-1
......@@ -1,10 +1,18 @@
11const expect = @import("std").testing.expect;
2const expectEqual = @import("std").testing.expectEqual;
23const a_namespace = @import("import/a_namespace.zig");
34
45test "call fn via namespace lookup" {
5 expect(a_namespace.foo() == 1234);
6 expectEqual(i32(1234), a_namespace.foo());
67}
78
89test "importing the same thing gives the same import" {
910 expect(@import("std") == @import("std"));
1011}
12
13test "import in non-toplevel scope" {
14 const S = struct {
15 use @import("import/a_namespace.zig");
16 };
17 expectEqual(i32(1234), S.foo());
18}