authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-20 16:42:14-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-20 16:42:14-05:00
log65a51b401cfe17daee0c64404c8f564b0f282224
tree9e799afd7d582bcbc14692ec6fb22b086a1edd2b
parenta06f3c74fdc0d8bf0f42427a261ab32351753fcb

add promise type

See #727

5 files changed, 80 insertions(+), 8 deletions(-)

src/all_types.hpp+8
......@@ -1096,6 +1096,11 @@ struct TypeTableEntryBoundFn {
10961096 TypeTableEntry *fn_type;
10971097};
10981098
1099struct TypeTableEntryPromise {
1100 // null if `promise` instead of `promise->T`
1101 TypeTableEntry *result_type;
1102};
1103
10991104enum TypeTableEntryId {
11001105 TypeTableEntryIdInvalid,
11011106 TypeTableEntryIdVar,
......@@ -1123,6 +1128,7 @@ enum TypeTableEntryId {
11231128 TypeTableEntryIdBoundFn,
11241129 TypeTableEntryIdArgTuple,
11251130 TypeTableEntryIdOpaque,
1131 TypeTableEntryIdPromise,
11261132};
11271133
11281134struct TypeTableEntry {
......@@ -1149,11 +1155,13 @@ struct TypeTableEntry {
11491155 TypeTableEntryUnion unionation;
11501156 TypeTableEntryFn fn;
11511157 TypeTableEntryBoundFn bound_fn;
1158 TypeTableEntryPromise promise;
11521159 } data;
11531160
11541161 // use these fields to make sure we don't duplicate type table entries for the same type
11551162 TypeTableEntry *pointer_parent[2]; // [0 - mut, 1 - const]
11561163 TypeTableEntry *maybe_parent;
1164 TypeTableEntry *promise_parent;
11571165 // If we generate a constant name value for this type, we memoize it here.
11581166 // The type of this is array
11591167 ConstExprValue *cached_const_name_val;
src/analyze.cpp+51-1
......@@ -230,6 +230,7 @@ bool type_is_complete(TypeTableEntry *type_entry) {
230230 case TypeTableEntryIdBlock:
231231 case TypeTableEntryIdBoundFn:
232232 case TypeTableEntryIdArgTuple:
233 case TypeTableEntryIdPromise:
233234 return true;
234235 }
235236 zig_unreachable();
......@@ -267,6 +268,7 @@ bool type_has_zero_bits_known(TypeTableEntry *type_entry) {
267268 case TypeTableEntryIdBoundFn:
268269 case TypeTableEntryIdArgTuple:
269270 case TypeTableEntryIdOpaque:
271 case TypeTableEntryIdPromise:
270272 return true;
271273 }
272274 zig_unreachable();
......@@ -339,6 +341,32 @@ TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
339341 return get_int_type(g, false, bits_needed_for_unsigned(x));
340342}
341343
344TypeTableEntry *get_promise_type(CodeGen *g, TypeTableEntry *result_type) {
345 if (result_type != nullptr && result_type->promise_parent != nullptr) {
346 return result_type->promise_parent;
347 } else if (result_type == nullptr && g->builtin_types.entry_promise != nullptr) {
348 return g->builtin_types.entry_promise;
349 }
350
351 TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, false);
352 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPromise);
353 entry->type_ref = u8_ptr_type->type_ref;
354 entry->zero_bits = false;
355 entry->data.promise.result_type = result_type;
356 buf_init_from_str(&entry->name, "promise");
357 if (result_type != nullptr) {
358 buf_appendf(&entry->name, "->%s", buf_ptr(&result_type->name));
359 }
360 entry->di_type = u8_ptr_type->di_type;
361
362 if (result_type != nullptr) {
363 result_type->promise_parent = entry;
364 } else if (result_type == nullptr) {
365 g->builtin_types.entry_promise = entry;
366 }
367 return entry;
368}
369
342370TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type, bool is_const,
343371 bool is_volatile, uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count)
344372{
......@@ -1203,6 +1231,7 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
12031231 case TypeTableEntryIdBoundFn:
12041232 case TypeTableEntryIdArgTuple:
12051233 case TypeTableEntryIdOpaque:
1234 case TypeTableEntryIdPromise:
12061235 return false;
12071236 case TypeTableEntryIdVoid:
12081237 case TypeTableEntryIdBool:
......@@ -1243,6 +1272,7 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
12431272 case TypeTableEntryIdBlock:
12441273 case TypeTableEntryIdBoundFn:
12451274 case TypeTableEntryIdArgTuple:
1275 case TypeTableEntryIdPromise:
12461276 return false;
12471277 case TypeTableEntryIdOpaque:
12481278 case TypeTableEntryIdUnreachable:
......@@ -1383,7 +1413,7 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
13831413 case TypeTableEntryIdBoundFn:
13841414 case TypeTableEntryIdMetaType:
13851415 add_node_error(g, param_node->data.param_decl.type,
1386 buf_sprintf("parameter of type '%s' must be declared inline",
1416 buf_sprintf("parameter of type '%s' must be declared comptime",
13871417 buf_ptr(&type_entry->name)));
13881418 return g->builtin_types.entry_invalid;
13891419 case TypeTableEntryIdVoid:
......@@ -1399,6 +1429,7 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
13991429 case TypeTableEntryIdEnum:
14001430 case TypeTableEntryIdUnion:
14011431 case TypeTableEntryIdFn:
1432 case TypeTableEntryIdPromise:
14021433 ensure_complete_type(g, type_entry);
14031434 if (fn_type_id.cc == CallingConventionUnspecified && !type_is_copyable(g, type_entry)) {
14041435 add_node_error(g, param_node->data.param_decl.type,
......@@ -1480,6 +1511,7 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
14801511 case TypeTableEntryIdEnum:
14811512 case TypeTableEntryIdUnion:
14821513 case TypeTableEntryIdFn:
1514 case TypeTableEntryIdPromise:
14831515 break;
14841516 }
14851517
......@@ -3175,6 +3207,7 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt
31753207 case TypeTableEntryIdUnion:
31763208 case TypeTableEntryIdFn:
31773209 case TypeTableEntryIdBoundFn:
3210 case TypeTableEntryIdPromise:
31783211 return type_entry;
31793212 }
31803213 zig_unreachable();
......@@ -3553,6 +3586,7 @@ static bool is_container(TypeTableEntry *type_entry) {
35533586 case TypeTableEntryIdBoundFn:
35543587 case TypeTableEntryIdArgTuple:
35553588 case TypeTableEntryIdOpaque:
3589 case TypeTableEntryIdPromise:
35563590 return false;
35573591 }
35583592 zig_unreachable();
......@@ -3603,6 +3637,7 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {
36033637 case TypeTableEntryIdVar:
36043638 case TypeTableEntryIdArgTuple:
36053639 case TypeTableEntryIdOpaque:
3640 case TypeTableEntryIdPromise:
36063641 zig_unreachable();
36073642 }
36083643}
......@@ -4095,6 +4130,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
40954130 case TypeTableEntryIdErrorSet:
40964131 case TypeTableEntryIdFn:
40974132 case TypeTableEntryIdEnum:
4133 case TypeTableEntryIdPromise:
40984134 return false;
40994135 case TypeTableEntryIdArray:
41004136 case TypeTableEntryIdStruct:
......@@ -4342,6 +4378,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
43424378 }
43434379 zig_unreachable();
43444380 }
4381 case TypeTableEntryIdPromise:
4382 // TODO better hashing algorithm
4383 return 223048345;
43454384 case TypeTableEntryIdUndefLit:
43464385 return 162837799;
43474386 case TypeTableEntryIdNullLit:
......@@ -4501,6 +4540,7 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {
45014540 case TypeTableEntryIdPointer:
45024541 case TypeTableEntryIdVoid:
45034542 case TypeTableEntryIdUnreachable:
4543 case TypeTableEntryIdPromise:
45044544 return false;
45054545 }
45064546 zig_unreachable();
......@@ -4970,6 +5010,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
49705010 case TypeTableEntryIdInvalid:
49715011 case TypeTableEntryIdUnreachable:
49725012 case TypeTableEntryIdVar:
5013 case TypeTableEntryIdPromise:
49735014 zig_unreachable();
49745015 }
49755016 zig_unreachable();
......@@ -5244,6 +5285,8 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
52445285 buf_appendf(buf, "(args value)");
52455286 return;
52465287 }
5288 case TypeTableEntryIdPromise:
5289 zig_unreachable();
52475290 }
52485291 zig_unreachable();
52495292}
......@@ -5305,6 +5348,7 @@ uint32_t type_id_hash(TypeId x) {
53055348 case TypeTableEntryIdBlock:
53065349 case TypeTableEntryIdBoundFn:
53075350 case TypeTableEntryIdArgTuple:
5351 case TypeTableEntryIdPromise:
53085352 zig_unreachable();
53095353 case TypeTableEntryIdErrorUnion:
53105354 return hash_ptr(x.data.error_union.err_set_type) ^ hash_ptr(x.data.error_union.payload_type);
......@@ -5342,6 +5386,7 @@ bool type_id_eql(TypeId a, TypeId b) {
53425386 case TypeTableEntryIdUndefLit:
53435387 case TypeTableEntryIdNullLit:
53445388 case TypeTableEntryIdMaybe:
5389 case TypeTableEntryIdPromise:
53455390 case TypeTableEntryIdErrorSet:
53465391 case TypeTableEntryIdEnum:
53475392 case TypeTableEntryIdUnion:
......@@ -5469,6 +5514,7 @@ static const TypeTableEntryId all_type_ids[] = {
54695514 TypeTableEntryIdBoundFn,
54705515 TypeTableEntryIdArgTuple,
54715516 TypeTableEntryIdOpaque,
5517 TypeTableEntryIdPromise,
54725518};
54735519
54745520TypeTableEntryId type_id_at_index(size_t index) {
......@@ -5533,6 +5579,8 @@ size_t type_id_index(TypeTableEntryId id) {
55335579 return 22;
55345580 case TypeTableEntryIdOpaque:
55355581 return 23;
5582 case TypeTableEntryIdPromise:
5583 return 24;
55365584 }
55375585 zig_unreachable();
55385586}
......@@ -5590,6 +5638,8 @@ const char *type_id_name(TypeTableEntryId id) {
55905638 return "ArgTuple";
55915639 case TypeTableEntryIdOpaque:
55925640 return "Opaque";
5641 case TypeTableEntryIdPromise:
5642 return "Promise";
55935643 }
55945644 zig_unreachable();
55955645}
src/analyze.hpp+1
......@@ -35,6 +35,7 @@ TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry);
3535TypeTableEntry *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *name);
3636TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
3737 TypeTableEntry *field_types[], size_t field_count);
38TypeTableEntry *get_promise_type(CodeGen *g, TypeTableEntry *result_type);
3839TypeTableEntry *get_test_fn_type(CodeGen *g);
3940bool handle_is_ptr(TypeTableEntry *type_entry);
4041void find_libc_include_path(CodeGen *g);
src/codegen.cpp+6-7
......@@ -4017,6 +4017,7 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
40174017 case TypeTableEntryIdPointer:
40184018 case TypeTableEntryIdFn:
40194019 case TypeTableEntryIdMaybe:
4020 case TypeTableEntryIdPromise:
40204021 {
40214022 LLVMValueRef ptr_val = gen_const_val(g, const_val, "");
40224023 LLVMValueRef ptr_size_int_val = LLVMConstPtrToInt(ptr_val, g->builtin_types.entry_usize->type_ref);
......@@ -4434,6 +4435,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
44344435 case TypeTableEntryIdVar:
44354436 case TypeTableEntryIdArgTuple:
44364437 case TypeTableEntryIdOpaque:
4438 case TypeTableEntryIdPromise:
44374439 zig_unreachable();
44384440
44394441 }
......@@ -5280,13 +5282,7 @@ static void define_builtin_types(CodeGen *g) {
52805282 g->primitive_type_table.put(&entry->name, entry);
52815283 }
52825284 {
5283 TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, false);
5284 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);
5285 entry->type_ref = u8_ptr_type->type_ref;
5286 entry->zero_bits = false;
5287 buf_init_from_str(&entry->name, "promise");
5288 entry->di_type = u8_ptr_type->di_type;
5289 g->builtin_types.entry_promise = entry;
5285 TypeTableEntry *entry = get_promise_type(g, nullptr);
52905286 g->primitive_type_table.put(&entry->name, entry);
52915287 }
52925288
......@@ -5916,6 +5912,7 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, TypeTableEntry
59165912 case TypeTableEntryIdArgTuple:
59175913 case TypeTableEntryIdErrorUnion:
59185914 case TypeTableEntryIdErrorSet:
5915 case TypeTableEntryIdPromise:
59195916 zig_unreachable();
59205917 case TypeTableEntryIdVoid:
59215918 case TypeTableEntryIdUnreachable:
......@@ -6102,6 +6099,7 @@ static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf
61026099 case TypeTableEntryIdNullLit:
61036100 case TypeTableEntryIdVar:
61046101 case TypeTableEntryIdArgTuple:
6102 case TypeTableEntryIdPromise:
61056103 zig_unreachable();
61066104 }
61076105}
......@@ -6262,6 +6260,7 @@ static void gen_h_file(CodeGen *g) {
62626260 case TypeTableEntryIdArgTuple:
62636261 case TypeTableEntryIdMaybe:
62646262 case TypeTableEntryIdFn:
6263 case TypeTableEntryIdPromise:
62656264 zig_unreachable();
62666265 case TypeTableEntryIdEnum:
62676266 assert(type_entry->data.enumeration.layout == ContainerLayoutExtern);
src/ir.cpp+14
......@@ -9589,6 +9589,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
95899589 case TypeTableEntryIdBlock:
95909590 case TypeTableEntryIdBoundFn:
95919591 case TypeTableEntryIdArgTuple:
9592 case TypeTableEntryIdPromise:
95929593 if (!is_equality_cmp) {
95939594 ir_add_error_node(ira, source_node,
95949595 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));
......@@ -10418,6 +10419,7 @@ static VarClassRequired get_var_class_required(TypeTableEntry *type_entry) {
1041810419 case TypeTableEntryIdVoid:
1041910420 case TypeTableEntryIdErrorSet:
1042010421 case TypeTableEntryIdFn:
10422 case TypeTableEntryIdPromise:
1042110423 return VarClassRequiredAny;
1042210424 case TypeTableEntryIdNumLitFloat:
1042310425 case TypeTableEntryIdNumLitInt:
......@@ -10688,6 +10690,7 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi
1068810690 case TypeTableEntryIdBoundFn:
1068910691 case TypeTableEntryIdArgTuple:
1069010692 case TypeTableEntryIdOpaque:
10693 case TypeTableEntryIdPromise:
1069110694 ir_add_error(ira, target,
1069210695 buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name)));
1069310696 break;
......@@ -10712,6 +10715,7 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi
1071210715 case TypeTableEntryIdBoundFn:
1071310716 case TypeTableEntryIdArgTuple:
1071410717 case TypeTableEntryIdOpaque:
10718 case TypeTableEntryIdPromise:
1071510719 ir_add_error(ira, target,
1071610720 buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name)));
1071710721 break;
......@@ -11481,6 +11485,7 @@ static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op
1148111485 case TypeTableEntryIdBlock:
1148211486 case TypeTableEntryIdBoundFn:
1148311487 case TypeTableEntryIdArgTuple:
11488 case TypeTableEntryIdPromise:
1148411489 {
1148511490 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base);
1148611491 out_val->data.x_type = get_maybe_type(ira->codegen, type_entry);
......@@ -12710,6 +12715,7 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi
1271012715 case TypeTableEntryIdFn:
1271112716 case TypeTableEntryIdArgTuple:
1271212717 case TypeTableEntryIdOpaque:
12718 case TypeTableEntryIdPromise:
1271312719 {
1271412720 ConstExprValue *out_val = ir_build_const_from(ira, &typeof_instruction->base);
1271512721 out_val->data.x_type = type_entry;
......@@ -12977,6 +12983,7 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
1297712983 case TypeTableEntryIdFn:
1297812984 case TypeTableEntryIdNamespace:
1297912985 case TypeTableEntryIdBoundFn:
12986 case TypeTableEntryIdPromise:
1298012987 {
1298112988 type_ensure_zero_bits_known(ira->codegen, child_type);
1298212989 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, child_type,
......@@ -13085,6 +13092,7 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira,
1308513092 case TypeTableEntryIdFn:
1308613093 case TypeTableEntryIdNamespace:
1308713094 case TypeTableEntryIdBoundFn:
13095 case TypeTableEntryIdPromise:
1308813096 {
1308913097 TypeTableEntry *result_type = get_array_type(ira->codegen, child_type, size);
1309013098 ConstExprValue *out_val = ir_build_const_from(ira, &array_type_instruction->base);
......@@ -13136,6 +13144,7 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,
1313613144 case TypeTableEntryIdEnum:
1313713145 case TypeTableEntryIdUnion:
1313813146 case TypeTableEntryIdFn:
13147 case TypeTableEntryIdPromise:
1313913148 {
1314013149 uint64_t size_in_bytes = type_size(ira->codegen, type_entry);
1314113150 ConstExprValue *out_val = ir_build_const_from(ira, &size_of_instruction->base);
......@@ -13465,6 +13474,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
1346513474 case TypeTableEntryIdNumLitFloat:
1346613475 case TypeTableEntryIdNumLitInt:
1346713476 case TypeTableEntryIdPointer:
13477 case TypeTableEntryIdPromise:
1346813478 case TypeTableEntryIdFn:
1346913479 case TypeTableEntryIdNamespace:
1347013480 case TypeTableEntryIdErrorSet:
......@@ -14053,6 +14063,7 @@ static TypeTableEntry *ir_analyze_min_max(IrAnalyze *ira, IrInstruction *source_
1405314063 case TypeTableEntryIdMetaType:
1405414064 case TypeTableEntryIdUnreachable:
1405514065 case TypeTableEntryIdPointer:
14066 case TypeTableEntryIdPromise:
1405614067 case TypeTableEntryIdArray:
1405714068 case TypeTableEntryIdStruct:
1405814069 case TypeTableEntryIdNumLitFloat:
......@@ -15313,6 +15324,7 @@ static TypeTableEntry *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruc
1531315324 case TypeTableEntryIdInt:
1531415325 case TypeTableEntryIdFloat:
1531515326 case TypeTableEntryIdPointer:
15327 case TypeTableEntryIdPromise:
1531615328 case TypeTableEntryIdArray:
1531715329 case TypeTableEntryIdStruct:
1531815330 case TypeTableEntryIdMaybe:
......@@ -16008,6 +16020,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
1600816020 case TypeTableEntryIdNumLitInt:
1600916021 case TypeTableEntryIdUndefLit:
1601016022 case TypeTableEntryIdNullLit:
16023 case TypeTableEntryIdPromise:
1601116024 zig_unreachable();
1601216025 case TypeTableEntryIdVoid:
1601316026 return;
......@@ -16075,6 +16088,7 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
1607516088 case TypeTableEntryIdNumLitInt:
1607616089 case TypeTableEntryIdUndefLit:
1607716090 case TypeTableEntryIdNullLit:
16091 case TypeTableEntryIdPromise:
1607816092 zig_unreachable();
1607916093 case TypeTableEntryIdVoid:
1608016094 return;