authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-05-21 17:07:40+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-05-21 17:07:40+02:00
logf67ca206557de58df91011744f656ed049d36372
tree0ccf3a4ac7da25a0330cdebe5f8058a9b075be6b
parent163a8e98bc04ea955ee54d5905436ffac34c93a2

Make use work with arbitrary structs


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

src/analyze.cpp+28-18
...@@ -3754,49 +3754,59 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {...@@ -3754,49 +3754,59 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
3754 analyze_fn_ir(g, fn_table_entry, return_type_node);3754 analyze_fn_ir(g, fn_table_entry, return_type_node);
3755}3755}
37563756
3757static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node, ScopeDecls* decls_scope) {3757static void add_symbols_from_struct(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node, ScopeDecls* decls_scope) {
3758 if (src_use_node->data.use.resolution == TldResolutionUnresolved) {3758 if (src_use_node->data.use.resolution == TldResolutionUnresolved) {
3759 preview_use_decl(g, src_use_node, decls_scope);3759 preview_use_decl(g, src_use_node, decls_scope);
3760 }3760 }
37613761
3762 ConstExprValue *use_target_value = src_use_node->data.use.using_namespace_value;3762 ConstExprValue *use_expr = src_use_node->data.use.using_namespace_value;
3763 if (type_is_invalid(use_target_value->type)) {3763 if (type_is_invalid(use_expr->type)) {
3764 decls_scope->any_imports_failed = true;3764 decls_scope->any_imports_failed = true;
3765 return;3765 return;
3766 }3766 }
37673767
3768 dst_use_node->data.use.resolution = TldResolutionOk;3768 dst_use_node->data.use.resolution = TldResolutionOk;
37693769
3770 assert(use_target_value->special != ConstValSpecialRuntime);3770 assert(use_expr->special != ConstValSpecialRuntime);
37713771
3772 ZigType *target_import = use_target_value->data.x_type;3772 // The source struct for the imported symbols
3773 assert(target_import);3773 ZigType *src_ty = use_expr->data.x_type;
3774 assert(src_ty);
37743775
3775 if (target_import->id != ZigTypeIdStruct) {3776 if (src_ty->id != ZigTypeIdStruct) {
3776 add_node_error(g, dst_use_node,3777 add_node_error(g, dst_use_node,
3777 buf_sprintf("expected struct, found '%s'", buf_ptr(&target_import->name)));3778 buf_sprintf("expected struct, found '%s'", buf_ptr(&src_ty->name)));
3778 decls_scope->any_imports_failed = true;3779 decls_scope->any_imports_failed = true;
3779 return;3780 return;
3780 }3781 }
37813782
3782 if (get_container_scope(target_import)->any_imports_failed) {3783 // The source scope for the imported symbols
3784 ScopeDecls *src_scope = get_container_scope(src_ty);
3785 // The top-level container where the symbols are defined, it's used in the
3786 // loop below in order to exclude the ones coming from an import statement
3787 ZigType *src_import = get_scope_import(reinterpret_cast<Scope*>(src_scope));
3788 assert(src_import && src_import->id == ZigTypeIdStruct);
3789
3790 if (src_scope->any_imports_failed) {
3783 decls_scope->any_imports_failed = true;3791 decls_scope->any_imports_failed = true;
3784 }3792 }
37853793
3786 auto it = get_container_scope(target_import)->decl_table.entry_iterator();3794 auto it = src_scope->decl_table.entry_iterator();
3787 for (;;) {3795 for (;;) {
3788 auto *entry = it.next();3796 auto *entry = it.next();
3789 if (!entry)3797 if (!entry)
3790 break;3798 break;
37913799
3800 Buf *target_tld_name = entry->key;
3792 Tld *target_tld = entry->value;3801 Tld *target_tld = entry->value;
3793 if (target_tld->import != target_import ||3802
3794 target_tld->visib_mod == VisibModPrivate)3803 if (target_tld->visib_mod == VisibModPrivate) {
3795 {
3796 continue;3804 continue;
3797 }3805 }
37983806
3799 Buf *target_tld_name = entry->key;3807 if (target_tld->import != src_import) {
3808 continue;
3809 }
38003810
3801 auto existing_entry = decls_scope->decl_table.put_unique(target_tld_name, target_tld);3811 auto existing_entry = decls_scope->decl_table.put_unique(target_tld_name, target_tld);
3802 if (existing_entry) {3812 if (existing_entry) {
...@@ -3811,10 +3821,10 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *...@@ -3811,10 +3821,10 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
3811 }3821 }
3812 }3822 }
38133823
3814 for (size_t i = 0; i < get_container_scope(target_import)->use_decls.length; i += 1) {3824 for (size_t i = 0; i < src_scope->use_decls.length; i += 1) {
3815 AstNode *use_decl_node = get_container_scope(target_import)->use_decls.at(i);3825 AstNode *use_decl_node = src_scope->use_decls.at(i);
3816 if (use_decl_node->data.use.visib_mod != VisibModPrivate)3826 if (use_decl_node->data.use.visib_mod != VisibModPrivate)
3817 add_symbols_from_import(g, use_decl_node, dst_use_node, decls_scope);3827 add_symbols_from_struct(g, use_decl_node, dst_use_node, decls_scope);
3818 }3828 }
3819}3829}
38203830
...@@ -3826,7 +3836,7 @@ void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {...@@ -3826,7 +3836,7 @@ void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
3826 {3836 {
3827 return;3837 return;
3828 }3838 }
3829 add_symbols_from_import(g, node, node, decls_scope);3839 add_symbols_from_struct(g, node, node, decls_scope);
3830}3840}
38313841
3832void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {3842void 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}