authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-19 16:56:44-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-19 16:56:44-04:00
logaf8661405b908c0abfc191501a8ad1a59a54e86a
treed76bde495229dc37b7436c547afe5f03aee6b61d
parent1d07bbbef23993338b231fbd9d7bbf5a349c5f31
signature Commit is signed but in an unrecognized format.

fix usingnamespace

It used to be that usingnamespace was only allowed at top level. This made it OK to put the state inside the AST node data structure. However, now usingnamespace can occur inside any aggregate data structure, and therefore the state must be in the TopLevelDeclaration rather than in the AST node. There were two other problems with the usingnamespace implementation: * It was passing the wrong destination ScopeDecl, so it could cause an incorrect error such as "import of file outside package path". * When doing `usingnamespace` on a file that already had `pub usingnamespace` in it would "steal" the usingnamespace, causing incorrect "use of undeclared identifier" errors in the target file. closes #2632 closes #2580

9 files changed, 170 insertions(+), 145 deletions(-)

src/all_types.hpp+9-7
...@@ -366,6 +366,7 @@ enum TldId {...@@ -366,6 +366,7 @@ enum TldId {
366 TldIdFn,366 TldIdFn,
367 TldIdContainer,367 TldIdContainer,
368 TldIdCompTime,368 TldIdCompTime,
369 TldIdUsingNamespace,
369};370};
370371
371enum TldResolution {372enum TldResolution {
...@@ -413,6 +414,12 @@ struct TldCompTime {...@@ -413,6 +414,12 @@ struct TldCompTime {
413 Tld base;414 Tld base;
414};415};
415416
417struct TldUsingNamespace {
418 Tld base;
419
420 ConstExprValue *using_namespace_value;
421};
422
416struct TypeEnumField {423struct TypeEnumField {
417 Buf *name;424 Buf *name;
418 BigInt value;425 BigInt value;
...@@ -453,7 +460,7 @@ enum NodeType {...@@ -453,7 +460,7 @@ enum NodeType {
453 NodeTypeFieldAccessExpr,460 NodeTypeFieldAccessExpr,
454 NodeTypePtrDeref,461 NodeTypePtrDeref,
455 NodeTypeUnwrapOptional,462 NodeTypeUnwrapOptional,
456 NodeTypeUse,463 NodeTypeUsingNamespace,
457 NodeTypeBoolLiteral,464 NodeTypeBoolLiteral,
458 NodeTypeNullLiteral,465 NodeTypeNullLiteral,
459 NodeTypeUndefinedLiteral,466 NodeTypeUndefinedLiteral,
...@@ -715,9 +722,6 @@ struct AstNodeArrayType {...@@ -715,9 +722,6 @@ struct AstNodeArrayType {
715struct AstNodeUsingNamespace {722struct AstNodeUsingNamespace {
716 VisibMod visib_mod;723 VisibMod visib_mod;
717 AstNode *expr;724 AstNode *expr;
718
719 TldResolution resolution;
720 ConstExprValue *using_namespace_value;
721};725};
722726
723struct AstNodeIfBoolExpr {727struct AstNodeIfBoolExpr {
...@@ -1745,8 +1749,6 @@ struct CodeGen {...@@ -1745,8 +1749,6 @@ struct CodeGen {
17451749
1746 ZigList<Tld *> resolve_queue;1750 ZigList<Tld *> resolve_queue;
1747 size_t resolve_queue_index;1751 size_t resolve_queue_index;
1748 ZigList<AstNode *> use_queue;
1749 size_t use_queue_index;
1750 ZigList<TimeEvent> timing_events;1752 ZigList<TimeEvent> timing_events;
1751 ZigList<AstNode *> tld_ref_source_node_stack;1753 ZigList<AstNode *> tld_ref_source_node_stack;
1752 ZigList<ZigFn *> inline_fns;1754 ZigList<ZigFn *> inline_fns;
...@@ -2005,7 +2007,7 @@ struct ScopeDecls {...@@ -2005,7 +2007,7 @@ struct ScopeDecls {
2005 Scope base;2007 Scope base;
20062008
2007 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> decl_table;2009 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> decl_table;
2008 ZigList<AstNode *> use_decls;2010 ZigList<TldUsingNamespace *> use_decls;
2009 AstNode *safety_set_node;2011 AstNode *safety_set_node;
2010 AstNode *fast_math_set_node;2012 AstNode *fast_math_set_node;
2011 ZigType *import;2013 ZigType *import;
src/analyze.cpp+137-128
...@@ -28,6 +28,8 @@ static Error ATTRIBUTE_MUST_USE resolve_union_zero_bits(CodeGen *g, ZigType *uni...@@ -28,6 +28,8 @@ static Error ATTRIBUTE_MUST_USE resolve_union_zero_bits(CodeGen *g, ZigType *uni
28static Error ATTRIBUTE_MUST_USE resolve_union_alignment(CodeGen *g, ZigType *union_type);28static Error ATTRIBUTE_MUST_USE resolve_union_alignment(CodeGen *g, ZigType *union_type);
29static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry);29static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry);
30static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status);30static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status);
31static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, ScopeDecls *dest_decls_scope);
32static void resolve_use_decl(CodeGen *g, TldUsingNamespace *tld_using_namespace, ScopeDecls *dest_decls_scope);
3133
32static bool is_top_level_struct(ZigType *import) {34static bool is_top_level_struct(ZigType *import) {
33 return import->id == ZigTypeIdStruct && import->data.structure.root_struct != nullptr;35 return import->id == ZigTypeIdStruct && import->data.structure.root_struct != nullptr;
...@@ -2854,6 +2856,8 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {...@@ -2854,6 +2856,8 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
2854 add_node_error(g, tld->source_node, buf_sprintf("non-extern function has no body"));2856 add_node_error(g, tld->source_node, buf_sprintf("non-extern function has no body"));
2855 return;2857 return;
2856 }2858 }
2859 } else if (tld->id == TldIdUsingNamespace) {
2860 g->resolve_queue.append(tld);
2857 }2861 }
2858 if (is_export) {2862 if (is_export) {
2859 g->resolve_queue.append(tld);2863 g->resolve_queue.append(tld);
...@@ -2867,7 +2871,7 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {...@@ -2867,7 +2871,7 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
2867 }2871 }
2868 }2872 }
28692873
2870 {2874 if (tld->name != nullptr) {
2871 auto entry = decls_scope->decl_table.put_unique(tld->name, tld);2875 auto entry = decls_scope->decl_table.put_unique(tld->name, tld);
2872 if (entry) {2876 if (entry) {
2873 Tld *other_tld = entry->value;2877 Tld *other_tld = entry->value;
...@@ -2875,9 +2879,7 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {...@@ -2875,9 +2879,7 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
2875 add_error_note(g, msg, other_tld->source_node, buf_sprintf("previous definition is here"));2879 add_error_note(g, msg, other_tld->source_node, buf_sprintf("previous definition is here"));
2876 return;2880 return;
2877 }2881 }
2878 }
28792882
2880 {
2881 ZigType *type;2883 ZigType *type;
2882 if (get_primitive_type(g, tld->name, &type) != ErrorPrimitiveTypeNotFound) {2884 if (get_primitive_type(g, tld->name, &type) != ErrorPrimitiveTypeNotFound) {
2883 add_node_error(g, tld->source_node,2885 add_node_error(g, tld->source_node,
...@@ -2977,12 +2979,14 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {...@@ -2977,12 +2979,14 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
29772979
2978 break;2980 break;
2979 }2981 }
2980 case NodeTypeUse:2982 case NodeTypeUsingNamespace: {
2981 {2983 VisibMod visib_mod = node->data.using_namespace.visib_mod;
2982 g->use_queue.append(node);2984 TldUsingNamespace *tld_using_namespace = allocate<TldUsingNamespace>(1);
2983 decls_scope->use_decls.append(node);2985 init_tld(&tld_using_namespace->base, TldIdUsingNamespace, nullptr, visib_mod, node, &decls_scope->base);
2984 break;2986 add_top_level_decl(g, decls_scope, &tld_using_namespace->base);
2985 }2987 decls_scope->use_decls.append(tld_using_namespace);
2988 break;
2989 }
2986 case NodeTypeTestDecl:2990 case NodeTypeTestDecl:
2987 preview_test_decl(g, node, decls_scope);2991 preview_test_decl(g, node, decls_scope);
2988 break;2992 break;
...@@ -3266,6 +3270,117 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {...@@ -3266,6 +3270,117 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
3266 g->global_vars.append(tld_var);3270 g->global_vars.append(tld_var);
3267}3271}
32683272
3273static void add_symbols_from_container(CodeGen *g, TldUsingNamespace *src_using_namespace,
3274 TldUsingNamespace *dst_using_namespace, ScopeDecls* dest_decls_scope)
3275{
3276 if (src_using_namespace->base.resolution == TldResolutionUnresolved ||
3277 src_using_namespace->base.resolution == TldResolutionResolving)
3278 {
3279 assert(src_using_namespace->base.parent_scope->id == ScopeIdDecls);
3280 ScopeDecls *src_decls_scope = (ScopeDecls *)src_using_namespace->base.parent_scope;
3281 preview_use_decl(g, src_using_namespace, src_decls_scope);
3282 if (src_using_namespace != dst_using_namespace) {
3283 resolve_use_decl(g, src_using_namespace, src_decls_scope);
3284 }
3285 }
3286
3287 ConstExprValue *use_expr = src_using_namespace->using_namespace_value;
3288 if (type_is_invalid(use_expr->type)) {
3289 dest_decls_scope->any_imports_failed = true;
3290 return;
3291 }
3292
3293 dst_using_namespace->base.resolution = TldResolutionOk;
3294
3295 assert(use_expr->special != ConstValSpecialRuntime);
3296
3297 // The source scope for the imported symbols
3298 ScopeDecls *src_scope = get_container_scope(use_expr->data.x_type);
3299 // The top-level container where the symbols are defined, it's used in the
3300 // loop below in order to exclude the ones coming from an import statement
3301 ZigType *src_import = get_scope_import(&src_scope->base);
3302 assert(src_import != nullptr);
3303
3304 if (src_scope->any_imports_failed) {
3305 dest_decls_scope->any_imports_failed = true;
3306 }
3307
3308 auto it = src_scope->decl_table.entry_iterator();
3309 for (;;) {
3310 auto *entry = it.next();
3311 if (!entry)
3312 break;
3313
3314 Buf *target_tld_name = entry->key;
3315 Tld *target_tld = entry->value;
3316
3317 if (target_tld->visib_mod == VisibModPrivate) {
3318 continue;
3319 }
3320
3321 if (target_tld->import != src_import) {
3322 continue;
3323 }
3324
3325 auto existing_entry = dest_decls_scope->decl_table.put_unique(target_tld_name, target_tld);
3326 if (existing_entry) {
3327 Tld *existing_decl = existing_entry->value;
3328 if (existing_decl != target_tld) {
3329 ErrorMsg *msg = add_node_error(g, dst_using_namespace->base.source_node,
3330 buf_sprintf("import of '%s' overrides existing definition",
3331 buf_ptr(target_tld_name)));
3332 add_error_note(g, msg, existing_decl->source_node, buf_sprintf("previous definition here"));
3333 add_error_note(g, msg, target_tld->source_node, buf_sprintf("imported definition here"));
3334 }
3335 }
3336 }
3337
3338 for (size_t i = 0; i < src_scope->use_decls.length; i += 1) {
3339 TldUsingNamespace *tld_using_namespace = src_scope->use_decls.at(i);
3340 if (tld_using_namespace->base.visib_mod != VisibModPrivate)
3341 add_symbols_from_container(g, tld_using_namespace, dst_using_namespace, dest_decls_scope);
3342 }
3343}
3344
3345static void resolve_use_decl(CodeGen *g, TldUsingNamespace *tld_using_namespace, ScopeDecls *dest_decls_scope) {
3346 if (tld_using_namespace->base.resolution == TldResolutionOk ||
3347 tld_using_namespace->base.resolution == TldResolutionInvalid)
3348 {
3349 return;
3350 }
3351 add_symbols_from_container(g, tld_using_namespace, tld_using_namespace, dest_decls_scope);
3352}
3353
3354static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, ScopeDecls *dest_decls_scope) {
3355 if (using_namespace->base.resolution == TldResolutionOk ||
3356 using_namespace->base.resolution == TldResolutionInvalid)
3357 {
3358 return;
3359 }
3360
3361 using_namespace->base.resolution = TldResolutionResolving;
3362 assert(using_namespace->base.source_node->type == NodeTypeUsingNamespace);
3363 ConstExprValue *result = analyze_const_value(g, &dest_decls_scope->base,
3364 using_namespace->base.source_node->data.using_namespace.expr, g->builtin_types.entry_type, nullptr);
3365 using_namespace->using_namespace_value = result;
3366
3367 if (type_is_invalid(result->type)) {
3368 dest_decls_scope->any_imports_failed = true;
3369 using_namespace->base.resolution = TldResolutionInvalid;
3370 using_namespace->using_namespace_value = &g->invalid_instruction->value;
3371 return;
3372 }
3373
3374 if (!is_container(result->data.x_type)) {
3375 add_node_error(g, using_namespace->base.source_node,
3376 buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&result->data.x_type->name)));
3377 dest_decls_scope->any_imports_failed = true;
3378 using_namespace->base.resolution = TldResolutionInvalid;
3379 using_namespace->using_namespace_value = &g->invalid_instruction->value;
3380 return;
3381 }
3382}
3383
3269void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) {3384void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) {
3270 if (tld->resolution != TldResolutionUnresolved)3385 if (tld->resolution != TldResolutionUnresolved)
3271 return;3386 return;
...@@ -3299,6 +3414,14 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) {...@@ -3299,6 +3414,14 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) {
3299 resolve_decl_comptime(g, tld_comptime);3414 resolve_decl_comptime(g, tld_comptime);
3300 break;3415 break;
3301 }3416 }
3417 case TldIdUsingNamespace: {
3418 TldUsingNamespace *tld_using_namespace = (TldUsingNamespace *)tld;
3419 assert(tld_using_namespace->base.parent_scope->id == ScopeIdDecls);
3420 ScopeDecls *dest_decls_scope = (ScopeDecls *)tld_using_namespace->base.parent_scope;
3421 preview_use_decl(g, tld_using_namespace, dest_decls_scope);
3422 resolve_use_decl(g, tld_using_namespace, dest_decls_scope);
3423 break;
3424 }
3302 }3425 }
33033426
3304 tld->resolution = TldResolutionOk;3427 tld->resolution = TldResolutionOk;
...@@ -3308,10 +3431,10 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) {...@@ -3308,10 +3431,10 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) {
3308Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name) {3431Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name) {
3309 // resolve all the using_namespace decls3432 // resolve all the using_namespace decls
3310 for (size_t i = 0; i < decls_scope->use_decls.length; i += 1) {3433 for (size_t i = 0; i < decls_scope->use_decls.length; i += 1) {
3311 AstNode *use_decl_node = decls_scope->use_decls.at(i);3434 TldUsingNamespace *tld_using_namespace = decls_scope->use_decls.at(i);
3312 if (use_decl_node->data.using_namespace.resolution == TldResolutionUnresolved) {3435 if (tld_using_namespace->base.resolution == TldResolutionUnresolved) {
3313 preview_use_decl(g, use_decl_node, decls_scope);3436 preview_use_decl(g, tld_using_namespace, decls_scope);
3314 resolve_use_decl(g, use_decl_node, decls_scope);3437 resolve_use_decl(g, tld_using_namespace, decls_scope);
3315 }3438 }
3316 }3439 }
33173440
...@@ -3752,110 +3875,6 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {...@@ -3752,110 +3875,6 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
3752 analyze_fn_ir(g, fn_table_entry, return_type_node);3875 analyze_fn_ir(g, fn_table_entry, return_type_node);
3753}3876}
37543877
3755static void add_symbols_from_container(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node, ScopeDecls* decls_scope) {
3756 if (src_use_node->data.using_namespace.resolution == TldResolutionUnresolved) {
3757 preview_use_decl(g, src_use_node, decls_scope);
3758 }
3759
3760 ConstExprValue *use_expr = src_use_node->data.using_namespace.using_namespace_value;
3761 if (type_is_invalid(use_expr->type)) {
3762 decls_scope->any_imports_failed = true;
3763 return;
3764 }
3765
3766 dst_use_node->data.using_namespace.resolution = TldResolutionOk;
3767
3768 assert(use_expr->special != ConstValSpecialRuntime);
3769
3770 // The source struct for the imported symbols
3771 ZigType *src_ty = use_expr->data.x_type;
3772 assert(src_ty);
3773
3774 if (!is_container(src_ty)) {
3775 add_node_error(g, dst_use_node,
3776 buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&src_ty->name)));
3777 decls_scope->any_imports_failed = true;
3778 return;
3779 }
3780
3781 // The source scope for the imported symbols
3782 ScopeDecls *src_scope = get_container_scope(src_ty);
3783 // The top-level container where the symbols are defined, it's used in the
3784 // loop below in order to exclude the ones coming from an import statement
3785 ZigType *src_import = get_scope_import(&src_scope->base);
3786 assert(src_import != nullptr);
3787
3788 if (src_scope->any_imports_failed) {
3789 decls_scope->any_imports_failed = true;
3790 }
3791
3792 auto it = src_scope->decl_table.entry_iterator();
3793 for (;;) {
3794 auto *entry = it.next();
3795 if (!entry)
3796 break;
3797
3798 Buf *target_tld_name = entry->key;
3799 Tld *target_tld = entry->value;
3800
3801 if (target_tld->visib_mod == VisibModPrivate) {
3802 continue;
3803 }
3804
3805 if (target_tld->import != src_import) {
3806 continue;
3807 }
3808
3809 auto existing_entry = decls_scope->decl_table.put_unique(target_tld_name, target_tld);
3810 if (existing_entry) {
3811 Tld *existing_decl = existing_entry->value;
3812 if (existing_decl != target_tld) {
3813 ErrorMsg *msg = add_node_error(g, dst_use_node,
3814 buf_sprintf("import of '%s' overrides existing definition",
3815 buf_ptr(target_tld_name)));
3816 add_error_note(g, msg, existing_decl->source_node, buf_sprintf("previous definition here"));
3817 add_error_note(g, msg, target_tld->source_node, buf_sprintf("imported definition here"));
3818 }
3819 }
3820 }
3821
3822 for (size_t i = 0; i < src_scope->use_decls.length; i += 1) {
3823 AstNode *use_decl_node = src_scope->use_decls.at(i);
3824 if (use_decl_node->data.using_namespace.visib_mod != VisibModPrivate)
3825 add_symbols_from_container(g, use_decl_node, dst_use_node, decls_scope);
3826 }
3827}
3828
3829void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
3830 assert(node->type == NodeTypeUse);
3831
3832 if (node->data.using_namespace.resolution == TldResolutionOk ||
3833 node->data.using_namespace.resolution == TldResolutionInvalid)
3834 {
3835 return;
3836 }
3837 add_symbols_from_container(g, node, node, decls_scope);
3838}
3839
3840void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
3841 assert(node->type == NodeTypeUse);
3842
3843 if (node->data.using_namespace.resolution == TldResolutionOk ||
3844 node->data.using_namespace.resolution == TldResolutionInvalid)
3845 {
3846 return;
3847 }
3848
3849 node->data.using_namespace.resolution = TldResolutionResolving;
3850 ConstExprValue *result = analyze_const_value(g, &decls_scope->base,
3851 node->data.using_namespace.expr, g->builtin_types.entry_type, nullptr);
3852
3853 if (type_is_invalid(result->type))
3854 decls_scope->any_imports_failed = true;
3855
3856 node->data.using_namespace.using_namespace_value = result;
3857}
3858
3859ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Buf *source_code,3878ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Buf *source_code,
3860 SourceKind source_kind)3879 SourceKind source_kind)
3861{3880{
...@@ -3975,18 +3994,8 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu...@@ -3975,18 +3994,8 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
39753994
3976void semantic_analyze(CodeGen *g) {3995void semantic_analyze(CodeGen *g) {
3977 while (g->resolve_queue_index < g->resolve_queue.length ||3996 while (g->resolve_queue_index < g->resolve_queue.length ||
3978 g->fn_defs_index < g->fn_defs.length ||3997 g->fn_defs_index < g->fn_defs.length)
3979 g->use_queue_index < g->use_queue.length)
3980 {3998 {
3981 for (; g->use_queue_index < g->use_queue.length; g->use_queue_index += 1) {
3982 AstNode *use_decl_node = g->use_queue.at(g->use_queue_index);
3983 // Get the top-level scope where `using_namespace` is used
3984 ScopeDecls *decls_scope = get_container_scope(use_decl_node->owner);
3985 if (use_decl_node->data.using_namespace.resolution == TldResolutionUnresolved) {
3986 preview_use_decl(g, use_decl_node, decls_scope);
3987 resolve_use_decl(g, use_decl_node, decls_scope);
3988 }
3989 }
3990 for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) {3999 for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) {
3991 Tld *tld = g->resolve_queue.at(g->resolve_queue_index);4000 Tld *tld = g->resolve_queue.at(g->resolve_queue_index);
3992 AstNode *source_node = nullptr;4001 AstNode *source_node = nullptr;
src/analyze.hpp-2
...@@ -86,8 +86,6 @@ bool is_array_ref(ZigType *type_entry);...@@ -86,8 +86,6 @@ bool is_array_ref(ZigType *type_entry);
86bool is_container_ref(ZigType *type_entry);86bool is_container_ref(ZigType *type_entry);
87bool is_valid_vector_elem_type(ZigType *elem_type);87bool is_valid_vector_elem_type(ZigType *elem_type);
88void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node);88void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node);
89void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls* decls_scope);
90void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls* decls_scope);
91ZigFn *scope_fn_entry(Scope *scope);89ZigFn *scope_fn_entry(Scope *scope);
92ZigPackage *scope_package(Scope *scope);90ZigPackage *scope_package(Scope *scope);
93ZigType *get_scope_import(Scope *scope);91ZigType *get_scope_import(Scope *scope);
src/ast_render.cpp+4-4
...@@ -193,8 +193,8 @@ static const char *node_type_str(NodeType node_type) {...@@ -193,8 +193,8 @@ static const char *node_type_str(NodeType node_type) {
193 return "Symbol";193 return "Symbol";
194 case NodeTypePrefixOpExpr:194 case NodeTypePrefixOpExpr:
195 return "PrefixOpExpr";195 return "PrefixOpExpr";
196 case NodeTypeUse:196 case NodeTypeUsingNamespace:
197 return "Use";197 return "UsingNamespace";
198 case NodeTypeBoolLiteral:198 case NodeTypeBoolLiteral:
199 return "BoolLiteral";199 return "BoolLiteral";
200 case NodeTypeNullLiteral:200 case NodeTypeNullLiteral:
...@@ -791,7 +791,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -791,7 +791,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
791 AstNode *decls_node = node->data.container_decl.decls.at(decl_i);791 AstNode *decls_node = node->data.container_decl.decls.at(decl_i);
792 render_node_grouped(ar, decls_node);792 render_node_grouped(ar, decls_node);
793793
794 if (decls_node->type == NodeTypeUse ||794 if (decls_node->type == NodeTypeUsingNamespace ||
795 decls_node->type == NodeTypeVariableDeclaration ||795 decls_node->type == NodeTypeVariableDeclaration ||
796 decls_node->type == NodeTypeFnProto)796 decls_node->type == NodeTypeFnProto)
797 {797 {
...@@ -1170,7 +1170,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -1170,7 +1170,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
1170 case NodeTypeParamDecl:1170 case NodeTypeParamDecl:
1171 case NodeTypeTestDecl:1171 case NodeTypeTestDecl:
1172 case NodeTypeStructField:1172 case NodeTypeStructField:
1173 case NodeTypeUse:1173 case NodeTypeUsingNamespace:
1174 zig_panic("TODO more ast rendering");1174 zig_panic("TODO more ast rendering");
1175 }1175 }
1176}1176}
src/ir.cpp+2-1
...@@ -8430,7 +8430,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop...@@ -8430,7 +8430,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
8430 switch (node->type) {8430 switch (node->type) {
8431 case NodeTypeStructValueField:8431 case NodeTypeStructValueField:
8432 case NodeTypeParamDecl:8432 case NodeTypeParamDecl:
8433 case NodeTypeUse:8433 case NodeTypeUsingNamespace:
8434 case NodeTypeSwitchProng:8434 case NodeTypeSwitchProng:
8435 case NodeTypeSwitchRange:8435 case NodeTypeSwitchRange:
8436 case NodeTypeStructField:8436 case NodeTypeStructField:
...@@ -17847,6 +17847,7 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_...@@ -17847,6 +17847,7 @@ static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_
17847 switch (tld->id) {17847 switch (tld->id) {
17848 case TldIdContainer:17848 case TldIdContainer:
17849 case TldIdCompTime:17849 case TldIdCompTime:
17850 case TldIdUsingNamespace:
17850 zig_unreachable();17851 zig_unreachable();
17851 case TldIdVar:17852 case TldIdVar:
17852 {17853 {
src/parser.cpp+2-2
...@@ -676,7 +676,7 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {...@@ -676,7 +676,7 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
676 AstNode *expr = ast_expect(pc, ast_parse_expr);676 AstNode *expr = ast_expect(pc, ast_parse_expr);
677 expect_token(pc, TokenIdSemicolon);677 expect_token(pc, TokenIdSemicolon);
678678
679 AstNode *res = ast_create_node(pc, NodeTypeUse, usingnamespace);679 AstNode *res = ast_create_node(pc, NodeTypeUsingNamespace, usingnamespace);
680 res->data.using_namespace.visib_mod = visib_mod;680 res->data.using_namespace.visib_mod = visib_mod;
681 res->data.using_namespace.expr = expr;681 res->data.using_namespace.expr = expr;
682 return res;682 return res;
...@@ -2938,7 +2938,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -2938,7 +2938,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
2938 case NodeTypeUnwrapOptional:2938 case NodeTypeUnwrapOptional:
2939 visit_field(&node->data.unwrap_optional.expr, visit, context);2939 visit_field(&node->data.unwrap_optional.expr, visit, context);
2940 break;2940 break;
2941 case NodeTypeUse:2941 case NodeTypeUsingNamespace:
2942 visit_field(&node->data.using_namespace.expr, visit, context);2942 visit_field(&node->data.using_namespace.expr, visit, context);
2943 break;2943 break;
2944 case NodeTypeBoolLiteral:2944 case NodeTypeBoolLiteral:
test/compile_errors.zig+1-1
...@@ -234,7 +234,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -234,7 +234,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
234234
235 cases.add(235 cases.add(
236 "usingnamespace with wrong type",236 "usingnamespace with wrong type",
237 \\use void;237 \\usingnamespace void;
238 ,238 ,
239 "tmp.zig:1:1: error: expected struct, enum, or union; found 'void'",239 "tmp.zig:1:1: error: expected struct, enum, or union; found 'void'",
240 );240 );
test/stage1/behavior.zig+1
...@@ -93,6 +93,7 @@ comptime {...@@ -93,6 +93,7 @@ comptime {
93 _ = @import("behavior/undefined.zig");93 _ = @import("behavior/undefined.zig");
94 _ = @import("behavior/underscore.zig");94 _ = @import("behavior/underscore.zig");
95 _ = @import("behavior/union.zig");95 _ = @import("behavior/union.zig");
96 _ = @import("behavior/usingnamespace.zig");
96 _ = @import("behavior/var_args.zig");97 _ = @import("behavior/var_args.zig");
97 _ = @import("behavior/vector.zig");98 _ = @import("behavior/vector.zig");
98 _ = @import("behavior/void.zig");99 _ = @import("behavior/void.zig");
test/stage1/behavior/usingnamespace.zig created+14
...@@ -0,0 +1,14 @@
1const std = @import("std");
2
3fn Foo(comptime T: type) type {
4 return struct {
5 usingnamespace T;
6 };
7}
8
9test "usingnamespace inside a generic struct" {
10 const std2 = Foo(std);
11 const testing2 = Foo(std.testing);
12 std2.testing.expect(true);
13 testing2.expect(true);
14}