mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
stage1: improve error message when casting tuples
This commit is contained in:
parent
35e989235b
commit
c9dde10f86
3 changed files with 40 additions and 12 deletions
|
|
@ -10405,7 +10405,7 @@ pub fn main() !void {
|
||||||
<p>String literals such as {#syntax#}"foo"{#endsyntax#} are in the global constant data section.
|
<p>String literals such as {#syntax#}"foo"{#endsyntax#} are in the global constant data section.
|
||||||
This is why it is an error to pass a string literal to a mutable slice, like this:
|
This is why it is an error to pass a string literal to a mutable slice, like this:
|
||||||
</p>
|
</p>
|
||||||
{#code_begin|test_err|expected type '[]u8'#}
|
{#code_begin|test_err|cannot cast pointer to array literal to slice type '[]u8'#}
|
||||||
fn foo(s: []u8) void {
|
fn foo(s: []u8) void {
|
||||||
_ = s;
|
_ = s;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7843,7 +7843,7 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou
|
||||||
bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0
|
bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0
|
||||||
|| !actual_type->data.pointer.is_const);
|
|| !actual_type->data.pointer.is_const);
|
||||||
|
|
||||||
if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type,
|
if (types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type,
|
||||||
array_type->data.array.child_type, source_node,
|
array_type->data.array.child_type, source_node,
|
||||||
!slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk &&
|
!slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk &&
|
||||||
(slice_ptr_type->data.pointer.sentinel == nullptr ||
|
(slice_ptr_type->data.pointer.sentinel == nullptr ||
|
||||||
|
|
@ -7851,6 +7851,14 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou
|
||||||
const_values_equal(ira->codegen, array_type->data.array.sentinel,
|
const_values_equal(ira->codegen, array_type->data.array.sentinel,
|
||||||
slice_ptr_type->data.pointer.sentinel))))
|
slice_ptr_type->data.pointer.sentinel))))
|
||||||
{
|
{
|
||||||
|
if (!const_ok) {
|
||||||
|
ErrorMsg *msg = ir_add_error_node(ira, source_node,
|
||||||
|
buf_sprintf("cannot cast pointer to array literal to slice type '%s'",
|
||||||
|
buf_ptr(&wanted_type->name)));
|
||||||
|
add_error_note(ira->codegen, msg, source_node,
|
||||||
|
buf_sprintf("cast discards const qualifier"));
|
||||||
|
return ira->codegen->invalid_inst_gen;
|
||||||
|
}
|
||||||
// If the pointers both have ABI align, it works.
|
// If the pointers both have ABI align, it works.
|
||||||
// Or if the array length is 0, alignment doesn't matter.
|
// Or if the array length is 0, alignment doesn't matter.
|
||||||
bool ok_align = array_type->data.array.len == 0 ||
|
bool ok_align = array_type->data.array.len == 0 ||
|
||||||
|
|
@ -8208,8 +8216,16 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou
|
||||||
ZigType *wanted_child = wanted_type->data.pointer.child_type;
|
ZigType *wanted_child = wanted_type->data.pointer.child_type;
|
||||||
bool const_ok = (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const);
|
bool const_ok = (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const);
|
||||||
if (wanted_child->id == ZigTypeIdArray && (is_array_init || field_count == 0) &&
|
if (wanted_child->id == ZigTypeIdArray && (is_array_init || field_count == 0) &&
|
||||||
wanted_child->data.array.len == field_count && (const_ok || field_count == 0))
|
wanted_child->data.array.len == field_count)
|
||||||
{
|
{
|
||||||
|
if (!const_ok && field_count != 0) {
|
||||||
|
ErrorMsg *msg = ir_add_error_node(ira, source_node,
|
||||||
|
buf_sprintf("cannot cast pointer to array literal to '%s'",
|
||||||
|
buf_ptr(&wanted_type->name)));
|
||||||
|
add_error_note(ira->codegen, msg, source_node,
|
||||||
|
buf_sprintf("cast discards const qualifier"));
|
||||||
|
return ira->codegen->invalid_inst_gen;
|
||||||
|
}
|
||||||
Stage1AirInst *res = ir_analyze_struct_literal_to_array(ira, scope, source_node, value, anon_type, wanted_child);
|
Stage1AirInst *res = ir_analyze_struct_literal_to_array(ira, scope, source_node, value, anon_type, wanted_child);
|
||||||
if (res->value->type->id == ZigTypeIdPointer)
|
if (res->value->type->id == ZigTypeIdPointer)
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -8241,6 +8257,13 @@ static Stage1AirInst *ir_analyze_cast(IrAnalyze *ira, Scope *scope, AstNode *sou
|
||||||
res = ir_get_ref(ira, scope, source_node, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);
|
res = ir_get_ref(ira, scope, source_node, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);
|
||||||
|
|
||||||
return ir_resolve_ptr_of_array_to_slice(ira, scope, source_node, res, wanted_type, nullptr);
|
return ir_resolve_ptr_of_array_to_slice(ira, scope, source_node, res, wanted_type, nullptr);
|
||||||
|
} else if (!slice_type->data.pointer.is_const && actual_type->data.pointer.is_const && field_count != 0) {
|
||||||
|
ErrorMsg *msg = ir_add_error_node(ira, source_node,
|
||||||
|
buf_sprintf("cannot cast pointer to array literal to slice type '%s'",
|
||||||
|
buf_ptr(&wanted_type->name)));
|
||||||
|
add_error_note(ira->codegen, msg, source_node,
|
||||||
|
buf_sprintf("cast discards const qualifier"));
|
||||||
|
return ira->codegen->invalid_inst_gen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -15068,7 +15091,7 @@ static Stage1AirInst *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, Stage1ZirI
|
||||||
return ira->codegen->invalid_inst_gen;
|
return ira->codegen->invalid_inst_gen;
|
||||||
if (actual_array_type->id != ZigTypeIdArray) {
|
if (actual_array_type->id != ZigTypeIdArray) {
|
||||||
ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node,
|
ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node,
|
||||||
buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'",
|
buf_sprintf("array literal requires address-of operator (&) to coerce to slice type '%s'",
|
||||||
buf_ptr(&actual_array_type->name)));
|
buf_ptr(&actual_array_type->name)));
|
||||||
return ira->codegen->invalid_inst_gen;
|
return ira->codegen->invalid_inst_gen;
|
||||||
}
|
}
|
||||||
|
|
@ -17473,7 +17496,7 @@ static Stage1AirInst *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
|
||||||
|
|
||||||
if (is_slice(container_type)) {
|
if (is_slice(container_type)) {
|
||||||
ir_add_error_node(ira, instruction->init_array_type_source_node,
|
ir_add_error_node(ira, instruction->init_array_type_source_node,
|
||||||
buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'",
|
buf_sprintf("array literal requires address-of operator (&) to coerce to slice type '%s'",
|
||||||
buf_ptr(&container_type->name)));
|
buf_ptr(&container_type->name)));
|
||||||
return ira->codegen->invalid_inst_gen;
|
return ira->codegen->invalid_inst_gen;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,9 +86,12 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||||
\\ _ = c;
|
\\ _ = c;
|
||||||
\\}
|
\\}
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
"tmp.zig:2:31: error: expected type '[][]const u8', found '*const struct:2:31'",
|
"tmp.zig:2:31: error: cannot cast pointer to array literal to slice type '[][]const u8'",
|
||||||
"tmp.zig:6:33: error: expected type '*[2][]const u8', found '*const struct:6:33'",
|
"tmp.zig:2:31: note: cast discards const qualifier",
|
||||||
|
"tmp.zig:6:33: error: cannot cast pointer to array literal to '*[2][]const u8'",
|
||||||
|
"tmp.zig:6:33: note: cast discards const qualifier",
|
||||||
"tmp.zig:11:21: error: expected type '*S', found '*const struct:11:21'",
|
"tmp.zig:11:21: error: expected type '*S', found '*const struct:11:21'",
|
||||||
|
"tmp.zig:11:21: note: cast discards const qualifier",
|
||||||
});
|
});
|
||||||
|
|
||||||
ctx.objErrStage1("@Type() union payload is undefined",
|
ctx.objErrStage1("@Type() union payload is undefined",
|
||||||
|
|
@ -1962,7 +1965,7 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||||
\\ _ = geo_data;
|
\\ _ = geo_data;
|
||||||
\\}
|
\\}
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
"tmp.zig:4:30: error: array literal requires address-of operator to coerce to slice type '[][2]f32'",
|
"tmp.zig:4:30: error: array literal requires address-of operator (&) to coerce to slice type '[][2]f32'",
|
||||||
});
|
});
|
||||||
|
|
||||||
ctx.objErrStage1("slicing of global undefined pointer",
|
ctx.objErrStage1("slicing of global undefined pointer",
|
||||||
|
|
@ -2537,7 +2540,7 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||||
\\ _ = x;
|
\\ _ = x;
|
||||||
\\}
|
\\}
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
"tmp.zig:2:15: error: array literal requires address-of operator to coerce to slice type '[]u8'",
|
"tmp.zig:2:15: error: array literal requires address-of operator (&) to coerce to slice type '[]u8'",
|
||||||
});
|
});
|
||||||
|
|
||||||
ctx.objErrStage1("slice passed as array init type",
|
ctx.objErrStage1("slice passed as array init type",
|
||||||
|
|
@ -2546,7 +2549,7 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||||
\\ _ = x;
|
\\ _ = x;
|
||||||
\\}
|
\\}
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
"tmp.zig:2:15: error: array literal requires address-of operator to coerce to slice type '[]u8'",
|
"tmp.zig:2:15: error: array literal requires address-of operator (&) to coerce to slice type '[]u8'",
|
||||||
});
|
});
|
||||||
|
|
||||||
ctx.objErrStage1("inferred array size invalid here",
|
ctx.objErrStage1("inferred array size invalid here",
|
||||||
|
|
@ -3493,7 +3496,8 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||||
\\ _ = sliceA;
|
\\ _ = sliceA;
|
||||||
\\}
|
\\}
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
"tmp.zig:3:27: error: expected type '[]u8', found '*const [1]u8'",
|
"tmp.zig:3:27: error: cannot cast pointer to array literal to slice type '[]u8'",
|
||||||
|
"tmp.zig:3:27: note: cast discards const qualifier",
|
||||||
});
|
});
|
||||||
|
|
||||||
ctx.objErrStage1("deref slice and get len field",
|
ctx.objErrStage1("deref slice and get len field",
|
||||||
|
|
@ -8717,7 +8721,8 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||||
\\ comptime ignore(@typeInfo(MyStruct).Struct.fields[0]);
|
\\ comptime ignore(@typeInfo(MyStruct).Struct.fields[0]);
|
||||||
\\}
|
\\}
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
":5:28: error: expected type '[]u8', found '*const [3:0]u8'",
|
":5:28: error: cannot cast pointer to array literal to slice type '[]u8'",
|
||||||
|
":5:28: note: cast discards const qualifier",
|
||||||
});
|
});
|
||||||
|
|
||||||
ctx.objErrStage1("integer underflow error",
|
ctx.objErrStage1("integer underflow error",
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue