authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-17 12:50:36+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-17 17:39:54+02:00
logc9dde10f8629c3ad2234f6220990b1dd70bac807
treef3f0a40024f282b8fae69dbc663c04dfbdc5a784
parent35e989235b29c5d921c8cf053a1d2f92fa0ce57a

stage1: improve error message when casting tuples


3 files changed, 40 insertions(+), 12 deletions(-)

doc/langref.html.in+1-1
...@@ -10405,7 +10405,7 @@ pub fn main() !void {...@@ -10405,7 +10405,7 @@ pub fn main() !void {
10405 <p>String literals such as {#syntax#}"foo"{#endsyntax#} are in the global constant data section.10405 <p>String literals such as {#syntax#}"foo"{#endsyntax#} are in the global constant data section.
10406 This is why it is an error to pass a string literal to a mutable slice, like this:10406 This is why it is an error to pass a string literal to a mutable slice, like this:
10407 </p>10407 </p>
10408 {#code_begin|test_err|expected type '[]u8'#}10408 {#code_begin|test_err|cannot cast pointer to array literal to slice type '[]u8'#}
10409fn foo(s: []u8) void {10409fn foo(s: []u8) void {
10410 _ = s;10410 _ = s;
10411}10411}
src/stage1/ir.cpp+27-4
...@@ -7843,7 +7843,7 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou...@@ -7843,7 +7843,7 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou
7843 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 07843 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0
7844 || !actual_type->data.pointer.is_const);7844 || !actual_type->data.pointer.is_const);
78457845
7846 if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type,7846 if (types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type,
7847 array_type->data.array.child_type, source_node,7847 array_type->data.array.child_type, source_node,
7848 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk &&7848 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk &&
7849 (slice_ptr_type->data.pointer.sentinel == nullptr ||7849 (slice_ptr_type->data.pointer.sentinel == nullptr ||
...@@ -7851,6 +7851,14 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou...@@ -7851,6 +7851,14 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou
7851 const_values_equal(ira->codegen, array_type->data.array.sentinel,7851 const_values_equal(ira->codegen, array_type->data.array.sentinel,
7852 slice_ptr_type->data.pointer.sentinel))))7852 slice_ptr_type->data.pointer.sentinel))))
7853 {7853 {
7854 if (!const_ok) {
7855 ErrorMsg *msg = ir_add_error_node(ira, source_node,
7856 buf_sprintf("cannot cast pointer to array literal to slice type '%s'",
7857 buf_ptr(&wanted_type->name)));
7858 add_error_note(ira->codegen, msg, source_node,
7859 buf_sprintf("cast discards const qualifier"));
7860 return ira->codegen->invalid_inst_gen;
7861 }
7854 // If the pointers both have ABI align, it works.7862 // If the pointers both have ABI align, it works.
7855 // Or if the array length is 0, alignment doesn't matter.7863 // Or if the array length is 0, alignment doesn't matter.
7856 bool ok_align = array_type->data.array.len == 0 ||7864 bool ok_align = array_type->data.array.len == 0 ||
...@@ -8208,8 +8216,16 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou...@@ -8208,8 +8216,16 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou
8208 ZigType *wanted_child = wanted_type->data.pointer.child_type;8216 ZigType *wanted_child = wanted_type->data.pointer.child_type;
8209 bool const_ok = (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const);8217 bool const_ok = (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const);
8210 if (wanted_child->id == ZigTypeIdArray && (is_array_init || field_count == 0) &&8218 if (wanted_child->id == ZigTypeIdArray && (is_array_init || field_count == 0) &&
8211 wanted_child->data.array.len == field_count && (const_ok || field_count == 0))8219 wanted_child->data.array.len == field_count)
8212 {8220 {
8221 if (!const_ok && field_count != 0) {
8222 ErrorMsg *msg = ir_add_error_node(ira, source_node,
8223 buf_sprintf("cannot cast pointer to array literal to '%s'",
8224 buf_ptr(&wanted_type->name)));
8225 add_error_note(ira->codegen, msg, source_node,
8226 buf_sprintf("cast discards const qualifier"));
8227 return ira->codegen->invalid_inst_gen;
8228 }
8213 Stage1AirInst *res = ir_analyze_struct_literal_to_array(ira, scope, source_node, value, anon_type, wanted_child);8229 Stage1AirInst *res = ir_analyze_struct_literal_to_array(ira, scope, source_node, value, anon_type, wanted_child);
8214 if (res->value->type->id == ZigTypeIdPointer)8230 if (res->value->type->id == ZigTypeIdPointer)
8215 return res;8231 return res;
...@@ -8241,6 +8257,13 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou...@@ -8241,6 +8257,13 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou
8241 res = ir_get_ref(ira, scope, source_node, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);8257 res = ir_get_ref(ira, scope, source_node, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);
82428258
8243 return ir_resolve_ptr_of_array_to_slice(ira, scope, source_node, res, wanted_type, nullptr);8259 return ir_resolve_ptr_of_array_to_slice(ira, scope, source_node, res, wanted_type, nullptr);
8260 } else if (!slice_type->data.pointer.is_const && actual_type->data.pointer.is_const && field_count != 0) {
8261 ErrorMsg *msg = ir_add_error_node(ira, source_node,
8262 buf_sprintf("cannot cast pointer to array literal to slice type '%s'",
8263 buf_ptr(&wanted_type->name)));
8264 add_error_note(ira->codegen, msg, source_node,
8265 buf_sprintf("cast discards const qualifier"));
8266 return ira->codegen->invalid_inst_gen;
8244 }8267 }
8245 }8268 }
8246 }8269 }
...@@ -15068,7 +15091,7 @@ static Stage1AirInst *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, Stage1ZirI...@@ -15068,7 +15091,7 @@ static Stage1AirInst *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, Stage1ZirI
15068 return ira->codegen->invalid_inst_gen;15091 return ira->codegen->invalid_inst_gen;
15069 if (actual_array_type->id != ZigTypeIdArray) {15092 if (actual_array_type->id != ZigTypeIdArray) {
15070 ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node,15093 ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node,
15071 buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'",15094 buf_sprintf("array literal requires address-of operator (&) to coerce to slice type '%s'",
15072 buf_ptr(&actual_array_type->name)));15095 buf_ptr(&actual_array_type->name)));
15073 return ira->codegen->invalid_inst_gen;15096 return ira->codegen->invalid_inst_gen;
15074 }15097 }
...@@ -17473,7 +17496,7 @@ static Stage1AirInst *ir_analyze_instruction_container_init_list(IrAnalyze *ira,...@@ -17473,7 +17496,7 @@ static Stage1AirInst *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
1747317496
17474 if (is_slice(container_type)) {17497 if (is_slice(container_type)) {
17475 ir_add_error_node(ira, instruction->init_array_type_source_node,17498 ir_add_error_node(ira, instruction->init_array_type_source_node,
17476 buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'",17499 buf_sprintf("array literal requires address-of operator (&) to coerce to slice type '%s'",
17477 buf_ptr(&container_type->name)));17500 buf_ptr(&container_type->name)));
17478 return ira->codegen->invalid_inst_gen;17501 return ira->codegen->invalid_inst_gen;
17479 }17502 }
test/compile_errors.zig+12-7
...@@ -86,9 +86,12 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -86,9 +86,12 @@ pub fn addCases(ctx: *TestContext) !void {
86 \\ _ = c;86 \\ _ = c;
87 \\}87 \\}
88 , &[_][]const u8{88 , &[_][]const u8{
89 "tmp.zig:2:31: error: expected type '[][]const u8', found '*const struct:2:31'",89 "tmp.zig:2:31: error: cannot cast pointer to array literal to slice type '[][]const u8'",
90 "tmp.zig:6:33: error: expected type '*[2][]const u8', found '*const struct:6:33'",90 "tmp.zig:2:31: note: cast discards const qualifier",
91 "tmp.zig:6:33: error: cannot cast pointer to array literal to '*[2][]const u8'",
92 "tmp.zig:6:33: note: cast discards const qualifier",
91 "tmp.zig:11:21: error: expected type '*S', found '*const struct:11:21'",93 "tmp.zig:11:21: error: expected type '*S', found '*const struct:11:21'",
94 "tmp.zig:11:21: note: cast discards const qualifier",
92 });95 });
9396
94 ctx.objErrStage1("@Type() union payload is undefined",97 ctx.objErrStage1("@Type() union payload is undefined",
...@@ -1962,7 +1965,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1962,7 +1965,7 @@ pub fn addCases(ctx: *TestContext) !void {
1962 \\ _ = geo_data;1965 \\ _ = geo_data;
1963 \\}1966 \\}
1964 , &[_][]const u8{1967 , &[_][]const u8{
1965 "tmp.zig:4:30: error: array literal requires address-of operator to coerce to slice type '[][2]f32'",1968 "tmp.zig:4:30: error: array literal requires address-of operator (&) to coerce to slice type '[][2]f32'",
1966 });1969 });
19671970
1968 ctx.objErrStage1("slicing of global undefined pointer",1971 ctx.objErrStage1("slicing of global undefined pointer",
...@@ -2537,7 +2540,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -2537,7 +2540,7 @@ pub fn addCases(ctx: *TestContext) !void {
2537 \\ _ = x;2540 \\ _ = x;
2538 \\}2541 \\}
2539 , &[_][]const u8{2542 , &[_][]const u8{
2540 "tmp.zig:2:15: error: array literal requires address-of operator to coerce to slice type '[]u8'",2543 "tmp.zig:2:15: error: array literal requires address-of operator (&) to coerce to slice type '[]u8'",
2541 });2544 });
25422545
2543 ctx.objErrStage1("slice passed as array init type",2546 ctx.objErrStage1("slice passed as array init type",
...@@ -2546,7 +2549,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -2546,7 +2549,7 @@ pub fn addCases(ctx: *TestContext) !void {
2546 \\ _ = x;2549 \\ _ = x;
2547 \\}2550 \\}
2548 , &[_][]const u8{2551 , &[_][]const u8{
2549 "tmp.zig:2:15: error: array literal requires address-of operator to coerce to slice type '[]u8'",2552 "tmp.zig:2:15: error: array literal requires address-of operator (&) to coerce to slice type '[]u8'",
2550 });2553 });
25512554
2552 ctx.objErrStage1("inferred array size invalid here",2555 ctx.objErrStage1("inferred array size invalid here",
...@@ -3493,7 +3496,8 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -3493,7 +3496,8 @@ pub fn addCases(ctx: *TestContext) !void {
3493 \\ _ = sliceA;3496 \\ _ = sliceA;
3494 \\}3497 \\}
3495 , &[_][]const u8{3498 , &[_][]const u8{
3496 "tmp.zig:3:27: error: expected type '[]u8', found '*const [1]u8'",3499 "tmp.zig:3:27: error: cannot cast pointer to array literal to slice type '[]u8'",
3500 "tmp.zig:3:27: note: cast discards const qualifier",
3497 });3501 });
34983502
3499 ctx.objErrStage1("deref slice and get len field",3503 ctx.objErrStage1("deref slice and get len field",
...@@ -8717,7 +8721,8 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -8717,7 +8721,8 @@ pub fn addCases(ctx: *TestContext) !void {
8717 \\ comptime ignore(@typeInfo(MyStruct).Struct.fields[0]);8721 \\ comptime ignore(@typeInfo(MyStruct).Struct.fields[0]);
8718 \\}8722 \\}
8719 , &[_][]const u8{8723 , &[_][]const u8{
8720 ":5:28: error: expected type '[]u8', found '*const [3:0]u8'",8724 ":5:28: error: cannot cast pointer to array literal to slice type '[]u8'",
8725 ":5:28: note: cast discards const qualifier",
8721 });8726 });
87228727
8723 ctx.objErrStage1("integer underflow error",8728 ctx.objErrStage1("integer underflow error",