more miscellaneous fixes

when will it end
This commit is contained in:
Andrew Kelley 2019-06-18 14:30:17 -04:00
parent fdc6e0af05
commit 077f9df15b
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9

View File

@ -14874,6 +14874,16 @@ static bool type_can_bit_cast(ZigType *t) {
}
}
static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) {
ConstExprValue *undef_child = create_const_vals(1);
undef_child->type = ptr->value.type->data.pointer.child_type;
undef_child->special = ConstValSpecialUndef;
ptr->value.special = ConstValSpecialStatic;
ptr->value.data.x_ptr.mut = ConstPtrMutInfer;
ptr->value.data.x_ptr.special = ConstPtrSpecialRef;
ptr->value.data.x_ptr.data.ref.pointee = undef_child;
}
// when calling this function, at the callsite must check for result type noreturn and propagate it up
static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr,
ResultLoc *result_loc, ZigType *value_type, IrInstruction *value)
@ -14901,6 +14911,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
return ira->codegen->invalid_instruction;
alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false,
PtrLenSingle, 0, 0, 0, false);
set_up_result_loc_for_inferred_comptime(&alloca_gen->base);
ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
if (fn_entry != nullptr) {
fn_entry->alloca_gen_list.append(alloca_gen);
@ -14958,6 +14969,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
ZigType *ptr_return_type = get_pointer_to_type(ira->codegen, ira->explicit_return_type, false);
result_loc->written = true;
result_loc->resolved_loc = ir_build_return_ptr(ira, result_loc->source_instruction, ptr_return_type);
set_up_result_loc_for_inferred_comptime(result_loc->resolved_loc);
return result_loc->resolved_loc;
}
case ResultLocIdPeer: {
@ -15132,7 +15144,6 @@ static void ir_reset_result(ResultLoc *result_loc) {
result_loc->resolved_loc = nullptr;
result_loc->gen_instruction = nullptr;
result_loc->implicit_elem_type = nullptr;
// TODO handle result_loc->scope_elide =
switch (result_loc->id) {
case ResultLocIdInvalid:
zig_unreachable();
@ -18289,27 +18300,77 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr
ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type,
ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false);
bool same_comptime_repr = types_have_same_zig_comptime_repr(type_entry, child_type);
if (instr_is_comptime(base_ptr)) {
ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad);
if (!val)
ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad);
if (!ptr_val)
return ira->codegen->invalid_instruction;
if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
ConstExprValue *maybe_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node);
if (maybe_val == nullptr)
if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
ConstExprValue *optional_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
if (optional_val == nullptr)
return ira->codegen->invalid_instruction;
if (optional_value_is_null(maybe_val)) {
if (initializing && optional_val->special == ConstValSpecialUndef) {
switch (type_has_one_possible_value(ira->codegen, child_type)) {
case OnePossibleValueInvalid:
return ira->codegen->invalid_instruction;
case OnePossibleValueNo:
if (!same_comptime_repr) {
ConstExprValue *payload_val = create_const_vals(1);
payload_val->type = child_type;
payload_val->special = ConstValSpecialUndef;
payload_val->parent.id = ConstParentIdOptionalPayload;
payload_val->parent.data.p_optional_payload.optional_val = optional_val;
optional_val->data.x_optional = payload_val;
optional_val->special = ConstValSpecialStatic;
}
break;
case OnePossibleValueYes: {
ConstExprValue *pointee = create_const_vals(1);
pointee->special = ConstValSpecialStatic;
pointee->type = child_type;
pointee->parent.id = ConstParentIdOptionalPayload;
pointee->parent.data.p_optional_payload.optional_val = optional_val;
optional_val->special = ConstValSpecialStatic;
optional_val->data.x_optional = pointee;
break;
}
}
} else if (optional_value_is_null(optional_val)) {
ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null"));
return ira->codegen->invalid_instruction;
}
IrInstruction *result = ir_const(ira, source_instr, result_type);
ConstExprValue *out_val = &result->value;
out_val->data.x_ptr.special = ConstPtrSpecialRef;
out_val->data.x_ptr.mut = val->data.x_ptr.mut;
if (types_have_same_zig_comptime_repr(type_entry, child_type)) {
out_val->data.x_ptr.data.ref.pointee = maybe_val;
IrInstruction *result;
if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
result = ir_build_optional_unwrap_ptr(&ira->new_irb, source_instr->scope,
source_instr->source_node, base_ptr, false, initializing);
result->value.type = result_type;
result->value.special = ConstValSpecialStatic;
} else {
out_val->data.x_ptr.data.ref.pointee = maybe_val->data.x_optional;
result = ir_const(ira, source_instr, result_type);
}
ConstExprValue *result_val = &result->value;
result_val->data.x_ptr.special = ConstPtrSpecialRef;
result_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut;
switch (type_has_one_possible_value(ira->codegen, child_type)) {
case OnePossibleValueInvalid:
return ira->codegen->invalid_instruction;
case OnePossibleValueNo:
if (same_comptime_repr) {
result_val->data.x_ptr.data.ref.pointee = optional_val;
} else {
assert(optional_val->data.x_optional != nullptr);
result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional;
}
break;
case OnePossibleValueYes:
assert(optional_val->data.x_optional != nullptr);
result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional;
break;
}
return result;
}
@ -22409,10 +22470,16 @@ static IrInstruction *ir_analyze_instruction_result_ptr(IrAnalyze *ira, IrInstru
!instr_is_comptime(result))
{
IrInstruction *result_ptr = instruction->result_loc->resolved_loc;
// Convert the pointer to the result type. They should be the same, except this will resolve
// inferred error sets.
ZigType *new_ptr_type = get_pointer_to_type(ira->codegen, result->value.type, true);
return ir_analyze_ptr_cast(ira, &instruction->base, result_ptr, new_ptr_type, &instruction->base, false);
if (result->value.type->id == ZigTypeIdErrorUnion &&
result_ptr->value.type->data.pointer.child_type->id == ZigTypeIdErrorUnion)
{
// Convert the pointer to the result type. They should be the same, except this will resolve
// inferred error sets.
ZigType *new_ptr_type = get_pointer_to_type(ira->codegen, result->value.type, true);
return ir_analyze_ptr_cast(ira, &instruction->base, result_ptr, new_ptr_type, &instruction->base, false);
} else {
return result_ptr;
}
}
return ir_get_ref(ira, &instruction->base, result, true, false);
}
@ -22465,7 +22532,6 @@ static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *
// This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing.
assert(ptr_type->id == ZigTypeIdPointer);
bool is_ptr_const = ptr_type->data.pointer.is_const;
ZigType *type_entry = ptr_type->data.pointer.child_type;
if (type_is_invalid(type_entry))
@ -22477,31 +22543,63 @@ static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *
return ira->codegen->invalid_instruction;
}
ZigType *err_set_type = type_entry->data.error_union.err_set_type;
ZigType *result_type = get_pointer_to_type_extra(ira->codegen, err_set_type,
ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle,
ptr_type->data.pointer.explicit_alignment, 0, 0, false);
if (instr_is_comptime(base_ptr)) {
ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad);
if (!ptr_val)
return ira->codegen->invalid_instruction;
if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar &&
ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)
{
ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
if (err_union_val == nullptr)
return ira->codegen->invalid_instruction;
if (err_union_val->special != ConstValSpecialRuntime) {
ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set;
assert(err != nullptr);
IrInstruction *err_set_val = ir_const(ira, source_instr, type_entry->data.error_union.err_set_type);
err_set_val->value.data.x_err_set = err;
err_set_val->value.parent.id = ConstParentIdErrUnionCode;
err_set_val->value.parent.data.p_err_union_code.err_union_val = err_union_val;
if (initializing && err_union_val->special == ConstValSpecialUndef) {
ConstExprValue *vals = create_const_vals(2);
ConstExprValue *err_set_val = &vals[0];
ConstExprValue *payload_val = &vals[1];
return ir_get_ref(ira, source_instr, err_set_val, is_ptr_const, false);
err_set_val->special = ConstValSpecialUndef;
err_set_val->type = err_set_type;
err_set_val->parent.id = ConstParentIdErrUnionCode;
err_set_val->parent.data.p_err_union_code.err_union_val = err_union_val;
payload_val->special = ConstValSpecialUndef;
payload_val->type = type_entry->data.error_union.payload_type;
payload_val->parent.id = ConstParentIdErrUnionPayload;
payload_val->parent.data.p_err_union_payload.err_union_val = err_union_val;
err_union_val->special = ConstValSpecialStatic;
err_union_val->data.x_err_union.error_set = err_set_val;
err_union_val->data.x_err_union.payload = payload_val;
}
ir_assert(err_union_val->special != ConstValSpecialRuntime, source_instr);
IrInstruction *result;
if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
result = ir_build_unwrap_err_code(&ira->new_irb, source_instr->scope,
source_instr->source_node, base_ptr);
result->value.type = result_type;
result->value.special = ConstValSpecialStatic;
} else {
result = ir_const(ira, source_instr, result_type);
}
ConstExprValue *const_val = &result->value;
const_val->data.x_ptr.special = ConstPtrSpecialBaseErrorUnionCode;
const_val->data.x_ptr.data.base_err_union_code.err_union_val = err_union_val;
const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut;
return result;
}
}
IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb,
source_instr->scope, source_instr->source_node, base_ptr);
result->value.type = get_pointer_to_type(ira->codegen, type_entry->data.error_union.err_set_type, is_ptr_const);
result->value.type = result_type;
return result;
}
@ -22547,6 +22645,23 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct
ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
if (err_union_val == nullptr)
return ira->codegen->invalid_instruction;
if (err_union_val->special == ConstValSpecialUndef && initializing) {
ConstExprValue *vals = create_const_vals(2);
ConstExprValue *err_set_val = &vals[0];
ConstExprValue *payload_val = &vals[1];
err_set_val->special = ConstValSpecialStatic;
err_set_val->type = type_entry->data.error_union.err_set_type;
err_set_val->data.x_err_set = nullptr;
payload_val->special = ConstValSpecialUndef;
payload_val->type = payload_type;
err_union_val->special = ConstValSpecialStatic;
err_union_val->data.x_err_union.error_set = err_set_val;
err_union_val->data.x_err_union.payload = payload_val;
}
if (err_union_val->special != ConstValSpecialRuntime) {
ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set;
if (err != nullptr) {
@ -22555,9 +22670,18 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct
return ira->codegen->invalid_instruction;
}
IrInstruction *result = ir_const(ira, source_instr, result_type);
IrInstruction *result;
if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
result = ir_build_unwrap_err_payload(&ira->new_irb, source_instr->scope,
source_instr->source_node, base_ptr, safety_check_on, initializing);
result->value.type = result_type;
result->value.special = ConstValSpecialStatic;
} else {
result = ir_const(ira, source_instr, result_type);
}
result->value.data.x_ptr.special = ConstPtrSpecialRef;
result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload;
result->value.data.x_ptr.mut = ptr_val->data.x_ptr.mut;
return result;
}
}
@ -23162,6 +23286,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdPromise:
case ZigTypeIdErrorUnion:
case ZigTypeIdErrorSet:
zig_unreachable();
case ZigTypeIdVoid:
return;
@ -23265,10 +23391,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
}
case ZigTypeIdOptional:
zig_panic("TODO buf_write_value_bytes maybe type");
case ZigTypeIdErrorUnion:
zig_panic("TODO buf_write_value_bytes error union");
case ZigTypeIdErrorSet:
zig_panic("TODO buf_write_value_bytes pure error type");
case ZigTypeIdFn:
zig_panic("TODO buf_write_value_bytes fn type");
case ZigTypeIdUnion:
@ -24502,24 +24624,24 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct
if (type_is_invalid(value->value.type))
return ira->codegen->invalid_instruction;
bool want_resolve_result = !instruction->result_loc->written;
if (want_resolve_result) {
IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
value->value.type, value, false);
if (result_loc != nullptr) {
if (type_is_invalid(result_loc->value.type))
return ira->codegen->invalid_instruction;
if (result_loc->value.type->id == ZigTypeIdUnreachable)
return result_loc;
bool was_written = instruction->result_loc->written;
IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
value->value.type, value, false);
if (result_loc != nullptr) {
if (type_is_invalid(result_loc->value.type))
return ira->codegen->invalid_instruction;
if (result_loc->value.type->id == ZigTypeIdUnreachable)
return result_loc;
instruction->result_loc->written = true;
if (!was_written) {
ir_analyze_store_ptr(ira, &instruction->base, result_loc, value);
if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) {
if (instr_is_comptime(value)) {
result_loc->value.data.x_ptr.mut = ConstPtrMutComptimeConst;
} else {
result_loc->value.special = ConstValSpecialRuntime;
}
}
if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) {
if (instr_is_comptime(value)) {
result_loc->value.data.x_ptr.mut = ConstPtrMutComptimeConst;
} else {
result_loc->value.special = ConstValSpecialRuntime;
}
}
}