mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
Sema: better error when coercing error sets
This commit is contained in:
parent
7862ab9f41
commit
d6e3988fe8
18
src/Sema.zig
18
src/Sema.zig
@ -5496,7 +5496,7 @@ fn analyzeCall(
|
||||
// TODO add error note: declared here
|
||||
return sema.fail(
|
||||
block,
|
||||
func_src,
|
||||
call_src,
|
||||
"expected {d} argument(s), found {d}",
|
||||
.{ fn_params_len, uncasted_args.len },
|
||||
);
|
||||
@ -21275,7 +21275,7 @@ fn coerceExtra(
|
||||
else => {},
|
||||
},
|
||||
.ErrorUnion => switch (inst_ty.zigTypeTag()) {
|
||||
.ErrorUnion => {
|
||||
.ErrorUnion => eu: {
|
||||
if (maybe_inst_val) |inst_val| {
|
||||
switch (inst_val.tag()) {
|
||||
.undef => return sema.addConstUndef(dest_ty),
|
||||
@ -21284,7 +21284,10 @@ fn coerceExtra(
|
||||
inst_ty.errorUnionPayload(),
|
||||
inst_val.castTag(.eu_payload).?.data,
|
||||
);
|
||||
return sema.wrapErrorUnionPayload(block, dest_ty, payload, inst_src);
|
||||
return sema.wrapErrorUnionPayload(block, dest_ty, payload, inst_src) catch |err| switch (err) {
|
||||
error.NotCoercible => break :eu,
|
||||
else => |e| return e,
|
||||
};
|
||||
},
|
||||
else => {
|
||||
const error_set = try sema.addConstant(
|
||||
@ -21303,9 +21306,12 @@ fn coerceExtra(
|
||||
.Undefined => {
|
||||
return sema.addConstUndef(dest_ty);
|
||||
},
|
||||
else => {
|
||||
else => eu: {
|
||||
// T to E!T
|
||||
return sema.wrapErrorUnionPayload(block, dest_ty, inst, inst_src);
|
||||
return sema.wrapErrorUnionPayload(block, dest_ty, inst, inst_src) catch |err| switch (err) {
|
||||
error.NotCoercible => break :eu,
|
||||
else => |e| return e,
|
||||
};
|
||||
},
|
||||
},
|
||||
.Union => switch (inst_ty.zigTypeTag()) {
|
||||
@ -24795,7 +24801,7 @@ fn wrapErrorUnionPayload(
|
||||
inst_src: LazySrcLoc,
|
||||
) !Air.Inst.Ref {
|
||||
const dest_payload_ty = dest_ty.errorUnionPayload();
|
||||
const coerced = try sema.coerce(block, dest_payload_ty, inst, inst_src);
|
||||
const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, false, false);
|
||||
if (try sema.resolveMaybeUndefVal(block, inst_src, coerced)) |val| {
|
||||
return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, val));
|
||||
}
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
export fn entry() void {
|
||||
var foo: u32 = @This(){};
|
||||
_ = foo;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:27: error: expected type 'u32', found 'tmp.tmp'
|
||||
// :1:1: note: struct declared here
|
||||
19
test/cases/compile_errors/nested_error_set_mismatch.zig
Normal file
19
test/cases/compile_errors/nested_error_set_mismatch.zig
Normal file
@ -0,0 +1,19 @@
|
||||
const NextError = error{NextError};
|
||||
const OtherError = error{OutOfMemory};
|
||||
|
||||
export fn entry() void {
|
||||
const a: ?NextError!i32 = foo();
|
||||
_ = a;
|
||||
}
|
||||
|
||||
fn foo() ?OtherError!i32 {
|
||||
return null;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=llvm
|
||||
// target=native
|
||||
//
|
||||
// :4:1: error: expected type '?error{NextError}!i32', found '?error{OutOfMemory}!i32'
|
||||
// :4:1: note: optional type child 'error{OutOfMemory}!i32' cannot cast into optional type child 'error{NextError}!i32'
|
||||
// :4:1: note: 'error.OutOfMemory' not a member of destination error set
|
||||
@ -5,4 +5,4 @@ test "example" { return 1; }
|
||||
// target=native
|
||||
// is_test=1
|
||||
//
|
||||
// :1:25: error: expected type 'void', found 'comptime_int'
|
||||
// :1:25: error: expected type '@typeInfo(@typeInfo(@TypeOf(tmp.test.example)).Fn.return_type.?).ErrorUnion.error_set!void', found 'comptime_int'
|
||||
@ -1,10 +0,0 @@
|
||||
export fn entry() void {
|
||||
var foo: u32 = @This(){};
|
||||
_ = foo;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:2:27: error: type 'u32' does not support array initialization
|
||||
@ -1,20 +0,0 @@
|
||||
const NextError = error{NextError};
|
||||
const OtherError = error{OutOfMemory};
|
||||
|
||||
export fn entry() void {
|
||||
const a: ?NextError!i32 = foo();
|
||||
_ = a;
|
||||
}
|
||||
|
||||
fn foo() ?OtherError!i32 {
|
||||
return null;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:5:34: error: expected type '?NextError!i32', found '?OtherError!i32'
|
||||
// tmp.zig:5:34: note: optional type child 'OtherError!i32' cannot cast into optional type child 'NextError!i32'
|
||||
// tmp.zig:5:34: note: error set 'OtherError' cannot cast into error set 'NextError'
|
||||
// tmp.zig:2:26: note: 'error.OutOfMemory' not a member of destination error set
|
||||
@ -3,7 +3,7 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=llvm
|
||||
// target=native
|
||||
//
|
||||
// ?:?:?: error: 10 unused arguments in '{d} {d} {d} {d} {d}'
|
||||
// :?:?: error: 10 unused arguments in '{d} {d} {d} {d} {d}'
|
||||
@ -4,7 +4,7 @@ export fn a() void {
|
||||
fn c(d: i32, e: i32, f: i32) void { _ = d; _ = e; _ = f; }
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:2:6: error: expected 3 argument(s), found 1
|
||||
// :2:6: error: expected 3 argument(s), found 1
|
||||
@ -4,7 +4,8 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:3:47: error: expected type 'std.builtin.AtomicOrder', found 'u32'
|
||||
// :3:47: error: expected type 'builtin.AtomicOrder', found 'u32'
|
||||
// :?:?: note: enum declared here
|
||||
@ -4,7 +4,8 @@ comptime {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:3:59: error: expected type 'std.builtin.GlobalLinkage', found 'comptime_int'
|
||||
// :3:50: error: expected type 'builtin.GlobalLinkage', found 'u32'
|
||||
// :?:?: note: enum declared here
|
||||
Loading…
x
Reference in New Issue
Block a user