Commit 0bc82a9070
Changed files (2)
src
stage1
src/stage1/ir.cpp
@@ -15955,38 +15955,46 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr,
anon_type->data.structure.special == StructSpecialInferredTuple;
const uint32_t field_count = anon_type->data.structure.src_field_count;
- if (wanted_type->id == ZigTypeIdPointer) {
+ if (wanted_type->id == ZigTypeIdPointer &&
+ (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile))
+ {
ZigType *wanted_child = wanted_type->data.pointer.child_type;
+ 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) &&
- wanted_child->data.array.len == field_count)
+ wanted_child->data.array.len == field_count && (const_ok || field_count == 0))
{
IrInstGen *res = ir_analyze_struct_literal_to_array(ira, source_instr, value, anon_type, wanted_child);
if (res->value->type->id == ZigTypeIdPointer)
return res;
- return ir_get_ref(ira, source_instr, res, wanted_type->data.pointer.is_const, wanted_type->data.pointer.is_volatile);
+ return ir_get_ref(ira, source_instr, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);
} else if (wanted_child->id == ZigTypeIdStruct && !is_slice(wanted_type) &&
- (!is_array_init || field_count == 0))
+ (!is_array_init || field_count == 0) && const_ok)
{
IrInstGen *res = ir_analyze_struct_literal_to_struct(ira, source_instr, value, anon_type, wanted_child);
if (res->value->type->id == ZigTypeIdPointer)
return res;
- return ir_get_ref(ira, source_instr, res, wanted_type->data.pointer.is_const, wanted_type->data.pointer.is_volatile);
- } else if (wanted_child->id == ZigTypeIdUnion && !is_array_init && field_count == 1) {
+ return ir_get_ref(ira, source_instr, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);
+ } else if (wanted_child->id == ZigTypeIdUnion && !is_array_init && field_count == 1 && const_ok) {
IrInstGen *res = ir_analyze_struct_literal_to_union(ira, source_instr, value, anon_type, wanted_child);
if (res->value->type->id == ZigTypeIdPointer)
return res;
- return ir_get_ref(ira, source_instr, res, wanted_type->data.pointer.is_const, wanted_type->data.pointer.is_volatile);
+ return ir_get_ref(ira, source_instr, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);
}
} else if (is_slice(wanted_type) && (is_array_init || field_count == 0)) {
- ZigType *slice_child_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.child_type;
- ZigType *slice_array_type = get_array_type(ira->codegen, slice_child_type, field_count, nullptr);
- IrInstGen *res = ir_analyze_struct_literal_to_array(ira, source_instr, value, anon_type, slice_array_type);
- if (type_is_invalid(res->value->type))
- return ira->codegen->invalid_inst_gen;
- if (res->value->type->id != ZigTypeIdPointer)
- res = ir_get_ref(ira, source_instr, res, wanted_type->data.pointer.is_const, wanted_type->data.pointer.is_volatile);
+ ZigType *slice_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry;
+ if ((!actual_type->data.pointer.is_const || slice_type->data.pointer.is_const || field_count == 0) &&
+ (!actual_type->data.pointer.is_volatile || slice_type->data.pointer.is_volatile))
+ {
+ ZigType *slice_child_type = slice_type->data.pointer.child_type;
+ ZigType *slice_array_type = get_array_type(ira->codegen, slice_child_type, field_count, nullptr);
+ IrInstGen *res = ir_analyze_struct_literal_to_array(ira, source_instr, value, anon_type, slice_array_type);
+ if (type_is_invalid(res->value->type))
+ return ira->codegen->invalid_inst_gen;
+ if (res->value->type->id != ZigTypeIdPointer)
+ res = ir_get_ref(ira, source_instr, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile);
- return ir_resolve_ptr_of_array_to_slice(ira, source_instr, res, wanted_type, nullptr);
+ return ir_resolve_ptr_of_array_to_slice(ira, source_instr, res, wanted_type, nullptr);
+ }
}
}
test/compile_errors.zig
@@ -12,6 +12,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"tmp.zig:4:17: error: integer value 1 cannot be coerced to type '*[10]u8'",
});
+ cases.add("pointer attributes checked when coercing pointer to anon literal",
+ \\comptime {
+ \\ const c: [][]const u8 = &.{"hello", "world" };
+ \\}
+ \\comptime {
+ \\ const c: *[2][]const u8 = &.{"hello", "world" };
+ \\}
+ \\const S = struct {a: u8 = 1, b: u32 = 2};
+ \\comptime {
+ \\ const c: *S = &.{};
+ \\}
+ , &[_][]const u8{
+ "mp.zig:2:31: error: expected type '[][]const u8', found '*const struct:2:31'",
+ "mp.zig:5:33: error: expected type '*[2][]const u8', found '*const struct:5:33'",
+ "mp.zig:9:21: error: expected type '*S', found '*const struct:9:21'",
+ });
+
cases.add("@Type() union payload is undefined",
\\const Foo = @Type(@import("std").builtin.TypeInfo{
\\ .Struct = undefined,