Commit 65a51b401c
Changed files (5)
src/all_types.hpp
@@ -1096,6 +1096,11 @@ struct TypeTableEntryBoundFn {
TypeTableEntry *fn_type;
};
+struct TypeTableEntryPromise {
+ // null if `promise` instead of `promise->T`
+ TypeTableEntry *result_type;
+};
+
enum TypeTableEntryId {
TypeTableEntryIdInvalid,
TypeTableEntryIdVar,
@@ -1123,6 +1128,7 @@ enum TypeTableEntryId {
TypeTableEntryIdBoundFn,
TypeTableEntryIdArgTuple,
TypeTableEntryIdOpaque,
+ TypeTableEntryIdPromise,
};
struct TypeTableEntry {
@@ -1149,11 +1155,13 @@ struct TypeTableEntry {
TypeTableEntryUnion unionation;
TypeTableEntryFn fn;
TypeTableEntryBoundFn bound_fn;
+ TypeTableEntryPromise promise;
} data;
// use these fields to make sure we don't duplicate type table entries for the same type
TypeTableEntry *pointer_parent[2]; // [0 - mut, 1 - const]
TypeTableEntry *maybe_parent;
+ TypeTableEntry *promise_parent;
// If we generate a constant name value for this type, we memoize it here.
// The type of this is array
ConstExprValue *cached_const_name_val;
src/analyze.cpp
@@ -230,6 +230,7 @@ bool type_is_complete(TypeTableEntry *type_entry) {
case TypeTableEntryIdBlock:
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdArgTuple:
+ case TypeTableEntryIdPromise:
return true;
}
zig_unreachable();
@@ -267,6 +268,7 @@ bool type_has_zero_bits_known(TypeTableEntry *type_entry) {
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdOpaque:
+ case TypeTableEntryIdPromise:
return true;
}
zig_unreachable();
@@ -339,6 +341,32 @@ TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
return get_int_type(g, false, bits_needed_for_unsigned(x));
}
+TypeTableEntry *get_promise_type(CodeGen *g, TypeTableEntry *result_type) {
+ if (result_type != nullptr && result_type->promise_parent != nullptr) {
+ return result_type->promise_parent;
+ } else if (result_type == nullptr && g->builtin_types.entry_promise != nullptr) {
+ return g->builtin_types.entry_promise;
+ }
+
+ TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, false);
+ TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPromise);
+ entry->type_ref = u8_ptr_type->type_ref;
+ entry->zero_bits = false;
+ entry->data.promise.result_type = result_type;
+ buf_init_from_str(&entry->name, "promise");
+ if (result_type != nullptr) {
+ buf_appendf(&entry->name, "->%s", buf_ptr(&result_type->name));
+ }
+ entry->di_type = u8_ptr_type->di_type;
+
+ if (result_type != nullptr) {
+ result_type->promise_parent = entry;
+ } else if (result_type == nullptr) {
+ g->builtin_types.entry_promise = entry;
+ }
+ return entry;
+}
+
TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type, bool is_const,
bool is_volatile, uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count)
{
@@ -1203,6 +1231,7 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdOpaque:
+ case TypeTableEntryIdPromise:
return false;
case TypeTableEntryIdVoid:
case TypeTableEntryIdBool:
@@ -1243,6 +1272,7 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
case TypeTableEntryIdBlock:
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdArgTuple:
+ case TypeTableEntryIdPromise:
return false;
case TypeTableEntryIdOpaque:
case TypeTableEntryIdUnreachable:
@@ -1383,7 +1413,7 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdMetaType:
add_node_error(g, param_node->data.param_decl.type,
- buf_sprintf("parameter of type '%s' must be declared inline",
+ buf_sprintf("parameter of type '%s' must be declared comptime",
buf_ptr(&type_entry->name)));
return g->builtin_types.entry_invalid;
case TypeTableEntryIdVoid:
@@ -1399,6 +1429,7 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
case TypeTableEntryIdEnum:
case TypeTableEntryIdUnion:
case TypeTableEntryIdFn:
+ case TypeTableEntryIdPromise:
ensure_complete_type(g, type_entry);
if (fn_type_id.cc == CallingConventionUnspecified && !type_is_copyable(g, type_entry)) {
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
case TypeTableEntryIdEnum:
case TypeTableEntryIdUnion:
case TypeTableEntryIdFn:
+ case TypeTableEntryIdPromise:
break;
}
@@ -3175,6 +3207,7 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt
case TypeTableEntryIdUnion:
case TypeTableEntryIdFn:
case TypeTableEntryIdBoundFn:
+ case TypeTableEntryIdPromise:
return type_entry;
}
zig_unreachable();
@@ -3553,6 +3586,7 @@ static bool is_container(TypeTableEntry *type_entry) {
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdOpaque:
+ case TypeTableEntryIdPromise:
return false;
}
zig_unreachable();
@@ -3603,6 +3637,7 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {
case TypeTableEntryIdVar:
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdOpaque:
+ case TypeTableEntryIdPromise:
zig_unreachable();
}
}
@@ -4095,6 +4130,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
case TypeTableEntryIdErrorSet:
case TypeTableEntryIdFn:
case TypeTableEntryIdEnum:
+ case TypeTableEntryIdPromise:
return false;
case TypeTableEntryIdArray:
case TypeTableEntryIdStruct:
@@ -4342,6 +4378,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
}
zig_unreachable();
}
+ case TypeTableEntryIdPromise:
+ // TODO better hashing algorithm
+ return 223048345;
case TypeTableEntryIdUndefLit:
return 162837799;
case TypeTableEntryIdNullLit:
@@ -4501,6 +4540,7 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {
case TypeTableEntryIdPointer:
case TypeTableEntryIdVoid:
case TypeTableEntryIdUnreachable:
+ case TypeTableEntryIdPromise:
return false;
}
zig_unreachable();
@@ -4970,6 +5010,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
case TypeTableEntryIdInvalid:
case TypeTableEntryIdUnreachable:
case TypeTableEntryIdVar:
+ case TypeTableEntryIdPromise:
zig_unreachable();
}
zig_unreachable();
@@ -5244,6 +5285,8 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
buf_appendf(buf, "(args value)");
return;
}
+ case TypeTableEntryIdPromise:
+ zig_unreachable();
}
zig_unreachable();
}
@@ -5305,6 +5348,7 @@ uint32_t type_id_hash(TypeId x) {
case TypeTableEntryIdBlock:
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdArgTuple:
+ case TypeTableEntryIdPromise:
zig_unreachable();
case TypeTableEntryIdErrorUnion:
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) {
case TypeTableEntryIdUndefLit:
case TypeTableEntryIdNullLit:
case TypeTableEntryIdMaybe:
+ case TypeTableEntryIdPromise:
case TypeTableEntryIdErrorSet:
case TypeTableEntryIdEnum:
case TypeTableEntryIdUnion:
@@ -5469,6 +5514,7 @@ static const TypeTableEntryId all_type_ids[] = {
TypeTableEntryIdBoundFn,
TypeTableEntryIdArgTuple,
TypeTableEntryIdOpaque,
+ TypeTableEntryIdPromise,
};
TypeTableEntryId type_id_at_index(size_t index) {
@@ -5533,6 +5579,8 @@ size_t type_id_index(TypeTableEntryId id) {
return 22;
case TypeTableEntryIdOpaque:
return 23;
+ case TypeTableEntryIdPromise:
+ return 24;
}
zig_unreachable();
}
@@ -5590,6 +5638,8 @@ const char *type_id_name(TypeTableEntryId id) {
return "ArgTuple";
case TypeTableEntryIdOpaque:
return "Opaque";
+ case TypeTableEntryIdPromise:
+ return "Promise";
}
zig_unreachable();
}
src/analyze.hpp
@@ -35,6 +35,7 @@ TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry);
TypeTableEntry *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *name);
TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
TypeTableEntry *field_types[], size_t field_count);
+TypeTableEntry *get_promise_type(CodeGen *g, TypeTableEntry *result_type);
TypeTableEntry *get_test_fn_type(CodeGen *g);
bool handle_is_ptr(TypeTableEntry *type_entry);
void find_libc_include_path(CodeGen *g);
src/codegen.cpp
@@ -4017,6 +4017,7 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
case TypeTableEntryIdPointer:
case TypeTableEntryIdFn:
case TypeTableEntryIdMaybe:
+ case TypeTableEntryIdPromise:
{
LLVMValueRef ptr_val = gen_const_val(g, const_val, "");
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
case TypeTableEntryIdVar:
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdOpaque:
+ case TypeTableEntryIdPromise:
zig_unreachable();
}
@@ -5280,13 +5282,7 @@ static void define_builtin_types(CodeGen *g) {
g->primitive_type_table.put(&entry->name, entry);
}
{
- TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, false);
- TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);
- entry->type_ref = u8_ptr_type->type_ref;
- entry->zero_bits = false;
- buf_init_from_str(&entry->name, "promise");
- entry->di_type = u8_ptr_type->di_type;
- g->builtin_types.entry_promise = entry;
+ TypeTableEntry *entry = get_promise_type(g, nullptr);
g->primitive_type_table.put(&entry->name, entry);
}
@@ -5916,6 +5912,7 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, TypeTableEntry
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdErrorUnion:
case TypeTableEntryIdErrorSet:
+ case TypeTableEntryIdPromise:
zig_unreachable();
case TypeTableEntryIdVoid:
case TypeTableEntryIdUnreachable:
@@ -6102,6 +6099,7 @@ static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf
case TypeTableEntryIdNullLit:
case TypeTableEntryIdVar:
case TypeTableEntryIdArgTuple:
+ case TypeTableEntryIdPromise:
zig_unreachable();
}
}
@@ -6262,6 +6260,7 @@ static void gen_h_file(CodeGen *g) {
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdMaybe:
case TypeTableEntryIdFn:
+ case TypeTableEntryIdPromise:
zig_unreachable();
case TypeTableEntryIdEnum:
assert(type_entry->data.enumeration.layout == ContainerLayoutExtern);
src/ir.cpp
@@ -9589,6 +9589,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
case TypeTableEntryIdBlock:
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdArgTuple:
+ case TypeTableEntryIdPromise:
if (!is_equality_cmp) {
ir_add_error_node(ira, source_node,
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) {
case TypeTableEntryIdVoid:
case TypeTableEntryIdErrorSet:
case TypeTableEntryIdFn:
+ case TypeTableEntryIdPromise:
return VarClassRequiredAny;
case TypeTableEntryIdNumLitFloat:
case TypeTableEntryIdNumLitInt:
@@ -10688,6 +10690,7 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdOpaque:
+ case TypeTableEntryIdPromise:
ir_add_error(ira, target,
buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name)));
break;
@@ -10712,6 +10715,7 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdOpaque:
+ case TypeTableEntryIdPromise:
ir_add_error(ira, target,
buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name)));
break;
@@ -11481,6 +11485,7 @@ static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op
case TypeTableEntryIdBlock:
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdArgTuple:
+ case TypeTableEntryIdPromise:
{
ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base);
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
case TypeTableEntryIdFn:
case TypeTableEntryIdArgTuple:
case TypeTableEntryIdOpaque:
+ case TypeTableEntryIdPromise:
{
ConstExprValue *out_val = ir_build_const_from(ira, &typeof_instruction->base);
out_val->data.x_type = type_entry;
@@ -12977,6 +12983,7 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
case TypeTableEntryIdFn:
case TypeTableEntryIdNamespace:
case TypeTableEntryIdBoundFn:
+ case TypeTableEntryIdPromise:
{
type_ensure_zero_bits_known(ira->codegen, child_type);
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,
case TypeTableEntryIdFn:
case TypeTableEntryIdNamespace:
case TypeTableEntryIdBoundFn:
+ case TypeTableEntryIdPromise:
{
TypeTableEntry *result_type = get_array_type(ira->codegen, child_type, size);
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,
case TypeTableEntryIdEnum:
case TypeTableEntryIdUnion:
case TypeTableEntryIdFn:
+ case TypeTableEntryIdPromise:
{
uint64_t size_in_bytes = type_size(ira->codegen, type_entry);
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,
case TypeTableEntryIdNumLitFloat:
case TypeTableEntryIdNumLitInt:
case TypeTableEntryIdPointer:
+ case TypeTableEntryIdPromise:
case TypeTableEntryIdFn:
case TypeTableEntryIdNamespace:
case TypeTableEntryIdErrorSet:
@@ -14053,6 +14063,7 @@ static TypeTableEntry *ir_analyze_min_max(IrAnalyze *ira, IrInstruction *source_
case TypeTableEntryIdMetaType:
case TypeTableEntryIdUnreachable:
case TypeTableEntryIdPointer:
+ case TypeTableEntryIdPromise:
case TypeTableEntryIdArray:
case TypeTableEntryIdStruct:
case TypeTableEntryIdNumLitFloat:
@@ -15313,6 +15324,7 @@ static TypeTableEntry *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruc
case TypeTableEntryIdInt:
case TypeTableEntryIdFloat:
case TypeTableEntryIdPointer:
+ case TypeTableEntryIdPromise:
case TypeTableEntryIdArray:
case TypeTableEntryIdStruct:
case TypeTableEntryIdMaybe:
@@ -16008,6 +16020,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
case TypeTableEntryIdNumLitInt:
case TypeTableEntryIdUndefLit:
case TypeTableEntryIdNullLit:
+ case TypeTableEntryIdPromise:
zig_unreachable();
case TypeTableEntryIdVoid:
return;
@@ -16075,6 +16088,7 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
case TypeTableEntryIdNumLitInt:
case TypeTableEntryIdUndefLit:
case TypeTableEntryIdNullLit:
+ case TypeTableEntryIdPromise:
zig_unreachable();
case TypeTableEntryIdVoid:
return;