stage2: better pointer source location

This commit is contained in:
Veikka Tuominen 2022-07-12 16:08:23 +03:00 committed by Andrew Kelley
parent 29815fe9de
commit d729173204
17 changed files with 202 additions and 152 deletions

View File

@ -1347,7 +1347,7 @@ fn arrayInitExpr(
}
}
const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr);
_ = try gz.addUnNode(.validate_array_init_ty, array_type_inst, node);
_ = try gz.addUnNode(.validate_array_init_ty, array_type_inst, array_init.ast.type_expr);
break :inst .{
.array = array_type_inst,
.elem = .none,
@ -2332,7 +2332,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
.err_union_code,
.err_union_code_ptr,
.ptr_type,
.ptr_type_simple,
.overflow_arithmetic_ptr,
.enum_literal,
.merge_error_sets,
.error_union_type,
@ -3110,24 +3110,6 @@ fn ptrType(
const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type);
const simple = ptr_info.ast.align_node == 0 and
ptr_info.ast.addrspace_node == 0 and
ptr_info.ast.sentinel == 0 and
ptr_info.ast.bit_range_start == 0;
if (simple) {
const result = try gz.add(.{ .tag = .ptr_type_simple, .data = .{
.ptr_type_simple = .{
.is_allowzero = ptr_info.allowzero_token != null,
.is_mutable = ptr_info.const_token == null,
.is_volatile = ptr_info.volatile_token != null,
.size = ptr_info.size,
.elem_type = elem_type,
},
} });
return rvalue(gz, rl, result, node);
}
var sentinel_ref: Zir.Inst.Ref = .none;
var align_ref: Zir.Inst.Ref = .none;
var addrspace_ref: Zir.Inst.Ref = .none;
@ -3160,7 +3142,10 @@ fn ptrType(
try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.PtrType).Struct.fields.len +
trailing_count);
const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.PtrType{ .elem_type = elem_type });
const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.PtrType{
.elem_type = elem_type,
.src_node = gz.nodeIndexToRelative(node),
});
if (sentinel_ref != .none) {
gz.astgen.extra.appendAssumeCapacity(@enumToInt(sentinel_ref));
}
@ -7588,15 +7573,7 @@ fn builtinCall(
.shl_with_overflow => {
const int_type = try typeExpr(gz, scope, params[0]);
const log2_int_type = try gz.addUnNode(.log2_int_type, int_type, params[0]);
const ptr_type = try gz.add(.{ .tag = .ptr_type_simple, .data = .{
.ptr_type_simple = .{
.is_allowzero = false,
.is_mutable = true,
.is_volatile = false,
.size = .One,
.elem_type = int_type,
},
} });
const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]);
const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]);
const rhs = try expr(gz, scope, .{ .ty = log2_int_type }, params[2]);
const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]);
@ -7987,15 +7964,7 @@ fn overflowArithmetic(
tag: Zir.Inst.Extended,
) InnerError!Zir.Inst.Ref {
const int_type = try typeExpr(gz, scope, params[0]);
const ptr_type = try gz.add(.{ .tag = .ptr_type_simple, .data = .{
.ptr_type_simple = .{
.is_allowzero = false,
.is_mutable = true,
.is_volatile = false,
.size = .One,
.elem_type = int_type,
},
} });
const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]);
const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]);
const rhs = try expr(gz, scope, .{ .ty = int_type }, params[2]);
const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]);

View File

