@@ -12693,34 +12693,50 @@ static IrInstGen *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInst* sourc
12693
12693
assert(array_ptr->value->type->data.pointer.child_type->id == ZigTypeIdArray);
12694
12694
12695
12695
ZigType *array_type = array_ptr->value->type->data.pointer.child_type;
12696
- const size_t array_len = array_type->data.array.len;
12696
+ size_t array_len = array_type->data.array.len;
12697
12697
12698
12698
// A zero-sized array can be casted regardless of the destination alignment, or
12699
12699
// whether the pointer is undefined, and the result is always comptime known.
12700
- if (array_len == 0) {
12701
- ZigValue *undef_array = ira->codegen->pass1_arena->create<ZigValue>();
12702
- undef_array->special = ConstValSpecialUndef;
12703
- undef_array->type = array_type;
12704
-
12705
- IrInstGen *result = ir_const(ira, source_instr, wanted_type);
12706
- init_const_slice(ira->codegen, result->value, undef_array, 0, 0, false);
12707
- result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutComptimeConst;
12708
- result->value->type = wanted_type;
12709
- return result;
12710
- }
12700
+ // TODO However, this is exposing a result location bug that I failed to solve on the first try.
12701
+ // If you want to try to fix the bug, uncomment this block and get the tests passing.
12702
+ //if (array_len == 0 && array_type->data.array.sentinel == nullptr) {
12703
+ // ZigValue *undef_array = ira->codegen->pass1_arena->create<ZigValue>();
12704
+ // undef_array->special = ConstValSpecialUndef;
12705
+ // undef_array->type = array_type;
12706
+
12707
+ // IrInstGen *result = ir_const(ira, source_instr, wanted_type);
12708
+ // init_const_slice(ira->codegen, result->value, undef_array, 0, 0, false);
12709
+ // result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutComptimeConst;
12710
+ // result->value->type = wanted_type;
12711
+ // return result;
12712
+ //}
12711
12713
12712
12714
if ((err = type_resolve(ira->codegen, array_ptr->value->type, ResolveStatusAlignmentKnown))) {
12713
12715
return ira->codegen->invalid_inst_gen;
12714
12716
}
12715
12717
12716
- wanted_type = adjust_slice_align(ira->codegen, wanted_type,
12717
- get_ptr_align(ira->codegen, array_ptr->value->type));
12718
+ if (array_len != 0) {
12719
+ wanted_type = adjust_slice_align(ira->codegen, wanted_type,
12720
+ get_ptr_align(ira->codegen, array_ptr->value->type));
12721
+ }
12718
12722
12719
12723
if (instr_is_comptime(array_ptr)) {
12720
- ZigValue *array_ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);
12724
+ UndefAllowed undef_allowed = (array_len == 0) ? UndefOk : UndefBad;
12725
+ ZigValue *array_ptr_val = ir_resolve_const(ira, array_ptr, undef_allowed);
12721
12726
if (array_ptr_val == nullptr)
12722
12727
return ira->codegen->invalid_inst_gen;
12723
12728
ir_assert(is_slice(wanted_type), source_instr);
12729
+ if (array_ptr_val->special == ConstValSpecialUndef) {
12730
+ ZigValue *undef_array = ira->codegen->pass1_arena->create<ZigValue>();
12731
+ undef_array->special = ConstValSpecialUndef;
12732
+ undef_array->type = array_type;
12733
+
12734
+ IrInstGen *result = ir_const(ira, source_instr, wanted_type);
12735
+ init_const_slice(ira->codegen, result->value, undef_array, 0, 0, false);
12736
+ result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutComptimeConst;
12737
+ result->value->type = wanted_type;
12738
+ return result;
12739
+ }
12724
12740
bool wanted_const = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const;
12725
12741
// Optimization to avoid creating unnecessary ZigValue in const_ptr_pointee
12726
12742
if (array_ptr_val->data.x_ptr.special == ConstPtrSpecialSubArray) {
@@ -26319,18 +26335,13 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
26319
26335
// then the pointer-to-array would be casted to a slice anyway. So, we preserve the laziness of these
26320
26336
// values by making the return type a slice.
26321
26337
ZigType *res_loc_type = get_result_loc_type(ira, instruction->result_loc);
26322
-
26323
- if ((res_loc_type == nullptr || !is_slice(res_loc_type)) &&
26324
- value_is_comptime(casted_start->value) &&
26338
+ bool result_loc_is_slice = (res_loc_type != nullptr && is_slice(res_loc_type));
26339
+ bool end_is_known = !result_loc_is_slice &&
26325
26340
((end != nullptr && value_is_comptime(end->value)) ||
26326
- (end == nullptr && child_array_type->id == ZigTypeIdArray)))
26327
- {
26328
- ZigValue *start_val = ir_resolve_const(ira, casted_start, UndefBad);
26329
- if (!start_val)
26330
- return ira->codegen->invalid_inst_gen;
26331
-
26332
- uint64_t start_scalar = bigint_as_u64(&start_val->data.x_bigint);
26341
+ (end == nullptr && child_array_type->id == ZigTypeIdArray));
26333
26342
26343
+ ZigValue *array_sentinel = sentinel_val;
26344
+ if (end_is_known) {
26334
26345
uint64_t end_scalar;
26335
26346
if (end != nullptr) {
26336
26347
ZigValue *end_val = ir_resolve_const(ira, end, UndefBad);
@@ -26340,36 +26351,46 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
26340
26351
} else {
26341
26352
end_scalar = child_array_type->data.array.len;
26342
26353
}
26343
- ZigValue *array_sentinel = (child_array_type->id == ZigTypeIdArray &&
26344
- end_scalar == child_array_type->data.array.len)
26345
- ? child_array_type->data.array.sentinel : nullptr;
26354
+ array_sentinel = (child_array_type->id == ZigTypeIdArray && end_scalar == child_array_type->data.array.len)
26355
+ ? child_array_type->data.array.sentinel : sentinel_val;
26346
26356
26347
- if (start_scalar > end_scalar ) {
26348
- ir_add_error (ira, &instruction->base.base, buf_sprintf("out of bounds slice") );
26349
- return ira->codegen->invalid_inst_gen;
26350
- }
26357
+ if (value_is_comptime(casted_start->value) ) {
26358
+ ZigValue *start_val = ir_resolve_const (ira, casted_start, UndefBad );
26359
+ if (!start_val)
26360
+ return ira->codegen->invalid_inst_gen;
26351
26361
26352
- uint32_t base_ptr_align = non_sentinel_slice_ptr_type ->data.pointer.explicit_alignment ;
26353
- uint32_t ptr_byte_alignment = 0;
26354
- if (end_scalar > start_scalar ) {
26355
- if ((err = compute_elem_align (ira, elem_type, base_ptr_align, start_scalar, &ptr_byte_alignment)))
26362
+ uint64_t start_scalar = bigint_as_u64(&start_val ->data.x_bigint) ;
26363
+
26364
+ if (start_scalar > end_scalar ) {
26365
+ ir_add_error (ira, &instruction->base.base, buf_sprintf("out of bounds slice"));
26356
26366
return ira->codegen->invalid_inst_gen;
26357
- }
26367
+ }
26368
+
26369
+ uint32_t base_ptr_align = non_sentinel_slice_ptr_type->data.pointer.explicit_alignment;
26370
+ uint32_t ptr_byte_alignment = 0;
26371
+ if (end_scalar > start_scalar) {
26372
+ if ((err = compute_elem_align(ira, elem_type, base_ptr_align, start_scalar, &ptr_byte_alignment)))
26373
+ return ira->codegen->invalid_inst_gen;
26374
+ }
26358
26375
26359
- ZigType *return_array_type = get_array_type(ira->codegen, elem_type, end_scalar - start_scalar,
26360
- array_sentinel);
26361
- return_type = get_pointer_to_type_extra(ira->codegen, return_array_type,
26362
- non_sentinel_slice_ptr_type->data.pointer.is_const,
26363
- non_sentinel_slice_ptr_type->data.pointer.is_volatile,
26364
- PtrLenSingle, ptr_byte_alignment, 0, 0, false);
26365
- } else if (sentinel_val != nullptr) {
26376
+ ZigType *return_array_type = get_array_type(ira->codegen, elem_type, end_scalar - start_scalar,
26377
+ array_sentinel);
26378
+ return_type = get_pointer_to_type_extra(ira->codegen, return_array_type,
26379
+ non_sentinel_slice_ptr_type->data.pointer.is_const,
26380
+ non_sentinel_slice_ptr_type->data.pointer.is_volatile,
26381
+ PtrLenSingle, ptr_byte_alignment, 0, 0, false);
26382
+ goto done_with_return_type;
26383
+ }
26384
+ }
26385
+ if (array_sentinel != nullptr) {
26366
26386
// TODO deal with non-abi-alignment here
26367
- ZigType *slice_ptr_type = adjust_ptr_sentinel(ira->codegen, non_sentinel_slice_ptr_type, sentinel_val );
26387
+ ZigType *slice_ptr_type = adjust_ptr_sentinel(ira->codegen, non_sentinel_slice_ptr_type, array_sentinel );
26368
26388
return_type = get_slice_type(ira->codegen, slice_ptr_type);
26369
26389
} else {
26370
26390
// TODO deal with non-abi-alignment here
26371
26391
return_type = get_slice_type(ira->codegen, non_sentinel_slice_ptr_type);
26372
26392
}
26393
+ done_with_return_type:
26373
26394
26374
26395
if (instr_is_comptime(ptr_ptr) &&
26375
26396
value_is_comptime(casted_start->value) &&
0 commit comments