Skip to content

Commit cbce61a

Browse files
committed
better field access of types which have one possible value
* When you do field access of a type which only has one possible value, the result is comptime-known. * StorePtr instructions which operate on pointers to types which only have one possible value, the result is a comptime no-op. closes #1554
1 parent 1066004 commit cbce61a

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

src/ir.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13779,16 +13779,26 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
1377913779
return ir_const_void(ira, source_instr);
1378013780
}
1378113781

13782+
ZigType *child_type = ptr->value.type->data.pointer.child_type;
13783+
1378213784
if (ptr->value.type->data.pointer.is_const && !source_instr->is_gen) {
1378313785
ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
1378413786
return ira->codegen->invalid_instruction;
1378513787
}
1378613788

13787-
ZigType *child_type = ptr->value.type->data.pointer.child_type;
1378813789
IrInstruction *value = ir_implicit_cast(ira, uncasted_value, child_type);
1378913790
if (value == ira->codegen->invalid_instruction)
1379013791
return ira->codegen->invalid_instruction;
1379113792

13793+
switch (type_has_one_possible_value(ira->codegen, child_type)) {
13794+
case OnePossibleValueInvalid:
13795+
return ira->codegen->invalid_instruction;
13796+
case OnePossibleValueYes:
13797+
return ir_const_void(ira, source_instr);
13798+
case OnePossibleValueNo:
13799+
break;
13800+
}
13801+
1379213802
if (instr_is_comptime(ptr) && ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
1379313803
if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst) {
1379413804
ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
@@ -13809,15 +13819,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
1380913819
bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar;
1381013820
copy_const_val(dest_val, &value->value, same_global_refs);
1381113821
if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) {
13812-
switch (type_has_one_possible_value(ira->codegen, child_type)) {
13813-
case OnePossibleValueInvalid:
13814-
return ira->codegen->invalid_instruction;
13815-
case OnePossibleValueNo:
13816-
ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr;
13817-
break;
13818-
case OnePossibleValueYes:
13819-
break;
13820-
}
13822+
ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr;
1382113823
}
1382213824
return ir_const_void(ira, source_instr);
1382313825
}
@@ -15346,6 +15348,16 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
1534615348
if (bare_type->id == ZigTypeIdStruct) {
1534715349
TypeStructField *field = find_struct_type_field(bare_type, field_name);
1534815350
if (field) {
15351+
switch (type_has_one_possible_value(ira->codegen, field->type_entry)) {
15352+
case OnePossibleValueInvalid:
15353+
return ira->codegen->invalid_instruction;
15354+
case OnePossibleValueYes: {
15355+
IrInstruction *elem = ir_const(ira, source_instr, field->type_entry);
15356+
return ir_get_ref(ira, source_instr, elem, false, false);
15357+
}
15358+
case OnePossibleValueNo:
15359+
break;
15360+
}
1534915361
bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked);
1535015362
uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry);
1535115363
uint32_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset_in_host;

test/stage1/behavior/struct.zig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,3 +491,11 @@ test "non-byte-aligned array inside packed struct" {
491491
S.doTheTest();
492492
comptime S.doTheTest();
493493
}
494+
495+
test "packed struct with u0 field access" {
496+
const S = packed struct {
497+
f0: u0,
498+
};
499+
var s = S{ .f0 = 0 };
500+
comptime expect(s.f0 == 0);
501+
}

0 commit comments

Comments
 (0)