authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-09-26 23:47:30-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-09-26 23:47:30-04:00
log183976b242dac0731caa7d925e88ad151a4dc8ee
tree426fe019d53dd2c27695518fc64f5fddd449fef0
parentf4d7c91363c2525741522a7ad942a419653ae47b

add this keyword refers to thing in immediate scope

See #169

16 files changed, 167 insertions(+), 16 deletions(-)

doc/langref.md+1-1
......@@ -151,7 +151,7 @@ GotoExpression = "goto" Symbol
151151
152152GroupedExpression = "(" Expression ")"
153153
154KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type"
154KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this"
155155```
156156
157157## Operator Precedence
doc/vim/syntax/zig.vim+1-1
......@@ -14,7 +14,7 @@ syn keyword zigStatement goto break return continue asm defer
1414syn keyword zigConditional if else switch
1515syn keyword zigRepeat while for
1616
17syn keyword zigConstant null undefined zeroes
17syn keyword zigConstant null undefined zeroes this
1818syn keyword zigKeyword fn use
1919syn keyword zigType bool f32 f64 void unreachable type error
2020syn keyword zigType i8 u8 i16 u16 i32 u32 i64 u64 isize usize
src/all_types.hpp+10-2
......@@ -85,6 +85,7 @@ struct ConstExprValue {
8585 ConstArrayValue x_array;
8686 ConstPtrValue x_ptr;
8787 ImportTableEntry *x_import;
88 BlockContext *x_block;
8889 } data;
8990};
9091
......@@ -174,6 +175,7 @@ enum NodeType {
174175 NodeTypeNullLiteral,
175176 NodeTypeUndefinedLiteral,
176177 NodeTypeZeroesLiteral,
178 NodeTypeThisLiteral,
177179 NodeTypeIfBoolExpr,
178180 NodeTypeIfVarExpr,
179181 NodeTypeWhileExpr,
......@@ -719,6 +721,11 @@ struct AstNodeZeroesLiteral {
719721 Expr resolved_expr;
720722};
721723
724struct AstNodeThisLiteral {
725 // populated by semantic analyzer
726 Expr resolved_expr;
727};
728
722729struct AstNodeSymbolExpr {
723730 Buf *symbol;
724731
......@@ -822,6 +829,7 @@ struct AstNode {
822829 AstNodeNullLiteral null_literal;
823830 AstNodeUndefinedLiteral undefined_literal;
824831 AstNodeZeroesLiteral zeroes_literal;
832 AstNodeThisLiteral this_literal;
825833 AstNodeSymbolExpr symbol_expr;
826834 AstNodeBoolLiteral bool_literal;
827835 AstNodeBreakExpr break_expr;
......@@ -1005,6 +1013,7 @@ enum TypeTableEntryId {
10051013 TypeTableEntryIdFn,
10061014 TypeTableEntryIdTypeDecl,
10071015 TypeTableEntryIdNamespace,
1016 TypeTableEntryIdBlock,
10081017 TypeTableEntryIdGenericFn,
10091018};
10101019
......@@ -1102,7 +1111,6 @@ struct FnTableEntry {
11021111 AstNode *want_pure_return_type;
11031112 bool safety_off;
11041113 FnInline fn_inline;
1105 BlockContext *parent_block_context;
11061114 FnAnalState anal_state;
11071115
11081116 ZigList<AstNode *> cast_alloca_list;
......@@ -1209,6 +1217,7 @@ struct CodeGen {
12091217 TypeTableEntry *entry_type;
12101218 TypeTableEntry *entry_invalid;
12111219 TypeTableEntry *entry_namespace;
1220 TypeTableEntry *entry_block;
12121221 TypeTableEntry *entry_num_lit_int;
12131222 TypeTableEntry *entry_num_lit_float;
12141223 TypeTableEntry *entry_undef;
......@@ -1340,7 +1349,6 @@ struct LabelTableEntry {
13401349};
13411350
13421351struct BlockContext {
1343 // One of: NodeTypeFnDef, NodeTypeBlock, NodeTypeRoot, NodeTypeDefer, NodeTypeVariableDeclaration
13441352 AstNode *node;
13451353
13461354 // any variables that are introduced by this scope
src/analyze.cpp+58-8
......@@ -91,6 +91,7 @@ static AstNode *first_executing_node(AstNode *node) {
9191 case NodeTypeNullLiteral:
9292 case NodeTypeUndefinedLiteral:
9393 case NodeTypeZeroesLiteral:
94 case NodeTypeThisLiteral:
9495 case NodeTypeIfBoolExpr:
9596 case NodeTypeIfVarExpr:
9697 case NodeTypeLabel:
......@@ -246,6 +247,7 @@ static bool type_is_complete(TypeTableEntry *type_entry) {
246247 case TypeTableEntryIdFn:
247248 case TypeTableEntryIdTypeDecl:
248249 case TypeTableEntryIdNamespace:
250 case TypeTableEntryIdBlock:
249251 case TypeTableEntryIdGenericFn:
250252 return true;
251253 }
......@@ -962,6 +964,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
962964 case TypeTableEntryIdNullLit:
963965 case TypeTableEntryIdUnreachable:
964966 case TypeTableEntryIdNamespace:
967 case TypeTableEntryIdBlock:
965968 case TypeTableEntryIdGenericFn:
966969 fn_proto->skip = true;
967970 add_node_error(g, child->data.param_decl.type,
......@@ -1012,6 +1015,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
10121015 case TypeTableEntryIdUndefLit:
10131016 case TypeTableEntryIdNullLit:
10141017 case TypeTableEntryIdNamespace:
1018 case TypeTableEntryIdBlock:
10151019 case TypeTableEntryIdGenericFn:
10161020 case TypeTableEntryIdVar:
10171021 fn_proto->skip = true;
......@@ -1896,6 +1900,7 @@ static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only)
18961900 case NodeTypeNullLiteral:
18971901 case NodeTypeUndefinedLiteral:
18981902 case NodeTypeZeroesLiteral:
1903 case NodeTypeThisLiteral:
18991904 case NodeTypeSymbol:
19001905 case NodeTypePrefixOpExpr:
19011906 case NodeTypeIfBoolExpr:
......@@ -1960,6 +1965,7 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) {
19601965 case TypeTableEntryIdUndefLit:
19611966 case TypeTableEntryIdNullLit:
19621967 case TypeTableEntryIdNamespace:
1968 case TypeTableEntryIdBlock:
19631969 case TypeTableEntryIdGenericFn:
19641970 return false;
19651971
......@@ -2745,6 +2751,7 @@ static bool is_container(TypeTableEntry *type_entry) {
27452751 case TypeTableEntryIdFn:
27462752 case TypeTableEntryIdTypeDecl:
27472753 case TypeTableEntryIdNamespace:
2754 case TypeTableEntryIdBlock:
27482755 case TypeTableEntryIdGenericFn:
27492756 return false;
27502757 }
......@@ -2791,6 +2798,7 @@ static void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {
27912798 case TypeTableEntryIdFn:
27922799 case TypeTableEntryIdTypeDecl:
27932800 case TypeTableEntryIdNamespace:
2801 case TypeTableEntryIdBlock:
27942802 case TypeTableEntryIdGenericFn:
27952803 case TypeTableEntryIdInvalid:
27962804 case TypeTableEntryIdVar:
......@@ -2965,7 +2973,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
29652973 }
29662974 if (decl_node) {
29672975 TopLevelDecl *tld = get_as_top_level_decl(decl_node);
2968 if (tld->visib_mod == VisibModPrivate) {
2976 if (tld->visib_mod == VisibModPrivate && decl_node->owner != import) {
29692977 ErrorMsg *msg = add_node_error(g, node,
29702978 buf_sprintf("'%s' is private", buf_ptr(field_name)));
29712979 add_error_note(g, msg, decl_node, buf_sprintf("declared here"));
......@@ -3093,6 +3101,16 @@ static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node,
30933101 return g->builtin_types.entry_type;
30943102}
30953103
3104static TypeTableEntry *resolve_expr_const_val_as_block(CodeGen *g, AstNode *node, BlockContext *block_context,
3105 bool depends_on_compile_var)
3106{
3107 Expr *expr = get_resolved_expr(node);
3108 expr->const_val.ok = true;
3109 expr->const_val.data.x_block = block_context;
3110 expr->const_val.depends_on_compile_var = depends_on_compile_var;
3111 return g->builtin_types.entry_block;
3112}
3113
30963114static TypeTableEntry *resolve_expr_const_val_as_other_expr(CodeGen *g, AstNode *node, AstNode *other,
30973115 bool depends_on_compile_var)
30983116{
......@@ -3221,6 +3239,13 @@ static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, As
32213239 return g->builtin_types.entry_num_lit_int;
32223240}
32233241
3242static TypeTableEntry *resolve_expr_const_val_as_import(CodeGen *g, AstNode *node, ImportTableEntry *import) {
3243 Expr *expr = get_resolved_expr(node);
3244 expr->const_val.ok = true;
3245 expr->const_val.data.x_import = import;
3246 return g->builtin_types.entry_namespace;
3247}
3248
32243249static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import,
32253250 BlockContext *context, AstNode *node, Buf *err_name)
32263251{
......@@ -3497,6 +3522,7 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im
34973522 case TypeTableEntryIdFn:
34983523 case TypeTableEntryIdTypeDecl:
34993524 case TypeTableEntryIdNamespace:
3525 case TypeTableEntryIdBlock:
35003526 case TypeTableEntryIdGenericFn:
35013527 if (!is_equality_cmp) {
35023528 add_node_error(g, node,
......@@ -4120,6 +4146,25 @@ static TypeTableEntry *analyze_zeroes_literal_expr(CodeGen *g, ImportTableEntry
41204146 return expected_type ? expected_type : g->builtin_types.entry_undef;
41214147}
41224148
4149static TypeTableEntry *analyze_this_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
4150 TypeTableEntry *expected_type, AstNode *node)
4151{
4152 if (!context->parent) {
4153 return resolve_expr_const_val_as_import(g, node, import);
4154 }
4155 if (context->fn_entry && (!context->parent->fn_entry ||
4156 (context->parent->parent && !context->parent->parent->fn_entry)))
4157 {
4158 return resolve_expr_const_val_as_fn(g, node, context->fn_entry, false);
4159 }
4160 if (context->node->type == NodeTypeContainerDecl) {
4161 return resolve_expr_const_val_as_type(g, node, context->node->data.struct_decl.type_entry, false);
4162 }
4163 if (context->node->type == NodeTypeBlock) {
4164 return resolve_expr_const_val_as_block(g, node, context, false);
4165 }
4166 zig_unreachable();
4167}
41234168
41244169static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry *import,
41254170 BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node)
......@@ -4793,13 +4838,6 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
47934838 return g->builtin_types.entry_invalid;
47944839}
47954840
4796static TypeTableEntry *resolve_expr_const_val_as_import(CodeGen *g, AstNode *node, ImportTableEntry *import) {
4797 Expr *expr = get_resolved_expr(node);
4798 expr->const_val.ok = true;
4799 expr->const_val.data.x_import = import;
4800 return g->builtin_types.entry_namespace;
4801}
4802
48034841static TypeTableEntry *analyze_import(CodeGen *g, ImportTableEntry *import, BlockContext *context,
48044842 AstNode *node)
48054843{
......@@ -5394,6 +5432,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
53945432 case TypeTableEntryIdUndefLit:
53955433 case TypeTableEntryIdNullLit:
53965434 case TypeTableEntryIdNamespace:
5435 case TypeTableEntryIdBlock:
53975436 case TypeTableEntryIdGenericFn:
53985437 case TypeTableEntryIdVar:
53995438 add_node_error(g, expr_node,
......@@ -6796,6 +6835,9 @@ static TypeTableEntry *analyze_expression_pointer_only(CodeGen *g, ImportTableEn
67966835 case NodeTypeZeroesLiteral:
67976836 return_type = analyze_zeroes_literal_expr(g, import, context, expected_type, node);
67986837 break;
6838 case NodeTypeThisLiteral:
6839 return_type = analyze_this_literal_expr(g, import, context, expected_type, node);
6840 break;
67996841 case NodeTypeSymbol:
68006842 return_type = analyze_symbol_expr(g, import, context, expected_type, node, pointer_only);
68016843 break;
......@@ -7085,6 +7127,7 @@ static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *conte
70857127 case NodeTypeNullLiteral:
70867128 case NodeTypeUndefinedLiteral:
70877129 case NodeTypeZeroesLiteral:
7130 case NodeTypeThisLiteral:
70887131 case NodeTypeSymbol:
70897132 case NodeTypePrefixOpExpr:
70907133 case NodeTypeIfBoolExpr:
......@@ -7347,6 +7390,8 @@ Expr *get_resolved_expr(AstNode *node) {
73477390 return &node->data.undefined_literal.resolved_expr;
73487391 case NodeTypeZeroesLiteral:
73497392 return &node->data.zeroes_literal.resolved_expr;
7393 case NodeTypeThisLiteral:
7394 return &node->data.this_literal.resolved_expr;
73507395 case NodeTypeGoto:
73517396 return &node->data.goto_expr.resolved_expr;
73527397 case NodeTypeBreak:
......@@ -7432,6 +7477,7 @@ static TopLevelDecl *get_as_top_level_decl(AstNode *node) {
74327477 case NodeTypeNullLiteral:
74337478 case NodeTypeUndefinedLiteral:
74347479 case NodeTypeZeroesLiteral:
7480 case NodeTypeThisLiteral:
74357481 case NodeTypeLabel:
74367482 case NodeTypeGoto:
74377483 case NodeTypeBreak:
......@@ -7499,6 +7545,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
74997545 case TypeTableEntryIdUndefLit:
75007546 case TypeTableEntryIdNullLit:
75017547 case TypeTableEntryIdNamespace:
7548 case TypeTableEntryIdBlock:
75027549 case TypeTableEntryIdGenericFn:
75037550 case TypeTableEntryIdVar:
75047551 zig_unreachable();
......@@ -7640,6 +7687,8 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)
76407687 return hash_ptr(const_val->data.x_type);
76417688 case TypeTableEntryIdNamespace:
76427689 return hash_ptr(const_val->data.x_import);
7690 case TypeTableEntryIdBlock:
7691 return hash_ptr(const_val->data.x_block);
76437692 case TypeTableEntryIdGenericFn:
76447693 case TypeTableEntryIdInvalid:
76457694 case TypeTableEntryIdUnreachable:
......@@ -7715,6 +7764,7 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry)
77157764 case TypeTableEntryIdMetaType:
77167765 case TypeTableEntryIdVoid:
77177766 case TypeTableEntryIdNamespace:
7767 case TypeTableEntryIdBlock:
77187768 case TypeTableEntryIdGenericFn:
77197769 case TypeTableEntryIdVar:
77207770 zig_unreachable();
src/ast_render.cpp+4
......@@ -173,6 +173,8 @@ static const char *node_type_str(NodeType node_type) {
173173 return "UndefinedLiteral";
174174 case NodeTypeZeroesLiteral:
175175 return "ZeroesLiteral";
176 case NodeTypeThisLiteral:
177 return "ThisLiteral";
176178 case NodeTypeIfBoolExpr:
177179 return "IfBoolExpr";
178180 case NodeTypeIfVarExpr:
......@@ -597,6 +599,8 @@ static void render_node(AstRender *ar, AstNode *node) {
597599 zig_panic("TODO");
598600 case NodeTypeZeroesLiteral:
599601 zig_panic("TODO");
602 case NodeTypeThisLiteral:
603 zig_panic("TODO");
600604 case NodeTypeIfBoolExpr:
601605 zig_panic("TODO");
602606 case NodeTypeIfVarExpr:
src/codegen.cpp+10
......@@ -3605,6 +3605,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
36053605 case NodeTypeNullLiteral:
36063606 case NodeTypeUndefinedLiteral:
36073607 case NodeTypeZeroesLiteral:
3608 case NodeTypeThisLiteral:
36083609 case NodeTypeErrorType:
36093610 case NodeTypeTypeLiteral:
36103611 case NodeTypeArrayType:
......@@ -3826,6 +3827,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
38263827 case TypeTableEntryIdNullLit:
38273828 case TypeTableEntryIdVoid:
38283829 case TypeTableEntryIdNamespace:
3830 case TypeTableEntryIdBlock:
38293831 case TypeTableEntryIdGenericFn:
38303832 case TypeTableEntryIdVar:
38313833 zig_unreachable();
......@@ -4349,6 +4351,13 @@ static void define_builtin_types(CodeGen *g) {
43494351 entry->deep_const = true;
43504352 g->builtin_types.entry_namespace = entry;
43514353 }
4354 {
4355 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBlock);
4356 buf_init_from_str(&entry->name, "(block)");
4357 entry->zero_bits = true;
4358 entry->deep_const = true;
4359 g->builtin_types.entry_block = entry;
4360 }
43524361 {
43534362 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitFloat);
43544363 buf_init_from_str(&entry->name, "(float literal)");
......@@ -5145,6 +5154,7 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
51455154 case TypeTableEntryIdMetaType:
51465155 case TypeTableEntryIdGenericFn:
51475156 case TypeTableEntryIdNamespace:
5157 case TypeTableEntryIdBlock:
51485158 case TypeTableEntryIdNumLitFloat:
51495159 case TypeTableEntryIdNumLitInt:
51505160 case TypeTableEntryIdUndefLit:
src/eval.cpp+2
......@@ -83,6 +83,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *ty
8383 zig_panic("TODO");
8484 case TypeTableEntryIdNamespace:
8585 zig_panic("TODO");
86 case TypeTableEntryIdBlock:
8687 zig_panic("TODO");
8788 case TypeTableEntryIdGenericFn:
8889 case TypeTableEntryIdInvalid:
......@@ -1373,6 +1374,7 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) {
13731374 case NodeTypeNullLiteral:
13741375 case NodeTypeUndefinedLiteral:
13751376 case NodeTypeZeroesLiteral:
1377 case NodeTypeThisLiteral:
13761378 case NodeTypeIfVarExpr:
13771379 case NodeTypeSwitchExpr:
13781380 case NodeTypeSwitchProng:
src/parser.cpp+11-1
......@@ -620,7 +620,7 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, size_t *token_index, bool m
620620
621621/*
622622PrimaryExpression = "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." "Symbol")
623KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type"
623KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this"
624624*/
625625static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
626626 Token *token = &pc->tokens->at(*token_index);
......@@ -672,6 +672,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
672672 AstNode *node = ast_create_node(pc, NodeTypeZeroesLiteral, token);
673673 *token_index += 1;
674674 return node;
675 } else if (token->id == TokenIdKeywordThis) {
676 AstNode *node = ast_create_node(pc, NodeTypeThisLiteral, token);
677 *token_index += 1;
678 return node;
675679 } else if (token->id == TokenIdKeywordType) {
676680 AstNode *node = ast_create_node(pc, NodeTypeTypeLiteral, token);
677681 *token_index += 1;
......@@ -2560,6 +2564,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
25602564 case NodeTypeZeroesLiteral:
25612565 // none
25622566 break;
2567 case NodeTypeThisLiteral:
2568 // none
2569 break;
25632570 case NodeTypeIfBoolExpr:
25642571 visit_field(&node->data.if_bool_expr.condition, visit, context);
25652572 visit_field(&node->data.if_bool_expr.then_block, visit, context);
......@@ -2840,6 +2847,9 @@ AstNode *ast_clone_subtree_special(AstNode *old_node, uint32_t *next_node_index,
28402847 case NodeTypeZeroesLiteral:
28412848 // none
28422849 break;
2850 case NodeTypeThisLiteral:
2851 // none
2852 break;
28432853 case NodeTypeIfBoolExpr:
28442854 clone_subtree_field(&new_node->data.if_bool_expr.condition, old_node->data.if_bool_expr.condition, next_node_index);
28452855 clone_subtree_field(&new_node->data.if_bool_expr.then_block, old_node->data.if_bool_expr.then_block, next_node_index);
src/tokenizer.cpp+2
......@@ -129,6 +129,7 @@ static const struct ZigKeyword zig_keywords[] = {
129129 {"return", TokenIdKeywordReturn},
130130 {"struct", TokenIdKeywordStruct},
131131 {"switch", TokenIdKeywordSwitch},
132 {"this", TokenIdKeywordThis},
132133 {"true", TokenIdKeywordTrue},
133134 {"type", TokenIdKeywordType},
134135 {"undefined", TokenIdKeywordUndefined},
......@@ -1470,6 +1471,7 @@ const char * token_name(TokenId id) {
14701471 case TokenIdKeywordSwitch: return "switch";
14711472 case TokenIdKeywordUndefined: return "undefined";
14721473 case TokenIdKeywordZeroes: return "zeroes";
1474 case TokenIdKeywordThis: return "this";
14731475 case TokenIdKeywordError: return "error";
14741476 case TokenIdKeywordType: return "type";
14751477 case TokenIdKeywordInline: return "inline";
src/tokenizer.hpp+1
......@@ -45,6 +45,7 @@ enum TokenId {
4545 TokenIdKeywordType,
4646 TokenIdKeywordInline,
4747 TokenIdKeywordDefer,
48 TokenIdKeywordThis,
4849 TokenIdLParen,
4950 TokenIdRParen,
5051 TokenIdComma,
std/hash_map.zig+1-1
......@@ -24,7 +24,7 @@ pub struct SmallHashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b
2424 // this is used to detect bugs where a hashtable is edited while an iterator is running.
2525 modification_count: debug_u32,
2626
27 const Self = SmallHashMap(K, V, hash, eql, static_size);
27 const Self = this;
2828
2929 pub struct Entry {
3030 used: bool,
std/list.zig+1-1
......@@ -4,7 +4,7 @@ const mem = @import("mem.zig");
44const Allocator = mem.Allocator;
55
66pub struct List(T: type) {
7 const Self = List(T);
7 const Self = this;
88
99 items: []T,
1010 len: usize,
std/rand.zig+1-1
......@@ -101,7 +101,7 @@ struct MersenneTwister(
101101 t: int, c: int,
102102 l: int, f: int)
103103{
104 const Self = MersenneTwister(int, n, m, r, a, u, d, s, b, t, c, l, f);
104 const Self = this;
105105
106106 array: [n]int,
107107 index: usize,
test/cases/this.zig created+47
......@@ -0,0 +1,47 @@
1const assert = @import("std").debug.assert;
2const module = this;
3
4struct Point(inline T: type) {
5 const Self = this;
6 x: T,
7 y: T,
8
9 fn addOne(self: &Self) {
10 self.x += 1;
11 self.y += 1;
12 }
13}
14
15fn add(x: i32, y: i32) -> i32 {
16 x + y
17}
18
19fn factorial(x: i32) -> i32 {
20 const selfFn = this;
21 if (x == 0) {
22 1
23 } else {
24 x * selfFn(x - 1)
25 }
26}
27
28#attribute("test")
29fn thisReferToModuleCallPrivateFn() {
30 assert(module.add(1, 2) == 3);
31}
32
33#attribute("test")
34fn thisReferToContainer() {
35 var pt = Point(i32) {
36 .x = 12,
37 .y = 34,
38 };
39 pt.addOne();
40 assert(pt.x == 13);
41 assert(pt.y == 35);
42}
43
44#attribute("test")
45fn thisReferToFn() {
46 assert(factorial(5) == 120);
47}
test/run_tests.cpp+16
......@@ -1597,6 +1597,22 @@ const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;
15971597var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);
15981598 )SOURCE", 1, ".tmp_source.zig:4:60: error: unable to perform binary not operation on type '(integer literal)'");
15991599
1600 {
1601 TestCase *tc = add_compile_fail_case("multiple files with private function error", R"SOURCE(
1602const foo = @import("foo.zig");
1603
1604fn callPrivFunction() {
1605 foo.privateFunction();
1606}
1607 )SOURCE", 2,
1608 ".tmp_source.zig:5:8: error: 'privateFunction' is private",
1609 "foo.zig:2:1: note: declared here");
1610
1611 add_source_file(tc, "foo.zig", R"SOURCE(
1612fn privateFunction() { }
1613 )SOURCE");
1614 }
1615
16001616}
16011617
16021618//////////////////////////////////////////////////////////////////////////////
test/self_hosted.zig+1
......@@ -15,6 +15,7 @@ const test_switch_prong_implicit_cast = @import("cases/switch_prong_implicit_cas
1515const test_switch_prong_err_enum = @import("cases/switch_prong_err_enum.zig");
1616const test_enum_with_members = @import("cases/enum_with_members.zig");
1717const test_struct_contains_slice_of_itself = @import("cases/struct_contains_slice_of_itself.zig");
18const test_this = @import("cases/this.zig");
1819
1920// normal comment
2021/// this is a documentation comment