stage 1: improve error message if error union is cast to payload (#10770)

Also: Added special error message for for `?T` to `T` casting
This commit is contained in:
Sebsatian Keller 2022-02-10 02:35:53 +01:00 committed by GitHub
parent 1e5a494603
commit f5471299d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 7 deletions

View file

@ -8242,6 +8242,34 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou
return ir_implicit_cast2(ira, scope, source_node, cast1, wanted_type); return ir_implicit_cast2(ira, scope, source_node, cast1, wanted_type);
} }
// E!T to T
if (actual_type->id == ZigTypeIdErrorUnion) {
if (types_match_const_cast_only(ira, actual_type->data.error_union.payload_type, wanted_type,
source_node, false).id == ConstCastResultIdOk)
{
ErrorMsg *parent_msg = ir_add_error_node(ira, source_node,
buf_sprintf("cannot convert error union to payload type. consider using `try`, `catch`, or `if`. expected type '%s', found '%s'",
buf_ptr(&wanted_type->name),
buf_ptr(&actual_type->name)));
report_recursive_error(ira, source_node, &const_cast_result, parent_msg);
return ira->codegen->invalid_inst_gen;
}
}
//?T to T
if (actual_type->id == ZigTypeIdOptional) {
if (types_match_const_cast_only(ira, actual_type->data.maybe.child_type, wanted_type,
source_node, false).id == ConstCastResultIdOk)
{
ErrorMsg *parent_msg = ir_add_error_node(ira, source_node,
buf_sprintf("cannot convert optional to payload type. consider using `.?`, `orelse`, or `if`. expected type '%s', found '%s'",
buf_ptr(&wanted_type->name),
buf_ptr(&actual_type->name)));
report_recursive_error(ira, source_node, &const_cast_result, parent_msg);
return ira->codegen->invalid_inst_gen;
}
}
ErrorMsg *parent_msg = ir_add_error_node(ira, source_node, ErrorMsg *parent_msg = ir_add_error_node(ira, source_node,
buf_sprintf("expected type '%s', found '%s'", buf_sprintf("expected type '%s', found '%s'",
buf_ptr(&wanted_type->name), buf_ptr(&wanted_type->name),

View file

@ -790,9 +790,9 @@ pub fn addCases(ctx: *TestContext) !void {
"tmp.zig:1:17: note: function cannot return an error", "tmp.zig:1:17: note: function cannot return an error",
"tmp.zig:8:5: error: expected type 'void', found '@typeInfo(@typeInfo(@TypeOf(bar)).Fn.return_type.?).ErrorUnion.error_set'", "tmp.zig:8:5: error: expected type 'void', found '@typeInfo(@typeInfo(@TypeOf(bar)).Fn.return_type.?).ErrorUnion.error_set'",
"tmp.zig:7:17: note: function cannot return an error", "tmp.zig:7:17: note: function cannot return an error",
"tmp.zig:11:15: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(bar)).Fn.return_type.?).ErrorUnion.error_set!u32'", "tmp.zig:11:15: error: cannot convert error union to payload type. consider using `try`, `catch`, or `if`. expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(bar)).Fn.return_type.?).ErrorUnion.error_set!u32'",
"tmp.zig:10:17: note: function cannot return an error", "tmp.zig:10:17: note: function cannot return an error",
"tmp.zig:15:14: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(bar)).Fn.return_type.?).ErrorUnion.error_set!u32'", "tmp.zig:15:14: error: cannot convert error union to payload type. consider using `try`, `catch`, or `if`. expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(bar)).Fn.return_type.?).ErrorUnion.error_set!u32'",
"tmp.zig:14:5: note: cannot store an error in type 'u32'", "tmp.zig:14:5: note: cannot store an error in type 'u32'",
}); });
@ -1879,7 +1879,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ _ = afoo; \\ _ = afoo;
\\} \\}
, &[_][]const u8{ , &[_][]const u8{
"tmp.zig:12:25: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(get_uval)).Fn.return_type.?).ErrorUnion.error_set!u32'", "tmp.zig:12:25: error: cannot convert error union to payload type. consider using `try`, `catch`, or `if`. expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(get_uval)).Fn.return_type.?).ErrorUnion.error_set!u32'",
}); });
ctx.objErrStage1("assigning to struct or union fields that are not optionals with a function that returns an optional", ctx.objErrStage1("assigning to struct or union fields that are not optionals with a function that returns an optional",
@ -1899,7 +1899,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ _ = s; \\ _ = s;
\\} \\}
, &[_][]const u8{ , &[_][]const u8{
"tmp.zig:11:27: error: expected type 'u8', found '?u8'", "tmp.zig:11:27: error: cannot convert optional to payload type. consider using `.?`, `orelse`, or `if`. expected type 'u8', found '?u8'",
}); });
ctx.objErrStage1("missing result type for phi node", ctx.objErrStage1("missing result type for phi node",
@ -2308,7 +2308,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ not_optional: i32, \\ not_optional: i32,
\\}; \\};
, &[_][]const u8{ , &[_][]const u8{
"tmp.zig:3:36: error: expected type 'i32', found '?i32'", "tmp.zig:3:36: error: cannot convert optional to payload type. consider using `.?`, `orelse`, or `if`. expected type 'i32', found '?i32'",
}); });
ctx.objErrStage1("result location incompatibility mismatching handle_is_ptr", ctx.objErrStage1("result location incompatibility mismatching handle_is_ptr",
@ -2325,7 +2325,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ not_optional: i32, \\ not_optional: i32,
\\}; \\};
, &[_][]const u8{ , &[_][]const u8{
"tmp.zig:3:36: error: expected type 'i32', found '?i32'", "tmp.zig:3:36: error: cannot convert optional to payload type. consider using `.?`, `orelse`, or `if`. expected type 'i32', found '?i32'",
}); });
ctx.objErrStage1("const frame cast to anyframe", ctx.objErrStage1("const frame cast to anyframe",
@ -8828,7 +8828,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ v = u; \\ v = u;
\\} \\}
, &[_][]const u8{ , &[_][]const u8{
"tmp.zig:4:9: error: expected type '*anyopaque', found '?*anyopaque'", "tmp.zig:4:9: error: cannot convert optional to payload type. consider using `.?`, `orelse`, or `if`. expected type '*anyopaque', found '?*anyopaque'",
}); });
ctx.objErrStage1("Issue #6823: don't allow .* to be followed by **", ctx.objErrStage1("Issue #6823: don't allow .* to be followed by **",