mirror of
https://github.com/ziglang/zig.git
synced 2024-11-15 08:33:06 +00:00
*WIP* error sets - fix implicit cast
This commit is contained in:
parent
5f518dbeb9
commit
13b36d458f
3
TODO
3
TODO
@ -2,4 +2,5 @@ sed -i 's/\(\bfn .*) \)%\(.*{\)$/\1!\2/g' $(find .. -name "*.zig")
|
|||||||
|
|
||||||
comptime assert(error{} ! i32 == i32);
|
comptime assert(error{} ! i32 == i32);
|
||||||
|
|
||||||
|
// TODO this is an explicit cast and should actually coerce the type
|
||||||
|
erorr set casting
|
||||||
|
@ -1274,7 +1274,7 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
|
|||||||
zig_unreachable();
|
zig_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypeTableEntry *get_auto_err_set_type(CodeGen *g, FnTableEntry *fn_entry) {
|
TypeTableEntry *get_auto_err_set_type(CodeGen *g, FnTableEntry *fn_entry) {
|
||||||
TypeTableEntry *err_set_type = new_type_table_entry(TypeTableEntryIdErrorSet);
|
TypeTableEntry *err_set_type = new_type_table_entry(TypeTableEntryIdErrorSet);
|
||||||
buf_resize(&err_set_type->name, 0);
|
buf_resize(&err_set_type->name, 0);
|
||||||
buf_appendf(&err_set_type->name, "%s.errors", buf_ptr(&fn_entry->symbol_name));
|
buf_appendf(&err_set_type->name, "%s.errors", buf_ptr(&fn_entry->symbol_name));
|
||||||
@ -3366,7 +3366,7 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *so
|
|||||||
g->tld_ref_source_node_stack.pop();
|
g->tld_ref_source_node_stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type) {
|
bool types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, TypeTableEntry *actual_type) {
|
||||||
if (expected_type == actual_type)
|
if (expected_type == actual_type)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -3379,7 +3379,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
|
|||||||
actual_type->data.pointer.unaligned_bit_count == expected_type->data.pointer.unaligned_bit_count &&
|
actual_type->data.pointer.unaligned_bit_count == expected_type->data.pointer.unaligned_bit_count &&
|
||||||
actual_type->data.pointer.alignment >= expected_type->data.pointer.alignment)
|
actual_type->data.pointer.alignment >= expected_type->data.pointer.alignment)
|
||||||
{
|
{
|
||||||
return types_match_const_cast_only(expected_type->data.pointer.child_type,
|
return types_match_const_cast_only(g, expected_type->data.pointer.child_type,
|
||||||
actual_type->data.pointer.child_type);
|
actual_type->data.pointer.child_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3397,7 +3397,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
|
|||||||
actual_ptr_type->data.pointer.unaligned_bit_count == expected_ptr_type->data.pointer.unaligned_bit_count &&
|
actual_ptr_type->data.pointer.unaligned_bit_count == expected_ptr_type->data.pointer.unaligned_bit_count &&
|
||||||
actual_ptr_type->data.pointer.alignment >= expected_ptr_type->data.pointer.alignment)
|
actual_ptr_type->data.pointer.alignment >= expected_ptr_type->data.pointer.alignment)
|
||||||
{
|
{
|
||||||
return types_match_const_cast_only(expected_ptr_type->data.pointer.child_type,
|
return types_match_const_cast_only(g, expected_ptr_type->data.pointer.child_type,
|
||||||
actual_ptr_type->data.pointer.child_type);
|
actual_ptr_type->data.pointer.child_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3406,7 +3406,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
|
|||||||
if (expected_type->id == TypeTableEntryIdMaybe &&
|
if (expected_type->id == TypeTableEntryIdMaybe &&
|
||||||
actual_type->id == TypeTableEntryIdMaybe)
|
actual_type->id == TypeTableEntryIdMaybe)
|
||||||
{
|
{
|
||||||
return types_match_const_cast_only(
|
return types_match_const_cast_only(g,
|
||||||
expected_type->data.maybe.child_type,
|
expected_type->data.maybe.child_type,
|
||||||
actual_type->data.maybe.child_type);
|
actual_type->data.maybe.child_type);
|
||||||
}
|
}
|
||||||
@ -3415,14 +3415,43 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
|
|||||||
if (expected_type->id == TypeTableEntryIdErrorUnion &&
|
if (expected_type->id == TypeTableEntryIdErrorUnion &&
|
||||||
actual_type->id == TypeTableEntryIdErrorUnion)
|
actual_type->id == TypeTableEntryIdErrorUnion)
|
||||||
{
|
{
|
||||||
return types_match_const_cast_only(
|
return types_match_const_cast_only(g,
|
||||||
expected_type->data.error_union.payload_type,
|
expected_type->data.error_union.payload_type,
|
||||||
actual_type->data.error_union.payload_type) &&
|
actual_type->data.error_union.payload_type) &&
|
||||||
types_match_const_cast_only(
|
types_match_const_cast_only(g,
|
||||||
expected_type->data.error_union.err_set_type,
|
expected_type->data.error_union.err_set_type,
|
||||||
actual_type->data.error_union.err_set_type);
|
actual_type->data.error_union.err_set_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// error set
|
||||||
|
if (expected_type->id == TypeTableEntryIdErrorSet &&
|
||||||
|
actual_type->id == TypeTableEntryIdErrorSet)
|
||||||
|
{
|
||||||
|
TypeTableEntry *contained_set = actual_type;
|
||||||
|
TypeTableEntry *container_set = expected_type;
|
||||||
|
|
||||||
|
if (container_set == g->builtin_types.entry_global_error_set ||
|
||||||
|
container_set->data.error_set.infer_fn != nullptr)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorTableEntry **errors = allocate<ErrorTableEntry *>(g->errors_by_index.length);
|
||||||
|
for (uint32_t i = 0; i < container_set->data.error_set.err_count; i += 1) {
|
||||||
|
ErrorTableEntry *error_entry = container_set->data.error_set.errors[i];
|
||||||
|
errors[error_entry->value] = error_entry;
|
||||||
|
}
|
||||||
|
for (uint32_t i = 0; i < contained_set->data.error_set.err_count; i += 1) {
|
||||||
|
ErrorTableEntry *contained_error_entry = contained_set->data.error_set.errors[i];
|
||||||
|
ErrorTableEntry *error_entry = errors[contained_error_entry->value];
|
||||||
|
if (error_entry == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(errors);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// fn
|
// fn
|
||||||
if (expected_type->id == TypeTableEntryIdFn &&
|
if (expected_type->id == TypeTableEntryIdFn &&
|
||||||
actual_type->id == TypeTableEntryIdFn)
|
actual_type->id == TypeTableEntryIdFn)
|
||||||
@ -3441,7 +3470,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
|
|||||||
}
|
}
|
||||||
if (!expected_type->data.fn.is_generic &&
|
if (!expected_type->data.fn.is_generic &&
|
||||||
actual_type->data.fn.fn_type_id.return_type->id != TypeTableEntryIdUnreachable &&
|
actual_type->data.fn.fn_type_id.return_type->id != TypeTableEntryIdUnreachable &&
|
||||||
!types_match_const_cast_only(
|
!types_match_const_cast_only(g,
|
||||||
expected_type->data.fn.fn_type_id.return_type,
|
expected_type->data.fn.fn_type_id.return_type,
|
||||||
actual_type->data.fn.fn_type_id.return_type))
|
actual_type->data.fn.fn_type_id.return_type))
|
||||||
{
|
{
|
||||||
@ -3460,7 +3489,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
|
|||||||
FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i];
|
FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i];
|
||||||
FnTypeParamInfo *expected_param_info = &expected_type->data.fn.fn_type_id.param_info[i];
|
FnTypeParamInfo *expected_param_info = &expected_type->data.fn.fn_type_id.param_info[i];
|
||||||
|
|
||||||
if (!types_match_const_cast_only(actual_param_info->type, expected_param_info->type)) {
|
if (!types_match_const_cast_only(g, actual_param_info->type, expected_param_info->type)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ bool type_has_bits(TypeTableEntry *type_entry);
|
|||||||
ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code);
|
ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code);
|
||||||
|
|
||||||
|
|
||||||
bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type);
|
bool types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, TypeTableEntry *actual_type);
|
||||||
VariableTableEntry *find_variable(CodeGen *g, Scope *orig_context, Buf *name);
|
VariableTableEntry *find_variable(CodeGen *g, Scope *orig_context, Buf *name);
|
||||||
Tld *find_decl(CodeGen *g, Scope *scope, Buf *name);
|
Tld *find_decl(CodeGen *g, Scope *scope, Buf *name);
|
||||||
void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *source_node);
|
void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *source_node);
|
||||||
@ -189,5 +189,6 @@ ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name);
|
|||||||
TypeTableEntry *get_ptr_to_stack_trace_type(CodeGen *g);
|
TypeTableEntry *get_ptr_to_stack_trace_type(CodeGen *g);
|
||||||
void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry);
|
void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry);
|
||||||
|
|
||||||
|
TypeTableEntry *get_auto_err_set_type(CodeGen *g, FnTableEntry *fn_entry);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
73
src/ir.cpp
73
src/ir.cpp
@ -6375,7 +6375,7 @@ enum ImplicitCastMatchResult {
|
|||||||
static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, TypeTableEntry *expected_type,
|
static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, TypeTableEntry *expected_type,
|
||||||
TypeTableEntry *actual_type, IrInstruction *value)
|
TypeTableEntry *actual_type, IrInstruction *value)
|
||||||
{
|
{
|
||||||
if (types_match_const_cast_only(expected_type, actual_type)) {
|
if (types_match_const_cast_only(ira->codegen, expected_type, actual_type)) {
|
||||||
return ImplicitCastMatchResultYes;
|
return ImplicitCastMatchResultYes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6412,13 +6412,6 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
|
|||||||
return ImplicitCastMatchResultYes;
|
return ImplicitCastMatchResultYes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// implicit conversion from error set to another error set
|
|
||||||
if (expected_type->id == TypeTableEntryIdErrorSet &&
|
|
||||||
actual_type->id == TypeTableEntryIdErrorSet)
|
|
||||||
{
|
|
||||||
return ImplicitCastMatchResultYes;
|
|
||||||
}
|
|
||||||
|
|
||||||
// implicit conversion from T to U!?T
|
// implicit conversion from T to U!?T
|
||||||
if (expected_type->id == TypeTableEntryIdErrorUnion &&
|
if (expected_type->id == TypeTableEntryIdErrorUnion &&
|
||||||
expected_type->data.error_union.payload_type->id == TypeTableEntryIdMaybe &&
|
expected_type->data.error_union.payload_type->id == TypeTableEntryIdMaybe &&
|
||||||
@ -6463,7 +6456,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
|
|||||||
assert(ptr_type->id == TypeTableEntryIdPointer);
|
assert(ptr_type->id == TypeTableEntryIdPointer);
|
||||||
|
|
||||||
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
|
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
|
||||||
types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
|
types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
|
||||||
{
|
{
|
||||||
return ImplicitCastMatchResultYes;
|
return ImplicitCastMatchResultYes;
|
||||||
}
|
}
|
||||||
@ -6482,7 +6475,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
|
|||||||
TypeTableEntry *array_type = actual_type->data.pointer.child_type;
|
TypeTableEntry *array_type = actual_type->data.pointer.child_type;
|
||||||
|
|
||||||
if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
|
if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
|
||||||
types_match_const_cast_only(ptr_type->data.pointer.child_type, array_type->data.array.child_type))
|
types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, array_type->data.array.child_type))
|
||||||
{
|
{
|
||||||
return ImplicitCastMatchResultYes;
|
return ImplicitCastMatchResultYes;
|
||||||
}
|
}
|
||||||
@ -6498,7 +6491,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
|
|||||||
expected_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
|
expected_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
|
||||||
assert(ptr_type->id == TypeTableEntryIdPointer);
|
assert(ptr_type->id == TypeTableEntryIdPointer);
|
||||||
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
|
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
|
||||||
types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
|
types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
|
||||||
{
|
{
|
||||||
return ImplicitCastMatchResultYes;
|
return ImplicitCastMatchResultYes;
|
||||||
}
|
}
|
||||||
@ -6513,7 +6506,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
|
|||||||
expected_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
|
expected_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
|
||||||
assert(ptr_type->id == TypeTableEntryIdPointer);
|
assert(ptr_type->id == TypeTableEntryIdPointer);
|
||||||
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
|
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
|
||||||
types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
|
types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
|
||||||
{
|
{
|
||||||
return ImplicitCastMatchResultYes;
|
return ImplicitCastMatchResultYes;
|
||||||
}
|
}
|
||||||
@ -6593,7 +6586,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
|
|||||||
// implicitly take a const pointer to something
|
// implicitly take a const pointer to something
|
||||||
if (!type_requires_comptime(actual_type)) {
|
if (!type_requires_comptime(actual_type)) {
|
||||||
TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);
|
TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);
|
||||||
if (types_match_const_cast_only(expected_type, const_ptr_actual)) {
|
if (types_match_const_cast_only(ira->codegen, expected_type, const_ptr_actual)) {
|
||||||
return ImplicitCastMatchResultYes;
|
return ImplicitCastMatchResultYes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6769,11 +6762,11 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (types_match_const_cast_only(prev_type, cur_type)) {
|
if (types_match_const_cast_only(ira->codegen, prev_type, cur_type)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (types_match_const_cast_only(cur_type, prev_type)) {
|
if (types_match_const_cast_only(ira->codegen, cur_type, prev_type)) {
|
||||||
prev_inst = cur_inst;
|
prev_inst = cur_inst;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -6796,26 +6789,26 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (prev_type->id == TypeTableEntryIdErrorUnion &&
|
if (prev_type->id == TypeTableEntryIdErrorUnion &&
|
||||||
types_match_const_cast_only(prev_type->data.error_union.payload_type, cur_type))
|
types_match_const_cast_only(ira->codegen, prev_type->data.error_union.payload_type, cur_type))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur_type->id == TypeTableEntryIdErrorUnion &&
|
if (cur_type->id == TypeTableEntryIdErrorUnion &&
|
||||||
types_match_const_cast_only(cur_type->data.error_union.payload_type, prev_type))
|
types_match_const_cast_only(ira->codegen, cur_type->data.error_union.payload_type, prev_type))
|
||||||
{
|
{
|
||||||
prev_inst = cur_inst;
|
prev_inst = cur_inst;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev_type->id == TypeTableEntryIdMaybe &&
|
if (prev_type->id == TypeTableEntryIdMaybe &&
|
||||||
types_match_const_cast_only(prev_type->data.maybe.child_type, cur_type))
|
types_match_const_cast_only(ira->codegen, prev_type->data.maybe.child_type, cur_type))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur_type->id == TypeTableEntryIdMaybe &&
|
if (cur_type->id == TypeTableEntryIdMaybe &&
|
||||||
types_match_const_cast_only(cur_type->data.maybe.child_type, prev_type))
|
types_match_const_cast_only(ira->codegen, cur_type->data.maybe.child_type, prev_type))
|
||||||
{
|
{
|
||||||
prev_inst = cur_inst;
|
prev_inst = cur_inst;
|
||||||
continue;
|
continue;
|
||||||
@ -6853,7 +6846,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
|
|||||||
|
|
||||||
if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&
|
if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&
|
||||||
cur_type->data.array.len != prev_type->data.array.len &&
|
cur_type->data.array.len != prev_type->data.array.len &&
|
||||||
types_match_const_cast_only(cur_type->data.array.child_type, prev_type->data.array.child_type))
|
types_match_const_cast_only(ira->codegen, cur_type->data.array.child_type, prev_type->data.array.child_type))
|
||||||
{
|
{
|
||||||
convert_to_const_slice = true;
|
convert_to_const_slice = true;
|
||||||
prev_inst = cur_inst;
|
prev_inst = cur_inst;
|
||||||
@ -6862,7 +6855,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
|
|||||||
|
|
||||||
if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&
|
if (cur_type->id == TypeTableEntryIdArray && prev_type->id == TypeTableEntryIdArray &&
|
||||||
cur_type->data.array.len != prev_type->data.array.len &&
|
cur_type->data.array.len != prev_type->data.array.len &&
|
||||||
types_match_const_cast_only(prev_type->data.array.child_type, cur_type->data.array.child_type))
|
types_match_const_cast_only(ira->codegen, prev_type->data.array.child_type, cur_type->data.array.child_type))
|
||||||
{
|
{
|
||||||
convert_to_const_slice = true;
|
convert_to_const_slice = true;
|
||||||
continue;
|
continue;
|
||||||
@ -6871,7 +6864,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
|
|||||||
if (cur_type->id == TypeTableEntryIdArray && is_slice(prev_type) &&
|
if (cur_type->id == TypeTableEntryIdArray && is_slice(prev_type) &&
|
||||||
(prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
|
(prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
|
||||||
cur_type->data.array.len == 0) &&
|
cur_type->data.array.len == 0) &&
|
||||||
types_match_const_cast_only(prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
|
types_match_const_cast_only(ira->codegen, prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
|
||||||
cur_type->data.array.child_type))
|
cur_type->data.array.child_type))
|
||||||
{
|
{
|
||||||
convert_to_const_slice = false;
|
convert_to_const_slice = false;
|
||||||
@ -6881,7 +6874,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
|
|||||||
if (prev_type->id == TypeTableEntryIdArray && is_slice(cur_type) &&
|
if (prev_type->id == TypeTableEntryIdArray && is_slice(cur_type) &&
|
||||||
(cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
|
(cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||
|
||||||
prev_type->data.array.len == 0) &&
|
prev_type->data.array.len == 0) &&
|
||||||
types_match_const_cast_only(cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
|
types_match_const_cast_only(ira->codegen, cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,
|
||||||
prev_type->data.array.child_type))
|
prev_type->data.array.child_type))
|
||||||
{
|
{
|
||||||
prev_inst = cur_inst;
|
prev_inst = cur_inst;
|
||||||
@ -7449,6 +7442,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO this is an explicit cast and should actually coerce the type
|
||||||
static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
|
static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
|
||||||
TypeTableEntry *wanted_type)
|
TypeTableEntry *wanted_type)
|
||||||
{
|
{
|
||||||
@ -7999,7 +7993,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
|
|||||||
return value;
|
return value;
|
||||||
|
|
||||||
// explicit match or non-const to const
|
// explicit match or non-const to const
|
||||||
if (types_match_const_cast_only(wanted_type, actual_type)) {
|
if (types_match_const_cast_only(ira->codegen, wanted_type, actual_type)) {
|
||||||
return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
|
return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8045,7 +8039,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
|
|||||||
TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
|
TypeTableEntry *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;
|
||||||
assert(ptr_type->id == TypeTableEntryIdPointer);
|
assert(ptr_type->id == TypeTableEntryIdPointer);
|
||||||
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
|
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
|
||||||
types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
|
types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
|
||||||
{
|
{
|
||||||
return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);
|
return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);
|
||||||
}
|
}
|
||||||
@ -8063,7 +8057,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
|
|||||||
TypeTableEntry *array_type = actual_type->data.pointer.child_type;
|
TypeTableEntry *array_type = actual_type->data.pointer.child_type;
|
||||||
|
|
||||||
if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
|
if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
|
||||||
types_match_const_cast_only(ptr_type->data.pointer.child_type, array_type->data.array.child_type))
|
types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, array_type->data.array.child_type))
|
||||||
{
|
{
|
||||||
return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);
|
return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type);
|
||||||
}
|
}
|
||||||
@ -8079,7 +8073,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
|
|||||||
wanted_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
|
wanted_type->data.pointer.child_type->data.structure.fields[slice_ptr_index].type_entry;
|
||||||
assert(ptr_type->id == TypeTableEntryIdPointer);
|
assert(ptr_type->id == TypeTableEntryIdPointer);
|
||||||
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
|
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
|
||||||
types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
|
types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
|
||||||
{
|
{
|
||||||
IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.pointer.child_type, value);
|
IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.pointer.child_type, value);
|
||||||
if (type_is_invalid(cast1->value.type))
|
if (type_is_invalid(cast1->value.type))
|
||||||
@ -8102,7 +8096,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
|
|||||||
wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
|
wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;
|
||||||
assert(ptr_type->id == TypeTableEntryIdPointer);
|
assert(ptr_type->id == TypeTableEntryIdPointer);
|
||||||
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
|
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
|
||||||
types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
|
types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
|
||||||
{
|
{
|
||||||
IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value);
|
IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value);
|
||||||
if (type_is_invalid(cast1->value.type))
|
if (type_is_invalid(cast1->value.type))
|
||||||
@ -8164,7 +8158,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
|
|||||||
|
|
||||||
// explicit cast from child type of maybe type to maybe type
|
// explicit cast from child type of maybe type to maybe type
|
||||||
if (wanted_type->id == TypeTableEntryIdMaybe) {
|
if (wanted_type->id == TypeTableEntryIdMaybe) {
|
||||||
if (types_match_const_cast_only(wanted_type->data.maybe.child_type, actual_type)) {
|
if (types_match_const_cast_only(ira->codegen, wanted_type->data.maybe.child_type, actual_type)) {
|
||||||
return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);
|
return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);
|
||||||
} else if (actual_type->id == TypeTableEntryIdNumLitInt ||
|
} else if (actual_type->id == TypeTableEntryIdNumLitInt ||
|
||||||
actual_type->id == TypeTableEntryIdNumLitFloat)
|
actual_type->id == TypeTableEntryIdNumLitFloat)
|
||||||
@ -8186,7 +8180,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
|
|||||||
|
|
||||||
// explicit cast from child type of error type to error type
|
// explicit cast from child type of error type to error type
|
||||||
if (wanted_type->id == TypeTableEntryIdErrorUnion) {
|
if (wanted_type->id == TypeTableEntryIdErrorUnion) {
|
||||||
if (types_match_const_cast_only(wanted_type->data.error_union.payload_type, actual_type)) {
|
if (types_match_const_cast_only(ira->codegen, wanted_type->data.error_union.payload_type, actual_type)) {
|
||||||
return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
|
return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
|
||||||
} else if (actual_type->id == TypeTableEntryIdNumLitInt ||
|
} else if (actual_type->id == TypeTableEntryIdNumLitInt ||
|
||||||
actual_type->id == TypeTableEntryIdNumLitFloat)
|
actual_type->id == TypeTableEntryIdNumLitFloat)
|
||||||
@ -8208,7 +8202,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
|
|||||||
wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry;
|
wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry;
|
||||||
assert(ptr_type->id == TypeTableEntryIdPointer);
|
assert(ptr_type->id == TypeTableEntryIdPointer);
|
||||||
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
|
if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
|
||||||
types_match_const_cast_only(ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
|
types_match_const_cast_only(ira->codegen, ptr_type->data.pointer.child_type, actual_type->data.array.child_type))
|
||||||
{
|
{
|
||||||
IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);
|
IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);
|
||||||
if (type_is_invalid(cast1->value.type))
|
if (type_is_invalid(cast1->value.type))
|
||||||
@ -8235,7 +8229,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
|
|||||||
actual_type->id != TypeTableEntryIdMaybe)
|
actual_type->id != TypeTableEntryIdMaybe)
|
||||||
{
|
{
|
||||||
TypeTableEntry *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type;
|
TypeTableEntry *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type;
|
||||||
if (types_match_const_cast_only(wanted_child_type, actual_type) ||
|
if (types_match_const_cast_only(ira->codegen, wanted_child_type, actual_type) ||
|
||||||
actual_type->id == TypeTableEntryIdNullLit ||
|
actual_type->id == TypeTableEntryIdNullLit ||
|
||||||
actual_type->id == TypeTableEntryIdNumLitInt ||
|
actual_type->id == TypeTableEntryIdNumLitInt ||
|
||||||
actual_type->id == TypeTableEntryIdNumLitFloat)
|
actual_type->id == TypeTableEntryIdNumLitFloat)
|
||||||
@ -8385,7 +8379,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
|
|||||||
// explicit cast from something to const pointer of it
|
// explicit cast from something to const pointer of it
|
||||||
if (!type_requires_comptime(actual_type)) {
|
if (!type_requires_comptime(actual_type)) {
|
||||||
TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);
|
TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true);
|
||||||
if (types_match_const_cast_only(wanted_type, const_ptr_actual)) {
|
if (types_match_const_cast_only(ira->codegen, wanted_type, const_ptr_actual)) {
|
||||||
return ir_analyze_cast_ref(ira, source_instr, value, wanted_type);
|
return ir_analyze_cast_ref(ira, source_instr, value, wanted_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10386,12 +10380,17 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
|
|||||||
|
|
||||||
{
|
{
|
||||||
AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
|
AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
|
||||||
TypeTableEntry *return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node);
|
TypeTableEntry *specified_return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node);
|
||||||
if (type_is_invalid(return_type))
|
if (type_is_invalid(specified_return_type))
|
||||||
return ira->codegen->builtin_types.entry_invalid;
|
return ira->codegen->builtin_types.entry_invalid;
|
||||||
inst_fn_type_id.return_type = return_type;
|
if (fn_proto_node->data.fn_proto.auto_err_set) {
|
||||||
|
TypeTableEntry *inferred_err_set_type = get_auto_err_set_type(ira->codegen, impl_fn);
|
||||||
|
inst_fn_type_id.return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type);
|
||||||
|
} else {
|
||||||
|
inst_fn_type_id.return_type = specified_return_type;
|
||||||
|
}
|
||||||
|
|
||||||
if (type_requires_comptime(return_type)) {
|
if (type_requires_comptime(specified_return_type)) {
|
||||||
// Throw out our work and call the function as if it were comptime.
|
// Throw out our work and call the function as if it were comptime.
|
||||||
return ir_analyze_fn_call(ira, call_instruction, fn_entry, fn_type, fn_ref, first_arg_ptr, true, FnInlineAuto);
|
return ir_analyze_fn_call(ira, call_instruction, fn_entry, fn_type, fn_ref, first_arg_ptr, true, FnInlineAuto);
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,7 @@ pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn(@
|
|||||||
return formatValue(err, context, Errors, output);
|
return formatValue(err, context, Errors, output);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
builtin.TypeId.Error => {
|
builtin.TypeId.ErrorSet => {
|
||||||
try output(context, "error.");
|
try output(context, "error.");
|
||||||
return output(context, @errorName(value));
|
return output(context, @errorName(value));
|
||||||
},
|
},
|
||||||
|
@ -26,7 +26,9 @@ test "import io tests" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getStdErr() !File {
|
const GetStdIoErrs = os.WindowsGetStdHandleErrs;
|
||||||
|
|
||||||
|
pub fn getStdErr() GetStdIoErrs!File {
|
||||||
const handle = if (is_windows)
|
const handle = if (is_windows)
|
||||||
try os.windowsGetStdHandle(system.STD_ERROR_HANDLE)
|
try os.windowsGetStdHandle(system.STD_ERROR_HANDLE)
|
||||||
else if (is_posix)
|
else if (is_posix)
|
||||||
@ -36,7 +38,7 @@ pub fn getStdErr() !File {
|
|||||||
return File.openHandle(handle);
|
return File.openHandle(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getStdOut() !File {
|
pub fn getStdOut() GetStdIoErrs!File {
|
||||||
const handle = if (is_windows)
|
const handle = if (is_windows)
|
||||||
try os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE)
|
try os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE)
|
||||||
else if (is_posix)
|
else if (is_posix)
|
||||||
@ -46,7 +48,7 @@ pub fn getStdOut() !File {
|
|||||||
return File.openHandle(handle);
|
return File.openHandle(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getStdIn() !File {
|
pub fn getStdIn() GetStdIoErrs!File {
|
||||||
const handle = if (is_windows)
|
const handle = if (is_windows)
|
||||||
try os.windowsGetStdHandle(system.STD_INPUT_HANDLE)
|
try os.windowsGetStdHandle(system.STD_INPUT_HANDLE)
|
||||||
else if (is_posix)
|
else if (is_posix)
|
||||||
|
@ -40,7 +40,7 @@ pub const Allocator = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29,
|
fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29,
|
||||||
n: usize) %[]align(alignment) T
|
n: usize) ![]align(alignment) T
|
||||||
{
|
{
|
||||||
const byte_count = try math.mul(usize, @sizeOf(T), n);
|
const byte_count = try math.mul(usize, @sizeOf(T), n);
|
||||||
const byte_slice = try self.allocFn(self, byte_count, alignment);
|
const byte_slice = try self.allocFn(self, byte_count, alignment);
|
||||||
@ -56,7 +56,7 @@ pub const Allocator = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn alignedRealloc(self: &Allocator, comptime T: type, comptime alignment: u29,
|
fn alignedRealloc(self: &Allocator, comptime T: type, comptime alignment: u29,
|
||||||
old_mem: []align(alignment) T, n: usize) %[]align(alignment) T
|
old_mem: []align(alignment) T, n: usize) ![]align(alignment) T
|
||||||
{
|
{
|
||||||
if (old_mem.len == 0) {
|
if (old_mem.len == 0) {
|
||||||
return self.alloc(T, n);
|
return self.alloc(T, n);
|
||||||
|
@ -1158,7 +1158,12 @@ pub fn posix_setregid(rgid: u32, egid: u32) !void {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn windowsGetStdHandle(handle_id: windows.DWORD) !windows.HANDLE {
|
pub const WindowsGetStdHandleErrs = error {
|
||||||
|
NoStdHandles,
|
||||||
|
Unexpected,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn windowsGetStdHandle(handle_id: windows.DWORD) WindowsGetStdHandleErrs!windows.HANDLE {
|
||||||
if (windows.GetStdHandle(handle_id)) |handle| {
|
if (windows.GetStdHandle(handle_id)) |handle| {
|
||||||
if (handle == windows.INVALID_HANDLE_VALUE) {
|
if (handle == windows.INVALID_HANDLE_VALUE) {
|
||||||
const err = windows.GetLastError();
|
const err = windows.GetLastError();
|
||||||
|
Loading…
Reference in New Issue
Block a user