From ff737cc6483e29b2b8c5af1b7c8ed17bb6c70f32 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 26 Jun 2019 12:31:51 -0400 Subject: [PATCH] fix peer type resolution: unreachable, error set, unreachable --- src/ir.cpp | 22 +++++++++++++++++----- std/event/fs.zig | 3 +-- test/stage1/behavior/cast.zig | 23 +++++++++++++++++++++++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index d6fdcd28e..794d41ce2 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -10093,9 +10093,21 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT { Error err; assert(instruction_count >= 1); - IrInstruction *prev_inst = instructions[0]; - if (type_is_invalid(prev_inst->value.type)) { - return ira->codegen->builtin_types.entry_invalid; + IrInstruction *prev_inst; + size_t i = 0; + for (;;) { + prev_inst = instructions[i]; + if (type_is_invalid(prev_inst->value.type)) { + return ira->codegen->builtin_types.entry_invalid; + } + if (prev_inst->value.type->id == ZigTypeIdUnreachable) { + i += 1; + if (i == instruction_count) { + return prev_inst->value.type; + } + continue; + } + break; } ErrorTableEntry **errors = nullptr; size_t errors_count = 0; @@ -10120,7 +10132,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT bool any_are_null = (prev_inst->value.type->id == ZigTypeIdNull); bool convert_to_const_slice = false; - for (size_t i = 1; i < instruction_count; i += 1) { + for (; i < instruction_count; i += 1) { IrInstruction *cur_inst = instructions[i]; ZigType *cur_type = cur_inst->value.type; ZigType *prev_type = prev_inst->value.type; @@ -10139,7 +10151,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT } if (prev_type->id == ZigTypeIdErrorSet) { - assert(err_set_type != nullptr); + ir_assert(err_set_type != nullptr, prev_inst); if (cur_type->id == ZigTypeIdErrorSet) { if (type_is_global_error_set(err_set_type)) { continue; diff --git a/std/event/fs.zig b/std/event/fs.zig index 0f4237527..c25426b98 100644 --- a/std/event/fs.zig +++ b/std/event/fs.zig @@ -1290,10 +1290,9 @@ pub fn Watch(comptime V: type) type { error.FileDescriptorAlreadyPresentInSet => unreachable, error.OperationCausesCircularLoop => unreachable, error.FileDescriptorNotRegistered => unreachable, - error.SystemResources => error.SystemResources, - error.UserResourceLimitReached => error.UserResourceLimitReached, error.FileDescriptorIncompatibleWithEpoll => unreachable, error.Unexpected => unreachable, + else => |e| e, }; await (async channel.put(transformed_err) catch unreachable); }; diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig index 5f702ff3e..edb0f4ff1 100644 --- a/test/stage1/behavior/cast.zig +++ b/test/stage1/behavior/cast.zig @@ -496,3 +496,26 @@ test "peer type resolution: unreachable, null, slice" { }; S.doTheTest(1, "hi"); } + +test "peer type resolution: unreachable, error set, unreachable" { + const Error = error { + FileDescriptorAlreadyPresentInSet, + OperationCausesCircularLoop, + FileDescriptorNotRegistered, + SystemResources, + UserResourceLimitReached, + FileDescriptorIncompatibleWithEpoll, + Unexpected, + }; + var err = Error.SystemResources; + const transformed_err = switch (err) { + error.FileDescriptorAlreadyPresentInSet => unreachable, + error.OperationCausesCircularLoop => unreachable, + error.FileDescriptorNotRegistered => unreachable, + error.SystemResources => error.SystemResources, + error.UserResourceLimitReached => error.UserResourceLimitReached, + error.FileDescriptorIncompatibleWithEpoll => unreachable, + error.Unexpected => unreachable, + }; + expect(transformed_err == error.SystemResources); +}