authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-05-09 13:44:29-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-05-09 13:44:29-07:00
logf1e5be96860406d7a4239b174c896799d8fd6545
tree4b322fa179f2eaca32664d415a4c069777bd3e7f
parent745c325d0f498406f229e532753e5d5712e824d4

fix ability to use previous generic params and

add error when `%return` shows up in a function with incorrect return type

6 files changed, 43 insertions(+), 25 deletions(-)

doc/langref.md+1-1
......@@ -17,7 +17,7 @@ VariableDeclaration = ("var" | "const") "Symbol" option(":" TypeExpr) "=" Expres
1717
1818ContainerDecl = ("struct" | "enum" | "union") "Symbol" option(ParamDeclList) "{" many(StructMember) "}"
1919
20StructMember = many(Directive) option(VisibleMod) (StructField | FnDef | GlobalVarDecl)
20StructMember = many(Directive) option(VisibleMod) (StructField | FnDef | GlobalVarDecl | ContainerDecl)
2121
2222StructField = "Symbol" option(":" Expression) ",")
2323
src/analyze.cpp+12-1
......@@ -5217,7 +5217,7 @@ static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *imp
52175217 AstNode **generic_param_type_node = &generic_param_decl_node->data.param_decl.type;
52185218
52195219 TypeTableEntry *expected_param_type = analyze_type_expr(g, decl_node->owner,
5220 decl_node->owner->block_context, *generic_param_type_node);
5220 child_context, *generic_param_type_node);
52215221 if (expected_param_type->id == TypeTableEntryIdInvalid) {
52225222 return expected_param_type;
52235223 }
......@@ -5809,6 +5809,17 @@ static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import,
58095809 if (resolved_type->id == TypeTableEntryIdInvalid) {
58105810 return resolved_type;
58115811 } else if (resolved_type->id == TypeTableEntryIdErrorUnion) {
5812 TypeTableEntry *return_type = context->fn_entry->type_entry->data.fn.fn_type_id.return_type;
5813 if (return_type->id != TypeTableEntryIdErrorUnion &&
5814 return_type->id != TypeTableEntryIdPureError)
5815 {
5816 ErrorMsg *msg = add_node_error(g, node,
5817 buf_sprintf("%%return statement in function with return type '%s'",
5818 buf_ptr(&return_type->name)));
5819 AstNode *return_type_node = context->fn_entry->fn_def_node->data.fn_def.fn_proto->data.fn_proto.return_type;
5820 add_error_note(g, msg, return_type_node, buf_sprintf("function return type here"));
5821 }
5822
58125823 return resolved_type->data.error.child_type;
58135824 } else {
58145825 add_node_error(g, node->data.return_expr.expr,
src/parser.cpp+7-1
......@@ -2605,7 +2605,7 @@ static AstNode *ast_parse_use(ParseContext *pc, int *token_index,
26052605
26062606/*
26072607ContainerDecl = ("struct" | "enum" | "union") "Symbol" option(ParamDeclList) "{" many(StructMember) "}"
2608StructMember = many(Directive) option(VisibleMod) (StructField | FnDef | GlobalVarDecl)
2608StructMember = many(Directive) option(VisibleMod) (StructField | FnDef | GlobalVarDecl | ContainerDecl)
26092609StructField : "Symbol" option(":" Expression) ",")
26102610*/
26112611static AstNode *ast_parse_container_decl(ParseContext *pc, int *token_index,
......@@ -2675,6 +2675,12 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, int *token_index,
26752675 continue;
26762676 }
26772677
2678 AstNode *container_decl_node = ast_parse_container_decl(pc, token_index, directive_list, visib_mod);
2679 if (container_decl_node) {
2680 node->data.struct_decl.decls.append(container_decl_node);
2681 continue;
2682 }
2683
26782684 Token *token = &pc->tokens->at(*token_index);
26792685
26802686 if (token->id == TokenIdRBrace) {
std/hash_map.zig+6-22
......@@ -47,7 +47,7 @@ pub struct HashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b: K)-
4747 }
4848 unreachable{} // no next item
4949 }
50 };
50 }
5151
5252 pub fn init(hm: &Self, allocator: &Allocator, capacity: isize) {
5353 assert(capacity > 0);
......@@ -56,7 +56,7 @@ pub struct HashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b: K)-
5656 }
5757
5858 pub fn deinit(hm: &Self) {
59 free(_entries);
59 hm.allocator.free(hm.allocator, ([]u8)(hm.entries));
6060 }
6161
6262 pub fn clear(hm: &Self) {
......@@ -128,8 +128,7 @@ pub struct HashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b: K)-
128128 }
129129
130130 fn init_capacity(hm: &Self, capacity: isize) {
131 hm.capacity = capacity;
132 hm.entries = ([]Entry)(hm.allocator.alloc(hm.allocator, capacity * @sizeof(Entry)));
131 hm.entries = ([]Entry)(%return hm.allocator.alloc(hm.allocator, capacity * @sizeof(Entry)));
133132 hm.size = 0;
134133 hm.max_distance_from_start_index = 0;
135134 for (hm.entries) |*entry| {
......@@ -143,7 +142,7 @@ pub struct HashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b: K)-
143142 }
144143 }
145144
146 fn internal_put(hm: &Self, K orig_key, V orig_value) {
145 fn internal_put(hm: &Self, orig_key: K, orig_value: V) {
147146 var key = orig_key;
148147 var value = orig_value;
149148 const start_index = key_to_index(key);
......@@ -179,7 +178,7 @@ pub struct HashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b: K)-
179178 }
180179
181180 hm.max_distance_from_start_index = math.max(isize)(distance_from_start_index, hm.max_distance_from_start_index);
182 *entry = {
181 *entry = Entry {
183182 .used = true,
184183 .distance_from_start_index = distance_from_start_index,
185184 .key = key,
......@@ -202,21 +201,6 @@ pub struct HashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b: K)-
202201 return null;
203202 }
204203
205 Entry *internal_get(const K &key) const {
206 int start_index = key_to_index(key);
207 for (int roll_over = 0; roll_over <= _max_distance_from_start_index; roll_over += 1) {
208 int index = (start_index + roll_over) % _capacity;
209 Entry *entry = &_entries[index];
210
211 if (!entry->used)
212 return NULL;
213
214 if (EqualFn(entry->key, key))
215 return entry;
216 }
217 return NULL;
218 }
219
220204 fn key_to_index(hm: &Self, key: K) -> isize {
221205 return isize(hash(key)) % hm.entries.len;
222206 }
......@@ -249,7 +233,7 @@ fn global_free(self: &Allocator, old_mem: []u8) {
249233
250234#attribute("test")
251235fn basic_hash_map_test() {
252 var map: HashMap(i32, i32, hash_i32, eql_i32);
236 var map: HashMap(i32, i32, hash_i32, eql_i32) = undefined;
253237 map.init(&global_allocator, 4);
254238 defer map.deinit();
255239}
test/run_tests.cpp+9
......@@ -1382,6 +1382,15 @@ fn f() {
13821382}
13831383 )SOURCE", 1, ".tmp_source.zig:4:19: error: type 'i8' has same or fewer bits than destination type 'i8'");
13841384
1385 add_compile_fail_case("truncate same bit count", R"SOURCE(
1386fn f() {
1387 %return something();
1388}
1389fn something() -> %void { }
1390 )SOURCE", 2,
1391 ".tmp_source.zig:3:5: error: %return statement in function with return type 'void'",
1392 ".tmp_source.zig:2:8: note: function return type here");
1393
13851394}
13861395
13871396//////////////////////////////////////////////////////////////////////////////
test/self_hosted.zig+8
......@@ -1648,3 +1648,11 @@ fn const_decls_in_struct() {
16481648struct GenericDataThing(count: isize) {
16491649 const count_plus_one = count + 1;
16501650}
1651
1652#attribute("test")
1653fn use_generic_param_in_generic_param() {
1654 assert(a_generic_fn(i32, 3)(4) == 7);
1655}
1656fn a_generic_fn(T: type, a: T)(b: T) -> T {
1657 return a + b;
1658}