| ... | ... | @@ -14874,6 +14874,16 @@ static bool type_can_bit_cast(ZigType *t) { |
| 14874 | 14874 | } |
| 14875 | 14875 | } |
| 14876 | 14876 | |
| 14877 | static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) { |
| 14878 | ConstExprValue *undef_child = create_const_vals(1); |
| 14879 | undef_child->type = ptr->value.type->data.pointer.child_type; |
| 14880 | undef_child->special = ConstValSpecialUndef; |
| 14881 | ptr->value.special = ConstValSpecialStatic; |
| 14882 | ptr->value.data.x_ptr.mut = ConstPtrMutInfer; |
| 14883 | ptr->value.data.x_ptr.special = ConstPtrSpecialRef; |
| 14884 | ptr->value.data.x_ptr.data.ref.pointee = undef_child; |
| 14885 | } |
| 14886 | |
| 14877 | 14887 | // when calling this function, at the callsite must check for result type noreturn and propagate it up |
| 14878 | 14888 | static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| 14879 | 14889 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value) |
| ... | ... | @@ -14901,6 +14911,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 14901 | 14911 | return ira->codegen->invalid_instruction; |
| 14902 | 14912 | alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false, |
| 14903 | 14913 | PtrLenSingle, 0, 0, 0, false); |
| 14914 | set_up_result_loc_for_inferred_comptime(&alloca_gen->base); |
| 14904 | 14915 | ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 14905 | 14916 | if (fn_entry != nullptr) { |
| 14906 | 14917 | fn_entry->alloca_gen_list.append(alloca_gen); |
| ... | ... | @@ -14958,6 +14969,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 14958 | 14969 | ZigType *ptr_return_type = get_pointer_to_type(ira->codegen, ira->explicit_return_type, false); |
| 14959 | 14970 | result_loc->written = true; |
| 14960 | 14971 | result_loc->resolved_loc = ir_build_return_ptr(ira, result_loc->source_instruction, ptr_return_type); |
| 14972 | set_up_result_loc_for_inferred_comptime(result_loc->resolved_loc); |
| 14961 | 14973 | return result_loc->resolved_loc; |
| 14962 | 14974 | } |
| 14963 | 14975 | case ResultLocIdPeer: { |
| ... | ... | @@ -15132,7 +15144,6 @@ static void ir_reset_result(ResultLoc *result_loc) { |
| 15132 | 15144 | result_loc->resolved_loc = nullptr; |
| 15133 | 15145 | result_loc->gen_instruction = nullptr; |
| 15134 | 15146 | result_loc->implicit_elem_type = nullptr; |
| 15135 | | // TODO handle result_loc->scope_elide = |
| 15136 | 15147 | switch (result_loc->id) { |
| 15137 | 15148 | case ResultLocIdInvalid: |
| 15138 | 15149 | zig_unreachable(); |
| ... | ... | @@ -18289,27 +18300,77 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr |
| 18289 | 18300 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, |
| 18290 | 18301 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 18291 | 18302 | |
| 18303 | bool same_comptime_repr = types_have_same_zig_comptime_repr(type_entry, child_type); |
| 18304 | |
| 18292 | 18305 | if (instr_is_comptime(base_ptr)) { |
| 18293 | | ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 18294 | | if (!val) |
| 18306 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 18307 | if (!ptr_val) |
| 18295 | 18308 | return ira->codegen->invalid_instruction; |
| 18296 | | if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 18297 | | ConstExprValue *maybe_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); |
| 18298 | | if (maybe_val == nullptr) |
| 18309 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 18310 | ConstExprValue *optional_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 18311 | if (optional_val == nullptr) |
| 18299 | 18312 | return ira->codegen->invalid_instruction; |
| 18300 | 18313 | |
| 18301 | | if (optional_value_is_null(maybe_val)) { |
| 18314 | if (initializing && optional_val->special == ConstValSpecialUndef) { |
| 18315 | switch (type_has_one_possible_value(ira->codegen, child_type)) { |
| 18316 | case OnePossibleValueInvalid: |
| 18317 | return ira->codegen->invalid_instruction; |
| 18318 | case OnePossibleValueNo: |
| 18319 | if (!same_comptime_repr) { |
| 18320 | ConstExprValue *payload_val = create_const_vals(1); |
| 18321 | payload_val->type = child_type; |
| 18322 | payload_val->special = ConstValSpecialUndef; |
| 18323 | payload_val->parent.id = ConstParentIdOptionalPayload; |
| 18324 | payload_val->parent.data.p_optional_payload.optional_val = optional_val; |
| 18325 | |
| 18326 | optional_val->data.x_optional = payload_val; |
| 18327 | optional_val->special = ConstValSpecialStatic; |
| 18328 | } |
| 18329 | break; |
| 18330 | case OnePossibleValueYes: { |
| 18331 | ConstExprValue *pointee = create_const_vals(1); |
| 18332 | pointee->special = ConstValSpecialStatic; |
| 18333 | pointee->type = child_type; |
| 18334 | pointee->parent.id = ConstParentIdOptionalPayload; |
| 18335 | pointee->parent.data.p_optional_payload.optional_val = optional_val; |
| 18336 | |
| 18337 | optional_val->special = ConstValSpecialStatic; |
| 18338 | optional_val->data.x_optional = pointee; |
| 18339 | break; |
| 18340 | } |
| 18341 | } |
| 18342 | } else if (optional_value_is_null(optional_val)) { |
| 18302 | 18343 | ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); |
| 18303 | 18344 | return ira->codegen->invalid_instruction; |
| 18304 | 18345 | } |
| 18305 | | IrInstruction *result = ir_const(ira, source_instr, result_type); |
| 18306 | | ConstExprValue *out_val = &result->value; |
| 18307 | | out_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 18308 | | out_val->data.x_ptr.mut = val->data.x_ptr.mut; |
| 18309 | | if (types_have_same_zig_comptime_repr(type_entry, child_type)) { |
| 18310 | | out_val->data.x_ptr.data.ref.pointee = maybe_val; |
| 18346 | |
| 18347 | IrInstruction *result; |
| 18348 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 18349 | result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope, |
| 18350 | source_instr->source_node, base_ptr, false, initializing); |
| 18351 | result->value.type = result_type; |
| 18352 | result->value.special = ConstValSpecialStatic; |
| 18311 | 18353 | } else { |
| 18312 | | out_val->data.x_ptr.data.ref.pointee = maybe_val->data.x_optional; |
| 18354 | result = ir_const(ira, source_instr, result_type); |
| 18355 | } |
| 18356 | ConstExprValue *result_val = &result->value; |
| 18357 | result_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 18358 | result_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| 18359 | switch (type_has_one_possible_value(ira->codegen, child_type)) { |
| 18360 | case OnePossibleValueInvalid: |
| 18361 | return ira->codegen->invalid_instruction; |
| 18362 | case OnePossibleValueNo: |
| 18363 | if (same_comptime_repr) { |
| 18364 | result_val->data.x_ptr.data.ref.pointee = optional_val; |
| 18365 | } else { |
| 18366 | assert(optional_val->data.x_optional != nullptr); |
| 18367 | result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; |
| 18368 | } |
| 18369 | break; |
| 18370 | case OnePossibleValueYes: |
| 18371 | assert(optional_val->data.x_optional != nullptr); |
| 18372 | result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; |
| 18373 | break; |
| 18313 | 18374 | } |
| 18314 | 18375 | return result; |
| 18315 | 18376 | } |
| ... | ... | @@ -22409,10 +22470,16 @@ static IrInstruction *ir_analyze_instruction_result_ptr(IrAnalyze *ira, IrInstru |
| 22409 | 22470 | !instr_is_comptime(result)) |
| 22410 | 22471 | { |
| 22411 | 22472 | IrInstruction *result_ptr = instruction->result_loc->resolved_loc; |
| 22412 | | // Convert the pointer to the result type. They should be the same, except this will resolve |
| 22413 | | // inferred error sets. |
| 22414 | | ZigType *new_ptr_type = get_pointer_to_type(ira->codegen, result->value.type, true); |
| 22415 | | return ir_analyze_ptr_cast(ira, &instruction->base, result_ptr, new_ptr_type, &instruction->base, false); |
| 22473 | if (result->value.type->id == ZigTypeIdErrorUnion && |
| 22474 | result_ptr->value.type->data.pointer.child_type->id == ZigTypeIdErrorUnion) |
| 22475 | { |
| 22476 | // Convert the pointer to the result type. They should be the same, except this will resolve |
| 22477 | // inferred error sets. |
| 22478 | ZigType *new_ptr_type = get_pointer_to_type(ira->codegen, result->value.type, true); |
| 22479 | return ir_analyze_ptr_cast(ira, &instruction->base, result_ptr, new_ptr_type, &instruction->base, false); |
| 22480 | } else { |
| 22481 | return result_ptr; |
| 22482 | } |
| 22416 | 22483 | } |
| 22417 | 22484 | return ir_get_ref(ira, &instruction->base, result, true, false); |
| 22418 | 22485 | } |
| ... | ... | @@ -22465,7 +22532,6 @@ static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction * |
| 22465 | 22532 | |
| 22466 | 22533 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. |
| 22467 | 22534 | assert(ptr_type->id == ZigTypeIdPointer); |
| 22468 | | bool is_ptr_const = ptr_type->data.pointer.is_const; |
| 22469 | 22535 | |
| 22470 | 22536 | ZigType *type_entry = ptr_type->data.pointer.child_type; |
| 22471 | 22537 | if (type_is_invalid(type_entry)) |
| ... | ... | @@ -22477,31 +22543,63 @@ static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction * |
| 22477 | 22543 | return ira->codegen->invalid_instruction; |
| 22478 | 22544 | } |
| 22479 | 22545 | |
| 22546 | ZigType *err_set_type = type_entry->data.error_union.err_set_type; |
| 22547 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, err_set_type, |
| 22548 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, |
| 22549 | ptr_type->data.pointer.explicit_alignment, 0, 0, false); |
| 22550 | |
| 22480 | 22551 | if (instr_is_comptime(base_ptr)) { |
| 22481 | 22552 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); |
| 22482 | 22553 | if (!ptr_val) |
| 22483 | 22554 | return ira->codegen->invalid_instruction; |
| 22484 | | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 22555 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar && |
| 22556 | ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) |
| 22557 | { |
| 22485 | 22558 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 22486 | 22559 | if (err_union_val == nullptr) |
| 22487 | 22560 | return ira->codegen->invalid_instruction; |
| 22488 | | if (err_union_val->special != ConstValSpecialRuntime) { |
| 22489 | | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; |
| 22490 | | assert(err != nullptr); |
| 22491 | 22561 | |
| 22492 | | IrInstruction *err_set_val = ir_const(ira, source_instr, type_entry->data.error_union.err_set_type); |
| 22493 | | err_set_val->value.data.x_err_set = err; |
| 22494 | | err_set_val->value.parent.id = ConstParentIdErrUnionCode; |
| 22495 | | err_set_val->value.parent.data.p_err_union_code.err_union_val = err_union_val; |
| 22562 | if (initializing && err_union_val->special == ConstValSpecialUndef) { |
| 22563 | ConstExprValue *vals = create_const_vals(2); |
| 22564 | ConstExprValue *err_set_val = &vals[0]; |
| 22565 | ConstExprValue *payload_val = &vals[1]; |
| 22496 | 22566 | |
| 22497 | | return ir_get_ref(ira, source_instr, err_set_val, is_ptr_const, false); |
| 22567 | err_set_val->special = ConstValSpecialUndef; |
| 22568 | err_set_val->type = err_set_type; |
| 22569 | err_set_val->parent.id = ConstParentIdErrUnionCode; |
| 22570 | err_set_val->parent.data.p_err_union_code.err_union_val = err_union_val; |
| 22571 | |
| 22572 | payload_val->special = ConstValSpecialUndef; |
| 22573 | payload_val->type = type_entry->data.error_union.payload_type; |
| 22574 | payload_val->parent.id = ConstParentIdErrUnionPayload; |
| 22575 | payload_val->parent.data.p_err_union_payload.err_union_val = err_union_val; |
| 22576 | |
| 22577 | err_union_val->special = ConstValSpecialStatic; |
| 22578 | err_union_val->data.x_err_union.error_set = err_set_val; |
| 22579 | err_union_val->data.x_err_union.payload = payload_val; |
| 22580 | } |
| 22581 | ir_assert(err_union_val->special != ConstValSpecialRuntime, source_instr); |
| 22582 | |
| 22583 | IrInstruction *result; |
| 22584 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 22585 | result = ir_build_unwrap_err_code(&ira->new_irb, source_instr->scope, |
| 22586 | source_instr->source_node, base_ptr); |
| 22587 | result->value.type = result_type; |
| 22588 | result->value.special = ConstValSpecialStatic; |
| 22589 | } else { |
| 22590 | result = ir_const(ira, source_instr, result_type); |
| 22498 | 22591 | } |
| 22592 | ConstExprValue *const_val = &result->value; |
| 22593 | const_val->data.x_ptr.special = ConstPtrSpecialBaseErrorUnionCode; |
| 22594 | const_val->data.x_ptr.data.base_err_union_code.err_union_val = err_union_val; |
| 22595 | const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| 22596 | return result; |
| 22499 | 22597 | } |
| 22500 | 22598 | } |
| 22501 | 22599 | |
| 22502 | 22600 | IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb, |
| 22503 | 22601 | source_instr->scope, source_instr->source_node, base_ptr); |
| 22504 | | result->value.type = get_pointer_to_type(ira->codegen, type_entry->data.error_union.err_set_type, is_ptr_const); |
| 22602 | result->value.type = result_type; |
| 22505 | 22603 | return result; |
| 22506 | 22604 | } |
| 22507 | 22605 | |
| ... | ... | @@ -22547,6 +22645,23 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct |
| 22547 | 22645 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 22548 | 22646 | if (err_union_val == nullptr) |
| 22549 | 22647 | return ira->codegen->invalid_instruction; |
| 22648 | if (err_union_val->special == ConstValSpecialUndef && initializing) { |
| 22649 | ConstExprValue *vals = create_const_vals(2); |
| 22650 | ConstExprValue *err_set_val = &vals[0]; |
| 22651 | ConstExprValue *payload_val = &vals[1]; |
| 22652 | |
| 22653 | err_set_val->special = ConstValSpecialStatic; |
| 22654 | err_set_val->type = type_entry->data.error_union.err_set_type; |
| 22655 | err_set_val->data.x_err_set = nullptr; |
| 22656 | |
| 22657 | payload_val->special = ConstValSpecialUndef; |
| 22658 | payload_val->type = payload_type; |
| 22659 | |
| 22660 | err_union_val->special = ConstValSpecialStatic; |
| 22661 | err_union_val->data.x_err_union.error_set = err_set_val; |
| 22662 | err_union_val->data.x_err_union.payload = payload_val; |
| 22663 | } |
| 22664 | |
| 22550 | 22665 | if (err_union_val->special != ConstValSpecialRuntime) { |
| 22551 | 22666 | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; |
| 22552 | 22667 | if (err != nullptr) { |
| ... | ... | @@ -22555,9 +22670,18 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct |
| 22555 | 22670 | return ira->codegen->invalid_instruction; |
| 22556 | 22671 | } |
| 22557 | 22672 | |
| 22558 | | IrInstruction *result = ir_const(ira, source_instr, result_type); |
| 22673 | IrInstruction *result; |
| 22674 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 22675 | result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope, |
| 22676 | source_instr->source_node, base_ptr, safety_check_on, initializing); |
| 22677 | result->value.type = result_type; |
| 22678 | result->value.special = ConstValSpecialStatic; |
| 22679 | } else { |
| 22680 | result = ir_const(ira, source_instr, result_type); |
| 22681 | } |
| 22559 | 22682 | result->value.data.x_ptr.special = ConstPtrSpecialRef; |
| 22560 | 22683 | result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; |
| 22684 | result->value.data.x_ptr.mut = ptr_val->data.x_ptr.mut; |
| 22561 | 22685 | return result; |
| 22562 | 22686 | } |
| 22563 | 22687 | } |
| ... | ... | @@ -23162,6 +23286,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 23162 | 23286 | case ZigTypeIdUndefined: |
| 23163 | 23287 | case ZigTypeIdNull: |
| 23164 | 23288 | case ZigTypeIdPromise: |
| 23289 | case ZigTypeIdErrorUnion: |
| 23290 | case ZigTypeIdErrorSet: |
| 23165 | 23291 | zig_unreachable(); |
| 23166 | 23292 | case ZigTypeIdVoid: |
| 23167 | 23293 | return; |
| ... | ... | @@ -23265,10 +23391,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 23265 | 23391 | } |
| 23266 | 23392 | case ZigTypeIdOptional: |
| 23267 | 23393 | zig_panic("TODO buf_write_value_bytes maybe type"); |
| 23268 | | case ZigTypeIdErrorUnion: |
| 23269 | | zig_panic("TODO buf_write_value_bytes error union"); |
| 23270 | | case ZigTypeIdErrorSet: |
| 23271 | | zig_panic("TODO buf_write_value_bytes pure error type"); |
| 23272 | 23394 | case ZigTypeIdFn: |
| 23273 | 23395 | zig_panic("TODO buf_write_value_bytes fn type"); |
| 23274 | 23396 | case ZigTypeIdUnion: |
| ... | ... | @@ -24502,24 +24624,24 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct |
| 24502 | 24624 | if (type_is_invalid(value->value.type)) |
| 24503 | 24625 | return ira->codegen->invalid_instruction; |
| 24504 | 24626 | |
| 24505 | | bool want_resolve_result = !instruction->result_loc->written; |
| 24506 | | if (want_resolve_result) { |
| 24507 | | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 24508 | | value->value.type, value, false); |
| 24509 | | if (result_loc != nullptr) { |
| 24510 | | if (type_is_invalid(result_loc->value.type)) |
| 24511 | | return ira->codegen->invalid_instruction; |
| 24512 | | if (result_loc->value.type->id == ZigTypeIdUnreachable) |
| 24513 | | return result_loc; |
| 24627 | bool was_written = instruction->result_loc->written; |
| 24628 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 24629 | value->value.type, value, false); |
| 24630 | if (result_loc != nullptr) { |
| 24631 | if (type_is_invalid(result_loc->value.type)) |
| 24632 | return ira->codegen->invalid_instruction; |
| 24633 | if (result_loc->value.type->id == ZigTypeIdUnreachable) |
| 24634 | return result_loc; |
| 24514 | 24635 | |
| 24515 | | instruction->result_loc->written = true; |
| 24636 | if (!was_written) { |
| 24516 | 24637 | ir_analyze_store_ptr(ira, &instruction->base, result_loc, value); |
| 24517 | | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 24518 | | if (instr_is_comptime(value)) { |
| 24519 | | result_loc->value.data.x_ptr.mut = ConstPtrMutComptimeConst; |
| 24520 | | } else { |
| 24521 | | result_loc->value.special = ConstValSpecialRuntime; |
| 24522 | | } |
| 24638 | } |
| 24639 | |
| 24640 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 24641 | if (instr_is_comptime(value)) { |
| 24642 | result_loc->value.data.x_ptr.mut = ConstPtrMutComptimeConst; |
| 24643 | } else { |
| 24644 | result_loc->value.special = ConstValSpecialRuntime; |
| 24523 | 24645 | } |
| 24524 | 24646 | } |
| 24525 | 24647 | } |