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) {...@@ -3765,49 +3765,59 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
3765 analyze_fn_ir(g, fn_table_entry, return_type_node);3765 analyze_fn_ir(g, fn_table_entry, return_type_node);
3766}3766}
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) {
3769 if (src_use_node->data.use.resolution == TldResolutionUnresolved) {3769 if (src_use_node->data.use.resolution == TldResolutionUnresolved) {
3770 preview_use_decl(g, src_use_node, decls_scope);3770 preview_use_decl(g, src_use_node, decls_scope);
3771 }3771 }
37723772
3773 ConstExprValue *use_target_value = src_use_node->data.use.using_namespace_value;3773 ConstExprValue *use_expr = src_use_node->data.use.using_namespace_value;
3774 if (type_is_invalid(use_target_value->type)) {3774 if (type_is_invalid(use_expr->type)) {
3775 decls_scope->any_imports_failed = true;3775 decls_scope->any_imports_failed = true;
3776 return;3776 return;
3777 }3777 }
37783778
3779 dst_use_node->data.use.resolution = TldResolutionOk;3779 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;3783 // The source struct for the imported symbols
3784 assert(target_import);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)) {
3787 add_node_error(g, dst_use_node,3788 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)));
3789 decls_scope->any_imports_failed = true;3790 decls_scope->any_imports_failed = true;
3790 return;3791 return;
3791 }3792 }
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) {
3794 decls_scope->any_imports_failed = true;3802 decls_scope->any_imports_failed = true;
3795 }3803 }
37963804
3797 auto it = get_container_scope(target_import)->decl_table.entry_iterator();3805 auto it = src_scope->decl_table.entry_iterator();
3798 for (;;) {3806 for (;;) {
3799 auto *entry = it.next();3807 auto *entry = it.next();
3800 if (!entry)3808 if (!entry)
3801 break;3809 break;
38023810
3811 Buf *target_tld_name = entry->key;
3803 Tld *target_tld = entry->value;3812 Tld *target_tld = entry->value;
3804 if (target_tld->import != target_import ||3813
3805 target_tld->visib_mod == VisibModPrivate)3814 if (target_tld->visib_mod == VisibModPrivate) {
3806 {
3807 continue;3815 continue;
3808 }3816 }
38093817
3810 Buf *target_tld_name = entry->key;3818 if (target_tld->import != src_import) {
3819 continue;
3820 }
38113821
3812 auto existing_entry = decls_scope->decl_table.put_unique(target_tld_name, target_tld);3822 auto existing_entry = decls_scope->decl_table.put_unique(target_tld_name, target_tld);
3813 if (existing_entry) {3823 if (existing_entry) {
...@@ -3822,10 +3832,10 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *...@@ -3822,10 +3832,10 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
3822 }3832 }
3823 }3833 }
38243834
3825 for (size_t i = 0; i < get_container_scope(target_import)->use_decls.length; i += 1) {3835 for (size_t i = 0; i < src_scope->use_decls.length; i += 1) {
3826 AstNode *use_decl_node = get_container_scope(target_import)->use_decls.at(i);3836 AstNode *use_decl_node = src_scope->use_decls.at(i);
3827 if (use_decl_node->data.use.visib_mod != VisibModPrivate)3837 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);
3829 }3839 }
3830}3840}
38313841
...@@ -3837,7 +3847,7 @@ void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {...@@ -3837,7 +3847,7 @@ void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
3837 {3847 {
3838 return;3848 return;
3839 }3849 }
3840 add_symbols_from_import(g, node, node, decls_scope);3850 add_symbols_from_struct(g, node, node, decls_scope);
3841}3851}
38423852
3843void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {3853void 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" {...@@ -549,3 +549,14 @@ test "packed struct with fp fields" {
549 expectEqual(f32(11.0), s.data[1]);549 expectEqual(f32(11.0), s.data[1]);
550 expectEqual(f32(20.0), s.data[2]);550 expectEqual(f32(20.0), s.data[2]);
551}551}
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}