From 98a01f99c9b6834608055417169c2b3531ea67b6 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Sat, 12 Mar 2022 11:14:17 +0200 Subject: [PATCH 1/5] Sema: fix typo in resolvePeerTypes --- src/Sema.zig | 2 +- test/behavior/error.zig | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Sema.zig b/src/Sema.zig index 82acbab9e5..860d9d63ac 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -18910,7 +18910,7 @@ fn resolvePeerTypes( } const chosen_set_ty = err_set_ty orelse chosen_ty.errorUnionSet(); - const candidate_set_ty = chosen_ty.errorUnionSet(); + const candidate_set_ty = candidate_ty.errorUnionSet(); if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, chosen_set_ty, candidate_set_ty, src, src)) { err_set_ty = chosen_set_ty; diff --git a/test/behavior/error.zig b/test/behavior/error.zig index b3503051fb..93d76443ae 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -626,3 +626,11 @@ test "inferred error set equality" { try expect(BarError == BarError); try expect(BazError == BazError); } + +test "peer type resolution of two different error unions" { + const a: error{B}!void = {}; + const b: error{A}!void = {}; + var cond = true; + const err = if (cond) a else b; + try err; +} From 07cc2fce2a2745a05c65fdd1a36c3198d0ec91b4 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Sat, 12 Mar 2022 11:25:37 +0200 Subject: [PATCH 2/5] Sema: fix else branch check when switching on error set --- src/Sema.zig | 2 +- test/behavior/switch.zig | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index 860d9d63ac..958a737ef7 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -6972,7 +6972,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError return sema.failWithOwnedErrorMsg(block, msg); } - if (special_prong == .@"else") { + if (special_prong == .@"else" and seen_errors.count() == operand_ty.errorSetNames().len) { return sema.fail( block, special_prong_src, diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index d99998a34e..5c47a24b38 100644 --- a/test/behavior/switch.zig +++ b/test/behavior/switch.zig @@ -610,14 +610,11 @@ test "switch on pointer type" { } test "switch on error set with single else" { - if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO - const S = struct { fn doTheTest() !void { var some: error{Foo} = error.Foo; try expect(switch (some) { - else => |a| blk: { - a catch {}; + else => blk: { break :blk true; }, }); From a3cfb15fb4be719fe11f231113020532ad0b1258 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Sat, 12 Mar 2022 11:36:05 +0200 Subject: [PATCH 3/5] Sema: always allow coercing error set to current inferred error set --- src/Sema.zig | 7 +++++++ test/behavior/error.zig | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/Sema.zig b/src/Sema.zig index 958a737ef7..d813cf374b 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -16692,6 +16692,13 @@ fn coerceInMemoryAllowedErrorSets( else => unreachable, } + if (dst_ies.func == sema.owner_func) { + // We are trying to coerce an error set to the current function's + // inferred error set. + try dst_ies.addErrorSet(sema.gpa, src_ty); + return .ok; + } + try sema.resolveInferredErrorSet(block, dest_src, dst_payload.data); // isAnyError might have changed from a false negative to a true positive after resolution. if (dest_ty.isAnyError()) { diff --git a/test/behavior/error.zig b/test/behavior/error.zig index 93d76443ae..e6c69f4abf 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -634,3 +634,18 @@ test "peer type resolution of two different error unions" { const err = if (cond) a else b; try err; } + +test "coerce error set to the current inferred error set" { + const S = struct { + fn foo() !void { + var a = false; + if (a) { + const b: error{A}!void = error.A; + return b; + } + const b = error.A; + return b; + } + }; + S.foo() catch {}; +} From 487ee79ec92a69832293d10b16beb4c8471af7ac Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Sat, 12 Mar 2022 12:33:32 +0200 Subject: [PATCH 4/5] stage2 llvm: do not use getIntrinsic for airFrameAddress getIntrinsic gets the return type wrong so we have to add the function manually --- lib/std/debug.zig | 1 - src/codegen/llvm.zig | 9 ++++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/std/debug.zig b/lib/std/debug.zig index a2cbf88730..3d06c16d57 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -1630,7 +1630,6 @@ fn getSymbolFromDwarf(address: u64, di: *DW.DwarfInfo) !SymbolInfo { .symbol_name = nosuspend di.getSymbolName(address) orelse "???", .compile_unit_name = compile_unit.die.getAttrString(di, DW.AT.name) catch |err| switch (err) { error.MissingDebugInfo, error.InvalidDebugInfo => "???", - else => return err, }, .line_info = nosuspend di.getLineNumberInfo(compile_unit.*, address) catch |err| switch (err) { error.MissingDebugInfo, error.InvalidDebugInfo => null, diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 32dcb302f6..c942a975df 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -5347,7 +5347,14 @@ pub const FuncGen = struct { if (self.liveness.isUnused(inst)) return null; const llvm_i32 = self.context.intType(32); - const llvm_fn = self.getIntrinsic("llvm.frameaddress", &.{llvm_i32}); + const llvm_fn_name = "llvm.frameaddress.p0i8"; + const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { + const llvm_p0i8 = self.context.intType(8).pointerType(0); + const param_types = [_]*const llvm.Type{llvm_i32}; + const fn_type = llvm.functionType(llvm_p0i8, ¶m_types, param_types.len, .False); + break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); + }; + const params = [_]*const llvm.Value{llvm_i32.constNull()}; const ptr_val = self.builder.buildCall(llvm_fn, ¶ms, params.len, .Fast, .Auto, ""); const llvm_usize = try self.dg.llvmType(Type.usize); From d532c21d890e1aa22cd4c57d6a3f749890256254 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Sat, 12 Mar 2022 13:40:47 +0200 Subject: [PATCH 5/5] AstGen: fix nosuspendExpr handling result location twice --- lib/std/dwarf.zig | 2 +- src/AstGen.zig | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/std/dwarf.zig b/lib/std/dwarf.zig index 12ec357849..93d744ca5f 100644 --- a/lib/std/dwarf.zig +++ b/lib/std/dwarf.zig @@ -822,7 +822,7 @@ pub const DwarfInfo = struct { // in the list itself. // If no starting value is specified use zero. var base_address = compile_unit.die.getAttrAddr(AT.low_pc) catch |err| switch (err) { - error.MissingDebugInfo => 0, + error.MissingDebugInfo => @as(u64, 0), // TODO https://github.com/ziglang/zig/issues/11135 else => return err, }; diff --git a/src/AstGen.zig b/src/AstGen.zig index 97ca9f0a12..f54af8d3fb 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -1035,9 +1035,8 @@ fn nosuspendExpr( }); } gz.nosuspend_node = node; - const result = try expr(gz, scope, rl, body_node); - gz.nosuspend_node = 0; - return rvalue(gz, rl, result, node); + defer gz.nosuspend_node = 0; + return expr(gz, scope, rl, body_node); } fn suspendExpr(