better result location semantics with optionals and return locations

somewhere along this branch, #1901 has been fixed.
This commit is contained in:
Andrew Kelley 2019-06-15 12:28:21 -04:00
parent 60025a3704
commit 6bf193af19
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
14 changed files with 281 additions and 169 deletions

View File

@ -4,10 +4,7 @@ Scratch pad for stuff to do before merging master
uncomment all the behavior tests
diff master branch to make sure
restore test_runner.zig to master branch
- also the default panic function and unexpected_error_tracing. see the commit
that adds this text to BRANCH_TODO file.
- and std/specia/bootstrap.zig
restore bootstrap.zig to master
get an empty file compiling successfully (with no panic fn override)

View File

@ -2257,7 +2257,8 @@ enum IrInstructionId {
IrInstructionIdHandle,
IrInstructionIdAlignOf,
IrInstructionIdOverflowOp,
IrInstructionIdTestErr,
IrInstructionIdTestErrSrc,
IrInstructionIdTestErrGen,
IrInstructionIdUnwrapErrCode,
IrInstructionIdUnwrapErrPayload,
IrInstructionIdErrWrapCode,
@ -2292,6 +2293,7 @@ enum IrInstructionId {
IrInstructionIdAlignCast,
IrInstructionIdImplicitCast,
IrInstructionIdResolveResult,
IrInstructionIdResultPtr,
IrInstructionIdOpaqueType,
IrInstructionIdSetAlignStack,
IrInstructionIdArgType,
@ -3082,10 +3084,16 @@ struct IrInstructionAlignOf {
};
// returns true if error, returns false if not error
struct IrInstructionTestErr {
struct IrInstructionTestErrSrc {
IrInstruction base;
IrInstruction *value;
IrInstruction *base_ptr;
};
struct IrInstructionTestErrGen {
IrInstruction base;
IrInstruction *err_union;
};
// Takes an error union pointer, returns a pointer to the error code.
@ -3596,6 +3604,7 @@ struct IrInstructionImplicitCast {
ResultLoc *result_loc;
};
// This one is for writing through the result pointer.
struct IrInstructionResolveResult {
IrInstruction base;
@ -3603,6 +3612,15 @@ struct IrInstructionResolveResult {
IrInstruction *ty;
};
// This one is when you want to read the value of the result.
// You have to give the value in case it is comptime.
struct IrInstructionResultPtr {
IrInstruction base;
ResultLoc *result_loc;
IrInstruction *result;
};
struct IrInstructionPtrOfArrayToSlice {
IrInstruction base;

View File

@ -1323,7 +1323,9 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {
LLVMBuildRetVoid(g->builder);
LLVMPositionBuilderAtEnd(g->builder, prev_block);
LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
if (!g->strip_debug_symbols) {
LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
}
g->add_error_return_trace_addr_fn_val = fn_val;
return fn_val;
@ -1454,7 +1456,9 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
LLVMBuildBr(g->builder, loop_block);
LLVMPositionBuilderAtEnd(g->builder, prev_block);
LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
if (!g->strip_debug_symbols) {
LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
}
g->merge_err_ret_traces_fn_val = fn_val;
return fn_val;
@ -1510,7 +1514,9 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
LLVMBuildRetVoid(g->builder);
LLVMPositionBuilderAtEnd(g->builder, prev_block);
LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
if (!g->strip_debug_symbols) {
LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
}
g->return_err_fn = fn_val;
return fn_val;
@ -1638,7 +1644,9 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
gen_panic(g, msg_slice, err_ret_trace_arg);
LLVMPositionBuilderAtEnd(g->builder, prev_block);
LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
if (!g->strip_debug_symbols) {
LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
}
g->safety_crash_err_fn = fn_val;
return fn_val;
@ -4353,7 +4361,9 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {
g->cur_fn = prev_cur_fn;
g->cur_fn_val = prev_cur_fn_val;
LLVMPositionBuilderAtEnd(g->builder, prev_block);
LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
if (!g->strip_debug_symbols) {
LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
}
enum_type->data.enumeration.name_function = fn_val;
return fn_val;
@ -4880,10 +4890,10 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutable *executable,
return overflow_bit;
}
static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrInstructionTestErr *instruction) {
ZigType *err_union_type = instruction->value->value.type;
static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrInstructionTestErrGen *instruction) {
ZigType *err_union_type = instruction->err_union->value.type;
ZigType *payload_type = err_union_type->data.error_union.payload_type;
LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->value);
LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->err_union);
LLVMValueRef err_val;
if (type_has_bits(payload_type)) {
@ -5276,7 +5286,9 @@ static LLVMValueRef get_coro_alloc_helper_fn_val(CodeGen *g, LLVMTypeRef alloc_f
g->cur_fn = prev_cur_fn;
g->cur_fn_val = prev_cur_fn_val;
LLVMPositionBuilderAtEnd(g->builder, prev_block);
LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
if (!g->strip_debug_symbols) {
LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
}
g->coro_alloc_helper_fn_val = fn_val;
return fn_val;
@ -5549,10 +5561,12 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdAllocaGen:
case IrInstructionIdImplicitCast:
case IrInstructionIdResolveResult:
case IrInstructionIdResultPtr:
case IrInstructionIdContainerInitList:
case IrInstructionIdSliceSrc:
case IrInstructionIdRef:
case IrInstructionIdBitCastSrc:
case IrInstructionIdTestErrSrc:
zig_unreachable();
case IrInstructionIdDeclVarGen:
@ -5635,8 +5649,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_handle(g, executable, (IrInstructionHandle *)instruction);
case IrInstructionIdOverflowOp:
return ir_render_overflow_op(g, executable, (IrInstructionOverflowOp *)instruction);
case IrInstructionIdTestErr:
return ir_render_test_err(g, executable, (IrInstructionTestErr *)instruction);
case IrInstructionIdTestErrGen:
return ir_render_test_err(g, executable, (IrInstructionTestErrGen *)instruction);
case IrInstructionIdUnwrapErrCode:
return ir_render_unwrap_err_code(g, executable, (IrInstructionUnwrapErrCode *)instruction);
case IrInstructionIdUnwrapErrPayload:

View File

@ -756,8 +756,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) {
return IrInstructionIdOverflowOp;
}
static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErr *) {
return IrInstructionIdTestErr;
static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErrSrc *) {
return IrInstructionIdTestErrSrc;
}
static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErrGen *) {
return IrInstructionIdTestErrGen;
}
static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrCode *) {
@ -900,6 +904,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionResolveResult *)
return IrInstructionIdResolveResult;
}
static constexpr IrInstructionId ir_instruction_id(IrInstructionResultPtr *) {
return IrInstructionIdResultPtr;
}
static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrOfArrayToSlice *) {
return IrInstructionIdPtrOfArrayToSlice;
}
@ -2418,13 +2426,26 @@ static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *s
return &instruction->base;
}
static IrInstruction *ir_build_test_err(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *value)
static IrInstruction *ir_build_test_err_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *base_ptr)
{
IrInstructionTestErr *instruction = ir_build_instruction<IrInstructionTestErr>(irb, scope, source_node);
instruction->value = value;
IrInstructionTestErrSrc *instruction = ir_build_instruction<IrInstructionTestErrSrc>(irb, scope, source_node);
instruction->base_ptr = base_ptr;
ir_ref_instruction(value, irb->current_basic_block);
ir_ref_instruction(base_ptr, irb->current_basic_block);
return &instruction->base;
}
static IrInstruction *ir_build_test_err_gen(IrAnalyze *ira, IrInstruction *source_instruction,
IrInstruction *err_union)
{
IrInstructionTestErrGen *instruction = ir_build_instruction<IrInstructionTestErrGen>(
&ira->new_irb, source_instruction->scope, source_instruction->source_node);
instruction->base.value.type = ira->codegen->builtin_types.entry_bool;
instruction->err_union = err_union;
ir_ref_instruction(err_union, ira->new_irb.current_basic_block);
return &instruction->base;
}
@ -2844,6 +2865,18 @@ static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstN
return &instruction->base;
}
static IrInstruction *ir_build_result_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
ResultLoc *result_loc, IrInstruction *result)
{
IrInstructionResultPtr *instruction = ir_build_instruction<IrInstructionResultPtr>(irb, scope, source_node);
instruction->result_loc = result_loc;
instruction->result = result;
ir_ref_instruction(result, irb->current_basic_block);
return &instruction->base;
}
static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) {
IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node);
@ -3531,7 +3564,9 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
ir_gen_defers_for_block(irb, scope, outer_scope, false);
}
IrInstruction *is_err = ir_build_test_err(irb, scope, node, return_value);
IrInstruction *ret_ptr = ir_build_result_ptr(irb, scope, node, &result_loc_ret->base,
return_value);
IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, ret_ptr);
bool should_inline = ir_should_inline(irb->exec, scope);
IrInstruction *is_comptime;
@ -3577,8 +3612,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
if (err_union_ptr == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
IrInstruction *err_union_val = ir_build_load_ptr(irb, scope, node, err_union_ptr);
IrInstruction *is_err_val = ir_build_test_err(irb, scope, node, err_union_val);
IrInstruction *is_err_val = ir_build_test_err_src(irb, scope, node, err_union_ptr);
IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn");
IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue");
@ -5940,8 +5974,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
LValPtr, nullptr);
if (err_val_ptr == irb->codegen->invalid_instruction)
return err_val_ptr;
IrInstruction *err_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, err_val_ptr);
IrInstruction *is_err = ir_build_test_err(irb, scope, node->data.while_expr.condition, err_val);
IrInstruction *is_err = ir_build_test_err_src(irb, scope, node->data.while_expr.condition, err_val_ptr);
IrBasicBlock *after_cond_block = irb->current_basic_block;
IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node));
IrInstruction *cond_br_inst;
@ -6722,7 +6755,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
return err_val_ptr;
IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr);
IrInstruction *is_err = ir_build_test_err(irb, scope, node, err_val);
IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, err_val_ptr);
IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk");
IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse");
@ -7330,8 +7363,7 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
if (err_union_ptr == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
IrInstruction *err_union_val = ir_build_load_ptr(irb, parent_scope, node, err_union_ptr);
IrInstruction *is_err = ir_build_test_err(irb, parent_scope, node, err_union_val);
IrInstruction *is_err = ir_build_test_err_src(irb, parent_scope, node, err_union_ptr);
IrInstruction *is_comptime;
if (ir_should_inline(irb->exec, parent_scope)) {
@ -15010,7 +15042,9 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
return result_loc;
ir_assert(result_loc->value.type->id == ZigTypeIdPointer, suspend_source_instr);
ZigType *actual_elem_type = result_loc->value.type->data.pointer.child_type;
if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional) {
if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional &&
value_type->id != ZigTypeIdNull)
{
return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true);
} else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion) {
if (value_type->id == ZigTypeIdErrorSet) {
@ -22190,15 +22224,34 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr
return result;
}
static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErr *instruction) {
IrInstruction *value = instruction->value->child;
if (type_is_invalid(value->value.type))
static IrInstruction *ir_analyze_instruction_result_ptr(IrAnalyze *ira, IrInstructionResultPtr *instruction) {
IrInstruction *result = instruction->result->child;
if (type_is_invalid(result->value.type))
return result;
if (instruction->result_loc->written && instruction->result_loc->resolved_loc != nullptr &&
!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);
}
return ir_get_ref(ira, &instruction->base, result, true, false);
}
static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErrSrc *instruction) {
IrInstruction *base_ptr = instruction->base_ptr->child;
if (type_is_invalid(base_ptr->value.type))
return ira->codegen->invalid_instruction;
IrInstruction *value = ir_get_deref(ira, &instruction->base, base_ptr, nullptr);
ZigType *type_entry = value->value.type;
if (type_is_invalid(type_entry)) {
if (type_is_invalid(type_entry))
return ira->codegen->invalid_instruction;
} else if (type_entry->id == ZigTypeIdErrorUnion) {
if (type_entry->id == ZigTypeIdErrorUnion) {
if (instr_is_comptime(value)) {
ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad);
if (!err_union_val)
@ -22221,10 +22274,7 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct
return ir_const_bool(ira, &instruction->base, false);
}
IrInstruction *result = ir_build_test_err(&ira->new_irb,
instruction->base.scope, instruction->base.source_node, value);
result->value.type = ira->codegen->builtin_types.entry_bool;
return result;
return ir_build_test_err_gen(ira, &instruction->base, value);
} else if (type_entry->id == ZigTypeIdErrorSet) {
return ir_const_bool(ira, &instruction->base, true);
} else {
@ -24343,6 +24393,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
case IrInstructionIdAllocaGen:
case IrInstructionIdSliceGen:
case IrInstructionIdRefGen:
case IrInstructionIdTestErrGen:
zig_unreachable();
case IrInstructionIdReturn:
@ -24497,8 +24548,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction);
case IrInstructionIdOverflowOp:
return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction);
case IrInstructionIdTestErr:
return ir_analyze_instruction_test_err(ira, (IrInstructionTestErr *)instruction);
case IrInstructionIdTestErrSrc:
return ir_analyze_instruction_test_err(ira, (IrInstructionTestErrSrc *)instruction);
case IrInstructionIdUnwrapErrCode:
return ir_analyze_instruction_unwrap_err_code(ira, (IrInstructionUnwrapErrCode *)instruction);
case IrInstructionIdUnwrapErrPayload:
@ -24543,6 +24594,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
return ir_analyze_instruction_implicit_cast(ira, (IrInstructionImplicitCast *)instruction);
case IrInstructionIdResolveResult:
return ir_analyze_instruction_resolve_result(ira, (IrInstructionResolveResult *)instruction);
case IrInstructionIdResultPtr:
return ir_analyze_instruction_result_ptr(ira, (IrInstructionResultPtr *)instruction);
case IrInstructionIdOpaqueType:
return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction);
case IrInstructionIdSetAlignStack:
@ -24672,6 +24725,9 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_
continue;
}
if (ira->codegen->verbose_ir) {
fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id);
}
IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction);
if (new_instruction != nullptr) {
ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction);
@ -24808,7 +24864,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdReturnAddress:
case IrInstructionIdFrameAddress:
case IrInstructionIdHandle:
case IrInstructionIdTestErr:
case IrInstructionIdTestErrSrc:
case IrInstructionIdTestErrGen:
case IrInstructionIdFnProto:
case IrInstructionIdTestComptime:
case IrInstructionIdPtrCastSrc:
@ -24860,6 +24917,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdHasDecl:
case IrInstructionIdAllocaSrc:
case IrInstructionIdAllocaGen:
case IrInstructionIdResultPtr:
return false;
case IrInstructionIdAsm:

