diff --git a/src/all_types.hpp b/src/all_types.hpp index 8c6f7456b3..77a0a9bd5e 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1308,6 +1308,13 @@ struct RootStruct { ZigLLVMDIFile *di_file; }; +enum StructSpecial { + StructSpecialNone, + StructSpecialSlice, + StructSpecialInferredTuple, + StructSpecialInferredStruct, +}; + struct ZigTypeStruct { AstNode *decl_node; TypeStructField **fields; @@ -1323,13 +1330,12 @@ struct ZigTypeStruct { ContainerLayout layout; ResolveStatus resolve_status; - bool is_slice; + StructSpecial special; // whether any of the fields require comptime // known after ResolveStatusZeroBitsKnown bool requires_comptime; bool resolve_loop_flag_zero_bits; bool resolve_loop_flag_other; - bool is_inferred; }; struct ZigTypeOptional { diff --git a/src/analyze.cpp b/src/analyze.cpp index 10576d4fb9..1f253ac157 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -420,7 +420,7 @@ uint32_t get_abi_alignment(CodeGen *g, ZigType *type_entry) { } static bool is_slice(ZigType *type) { - return type->id == ZigTypeIdStruct && type->data.structure.is_slice; + return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialSlice; } ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) { @@ -832,7 +832,7 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) { entry->data.structure.resolve_status = ResolveStatusSizeKnown; entry->data.structure.layout = ContainerLayoutAuto; - entry->data.structure.is_slice = true; + entry->data.structure.special = StructSpecialSlice; entry->data.structure.src_field_count = element_count; entry->data.structure.gen_field_count = element_count; entry->data.structure.fields = alloc_type_struct_fields(element_count); @@ -2752,7 +2752,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { } else if (decl_node->type == NodeTypeContainerInitExpr) { field_count = struct_type->data.structure.src_field_count; - src_assert(struct_type->data.structure.is_inferred, decl_node); + src_assert(is_anon_container(struct_type), decl_node); src_assert(field_count == 0 || struct_type->data.structure.fields != nullptr, decl_node); } else zig_unreachable(); @@ -4256,7 +4256,7 @@ bool is_container(ZigType *type_entry) { case ZigTypeIdInvalid: zig_unreachable(); case ZigTypeIdStruct: - return !type_entry->data.structure.is_slice; + return type_entry->data.structure.special != StructSpecialSlice; case ZigTypeIdEnum: case ZigTypeIdUnion: return true; @@ -7391,7 +7391,7 @@ size_t type_id_index(ZigType *entry) { case ZigTypeIdArray: return 7; case ZigTypeIdStruct: - if (entry->data.structure.is_slice) + if (entry->data.structure.special == StructSpecialSlice) return 6; return 8; case ZigTypeIdComptimeFloat: @@ -9077,7 +9077,7 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r assert(type->llvm_di_type != nullptr); return; case ZigTypeIdStruct: - if (type->data.structure.is_slice) + if (type->data.structure.special == StructSpecialSlice) return resolve_llvm_types_slice(g, type, wanted_resolve_status); else return resolve_llvm_types_struct(g, type, wanted_resolve_status, nullptr); @@ -9229,3 +9229,9 @@ void IrExecutable::src() { it->source_node->src(); } } + +bool is_anon_container(ZigType *ty) { + return ty->id == ZigTypeIdStruct && ( + ty->data.structure.special == StructSpecialInferredTuple || + ty->data.structure.special == StructSpecialInferredStruct); +} diff --git a/src/analyze.hpp b/src/analyze.hpp index dd22c914db..2fdaa00ab2 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -278,4 +278,5 @@ IrInstruction *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, Error analyze_import(CodeGen *codegen, ZigType *source_import, Buf *import_target_str, ZigType **out_import, Buf **out_import_target_path, Buf *out_full_path); ZigValue *get_the_one_possible_value(CodeGen *g, ZigType *type_entry); +bool is_anon_container(ZigType *ty); #endif diff --git a/src/codegen.cpp b/src/codegen.cpp index 04b3c3fbaa..387d10a189 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2998,9 +2998,9 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable, LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); assert(wanted_type->id == ZigTypeIdStruct); - assert(wanted_type->data.structure.is_slice); + assert(wanted_type->data.structure.special == StructSpecialSlice); assert(actual_type->id == ZigTypeIdStruct); - assert(actual_type->data.structure.is_slice); + assert(actual_type->data.structure.special == StructSpecialSlice); ZigType *actual_pointer_type = actual_type->data.structure.fields[0]->type_entry; ZigType *actual_child_type = actual_pointer_type->data.pointer.child_type; @@ -3751,7 +3751,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 1, ""); } else if (array_type->id == ZigTypeIdStruct) { LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type); - assert(array_type->data.structure.is_slice); + assert(array_type->data.structure.special == StructSpecialSlice); ZigType *ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry; if (!type_has_bits(ptr_type)) { @@ -5028,7 +5028,9 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I { align_bytes = target_type->data.maybe.child_type->data.fn.fn_type_id.alignment; ptr_val = target_val; - } else if (target_type->id == ZigTypeIdStruct && target_type->data.structure.is_slice) { + } else if (target_type->id == ZigTypeIdStruct && + target_type->data.structure.special == StructSpecialSlice) + { ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index]->type_entry; align_bytes = get_ptr_align(g, slice_ptr_type); @@ -5290,7 +5292,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst return tmp_struct_ptr; } else if (array_type->id == ZigTypeIdStruct) { - assert(array_type->data.structure.is_slice); + assert(array_type->data.structure.special == StructSpecialSlice); assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind); assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind); assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(tmp_struct_ptr))) == LLVMStructTypeKind); diff --git a/src/dump_analysis.cpp b/src/dump_analysis.cpp index 832035afb2..2b7d7a8bd9 100644 --- a/src/dump_analysis.cpp +++ b/src/dump_analysis.cpp @@ -744,7 +744,7 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) { case ZigTypeIdEnumLiteral: break; case ZigTypeIdStruct: { - if (ty->data.structure.is_slice) { + if (ty->data.structure.special == StructSpecialSlice) { jw_object_field(jw, "len"); jw_int(jw, 2); anal_dump_pointer_attrs(ctx, ty->data.structure.fields[slice_ptr_index]->type_entry); diff --git a/src/ir.cpp b/src/ir.cpp index f9985d602a..fc53e2ecdf 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -724,14 +724,11 @@ static bool is_opt_err_set(ZigType *ty) { } static bool is_tuple(ZigType *type) { - return type->id == ZigTypeIdStruct && type->data.structure.decl_node != nullptr && - type->data.structure.decl_node->type == NodeTypeContainerInitExpr && - (type->data.structure.decl_node->data.container_init_expr.kind == ContainerInitKindArray || - type->data.structure.decl_node->data.container_init_expr.entries.length == 0); + return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialInferredTuple; } static bool is_slice(ZigType *type) { - return type->id == ZigTypeIdStruct && type->data.structure.is_slice; + return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialSlice; } static bool slice_is_const(ZigType *type) { @@ -13928,7 +13925,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst } // cast from inferred struct type to array, union, or struct - if (actual_type->id == ZigTypeIdStruct && actual_type->data.structure.is_inferred) { + if (is_anon_container(actual_type)) { AstNode *decl_node = actual_type->data.structure.decl_node; ir_assert(decl_node->type == NodeTypeContainerInitExpr, source_instr); ContainerInitKind init_kind = decl_node->data.container_init_expr.kind; @@ -17047,10 +17044,17 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct), instruction->base.scope, instruction->base.source_node, bare_name); + StructSpecial struct_special = StructSpecialInferredStruct; + if (instruction->base.source_node->type == NodeTypeContainerInitExpr && + instruction->base.source_node->data.container_init_expr.kind == ContainerInitKindArray) + { + struct_special = StructSpecialInferredTuple; + } + ZigType *inferred_struct_type = get_partial_container_type(ira->codegen, instruction->base.scope, ContainerKindStruct, instruction->base.source_node, buf_ptr(name), bare_name, ContainerLayoutAuto); - inferred_struct_type->data.structure.is_inferred = true; + inferred_struct_type->data.structure.special = struct_special; inferred_struct_type->data.structure.resolve_status = ResolveStatusBeingInferred; implicit_elem_type = inferred_struct_type; } @@ -19570,7 +19574,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction bool is_const = struct_ptr->value->type->data.pointer.is_const; bool is_volatile = struct_ptr->value->type->data.pointer.is_volatile; ZigType *ptr_type; - if (struct_type->data.structure.is_inferred) { + if (is_anon_container(struct_type)) { ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); } else { @@ -22816,7 +22820,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr } case ZigTypeIdStruct: { - if (type_entry->data.structure.is_slice) { + if (type_entry->data.structure.special == StructSpecialSlice) { result = create_ptr_like_type_info(ira, type_entry); if (result == nullptr) return ErrorSemanticAnalyzeFail;