Commit 6504c5098e

Andrew Kelley <andrew@ziglang.org>
2019-12-09 00:39:52
tuple detection does not require AST node
1 parent d5e7880
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 {
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);
+}
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
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);
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);
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;