View File

@ -961,9 +961,15 @@ static void ir_print_overflow_op(IrPrint *irp, IrInstructionOverflowOp *instruct
fprintf(irp->f, ")");
}
static void ir_print_test_err(IrPrint *irp, IrInstructionTestErr *instruction) {
static void ir_print_test_err_src(IrPrint *irp, IrInstructionTestErrSrc *instruction) {
fprintf(irp->f, "@testError(");
ir_print_other_instruction(irp, instruction->value);
ir_print_other_instruction(irp, instruction->base_ptr);
fprintf(irp->f, ")");
}
static void ir_print_test_err_gen(IrPrint *irp, IrInstructionTestErrGen *instruction) {
fprintf(irp->f, "@testError(");
ir_print_other_instruction(irp, instruction->err_union);
fprintf(irp->f, ")");
}
@ -976,10 +982,7 @@ static void ir_print_unwrap_err_code(IrPrint *irp, IrInstructionUnwrapErrCode *i
static void ir_print_unwrap_err_payload(IrPrint *irp, IrInstructionUnwrapErrPayload *instruction) {
fprintf(irp->f, "ErrorUnionFieldPayload(");
ir_print_other_instruction(irp, instruction->value);
fprintf(irp->f, ")");
if (!instruction->safety_check_on) {
fprintf(irp->f, " // no safety");
}
fprintf(irp->f, ")safety=%d,init=%d",instruction->safety_check_on, instruction->initializing);
}
static void ir_print_optional_wrap(IrPrint *irp, IrInstructionOptionalWrap *instruction) {
@ -1301,6 +1304,14 @@ static void ir_print_resolve_result(IrPrint *irp, IrInstructionResolveResult *in
fprintf(irp->f, ")");
}
static void ir_print_result_ptr(IrPrint *irp, IrInstructionResultPtr *instruction) {
fprintf(irp->f, "ResultPtr(");
ir_print_result_loc(irp, instruction->result_loc);
fprintf(irp->f, ",");
ir_print_other_instruction(irp, instruction->result);
fprintf(irp->f, ")");
}
static void ir_print_opaque_type(IrPrint *irp, IrInstructionOpaqueType *instruction) {
fprintf(irp->f, "@OpaqueType()");
}
@ -1837,8 +1848,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdOverflowOp:
ir_print_overflow_op(irp, (IrInstructionOverflowOp *)instruction);
break;
case IrInstructionIdTestErr:
ir_print_test_err(irp, (IrInstructionTestErr *)instruction);
case IrInstructionIdTestErrSrc:
ir_print_test_err_src(irp, (IrInstructionTestErrSrc *)instruction);
break;
case IrInstructionIdTestErrGen:
ir_print_test_err_gen(irp, (IrInstructionTestErrGen *)instruction);
break;
case IrInstructionIdUnwrapErrCode:
ir_print_unwrap_err_code(irp, (IrInstructionUnwrapErrCode *)instruction);
@ -1939,6 +1953,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdResolveResult:
ir_print_resolve_result(irp, (IrInstructionResolveResult *)instruction);
break;
case IrInstructionIdResultPtr:
ir_print_result_ptr(irp, (IrInstructionResultPtr *)instruction);
break;
case IrInstructionIdOpaqueType:
ir_print_opaque_type(irp, (IrInstructionOpaqueType *)instruction);
break;

View File

@ -2487,7 +2487,7 @@ pub fn toPosixPath(file_path: []const u8) ![PATH_MAX]u8 {
/// if this happens the fix is to add the error code to the corresponding
/// switch expression, possibly introduce a new error in the error set, and
/// send a patch to Zig.
pub const unexpected_error_tracing = false;
pub const unexpected_error_tracing = builtin.mode == .Debug;
pub const UnexpectedError = error{
/// The Operating System returned an undocumented error code.

View File

@ -7,8 +7,23 @@ const builtin = @import("builtin");
const std = @import("std");
pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
const stderr = std.io.getStdErr() catch std.process.abort();
stderr.write("panic: ") catch std.process.abort();
stderr.write(msg) catch std.process.abort();
std.process.abort();
@setCold(true);
switch (builtin.os) {
.freestanding => {
while (true) {}
},
.wasi => {
std.debug.warn("{}", msg);
_ = std.os.wasi.proc_raise(std.os.wasi.SIGABRT);
unreachable;
},
.uefi => {
// TODO look into using the debug info and logging helpful messages
std.os.abort();
},
else => {
const first_trace_addr = @returnAddress();
std.debug.panicExtra(error_return_trace, first_trace_addr, "{}", msg);
},
}
}

View File

@ -2,34 +2,28 @@ const std = @import("std");
const io = std.io;
const builtin = @import("builtin");
const test_fn_list = builtin.test_functions;
const warn = std.debug.warn;
pub fn main() void {
const stderr = io.getStdErr() catch std.process.abort();
pub fn main() !void {
var ok_count: usize = 0;
var skip_count: usize = 0;
for (test_fn_list) |test_fn, i| {
stderr.write("test ") catch std.process.abort();
stderr.write(test_fn.name) catch std.process.abort();
warn("{}/{} {}...", i + 1, test_fn_list.len, test_fn.name);
if (test_fn.func()) |_| {
ok_count += 1;
stderr.write("...OK\n") catch std.process.abort();
warn("OK\n");
} else |err| switch (err) {
error.SkipZigTest => {
skip_count += 1;
stderr.write("...SKIP\n") catch std.process.abort();
},
else => {
stderr.write("error: ") catch std.process.abort();
stderr.write(@errorName(err)) catch std.process.abort();
std.process.abort();
warn("SKIP\n");
},
else => return err,
}
}
if (ok_count == test_fn_list.len) {
stderr.write("All tests passed.\n") catch std.process.abort();
warn("All tests passed.\n");
} else {
stderr.write("Some tests skipped.\n") catch std.process.abort();
warn("{} passed; {} skipped.\n", ok_count, skip_count);
}
}

View File

@ -40,46 +40,46 @@ comptime {
//_ = @import("behavior/bugs/920.zig");
_ = @import("behavior/byval_arg_var.zig");
//_ = @import("behavior/cancel.zig");
_ = @import("behavior/cast.zig"); // TODO
_ = @import("behavior/cast.zig");
_ = @import("behavior/const_slice_child.zig");
//_ = @import("behavior/coroutine_await_struct.zig");
//_ = @import("behavior/coroutines.zig");
_ = @import("behavior/defer.zig");
_ = @import("behavior/enum.zig");
_ = @import("behavior/enum_with_members.zig");
//_ = @import("behavior/error.zig");
_ = @import("behavior/error.zig"); // TODO
_ = @import("behavior/eval.zig"); // TODO
_ = @import("behavior/field_parent_ptr.zig");
_ = @import("behavior/fn.zig");
_ = @import("behavior/fn_in_struct_in_comptime.zig");
_ = @import("behavior/for.zig");
_ = @import("behavior/generics.zig"); // TODO
_ = @import("behavior/generics.zig");
_ = @import("behavior/hasdecl.zig");
_ = @import("behavior/if.zig");
//_ = @import("behavior/import.zig");
_ = @import("behavior/import.zig");
_ = @import("behavior/incomplete_struct_param_tld.zig");
_ = @import("behavior/inttoptr.zig");
_ = @import("behavior/ir_block_deps.zig");
//_ = @import("behavior/math.zig");
_ = @import("behavior/math.zig");
_ = @import("behavior/merge_error_sets.zig");
_ = @import("behavior/misc.zig"); // TODO
_ = @import("behavior/namespace_depends_on_compile_var.zig");
_ = @import("behavior/new_stack_call.zig");
_ = @import("behavior/null.zig");
_ = @import("behavior/optional.zig"); // TODO
//_ = @import("behavior/pointers.zig");
_ = @import("behavior/pointers.zig");
_ = @import("behavior/popcount.zig");
_ = @import("behavior/ptrcast.zig"); // TODO
_ = @import("behavior/pub_enum.zig");
_ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
_ = @import("behavior/reflection.zig");
_ = @import("behavior/sizeof_and_typeof.zig");
//_ = @import("behavior/slice.zig");
_ = @import("behavior/slice.zig");
_ = @import("behavior/slicetobytes.zig");
//_ = @import("behavior/struct.zig");
_ = @import("behavior/struct_contains_null_ptr_itself.zig");
_ = @import("behavior/struct_contains_slice_of_itself.zig");
//_ = @import("behavior/switch.zig");
_ = @import("behavior/switch.zig");
//_ = @import("behavior/switch_prong_err_enum.zig");
_ = @import("behavior/switch_prong_implicit_cast.zig");
_ = @import("behavior/syntax.zig");
@ -87,7 +87,7 @@ comptime {
_ = @import("behavior/truncate.zig");
_ = @import("behavior/try.zig");
_ = @import("behavior/type_info.zig");
//_ = @import("behavior/typename.zig");
_ = @import("behavior/typename.zig");
_ = @import("behavior/undefined.zig");
_ = @import("behavior/underscore.zig");
_ = @import("behavior/union.zig");

View File

@ -124,14 +124,14 @@ fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A {
return null;
}
//test "peer type resolution: ?T and T" {
// expect(peerTypeTAndOptionalT(true, false).? == 0);
// expect(peerTypeTAndOptionalT(false, false).? == 3);
// comptime {
// expect(peerTypeTAndOptionalT(true, false).? == 0);
// expect(peerTypeTAndOptionalT(false, false).? == 3);
// }
//}
test "peer type resolution: ?T and T" {
expect(peerTypeTAndOptionalT(true, false).? == 0);
expect(peerTypeTAndOptionalT(false, false).? == 3);
comptime {
expect(peerTypeTAndOptionalT(true, false).? == 0);
expect(peerTypeTAndOptionalT(false, false).? == 3);
}
}
fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {
if (c) {
return if (b) null else usize(0);

View File

@ -249,48 +249,48 @@ fn intLiteral(str: []const u8) !?i64 {
return error.T;
}
test "nested error union function call in optional unwrap" {
const S = struct {
const Foo = struct {
a: i32,
};
fn errorable() !i32 {
var x: Foo = (try getFoo()) orelse return error.Other;
return x.a;
}
fn errorable2() !i32 {
var x: Foo = (try getFoo2()) orelse return error.Other;
return x.a;
}
fn errorable3() !i32 {
var x: Foo = (try getFoo3()) orelse return error.Other;
return x.a;
}
fn getFoo() anyerror!?Foo {
return Foo{ .a = 1234 };
}
fn getFoo2() anyerror!?Foo {
return error.Failure;
}
fn getFoo3() anyerror!?Foo {
return null;
}
};
expect((try S.errorable()) == 1234);
expectError(error.Failure, S.errorable2());
expectError(error.Other, S.errorable3());
comptime {
expect((try S.errorable()) == 1234);
expectError(error.Failure, S.errorable2());
expectError(error.Other, S.errorable3());
}
}
//test "nested error union function call in optional unwrap" {
// const S = struct {
// const Foo = struct {
// a: i32,
// };
//
// fn errorable() !i32 {
// var x: Foo = (try getFoo()) orelse return error.Other;
// return x.a;
// }
//
// fn errorable2() !i32 {
// var x: Foo = (try getFoo2()) orelse return error.Other;
// return x.a;
// }
//
// fn errorable3() !i32 {
// var x: Foo = (try getFoo3()) orelse return error.Other;
// return x.a;
// }
//
// fn getFoo() anyerror!?Foo {
// return Foo{ .a = 1234 };
// }
//
// fn getFoo2() anyerror!?Foo {
// return error.Failure;
// }
//
// fn getFoo3() anyerror!?Foo {
// return null;
// }
// };
// expect((try S.errorable()) == 1234);
// expectError(error.Failure, S.errorable2());
// expectError(error.Other, S.errorable3());
// comptime {
// expect((try S.errorable()) == 1234);
// expectError(error.Failure, S.errorable2());
// expectError(error.Other, S.errorable3());
// }
//}
test "widen cast integer payload of error union function call" {
const S = struct {

View File

@ -80,19 +80,19 @@ test "function with return type type" {
expect(list2.prealloc_items.len == 8);
}
//test "generic struct" {
// var a1 = GenNode(i32){
// .value = 13,
// .next = null,
// };
// var b1 = GenNode(bool){
// .value = true,
// .next = null,
// };
// expect(a1.value == 13);
// expect(a1.value == a1.getVal());
// expect(b1.getVal());
//}
test "generic struct" {
var a1 = GenNode(i32){
.value = 13,
.next = null,
};
var b1 = GenNode(bool){
.value = true,
.next = null,
};
expect(a1.value == 13);
expect(a1.value == a1.getVal());
expect(b1.getVal());
}
fn GenNode(comptime T: type) type {
return struct {
value: T,

View File

@ -76,6 +76,5 @@ test "unwrap function call with optional pointer return value" {
}
};
S.entry();
// TODO https://github.com/ziglang/zig/issues/1901
//comptime S.entry();
comptime S.entry();
}

View File

@ -82,28 +82,28 @@ test "while with else" {
expect(got_else == 1);
}
//test "while with optional as condition" {
// numbers_left = 10;
// var sum: i32 = 0;
// while (getNumberOrNull()) |value| {
// sum += value;
// }
// expect(sum == 45);
//}
//
//test "while with optional as condition with else" {
// numbers_left = 10;
// var sum: i32 = 0;
// var got_else: i32 = 0;
// while (getNumberOrNull()) |value| {
// sum += value;
// expect(got_else == 0);
// } else {
// got_else += 1;
// }
// expect(sum == 45);
// expect(got_else == 1);
//}
test "while with optional as condition" {
numbers_left = 10;
var sum: i32 = 0;
while (getNumberOrNull()) |value| {
sum += value;
}
expect(sum == 45);
}
test "while with optional as condition with else" {
numbers_left = 10;
var sum: i32 = 0;
var got_else: i32 = 0;
while (getNumberOrNull()) |value| {
sum += value;
expect(got_else == 0);
} else {
got_else += 1;
}
expect(sum == 45);
expect(got_else == 1);
}
test "while with error union condition" {
numbers_left = 10;