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
signature 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...@@ -8242,6 +8242,34 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou
8242 return ir_implicit_cast2(ira, scope, source_node, cast1, wanted_type);8242 return ir_implicit_cast2(ira, scope, source_node, cast1, wanted_type);
8243 }8243 }
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
8245 ErrorMsg *parent_msg = ir_add_error_node(ira, source_node,8273 ErrorMsg *parent_msg = ir_add_error_node(ira, source_node,
8246 buf_sprintf("expected type '%s', found '%s'",8274 buf_sprintf("expected type '%s', found '%s'",
8247 buf_ptr(&wanted_type->name),8275 buf_ptr(&wanted_type->name),
test/compile_errors.zig+7-7
...@@ -790,9 +790,9 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -790,9 +790,9 @@ pub fn addCases(ctx: *TestContext) !void {
790 "tmp.zig:1:17: note: function cannot return an error",790 "tmp.zig:1:17: note: function cannot return an error",
791 "tmp.zig:8:5: error: expected type 'void', found '@typeInfo(@typeInfo(@TypeOf(bar)).Fn.return_type.?).ErrorUnion.error_set'",791 "tmp.zig:8:5: error: expected type 'void', found '@typeInfo(@typeInfo(@TypeOf(bar)).Fn.return_type.?).ErrorUnion.error_set'",
792 "tmp.zig:7:17: note: function cannot return an error",792 "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'",
794 "tmp.zig:10:17: note: function cannot return an error",794 "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'",
796 "tmp.zig:14:5: note: cannot store an error in type 'u32'",796 "tmp.zig:14:5: note: cannot store an error in type 'u32'",
797 });797 });
798798
...@@ -1879,7 +1879,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1879,7 +1879,7 @@ pub fn addCases(ctx: *TestContext) !void {
1879 \\ _ = afoo;1879 \\ _ = afoo;
1880 \\}1880 \\}
1881 , &[_][]const u8{1881 , &[_][]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'",
1883 });1883 });
18841884
1885 ctx.objErrStage1("assigning to struct or union fields that are not optionals with a function that returns an optional",1885 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 {...@@ -1899,7 +1899,7 @@ pub fn addCases(ctx: *TestContext) !void {
1899 \\ _ = s;1899 \\ _ = s;
1900 \\}1900 \\}
1901 , &[_][]const u8{1901 , &[_][]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'",
1903 });1903 });
19041904
1905 ctx.objErrStage1("missing result type for phi node",1905 ctx.objErrStage1("missing result type for phi node",
...@@ -2308,7 +2308,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -2308,7 +2308,7 @@ pub fn addCases(ctx: *TestContext) !void {
2308 \\ not_optional: i32,2308 \\ not_optional: i32,
2309 \\};2309 \\};
2310 , &[_][]const u8{2310 , &[_][]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'",
2312 });2312 });
23132313
2314 ctx.objErrStage1("result location incompatibility mismatching handle_is_ptr",2314 ctx.objErrStage1("result location incompatibility mismatching handle_is_ptr",
...@@ -2325,7 +2325,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -2325,7 +2325,7 @@ pub fn addCases(ctx: *TestContext) !void {
2325 \\ not_optional: i32,2325 \\ not_optional: i32,
2326 \\};2326 \\};
2327 , &[_][]const u8{2327 , &[_][]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'",
2329 });2329 });
23302330
2331 ctx.objErrStage1("const frame cast to anyframe",2331 ctx.objErrStage1("const frame cast to anyframe",
...@@ -8828,7 +8828,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -8828,7 +8828,7 @@ pub fn addCases(ctx: *TestContext) !void {
8828 \\ v = u;8828 \\ v = u;
8829 \\}8829 \\}
8830 , &[_][]const u8{8830 , &[_][]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'",
8832 });8832 });
88338833
8834 ctx.objErrStage1("Issue #6823: don't allow .* to be followed by **",8834 ctx.objErrStage1("Issue #6823: don't allow .* to be followed by **",