From ef5e7bb4693ed7e1582fb0b68cab01e00638d615 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 3 Feb 2018 14:06:37 -0500 Subject: *WIP* error sets - an inferred error set can end up being the global one --- src/analyze.cpp | 193 +++++--------------------------------------------------- 1 file changed, 15 insertions(+), 178 deletions(-) (limited to 'src/analyze.cpp') diff --git a/src/analyze.cpp b/src/analyze.cpp index 073a91aeff..be6057a309 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3372,180 +3372,6 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *so g->tld_ref_source_node_stack.pop(); } -ConstCastOnly types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, TypeTableEntry *actual_type) { - ConstCastOnly result = {}; - result.id = ConstCastResultIdOk; - - if (expected_type == actual_type) - return result; - - // pointer const - if (expected_type->id == TypeTableEntryIdPointer && - actual_type->id == TypeTableEntryIdPointer && - (!actual_type->data.pointer.is_const || expected_type->data.pointer.is_const) && - (!actual_type->data.pointer.is_volatile || expected_type->data.pointer.is_volatile) && - actual_type->data.pointer.bit_offset == expected_type->data.pointer.bit_offset && - actual_type->data.pointer.unaligned_bit_count == expected_type->data.pointer.unaligned_bit_count && - actual_type->data.pointer.alignment >= expected_type->data.pointer.alignment) - { - ConstCastOnly child = types_match_const_cast_only(g, expected_type->data.pointer.child_type, actual_type->data.pointer.child_type); - if (child.id != ConstCastResultIdOk) { - result.id = ConstCastResultIdPointerChild; - result.data.pointer_child = allocate_nonzero(1); - *result.data.pointer_child = child; - } - return result; - } - - // slice const - if (expected_type->id == TypeTableEntryIdStruct && actual_type->id == TypeTableEntryIdStruct && - expected_type->data.structure.is_slice && actual_type->data.structure.is_slice) - { - TypeTableEntry *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index].type_entry; - TypeTableEntry *expected_ptr_type = expected_type->data.structure.fields[slice_ptr_index].type_entry; - if ((!actual_ptr_type->data.pointer.is_const || expected_ptr_type->data.pointer.is_const) && - (!actual_ptr_type->data.pointer.is_volatile || expected_ptr_type->data.pointer.is_volatile) && - actual_ptr_type->data.pointer.bit_offset == expected_ptr_type->data.pointer.bit_offset && - 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) - { - ConstCastOnly child = types_match_const_cast_only(g, expected_ptr_type->data.pointer.child_type, - actual_ptr_type->data.pointer.child_type); - if (child.id != ConstCastResultIdOk) { - result.id = ConstCastResultIdSliceChild; - result.data.slice_child = allocate_nonzero(1); - *result.data.slice_child = child; - } - return result; - } - } - - // maybe - if (expected_type->id == TypeTableEntryIdMaybe && actual_type->id == TypeTableEntryIdMaybe) { - ConstCastOnly child = types_match_const_cast_only(g, expected_type->data.maybe.child_type, actual_type->data.maybe.child_type); - if (child.id != ConstCastResultIdOk) { - result.id = ConstCastResultIdNullableChild; - result.data.nullable_child = allocate_nonzero(1); - *result.data.nullable_child = child; - } - return result; - } - - // error union - if (expected_type->id == TypeTableEntryIdErrorUnion && actual_type->id == TypeTableEntryIdErrorUnion) { - ConstCastOnly payload_child = types_match_const_cast_only(g, expected_type->data.error_union.payload_type, actual_type->data.error_union.payload_type); - if (payload_child.id != ConstCastResultIdOk) { - result.id = ConstCastResultIdErrorUnionPayload; - result.data.error_union_payload = allocate_nonzero(1); - *result.data.error_union_payload = payload_child; - return result; - } - ConstCastOnly error_set_child = types_match_const_cast_only(g, expected_type->data.error_union.err_set_type, actual_type->data.error_union.err_set_type); - if (error_set_child.id != ConstCastResultIdOk) { - result.id = ConstCastResultIdErrorUnionErrorSet; - result.data.error_union_error_set = allocate_nonzero(1); - *result.data.error_union_error_set = error_set_child; - return result; - } - return result; - } - - // 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 result; - } - - ErrorTableEntry **errors = allocate(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) { - if (result.id == ConstCastResultIdOk) { - result.id = ConstCastResultIdErrSet; - } - result.data.error_set.missing_errors.append(contained_error_entry); - } - } - free(errors); - return result; - } - - // fn - if (expected_type->id == TypeTableEntryIdFn && - actual_type->id == TypeTableEntryIdFn) - { - if (expected_type->data.fn.fn_type_id.alignment > actual_type->data.fn.fn_type_id.alignment) { - result.id = ConstCastResultIdFnAlign; - return result; - } - if (expected_type->data.fn.fn_type_id.cc != actual_type->data.fn.fn_type_id.cc) { - result.id = ConstCastResultIdFnCC; - return result; - } - if (expected_type->data.fn.fn_type_id.is_var_args != actual_type->data.fn.fn_type_id.is_var_args) { - result.id = ConstCastResultIdFnVarArgs; - return result; - } - if (expected_type->data.fn.is_generic != actual_type->data.fn.is_generic) { - result.id = ConstCastResultIdFnIsGeneric; - return result; - } - if (!expected_type->data.fn.is_generic && - actual_type->data.fn.fn_type_id.return_type->id != TypeTableEntryIdUnreachable) - { - ConstCastOnly child = types_match_const_cast_only(g, expected_type->data.fn.fn_type_id.return_type, actual_type->data.fn.fn_type_id.return_type); - if (child.id != ConstCastResultIdOk) { - result.id = ConstCastResultIdFnReturnType; - result.data.return_type = allocate_nonzero(1); - *result.data.return_type = child; - } - return result; - } - if (expected_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) { - result.id = ConstCastResultIdFnArgCount; - return result; - } - if (expected_type->data.fn.fn_type_id.next_param_index != actual_type->data.fn.fn_type_id.next_param_index) { - result.id = ConstCastResultIdFnGenericArgCount; - return result; - } - assert(expected_type->data.fn.is_generic || - expected_type->data.fn.fn_type_id.next_param_index == expected_type->data.fn.fn_type_id.param_count); - for (size_t i = 0; i < expected_type->data.fn.fn_type_id.next_param_index; i += 1) { - // note it's reversed for parameters - 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]; - - ConstCastOnly arg_child = types_match_const_cast_only(g, actual_param_info->type, expected_param_info->type); - if (arg_child.id != ConstCastResultIdOk) { - result.id = ConstCastResultIdFnArg; - result.data.fn_arg.arg_index = i; - result.data.fn_arg.child = allocate_nonzero(1); - *result.data.fn_arg.child = arg_child; - return result; - } - - if (expected_param_info->is_noalias != actual_param_info->is_noalias) { - result.id = ConstCastResultIdFnArgNoAlias; - result.data.arg_no_alias.arg_index = i; - return result; - } - } - return result; - } - - result.id = ConstCastResultIdType; - return result; -} - Tld *find_decl(CodeGen *g, Scope *scope, Buf *name) { // we must resolve all the use decls ImportTableEntry *import = get_scope_import(scope); @@ -3906,10 +3732,16 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ } return_err_set_type->data.error_set.infer_fn = nullptr; - return_err_set_type->data.error_set.err_count = inferred_err_set_type->data.error_set.err_count; - return_err_set_type->data.error_set.errors = allocate(inferred_err_set_type->data.error_set.err_count); - for (uint32_t i = 0; i < inferred_err_set_type->data.error_set.err_count; i += 1) { - return_err_set_type->data.error_set.errors[i] = inferred_err_set_type->data.error_set.errors[i]; + if (type_is_global_error_set(inferred_err_set_type)) { + return_err_set_type->data.error_set.err_count = UINT32_MAX; + } else { + return_err_set_type->data.error_set.err_count = inferred_err_set_type->data.error_set.err_count; + if (inferred_err_set_type->data.error_set.err_count > 0) { + return_err_set_type->data.error_set.errors = allocate(inferred_err_set_type->data.error_set.err_count); + for (uint32_t i = 0; i < inferred_err_set_type->data.error_set.err_count; i += 1) { + return_err_set_type->data.error_set.errors[i] = inferred_err_set_type->data.error_set.errors[i]; + } + } } } } @@ -5833,3 +5665,8 @@ ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name) { return var_value; } +bool type_is_global_error_set(TypeTableEntry *err_set_type) { + assert(err_set_type->id == TypeTableEntryIdErrorSet); + assert(err_set_type->data.error_set.infer_fn == nullptr); + return err_set_type->data.error_set.err_count == UINT32_MAX; +} -- cgit v1.2.3