authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-29 15:48:49-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-29 15:48:49-04:00
log9891c4f30ddfb2692ecdcc9061d0b45c9d335f6c
tree69e278bd59e7490c9451b3ffe129ec80a82c4d50
parentf9ada1cfba5140ef01baa138813241c6b93a1ea9
parent86b3007b945d2145bc7467625c658fd5480b5135
signaturelock-open Commit is signed but in an unrecognized format.

Merge branch 'use-struct-pt2' of https://github.com/LemonBoy/zig into LemonBoy-use-struct-pt2


2 files changed, 39 insertions(+), 18 deletions(-)

src/analyze.cpp+28-18
......@@ -3765,49 +3765,59 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
37653765 analyze_fn_ir(g, fn_table_entry, return_type_node);
37663766}
37673767
3768static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node, ScopeDecls* decls_scope) {
3768static void add_symbols_from_struct(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node, ScopeDecls* decls_scope) {
37693769 if (src_use_node->data.use.resolution == TldResolutionUnresolved) {
37703770 preview_use_decl(g, src_use_node, decls_scope);
37713771 }
37723772
3773 ConstExprValue *use_target_value = src_use_node->data.use.using_namespace_value;
3774 if (type_is_invalid(use_target_value->type)) {
3773 ConstExprValue *use_expr = src_use_node->data.use.using_namespace_value;
3774 if (type_is_invalid(use_expr->type)) {
37753775 decls_scope->any_imports_failed = true;
37763776 return;
37773777 }
37783778
37793779 dst_use_node->data.use.resolution = TldResolutionOk;
37803780
3781 assert(use_target_value->special != ConstValSpecialRuntime);
3781 assert(use_expr->special != ConstValSpecialRuntime);
37823782
3783 ZigType *target_import = use_target_value->data.x_type;
3784 assert(target_import);
3783 // The source struct for the imported symbols
3784 ZigType *src_ty = use_expr->data.x_type;
3785 assert(src_ty);
37853786
3786 if (target_import->id != ZigTypeIdStruct) {
3787 if (src_ty->id != ZigTypeIdStruct || is_slice(src_ty)) {
37873788 add_node_error(g, dst_use_node,
3788 buf_sprintf("expected struct, found '%s'", buf_ptr(&target_import->name)));
3789 buf_sprintf("expected struct, found '%s'", buf_ptr(&src_ty->name)));
37893790 decls_scope->any_imports_failed = true;
37903791 return;
37913792 }
37923793
3793 if (get_container_scope(target_import)->any_imports_failed) {
3794 // The source scope for the imported symbols
3795 ScopeDecls *src_scope = get_container_scope(src_ty);
3796 // The top-level container where the symbols are defined, it's used in the
3797 // loop below in order to exclude the ones coming from an import statement
3798 ZigType *src_import = get_scope_import(reinterpret_cast<Scope*>(src_scope));
3799 assert(src_import && src_import->id == ZigTypeIdStruct);
3800
3801 if (src_scope->any_imports_failed) {
37943802 decls_scope->any_imports_failed = true;
37953803 }
37963804
3797 auto it = get_container_scope(target_import)->decl_table.entry_iterator();
3805 auto it = src_scope->decl_table.entry_iterator();
37983806 for (;;) {
37993807 auto *entry = it.next();
38003808 if (!entry)
38013809 break;
38023810
3811 Buf *target_tld_name = entry->key;
38033812 Tld *target_tld = entry->value;
3804 if (target_tld->import != target_import ||
3805 target_tld->visib_mod == VisibModPrivate)
3806 {
3813
3814 if (target_tld->visib_mod == VisibModPrivate) {
38073815 continue;
38083816 }
38093817
3810 Buf *target_tld_name = entry->key;
3818 if (target_tld->import != src_import) {
3819 continue;
3820 }
38113821
38123822 auto existing_entry = decls_scope->decl_table.put_unique(target_tld_name, target_tld);
38133823 if (existing_entry) {
......@@ -3822,10 +3832,10 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
38223832 }
38233833 }
38243834
3825 for (size_t i = 0; i < get_container_scope(target_import)->use_decls.length; i += 1) {
3826 AstNode *use_decl_node = get_container_scope(target_import)->use_decls.at(i);
3835 for (size_t i = 0; i < src_scope->use_decls.length; i += 1) {
3836 AstNode *use_decl_node = src_scope->use_decls.at(i);
38273837 if (use_decl_node->data.use.visib_mod != VisibModPrivate)
3828 add_symbols_from_import(g, use_decl_node, dst_use_node, decls_scope);
3838 add_symbols_from_struct(g, use_decl_node, dst_use_node, decls_scope);
38293839 }
38303840}
38313841
......@@ -3837,7 +3847,7 @@ void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
38373847 {
38383848 return;
38393849 }
3840 add_symbols_from_import(g, node, node, decls_scope);
3850 add_symbols_from_struct(g, node, node, decls_scope);
38413851}
38423852
38433853void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
test/stage1/behavior/struct.zig+11
......@@ -549,3 +549,14 @@ test "packed struct with fp fields" {
549549 expectEqual(f32(11.0), s.data[1]);
550550 expectEqual(f32(20.0), s.data[2]);
551551}
552
553test "use within struct scope" {
554 const S = struct {
555 use struct {
556 pub fn inner() i32 {
557 return 42;
558 }
559 };
560 };
561 expectEqual(i32(42), S.inner());
562}