| ... | ... | @@ -398,7 +398,6 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type |
| 398 | 398 | |
| 399 | 399 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer); |
| 400 | 400 | entry->is_copyable = true; |
| 401 | | entry->can_mutate_state_through_it = is_const ? child_type->can_mutate_state_through_it : true; |
| 402 | 401 | |
| 403 | 402 | const char *const_str = is_const ? "const " : ""; |
| 404 | 403 | const char *volatile_str = is_volatile ? "volatile " : ""; |
| ... | ... | @@ -483,7 +482,6 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) { |
| 483 | 482 | assert(child_type->type_ref || child_type->zero_bits); |
| 484 | 483 | assert(child_type->di_type); |
| 485 | 484 | entry->is_copyable = type_is_copyable(g, child_type); |
| 486 | | entry->can_mutate_state_through_it = child_type->can_mutate_state_through_it; |
| 487 | 485 | |
| 488 | 486 | buf_resize(&entry->name, 0); |
| 489 | 487 | buf_appendf(&entry->name, "?%s", buf_ptr(&child_type->name)); |
| ... | ... | @@ -574,7 +572,6 @@ TypeTableEntry *get_error_union_type(CodeGen *g, TypeTableEntry *err_set_type, T |
| 574 | 572 | entry->is_copyable = true; |
| 575 | 573 | assert(payload_type->di_type); |
| 576 | 574 | ensure_complete_type(g, payload_type); |
| 577 | | entry->can_mutate_state_through_it = payload_type->can_mutate_state_through_it; |
| 578 | 575 | |
| 579 | 576 | buf_resize(&entry->name, 0); |
| 580 | 577 | buf_appendf(&entry->name, "%s!%s", buf_ptr(&err_set_type->name), buf_ptr(&payload_type->name)); |
| ... | ... | @@ -733,7 +730,6 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *ptr_type) { |
| 733 | 730 | |
| 734 | 731 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct); |
| 735 | 732 | entry->is_copyable = true; |
| 736 | | entry->can_mutate_state_through_it = ptr_type->can_mutate_state_through_it; |
| 737 | 733 | |
| 738 | 734 | // replace the & with [] to go from a ptr type name to a slice type name |
| 739 | 735 | buf_resize(&entry->name, 0); |
| ... | ... | @@ -1739,8 +1735,6 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f |
| 1739 | 1735 | struct_type->data.structure.gen_field_count += 1; |
| 1740 | 1736 | } else { |
| 1741 | 1737 | field->gen_index = SIZE_MAX; |
| 1742 | | struct_type->can_mutate_state_through_it = struct_type->can_mutate_state_through_it || |
| 1743 | | field->type_entry->can_mutate_state_through_it; |
| 1744 | 1738 | } |
| 1745 | 1739 | |
| 1746 | 1740 | auto prev_entry = struct_type->data.structure.fields_by_name.put_unique(field->name, field); |
| ... | ... | @@ -2481,9 +2475,6 @@ static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type) { |
| 2481 | 2475 | if (!type_has_bits(field_type)) |
| 2482 | 2476 | continue; |
| 2483 | 2477 | |
| 2484 | | struct_type->can_mutate_state_through_it = struct_type->can_mutate_state_through_it || |
| 2485 | | field_type->can_mutate_state_through_it; |
| 2486 | | |
| 2487 | 2478 | if (gen_field_index == 0) { |
| 2488 | 2479 | if (struct_type->data.structure.layout == ContainerLayoutPacked) { |
| 2489 | 2480 | struct_type->data.structure.abi_alignment = 1; |
| ... | ... | @@ -2671,8 +2662,6 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) { |
| 2671 | 2662 | } |
| 2672 | 2663 | } |
| 2673 | 2664 | union_field->type_entry = field_type; |
| 2674 | | union_type->can_mutate_state_through_it = union_type->can_mutate_state_through_it || |
| 2675 | | field_type->can_mutate_state_through_it; |
| 2676 | 2665 | |
| 2677 | 2666 | if (field_node->data.struct_field.value != nullptr && !decl_node->data.container_decl.auto_enum) { |
| 2678 | 2667 | ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.value, |
| ... | ... | @@ -4576,11 +4565,77 @@ bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) { |
| 4576 | 4565 | return true; |
| 4577 | 4566 | } |
| 4578 | 4567 | |
| 4568 | static bool can_mutate_comptime_var_state(ConstExprValue *value) { |
| 4569 | assert(value != nullptr); |
| 4570 | switch (value->type->id) { |
| 4571 | case TypeTableEntryIdInvalid: |
| 4572 | zig_unreachable(); |
| 4573 | case TypeTableEntryIdMetaType: |
| 4574 | case TypeTableEntryIdVoid: |
| 4575 | case TypeTableEntryIdBool: |
| 4576 | case TypeTableEntryIdUnreachable: |
| 4577 | case TypeTableEntryIdInt: |
| 4578 | case TypeTableEntryIdFloat: |
| 4579 | case TypeTableEntryIdNumLitFloat: |
| 4580 | case TypeTableEntryIdNumLitInt: |
| 4581 | case TypeTableEntryIdUndefLit: |
| 4582 | case TypeTableEntryIdNullLit: |
| 4583 | case TypeTableEntryIdNamespace: |
| 4584 | case TypeTableEntryIdBoundFn: |
| 4585 | case TypeTableEntryIdFn: |
| 4586 | case TypeTableEntryIdBlock: |
| 4587 | case TypeTableEntryIdOpaque: |
| 4588 | case TypeTableEntryIdPromise: |
| 4589 | case TypeTableEntryIdErrorSet: |
| 4590 | case TypeTableEntryIdEnum: |
| 4591 | return false; |
| 4592 | |
| 4593 | case TypeTableEntryIdPointer: |
| 4594 | return value->data.x_ptr.mut == ConstPtrMutComptimeVar; |
| 4595 | |
| 4596 | case TypeTableEntryIdArray: |
| 4597 | if (value->type->data.array.len == 0) |
| 4598 | return false; |
| 4599 | if (value->data.x_array.special == ConstArraySpecialUndef) |
| 4600 | return false; |
| 4601 | for (uint32_t i = 0; i < value->type->data.array.len; i += 1) { |
| 4602 | if (can_mutate_comptime_var_state(&value->data.x_array.s_none.elements[i])) |
| 4603 | return true; |
| 4604 | } |
| 4605 | return false; |
| 4606 | |
| 4607 | case TypeTableEntryIdStruct: |
| 4608 | for (uint32_t i = 0; i < value->type->data.structure.src_field_count; i += 1) { |
| 4609 | if (can_mutate_comptime_var_state(&value->data.x_struct.fields[i])) |
| 4610 | return true; |
| 4611 | } |
| 4612 | return false; |
| 4613 | |
| 4614 | case TypeTableEntryIdMaybe: |
| 4615 | if (value->data.x_maybe == nullptr) |
| 4616 | return false; |
| 4617 | return can_mutate_comptime_var_state(value->data.x_maybe); |
| 4618 | |
| 4619 | case TypeTableEntryIdErrorUnion: |
| 4620 | if (value->data.x_err_union.err != nullptr) |
| 4621 | return false; |
| 4622 | assert(value->data.x_err_union.payload != nullptr); |
| 4623 | return can_mutate_comptime_var_state(value->data.x_err_union.payload); |
| 4624 | |
| 4625 | case TypeTableEntryIdUnion: |
| 4626 | return can_mutate_comptime_var_state(value->data.x_union.payload); |
| 4627 | |
| 4628 | case TypeTableEntryIdArgTuple: |
| 4629 | zig_panic("TODO var args at comptime is currently not supported"); |
| 4630 | } |
| 4631 | zig_unreachable(); |
| 4632 | } |
| 4633 | |
| 4579 | 4634 | bool fn_eval_cacheable(Scope *scope) { |
| 4580 | 4635 | while (scope) { |
| 4581 | 4636 | if (scope->id == ScopeIdVarDecl) { |
| 4582 | 4637 | ScopeVarDecl *var_scope = (ScopeVarDecl *)scope; |
| 4583 | | if (var_scope->var->value->type->can_mutate_state_through_it) |
| 4638 | if (can_mutate_comptime_var_state(var_scope->var->value)) |
| 4584 | 4639 | return false; |
| 4585 | 4640 | } else if (scope->id == ScopeIdFnDef) { |
| 4586 | 4641 | return true; |