mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
Sema: better error when coercing error sets
This commit is contained in:
parent
7862ab9f41
commit
d6e3988fe8
10 changed files with 53 additions and 45 deletions
18
src/Sema.zig
18
src/Sema.zig
|
|
@ -5496,7 +5496,7 @@ fn analyzeCall(
|
||||||
// TODO add error note: declared here
|
// TODO add error note: declared here
|
||||||
return sema.fail(
|
return sema.fail(
|
||||||
block,
|
block,
|
||||||
func_src,
|
call_src,
|
||||||
"expected {d} argument(s), found {d}",
|
"expected {d} argument(s), found {d}",
|
||||||
.{ fn_params_len, uncasted_args.len },
|
.{ fn_params_len, uncasted_args.len },
|
||||||
);
|
);
|
||||||
|
|
@ -21275,7 +21275,7 @@ fn coerceExtra(
|
||||||
else => {},
|
else => {},
|
||||||
},
|
},
|
||||||
.ErrorUnion => switch (inst_ty.zigTypeTag()) {
|
.ErrorUnion => switch (inst_ty.zigTypeTag()) {
|
||||||
.ErrorUnion => {
|
.ErrorUnion => eu: {
|
||||||
if (maybe_inst_val) |inst_val| {
|
if (maybe_inst_val) |inst_val| {
|
||||||
switch (inst_val.tag()) {
|
switch (inst_val.tag()) {
|
||||||
.undef => return sema.addConstUndef(dest_ty),
|
.undef => return sema.addConstUndef(dest_ty),
|
||||||
|
|
@ -21284,7 +21284,10 @@ fn coerceExtra(
|
||||||
inst_ty.errorUnionPayload(),
|
inst_ty.errorUnionPayload(),
|
||||||
inst_val.castTag(.eu_payload).?.data,
|
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 => {
|
else => {
|
||||||
const error_set = try sema.addConstant(
|
const error_set = try sema.addConstant(
|
||||||
|
|
@ -21303,9 +21306,12 @@ fn coerceExtra(
|
||||||
.Undefined => {
|
.Undefined => {
|
||||||
return sema.addConstUndef(dest_ty);
|
return sema.addConstUndef(dest_ty);
|
||||||
},
|
},
|
||||||
else => {
|
else => eu: {
|
||||||
// T to E!T
|
// 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()) {
|
.Union => switch (inst_ty.zigTypeTag()) {
|
||||||
|
|
@ -24795,7 +24801,7 @@ fn wrapErrorUnionPayload(
|
||||||
inst_src: LazySrcLoc,
|
inst_src: LazySrcLoc,
|
||||||
) !Air.Inst.Ref {
|
) !Air.Inst.Ref {
|
||||||
const dest_payload_ty = dest_ty.errorUnionPayload();
|
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| {
|
if (try sema.resolveMaybeUndefVal(block, inst_src, coerced)) |val| {
|
||||||
return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, 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
|
// target=native
|
||||||
// is_test=1
|
// 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
|
// error
|
||||||
// backend=stage1
|
// backend=llvm
|
||||||
// target=native
|
// 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; }
|
fn c(d: i32, e: i32, f: i32) void { _ = d; _ = e; _ = f; }
|
||||||
|
|
||||||
// error
|
// error
|
||||||
// backend=stage1
|
// backend=stage2
|
||||||
// target=native
|
// 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
|
// error
|
||||||
// backend=stage1
|
// backend=stage2
|
||||||
// target=native
|
// 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
|
// error
|
||||||
// backend=stage1
|
// backend=stage2
|
||||||
// target=native
|
// 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…
Add table
Reference in a new issue