authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-29 16:32:16-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-29 16:32:16-04:00
log7017388e9ea9a5b144780c0a5c090bb7a221c9b6
tree7e4f95bffdf56633dcb47b98866b0f8804e134b1
parentf9ada1cfba5140ef01baa138813241c6b93a1ea9
parent1ccbd1fb67898c0691c74e65a7b9786fb5698619
signaturelock-open Commit is signed but in an unrecognized format.

Merge branch 'LemonBoy-use-struct-pt2'


5 files changed, 48 insertions(+), 31 deletions(-)

src/analyze.cpp+33-22
...@@ -3453,11 +3453,12 @@ TypeEnumField *find_enum_field_by_tag(ZigType *enum_type, const BigInt *tag) {...@@ -3453,11 +3453,12 @@ TypeEnumField *find_enum_field_by_tag(ZigType *enum_type, const BigInt *tag) {
3453}3453}
34543454
34553455
3456static bool is_container(ZigType *type_entry) {3456bool is_container(ZigType *type_entry) {
3457 switch (type_entry->id) {3457 switch (type_entry->id) {
3458 case ZigTypeIdInvalid:3458 case ZigTypeIdInvalid:
3459 zig_unreachable();3459 zig_unreachable();
3460 case ZigTypeIdStruct:3460 case ZigTypeIdStruct:
3461 return !type_entry->data.structure.is_slice;
3461 case ZigTypeIdEnum:3462 case ZigTypeIdEnum:
3462 case ZigTypeIdUnion:3463 case ZigTypeIdUnion:
3463 return true;3464 return true;
...@@ -3498,9 +3499,9 @@ bool is_array_ref(ZigType *type_entry) {...@@ -3498,9 +3499,9 @@ bool is_array_ref(ZigType *type_entry) {
3498 return array->id == ZigTypeIdArray;3499 return array->id == ZigTypeIdArray;
3499}3500}
35003501
3501bool is_container_ref(ZigType *type_entry) {3502bool is_container_ref(ZigType *parent_ty) {
3502 return is_ref(type_entry) ?3503 ZigType *ty = is_ref(parent_ty) ? parent_ty->data.pointer.child_type : parent_ty;
3503 is_container(type_entry->data.pointer.child_type) : is_container(type_entry);3504 return is_slice(ty) || is_container(ty);
3504}3505}
35053506
3506ZigType *container_ref_type(ZigType *type_entry) {3507ZigType *container_ref_type(ZigType *type_entry) {
...@@ -3765,49 +3766,59 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {...@@ -3765,49 +3766,59 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
3765 analyze_fn_ir(g, fn_table_entry, return_type_node);3766 analyze_fn_ir(g, fn_table_entry, return_type_node);
3766}3767}
37673768
3768static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node, ScopeDecls* decls_scope) {3769static void add_symbols_from_container(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node, ScopeDecls* decls_scope) {
3769 if (src_use_node->data.use.resolution == TldResolutionUnresolved) {3770 if (src_use_node->data.use.resolution == TldResolutionUnresolved) {
3770 preview_use_decl(g, src_use_node, decls_scope);3771 preview_use_decl(g, src_use_node, decls_scope);
3771 }3772 }
37723773
3773 ConstExprValue *use_target_value = src_use_node->data.use.using_namespace_value;3774 ConstExprValue *use_expr = src_use_node->data.use.using_namespace_value;
3774 if (type_is_invalid(use_target_value->type)) {3775 if (type_is_invalid(use_expr->type)) {
3775 decls_scope->any_imports_failed = true;3776 decls_scope->any_imports_failed = true;
3776 return;3777 return;
3777 }3778 }
37783779
3779 dst_use_node->data.use.resolution = TldResolutionOk;3780 dst_use_node->data.use.resolution = TldResolutionOk;
37803781
3781 assert(use_target_value->special != ConstValSpecialRuntime);3782 assert(use_expr->special != ConstValSpecialRuntime);
37823783
3783 ZigType *target_import = use_target_value->data.x_type;3784 // The source struct for the imported symbols
3784 assert(target_import);3785 ZigType *src_ty = use_expr->data.x_type;
3786 assert(src_ty);
37853787
3786 if (target_import->id != ZigTypeIdStruct) {3788 if (!is_container(src_ty)) {
3787 add_node_error(g, dst_use_node,3789 add_node_error(g, dst_use_node,
3788 buf_sprintf("expected struct, found '%s'", buf_ptr(&target_import->name)));3790 buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&src_ty->name)));
3789 decls_scope->any_imports_failed = true;3791 decls_scope->any_imports_failed = true;
3790 return;3792 return;
3791 }3793 }
37923794
3793 if (get_container_scope(target_import)->any_imports_failed) {3795 // The source scope for the imported symbols
3796 ScopeDecls *src_scope = get_container_scope(src_ty);
3797 // The top-level container where the symbols are defined, it's used in the
3798 // loop below in order to exclude the ones coming from an import statement
3799 ZigType *src_import = get_scope_import(&src_scope->base);
3800 assert(src_import != nullptr);
3801
3802 if (src_scope->any_imports_failed) {
3794 decls_scope->any_imports_failed = true;3803 decls_scope->any_imports_failed = true;
3795 }3804 }
37963805
3797 auto it = get_container_scope(target_import)->decl_table.entry_iterator();3806 auto it = src_scope->decl_table.entry_iterator();
3798 for (;;) {3807 for (;;) {
3799 auto *entry = it.next();3808 auto *entry = it.next();
3800 if (!entry)3809 if (!entry)
3801 break;3810 break;
38023811
3812 Buf *target_tld_name = entry->key;
3803 Tld *target_tld = entry->value;3813 Tld *target_tld = entry->value;
3804 if (target_tld->import != target_import ||3814
3805 target_tld->visib_mod == VisibModPrivate)3815 if (target_tld->visib_mod == VisibModPrivate) {
3806 {
3807 continue;3816 continue;
3808 }3817 }
38093818
3810 Buf *target_tld_name = entry->key;3819 if (target_tld->import != src_import) {
3820 continue;
3821 }
38113822
3812 auto existing_entry = decls_scope->decl_table.put_unique(target_tld_name, target_tld);3823 auto existing_entry = decls_scope->decl_table.put_unique(target_tld_name, target_tld);
3813 if (existing_entry) {3824 if (existing_entry) {
...@@ -3822,10 +3833,10 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *...@@ -3822,10 +3833,10 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
3822 }3833 }
3823 }3834 }
38243835
3825 for (size_t i = 0; i < get_container_scope(target_import)->use_decls.length; i += 1) {3836 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);3837 AstNode *use_decl_node = src_scope->use_decls.at(i);
3827 if (use_decl_node->data.use.visib_mod != VisibModPrivate)3838 if (use_decl_node->data.use.visib_mod != VisibModPrivate)
3828 add_symbols_from_import(g, use_decl_node, dst_use_node, decls_scope);3839 add_symbols_from_container(g, use_decl_node, dst_use_node, decls_scope);
3829 }3840 }
3830}3841}
38313842
...@@ -3837,7 +3848,7 @@ void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {...@@ -3837,7 +3848,7 @@ void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
3837 {3848 {
3838 return;3849 return;
3839 }3850 }
3840 add_symbols_from_import(g, node, node, decls_scope);3851 add_symbols_from_container(g, node, node, decls_scope);
3841}3852}
38423853
3843void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {3854void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
src/analyze.hpp+1
...@@ -250,5 +250,6 @@ ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type);...@@ -250,5 +250,6 @@ ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type);
250void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_path, bool translate_c);250void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_path, bool translate_c);
251251
252void src_assert(bool ok, AstNode *source_node);252void src_assert(bool ok, AstNode *source_node);
253bool is_container(ZigType *type_entry);
253254
254#endif255#endif
src/ir.cpp+2-8
...@@ -10266,12 +10266,6 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc...@@ -10266,12 +10266,6 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc
10266 return result;10266 return result;
10267}10267}
1026810268
10269static bool is_container(ZigType *type) {
10270 return type->id == ZigTypeIdStruct ||
10271 type->id == ZigTypeIdEnum ||
10272 type->id == ZigTypeIdUnion;
10273}
10274
10275static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) {10269static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) {
10276 assert(old_bb);10270 assert(old_bb);
1027710271
...@@ -16179,7 +16173,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc...@@ -16179,7 +16173,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
1617916173
16180 if (type_is_invalid(container_type)) {16174 if (type_is_invalid(container_type)) {
16181 return ira->codegen->invalid_instruction;16175 return ira->codegen->invalid_instruction;
16182 } else if (is_container_ref(container_type)) {16176 } else if (is_slice(container_type) || is_container_ref(container_type)) {
16183 assert(container_ptr->value.type->id == ZigTypeIdPointer);16177 assert(container_ptr->value.type->id == ZigTypeIdPointer);
16184 if (container_type->id == ZigTypeIdPointer) {16178 if (container_type->id == ZigTypeIdPointer) {
16185 ZigType *bare_type = container_ref_type(container_type);16179 ZigType *bare_type = container_ref_type(container_type);
...@@ -16249,7 +16243,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc...@@ -16249,7 +16243,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
1624916243
16250 if (type_is_invalid(child_type)) {16244 if (type_is_invalid(child_type)) {
16251 return ira->codegen->invalid_instruction;16245 return ira->codegen->invalid_instruction;
16252 } else if (is_container(child_type) && !is_slice(child_type)) {16246 } else if (is_container(child_type)) {
16253 if (child_type->id == ZigTypeIdEnum) {16247 if (child_type->id == ZigTypeIdEnum) {
16254 if ((err = ensure_complete_type(ira->codegen, child_type)))16248 if ((err = ensure_complete_type(ira->codegen, child_type)))
16255 return ira->codegen->invalid_instruction;16249 return ira->codegen->invalid_instruction;
test/compile_errors.zig+1-1
...@@ -163,7 +163,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -163,7 +163,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
163 "usingnamespace with wrong type",163 "usingnamespace with wrong type",
164 \\use void;164 \\use void;
165 ,165 ,
166 "tmp.zig:1:1: error: expected struct, found 'void'",166 "tmp.zig:1:1: error: expected struct, enum, or union; found 'void'",
167 );167 );
168168
169 cases.add(169 cases.add(
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}