authorgravatar for sebastiankeller@fastmail.netSebsatian Keller <sebastiankeller@fastmail.net> 2022-02-10 02:35:53+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-02-09 20:35:53-05:00
logf5471299d81e809c706e147d2ea79c83aeb8b650
tree1683dd8fbabedf2ffc1e6abb6c7d838f619f41d1
parent1e5a494603d287ea3005dc35f0528c0311f43515
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

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

Also: Added special error message for for `?T` to `T` casting

2 files changed, 35 insertions(+), 7 deletions(-)

src/stage1/ir.cpp+28
......@@ -8242,6 +8242,34 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou
82428242 return ir_implicit_cast2(ira, scope, source_node, cast1, wanted_type);
82438243 }
82448244
8245 // E!T to T
8246 if (actual_type->id == ZigTypeIdErrorUnion) {
8247 if (types_match_const_cast_only(ira, actual_type->data.error_union.payload_type, wanted_type,
8248 source_node, false).id == ConstCastResultIdOk)
8249 {
8250 ErrorMsg *parent_msg = ir_add_error_node(ira, source_node,
8251 buf_sprintf("cannot convert error union to payload type. consider using `try`, `catch`, or `if`. expected type '%s', found '%s'",
8252 buf_ptr(&wanted_type->name),
8253 buf_ptr(&actual_type->name)));
8254 report_recursive_error(ira, source_node, &const_cast_result, parent_msg);
8255 return ira->codegen->invalid_inst_gen;
8256 }
8257 }
8258
8259 //?T to T
8260 if (actual_type->id == ZigTypeIdOptional) {
8261 if (types_match_const_cast_only(ira, actual_type->data.maybe.child_type, wanted_type,
8262 source_node, false).id == ConstCastResultIdOk)
8263 {
8264 ErrorMsg *parent_msg = ir_add_error_node(ira, source_node,
8265 buf_sprintf("cannot convert optional to payload type. consider using `.?`, `orelse`, or `if`. expected type '%s', found '%s'",
8266 buf_ptr(&wanted_type->name),
8267 buf_ptr(&actual_type->name)));
8268 report_recursive_error(ira, source_node, &const_cast_result, parent_msg);
8269 return ira->codegen->invalid_inst_gen;
8270 }
8271 }
8272
82458273 ErrorMsg *parent_msg = ir_add_error_node(ira, source_node,
82468274 buf_sprintf("expected type '%s', found '%s'",
82478275 buf_ptr(&wanted_type->name),
test/compile_errors.zig+7-7
......@@ -790,9 +790,9 @@ pub fn addCases(ctx: *TestContext) !void {
790790 "tmp.zig:1:17: note: function cannot return an error",
791791 "tmp.zig:8:5: error: expected type 'void', found '@typeInfo(@typeInfo(@TypeOf(bar)).Fn.return_type.?).ErrorUnion.error_set'",
792792 "tmp.zig:7:17: note: function cannot return an error",
793 "tmp.zig:11:15: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(bar)).Fn.return_type.?).ErrorUnion.error_set!u32'",
793 "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'",
794794 "tmp.zig:10:17: note: function cannot return an error",
795 "tmp.zig:15:14: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(bar)).Fn.return_type.?).ErrorUnion.error_set!u32'",
795 "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'",
796796 "tmp.zig:14:5: note: cannot store an error in type 'u32'",
797797 });
798798
......@@ -1879,7 +1879,7 @@ pub fn addCases(ctx: *TestContext) !void {
18791879 \\ _ = afoo;
18801880 \\}
18811881 , &[_][]const u8{
1882 "tmp.zig:12:25: error: expected type 'u32', found '@typeInfo(@typeInfo(@TypeOf(get_uval)).Fn.return_type.?).ErrorUnion.error_set!u32'",
1882 "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'",
18831883 });
18841884
18851885 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 {
18991899 \\ _ = s;
19001900 \\}
19011901 , &[_][]const u8{
1902 "tmp.zig:11:27: error: expected type 'u8', found '?u8'",
1902 "tmp.zig:11:27: error: cannot convert optional to payload type. consider using `.?`, `orelse`, or `if`. expected type 'u8', found '?u8'",
19031903 });
19041904
19051905 ctx.objErrStage1("missing result type for phi node",
......@@ -2308,7 +2308,7 @@ pub fn addCases(ctx: *TestContext) !void {
23082308 \\ not_optional: i32,
23092309 \\};
23102310 , &[_][]const u8{
2311 "tmp.zig:3:36: error: expected type 'i32', found '?i32'",
2311 "tmp.zig:3:36: error: cannot convert optional to payload type. consider using `.?`, `orelse`, or `if`. expected type 'i32', found '?i32'",
23122312 });
23132313
23142314 ctx.objErrStage1("result location incompatibility mismatching handle_is_ptr",
......@@ -2325,7 +2325,7 @@ pub fn addCases(ctx: *TestContext) !void {
23252325 \\ not_optional: i32,
23262326 \\};
23272327 , &[_][]const u8{
2328 "tmp.zig:3:36: error: expected type 'i32', found '?i32'",
2328 "tmp.zig:3:36: error: cannot convert optional to payload type. consider using `.?`, `orelse`, or `if`. expected type 'i32', found '?i32'",
23292329 });
23302330
23312331 ctx.objErrStage1("const frame cast to anyframe",
......@@ -8828,7 +8828,7 @@ pub fn addCases(ctx: *TestContext) !void {
88288828 \\ v = u;
88298829 \\}
88308830 , &[_][]const u8{
8831 "tmp.zig:4:9: error: expected type '*anyopaque', found '?*anyopaque'",
8831 "tmp.zig:4:9: error: cannot convert optional to payload type. consider using `.?`, `orelse`, or `if`. expected type '*anyopaque', found '?*anyopaque'",
88328832 });
88338833
88348834 ctx.objErrStage1("Issue #6823: don't allow .* to be followed by **",