@ -2466,6 +2466,90 @@ pub const SrcLoc = struct {
return nodeToSpan(tree, node_datas[node].lhs);
},
.node_offset_ptr_elem => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
const node_tags = tree.nodes.items(.tag);
const parent_node = src_loc.declRelativeToNodeIndex(node_off);
const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
.ptr_type_aligned => tree.ptrTypeAligned(parent_node),
.ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
.ptr_type => tree.ptrType(parent_node),
.ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
else => unreachable,
};
return nodeToSpan(tree, full.ast.child_type);
},
.node_offset_ptr_sentinel => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
const node_tags = tree.nodes.items(.tag);
const parent_node = src_loc.declRelativeToNodeIndex(node_off);
const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
.ptr_type_aligned => tree.ptrTypeAligned(parent_node),
.ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
.ptr_type => tree.ptrType(parent_node),
.ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
else => unreachable,
};
return nodeToSpan(tree, full.ast.sentinel);
},
.node_offset_ptr_align => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
const node_tags = tree.nodes.items(.tag);
const parent_node = src_loc.declRelativeToNodeIndex(node_off);
const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
.ptr_type_aligned => tree.ptrTypeAligned(parent_node),
.ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
.ptr_type => tree.ptrType(parent_node),
.ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
else => unreachable,
};
return nodeToSpan(tree, full.ast.align_node);
},
.node_offset_ptr_addrspace => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
const node_tags = tree.nodes.items(.tag);
const parent_node = src_loc.declRelativeToNodeIndex(node_off);
const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
.ptr_type_aligned => tree.ptrTypeAligned(parent_node),
.ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
.ptr_type => tree.ptrType(parent_node),
.ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
else => unreachable,
};
return nodeToSpan(tree, full.ast.addrspace_node);
},
.node_offset_ptr_bitoffset => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
const node_tags = tree.nodes.items(.tag);
const parent_node = src_loc.declRelativeToNodeIndex(node_off);
const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
.ptr_type_aligned => tree.ptrTypeAligned(parent_node),
.ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
.ptr_type => tree.ptrType(parent_node),
.ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
else => unreachable,
};
return nodeToSpan(tree, full.ast.bit_range_start);
},
.node_offset_ptr_hostsize => |node_off| {
const tree = try src_loc.file_scope.getTree(gpa);
const node_tags = tree.nodes.items(.tag);
const parent_node = src_loc.declRelativeToNodeIndex(node_off);
const full: Ast.full.PtrType = switch (node_tags[parent_node]) {
.ptr_type_aligned => tree.ptrTypeAligned(parent_node),
.ptr_type_sentinel => tree.ptrTypeSentinel(parent_node),
.ptr_type => tree.ptrType(parent_node),
.ptr_type_bit_range => tree.ptrTypeBitRange(parent_node),
else => unreachable,
};
return nodeToSpan(tree, full.ast.bit_range_end);
},
}
}
@ -2739,6 +2823,24 @@ pub const LazySrcLoc = union(enum) {
/// The source location points to the operand of an unary expression.
/// The Decl is determined contextually.
node_offset_un_op: i32,
/// The source location points to the elem type of a pointer.
/// The Decl is determined contextually.
node_offset_ptr_elem: i32,
/// The source location points to the sentinel of a pointer.
/// The Decl is determined contextually.
node_offset_ptr_sentinel: i32,
/// The source location points to the align expr of a pointer.
/// The Decl is determined contextually.
node_offset_ptr_align: i32,
/// The source location points to the addrspace expr of a pointer.
/// The Decl is determined contextually.
node_offset_ptr_addrspace: i32,
/// The source location points to the bit-offset of a pointer.
/// The Decl is determined contextually.
node_offset_ptr_bitoffset: i32,
/// The source location points to the host size of a pointer.
/// The Decl is determined contextually.
node_offset_ptr_hostsize: i32,
pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease;
@ -2803,6 +2905,12 @@ pub const LazySrcLoc = union(enum) {
.node_offset_array_type_sentinel,
.node_offset_array_type_elem,
.node_offset_un_op,
.node_offset_ptr_elem,
.node_offset_ptr_sentinel,
.node_offset_ptr_align,
.node_offset_ptr_addrspace,
.node_offset_ptr_bitoffset,
.node_offset_ptr_hostsize,
=> .{
.file_scope = decl.getFileScope(),
.parent_decl_node = decl.src_node,

View File

@ -768,7 +768,7 @@ fn analyzeBodyInner(
.optional_type => try sema.zirOptionalType(block, inst),
.param_type => try sema.zirParamType(block, inst),
.ptr_type => try sema.zirPtrType(block, inst),
.ptr_type_simple => try sema.zirPtrTypeSimple(block, inst),
.overflow_arithmetic_ptr => try sema.zirOverflowArithmeticPtr(block, inst),
.ref => try sema.zirRef(block, inst),
.ret_err_value_code => try sema.zirRetErrValueCode(inst),
.shr => try sema.zirShr(block, inst, .shr),
@ -13835,22 +13835,21 @@ fn floatOpAllowed(tag: Zir.Inst.Tag) bool {
};
}
fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
fn zirOverflowArithmeticPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const tracy = trace(@src());
defer tracy.end();
const inst_data = sema.code.instructions.items(.data)[inst].ptr_type_simple;
const elem_ty_src = sema.src; // TODO better source location
const elem_type = try sema.resolveType(block, elem_ty_src, inst_data.elem_type);
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const elem_ty_src = inst_data.src();
const elem_type = try sema.resolveType(block, elem_ty_src, inst_data.operand);
const ty = try Type.ptr(sema.arena, sema.mod, .{
.pointee_type = elem_type,
.@"addrspace" = .generic,
.mutable = inst_data.is_mutable,
.@"allowzero" = inst_data.is_allowzero or inst_data.size == .C,
.@"volatile" = inst_data.is_volatile,
.size = inst_data.size,
.mutable = true,
.@"allowzero" = false,
.@"volatile" = false,
.size = .One,
});
try sema.validatePtrTy(block, elem_ty_src, ty);
return sema.addType(ty);
}
@ -13858,14 +13857,15 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const tracy = trace(@src());
defer tracy.end();
const src: LazySrcLoc = sema.src; // TODO better source location
const elem_ty_src: LazySrcLoc = sema.src; // TODO better source location
const sentinel_src: LazySrcLoc = sema.src; // TODO better source location
const addrspace_src: LazySrcLoc = sema.src; // TODO better source location
const bitoffset_src: LazySrcLoc = sema.src; // TODO better source location
const hostsize_src: LazySrcLoc = sema.src; // TODO better source location
const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;
const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index);
const elem_ty_src: LazySrcLoc = .{ .node_offset_ptr_elem = extra.data.src_node };
const sentinel_src: LazySrcLoc = .{ .node_offset_ptr_sentinel = extra.data.src_node };
const align_src: LazySrcLoc = .{ .node_offset_ptr_align = extra.data.src_node };
const addrspace_src: LazySrcLoc = .{ .node_offset_ptr_addrspace = extra.data.src_node };
const bitoffset_src: LazySrcLoc = .{ .node_offset_ptr_bitoffset = extra.data.src_node };
const hostsize_src: LazySrcLoc = .{ .node_offset_ptr_hostsize = extra.data.src_node };
const unresolved_elem_ty = try sema.resolveType(block, elem_ty_src, extra.data.elem_type);
const target = sema.mod.getTarget();
@ -13880,8 +13880,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const abi_align: u32 = if (inst_data.flags.has_align) blk: {
const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
extra_i += 1;
const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), src);
const val = try sema.resolveConstValue(block, src, coerced);
const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src);
const val = try sema.resolveConstValue(block, align_src, coerced);
// Check if this happens to be the lazy alignment of our element type, in
// which case we can make this 0 without resolving it.
if (val.castTag(.lazy_align)) |payload| {
@ -13889,7 +13889,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
break :blk 0;
}
}
const abi_align = (try val.getUnsignedIntAdvanced(target, sema.kit(block, src))).?;
const abi_align = (try val.getUnsignedIntAdvanced(target, sema.kit(block, align_src))).?;
break :blk @intCast(u32, abi_align);
} else 0;
@ -13914,7 +13914,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
} else 0;
if (host_size != 0 and bit_offset >= host_size * 8) {
return sema.fail(block, src, "bit offset starts after end of host integer", .{});
return sema.fail(block, bitoffset_src, "bit offset starts after end of host integer", .{});
}
const elem_ty = if (abi_align == 0)
@ -13924,6 +13924,30 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
try sema.resolveTypeLayout(block, elem_ty_src, elem_ty);
break :t elem_ty;
};
if (elem_ty.zigTypeTag() == .NoReturn) {
return sema.fail(block, elem_ty_src, "pointer to noreturn not allowed", .{});
} else if (inst_data.size == .Many and elem_ty.zigTypeTag() == .Opaque) {
return sema.fail(block, elem_ty_src, "unknown-length pointer to opaque not allowed", .{});
} else if (inst_data.size == .C) {
if (!(try sema.validateExternType(elem_ty, .other))) {
const msg = msg: {
const msg = try sema.errMsg(block, elem_ty_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa);
const src_decl = sema.mod.declPtr(block.src_decl);
try sema.explainWhyTypeIsNotExtern(block, elem_ty_src, msg, elem_ty_src.toSrcLoc(src_decl), elem_ty, .other);
try sema.addDeclaredHereNote(msg, elem_ty);
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
}
if (elem_ty.zigTypeTag() == .Opaque) {
return sema.fail(block, elem_ty_src, "C pointers cannot point to opaque types", .{});
}
}
const ty = try Type.ptr(sema.arena, sema.mod, .{
.pointee_type = elem_ty,
.sentinel = sentinel,
@ -13936,38 +13960,9 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
.@"volatile" = inst_data.flags.is_volatile,
.size = inst_data.size,
});
try sema.validatePtrTy(block, elem_ty_src, ty);
return sema.addType(ty);
}
fn validatePtrTy(sema: *Sema, block: *Block, elem_src: LazySrcLoc, ty: Type) CompileError!void {
const ptr_info = ty.ptrInfo().data;
const pointee_tag = ptr_info.pointee_type.zigTypeTag();
if (pointee_tag == .NoReturn) {
return sema.fail(block, elem_src, "pointer to noreturn not allowed", .{});
} else if (ptr_info.size == .Many and pointee_tag == .Opaque) {
return sema.fail(block, elem_src, "unknown-length pointer to opaque not allowed", .{});
} else if (ptr_info.size == .C) {
const elem_ty = ptr_info.pointee_type;
if (!(try sema.validateExternType(elem_ty, .other))) {
const msg = msg: {
const msg = try sema.errMsg(block, elem_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa);
const src_decl = sema.mod.declPtr(block.src_decl);
try sema.explainWhyTypeIsNotExtern(block, elem_src, msg, elem_src.toSrcLoc(src_decl), elem_ty, .other);
try sema.addDeclaredHereNote(msg, elem_ty);
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
}
if (pointee_tag == .Opaque) {
return sema.fail(block, elem_src, "C pointers cannot point to opaque types", .{});
}
}
}
fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const tracy = trace(@src());
defer tracy.end();

View File

@ -534,9 +534,9 @@ pub const Inst = struct {
/// Obtains the return type of the in-scope function.
/// Uses the `node` union field.
ret_type,
/// Create a pointer type that does not have a sentinel, alignment, address space, or bit range specified.
/// Uses the `ptr_type_simple` union field.
ptr_type_simple,
/// Create a pointer type for overflow arithmetic.
/// TODO remove when doing https://github.com/ziglang/zig/issues/10248
overflow_arithmetic_ptr,
/// Create a pointer type which can have a sentinel, alignment, address space, and/or bit range.
/// Uses the `ptr_type` union field.
ptr_type,
@ -1121,7 +1121,7 @@ pub const Inst = struct {
.err_union_code,
.err_union_code_ptr,
.ptr_type,
.ptr_type_simple,
.overflow_arithmetic_ptr,
.ensure_err_payload_void,
.enum_literal,
.merge_error_sets,
@ -1417,7 +1417,7 @@ pub const Inst = struct {
.err_union_code,
.err_union_code_ptr,
.ptr_type,
.ptr_type_simple,
.overflow_arithmetic_ptr,
.enum_literal,
.merge_error_sets,
.error_union_type,
@ -1659,7 +1659,7 @@ pub const Inst = struct {
.ret_err_value_code = .str_tok,
.ret_ptr = .node,
.ret_type = .node,
.ptr_type_simple = .ptr_type_simple,
.overflow_arithmetic_ptr = .un_node,
.ptr_type = .ptr_type,
.slice_start = .pl_node,
.slice_end = .pl_node,
@ -2499,13 +2499,6 @@ pub const Inst = struct {
node: i32,
int: u64,
float: f64,
ptr_type_simple: struct {
is_allowzero: bool,
is_mutable: bool,
is_volatile: bool,
size: std.builtin.Type.Pointer.Size,
elem_type: Ref,
},
ptr_type: struct {
flags: packed struct {
is_allowzero: bool,
@ -2608,7 +2601,6 @@ pub const Inst = struct {
node,
int,
float,
ptr_type_simple,
ptr_type,
int_type,
bool_br,
@ -2869,6 +2861,7 @@ pub const Inst = struct {
/// 4. host_size: Ref // if `has_bit_range` flag is set
pub const PtrType = struct {
elem_type: Ref,
src_node: i32,
};
pub const ArrayTypeSentinel = struct {

View File

@ -233,6 +233,7 @@ const Writer = struct {
.validate_struct_init_ty,
.make_ptr_const,
.validate_deref,
.overflow_arithmetic_ptr,
=> try self.writeUnNode(stream, inst),
.ref,
@ -247,7 +248,6 @@ const Writer = struct {
.array_type_sentinel => try self.writeArrayTypeSentinel(stream, inst),
.param_type => try self.writeParamType(stream, inst),
.ptr_type_simple => try self.writePtrTypeSimple(stream, inst),
.ptr_type => try self.writePtrType(stream, inst),
.int => try self.writeInt(stream, inst),
.int_big => try self.writeIntBig(stream, inst),
@ -601,24 +601,6 @@ const Writer = struct {
try stream.print(", {d})", .{inst_data.param_index});
}
fn writePtrTypeSimple(
self: *Writer,
stream: anytype,
inst: Zir.Inst.Index,
) (@TypeOf(stream).Error || error{OutOfMemory})!void {
const inst_data = self.code.instructions.items(.data)[inst].ptr_type_simple;
const str_allowzero = if (inst_data.is_allowzero) "allowzero, " else "";
const str_const = if (!inst_data.is_mutable) "const, " else "";
const str_volatile = if (inst_data.is_volatile) "volatile, " else "";
try self.writeInstRef(stream, inst_data.elem_type);
try stream.print(", {s}{s}{s}{s})", .{
str_allowzero,
str_const,
str_volatile,
@tagName(inst_data.size),
});
}
fn writePtrType(
self: *Writer,
stream: anytype,
@ -660,7 +642,8 @@ const Writer = struct {
try self.writeInstRef(stream, @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]));
try stream.writeAll(")");
}
try stream.writeAll(")");
try stream.writeAll(") ");
try self.writeSrc(stream, LazySrcLoc.nodeOffset(extra.data.src_node));
}
fn writeInt(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {

View File

@ -0,0 +1,14 @@
const Foo = struct {};
export fn a() void {
const T = [*c]Foo;
var t: T = undefined;
_ = t;
}
// error
// backend=stage2
// target=native
//
// :3:19: error: C pointers cannot point to non-C-ABI-compatible type 'tmp.Foo'
// :3:19: note: only structs with packed or extern layout are extern compatible
// :1:13: note: struct declared here

View File

@ -5,7 +5,7 @@ export fn a() void {
}
// error
// backend=stage1
// backend=stage2
// target=native
//
// tmp.zig:3:16: error: C pointers cannot point to opaque types
// :3:16: error: C pointers cannot point to opaque types

View File

@ -7,5 +7,5 @@ export fn entry() void {
// backend=stage2
// target=native
//
// :1:1: error: C pointers cannot point to non-C-ABI-compatible type 'void'
// :1:1: note: 'void' is a zero bit type; for C 'void' use 'anyopaque'
// :2:16: error: C pointers cannot point to non-C-ABI-compatible type 'void'
// :2:16: note: 'void' is a zero bit type; for C 'void' use 'anyopaque'

View File

@ -7,4 +7,4 @@ export fn entry() usize { return @sizeOf(@TypeOf(a)); }
// backend=stage2
// target=native
//
// :2:15: error: expected type 'type', found 'i32'
// :2:11: error: expected type 'type', found 'i32'

View File

@ -2,7 +2,7 @@ fn a() *noreturn {}
export fn entry() void { _ = a(); }
// error
// backend=stage1
// backend=stage2
// target=native
//
// tmp.zig:1:9: error: pointer to noreturn not allowed
// :1:9: error: pointer to noreturn not allowed

View File

@ -7,5 +7,5 @@ export fn entry() void {
// backend=stage2
// target=native
//
// :2:19: error: type '[]u8' does not support array initialization syntax
// :2:19: note: inferred array length is specified with an underscore: '[_]u8'
// :2:15: error: type '[]u8' does not support array initialization syntax
// :2:15: note: inferred array length is specified with an underscore: '[_]u8'

View File

@ -1,12 +0,0 @@
const Foo = struct {};
export fn a() void {
const T = [*c]Foo;
var t: T = undefined;
_ = t;
}
// error
// backend=stage1
// target=native
//
// tmp.zig:3:19: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'

View File

@ -1,7 +0,0 @@
export const T = [*]opaque {};
// error
// backend=stage1
// target=native
//
// tmp.zig:1:21: error: unknown-length pointer to opaque

View File

@ -0,0 +1,7 @@
export const T = [*]opaque {};
// error
// backend=stage2
// target=native
//
// :1:21: error: unknown-length pointer to opaque not allowed

View File

@ -7,7 +7,7 @@ comptime {
}
// error
// backend=stage1
// backend=stage2
// target=native
//
// tmp.zig:1:21: error: expected array type or [_], found '[*][*]const u8'
// :1:22: error: type '[*][*]const u8' does not support array initialization syntax