mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
compiler: allow @import of ZON without a result type
In particular, this allows importing `build.zig.zon` at comptime.
This commit is contained in:
parent
1b62a22268
commit
06ee383da9
11 changed files with 302 additions and 37 deletions
|
|
@ -2136,6 +2136,7 @@ pub const Key = union(enum) {
|
||||||
/// To avoid making this key overly complex, the type-specific data is hashed by Sema.
|
/// To avoid making this key overly complex, the type-specific data is hashed by Sema.
|
||||||
reified: struct {
|
reified: struct {
|
||||||
/// A `reify`, `struct_init`, `struct_init_ref`, or `struct_init_anon` instruction.
|
/// A `reify`, `struct_init`, `struct_init_ref`, or `struct_init_anon` instruction.
|
||||||
|
/// Alternatively, this is `main_struct_inst` of a ZON file.
|
||||||
zir_index: TrackedInst.Index,
|
zir_index: TrackedInst.Index,
|
||||||
/// A hash of this type's attributes, fields, etc, generated by Sema.
|
/// A hash of this type's attributes, fields, etc, generated by Sema.
|
||||||
type_hash: u64,
|
type_hash: u64,
|
||||||
|
|
|
||||||
19
src/Sema.zig
19
src/Sema.zig
|
|
@ -2998,7 +2998,7 @@ fn zirStructDecl(
|
||||||
return Air.internedToRef(wip_ty.finish(ip, new_namespace_index));
|
return Air.internedToRef(wip_ty.finish(ip, new_namespace_index));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn createTypeName(
|
pub fn createTypeName(
|
||||||
sema: *Sema,
|
sema: *Sema,
|
||||||
block: *Block,
|
block: *Block,
|
||||||
name_strategy: Zir.Inst.NameStrategy,
|
name_strategy: Zir.Inst.NameStrategy,
|
||||||
|
|
@ -14065,14 +14065,13 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
|
||||||
return Air.internedToRef(ty);
|
return Air.internedToRef(ty);
|
||||||
},
|
},
|
||||||
.zon => {
|
.zon => {
|
||||||
if (extra.res_ty == .none) {
|
const res_ty: InternPool.Index = b: {
|
||||||
return sema.fail(block, operand_src, "'@import' of ZON must have a known result type", .{});
|
if (extra.res_ty == .none) break :b .none;
|
||||||
}
|
const res_ty_inst = try sema.resolveInst(extra.res_ty);
|
||||||
const res_ty_inst = try sema.resolveInst(extra.res_ty);
|
const res_ty = try sema.analyzeAsType(block, operand_src, res_ty_inst);
|
||||||
const res_ty = try sema.analyzeAsType(block, operand_src, res_ty_inst);
|
if (res_ty.isGenericPoison()) break :b .none;
|
||||||
if (res_ty.isGenericPoison()) {
|
break :b res_ty.toIntern();
|
||||||
return sema.fail(block, operand_src, "'@import' of ZON must have a known result type", .{});
|
};
|
||||||
}
|
|
||||||
|
|
||||||
try sema.declareDependency(.{ .zon_file = result.file_index });
|
try sema.declareDependency(.{ .zon_file = result.file_index });
|
||||||
const interned = try LowerZon.run(
|
const interned = try LowerZon.run(
|
||||||
|
|
@ -31699,7 +31698,7 @@ fn addReferenceEntry(
|
||||||
try zcu.addUnitReference(sema.owner, referenced_unit, src);
|
try zcu.addUnitReference(sema.owner, referenced_unit, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn addTypeReferenceEntry(
|
pub fn addTypeReferenceEntry(
|
||||||
sema: *Sema,
|
sema: *Sema,
|
||||||
src: LazySrcLoc,
|
src: LazySrcLoc,
|
||||||
referenced_type: InternPool.Index,
|
referenced_type: InternPool.Index,
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ pub fn run(
|
||||||
sema: *Sema,
|
sema: *Sema,
|
||||||
file: *File,
|
file: *File,
|
||||||
file_index: Zcu.File.Index,
|
file_index: Zcu.File.Index,
|
||||||
res_ty: Type,
|
res_ty_interned: InternPool.Index,
|
||||||
import_loc: LazySrcLoc,
|
import_loc: LazySrcLoc,
|
||||||
block: *Sema.Block,
|
block: *Sema.Block,
|
||||||
) CompileError!InternPool.Index {
|
) CompileError!InternPool.Index {
|
||||||
|
|
@ -53,13 +53,167 @@ pub fn run(
|
||||||
.base_node_inst = tracked_inst,
|
.base_node_inst = tracked_inst,
|
||||||
};
|
};
|
||||||
|
|
||||||
try lower_zon.checkType(res_ty);
|
if (res_ty_interned == .none) {
|
||||||
|
return lower_zon.lowerExprAnonResTy(.root);
|
||||||
return lower_zon.lowerExpr(.root, res_ty);
|
} else {
|
||||||
|
const res_ty: Type = .fromInterned(res_ty_interned);
|
||||||
|
try lower_zon.checkType(res_ty);
|
||||||
|
return lower_zon.lowerExprKnownResTy(.root, res_ty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Validate that `ty` is a valid ZON type. If not, emit a compile error.
|
fn lowerExprAnonResTy(self: *LowerZon, node: Zoir.Node.Index) CompileError!InternPool.Index {
|
||||||
/// i.e. no nested optionals, no error sets, etc.
|
const gpa = self.sema.gpa;
|
||||||
|
const pt = self.sema.pt;
|
||||||
|
const ip = &pt.zcu.intern_pool;
|
||||||
|
switch (node.get(self.file.zoir.?)) {
|
||||||
|
.true => return .bool_true,
|
||||||
|
.false => return .bool_false,
|
||||||
|
.null => return .null_value,
|
||||||
|
.pos_inf => return self.fail(node, "infinity requires a known result type", .{}),
|
||||||
|
.neg_inf => return self.fail(node, "negative infinity requires a known result type", .{}),
|
||||||
|
.nan => return self.fail(node, "NaN requires a known result type", .{}),
|
||||||
|
.int_literal => |int| switch (int) {
|
||||||
|
.small => |val| return pt.intern(.{ .int = .{
|
||||||
|
.ty = .comptime_int_type,
|
||||||
|
.storage = .{ .i64 = val },
|
||||||
|
} }),
|
||||||
|
.big => |val| return pt.intern(.{ .int = .{
|
||||||
|
.ty = .comptime_int_type,
|
||||||
|
.storage = .{ .big_int = val },
|
||||||
|
} }),
|
||||||
|
},
|
||||||
|
.float_literal => |val| {
|
||||||
|
const result = try pt.floatValue(.comptime_float, val);
|
||||||
|
return result.toIntern();
|
||||||
|
},
|
||||||
|
.char_literal => |val| return pt.intern(.{ .int = .{
|
||||||
|
.ty = .comptime_int_type,
|
||||||
|
.storage = .{ .i64 = val },
|
||||||
|
} }),
|
||||||
|
.enum_literal => |val| return pt.intern(.{
|
||||||
|
.enum_literal = try ip.getOrPutString(
|
||||||
|
gpa,
|
||||||
|
pt.tid,
|
||||||
|
val.get(self.file.zoir.?),
|
||||||
|
.no_embedded_nulls,
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
.string_literal => |val| {
|
||||||
|
const ip_str = try ip.getOrPutString(gpa, pt.tid, val, .maybe_embedded_nulls);
|
||||||
|
const result = try self.sema.addStrLit(ip_str, val.len);
|
||||||
|
return result.toInterned().?;
|
||||||
|
},
|
||||||
|
.empty_literal => return .empty_tuple,
|
||||||
|
.array_literal => |nodes| {
|
||||||
|
const types = try self.sema.arena.alloc(InternPool.Index, nodes.len);
|
||||||
|
const values = try self.sema.arena.alloc(InternPool.Index, nodes.len);
|
||||||
|
for (0..nodes.len) |i| {
|
||||||
|
values[i] = try self.lowerExprAnonResTy(nodes.at(@intCast(i)));
|
||||||
|
types[i] = Value.fromInterned(values[i]).typeOf(pt.zcu).toIntern();
|
||||||
|
}
|
||||||
|
const ty = try ip.getTupleType(
|
||||||
|
gpa,
|
||||||
|
pt.tid,
|
||||||
|
.{
|
||||||
|
.types = types,
|
||||||
|
.values = values,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return pt.intern(.{ .aggregate = .{
|
||||||
|
.ty = ty,
|
||||||
|
.storage = .{ .elems = values },
|
||||||
|
} });
|
||||||
|
},
|
||||||
|
.struct_literal => |init| {
|
||||||
|
const elems = try self.sema.arena.alloc(InternPool.Index, init.names.len);
|
||||||
|
for (0..init.names.len) |i| {
|
||||||
|
elems[i] = try self.lowerExprAnonResTy(init.vals.at(@intCast(i)));
|
||||||
|
}
|
||||||
|
const struct_ty = switch (try ip.getStructType(
|
||||||
|
gpa,
|
||||||
|
pt.tid,
|
||||||
|
.{
|
||||||
|
.layout = .auto,
|
||||||
|
.fields_len = @intCast(init.names.len),
|
||||||
|
.known_non_opv = false,
|
||||||
|
.requires_comptime = .no,
|
||||||
|
.any_comptime_fields = true,
|
||||||
|
.any_default_inits = true,
|
||||||
|
.inits_resolved = true,
|
||||||
|
.any_aligned_fields = false,
|
||||||
|
.key = .{ .reified = .{
|
||||||
|
.zir_index = self.base_node_inst,
|
||||||
|
.type_hash = hash: {
|
||||||
|
var hasher: std.hash.Wyhash = .init(0);
|
||||||
|
hasher.update(std.mem.asBytes(&node));
|
||||||
|
hasher.update(std.mem.sliceAsBytes(elems));
|
||||||
|
hasher.update(std.mem.sliceAsBytes(init.names));
|
||||||
|
break :hash hasher.final();
|
||||||
|
},
|
||||||
|
} },
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
)) {
|
||||||
|
.wip => |wip| ty: {
|
||||||
|
errdefer wip.cancel(ip, pt.tid);
|
||||||
|
wip.setName(ip, try self.sema.createTypeName(
|
||||||
|
self.block,
|
||||||
|
.anon,
|
||||||
|
"struct",
|
||||||
|
self.base_node_inst.resolve(ip),
|
||||||
|
wip.index,
|
||||||
|
));
|
||||||
|
|
||||||
|
const struct_type = ip.loadStructType(wip.index);
|
||||||
|
|
||||||
|
for (init.names, 0..) |name, field_idx| {
|
||||||
|
const name_interned = try ip.getOrPutString(
|
||||||
|
gpa,
|
||||||
|
pt.tid,
|
||||||
|
name.get(self.file.zoir.?),
|
||||||
|
.no_embedded_nulls,
|
||||||
|
);
|
||||||
|
assert(struct_type.addFieldName(ip, name_interned) == null);
|
||||||
|
struct_type.setFieldComptime(ip, field_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
@memcpy(struct_type.field_inits.get(ip), elems);
|
||||||
|
const types = struct_type.field_types.get(ip);
|
||||||
|
for (0..init.names.len) |i| {
|
||||||
|
types[i] = Value.fromInterned(elems[i]).typeOf(pt.zcu).toIntern();
|
||||||
|
}
|
||||||
|
|
||||||
|
const new_namespace_index = try pt.createNamespace(.{
|
||||||
|
.parent = self.block.namespace.toOptional(),
|
||||||
|
.owner_type = wip.index,
|
||||||
|
.file_scope = self.block.getFileScopeIndex(pt.zcu),
|
||||||
|
.generation = pt.zcu.generation,
|
||||||
|
});
|
||||||
|
try pt.zcu.comp.queueJob(.{ .resolve_type_fully = wip.index });
|
||||||
|
codegen_type: {
|
||||||
|
if (pt.zcu.comp.config.use_llvm) break :codegen_type;
|
||||||
|
if (self.block.ownerModule().strip) break :codegen_type;
|
||||||
|
try pt.zcu.comp.queueJob(.{ .codegen_type = wip.index });
|
||||||
|
}
|
||||||
|
break :ty wip.finish(ip, new_namespace_index);
|
||||||
|
},
|
||||||
|
.existing => |ty| ty,
|
||||||
|
};
|
||||||
|
try self.sema.declareDependency(.{ .interned = struct_ty });
|
||||||
|
try self.sema.addTypeReferenceEntry(self.nodeSrc(node), struct_ty);
|
||||||
|
|
||||||
|
return try pt.intern(.{ .aggregate = .{
|
||||||
|
.ty = struct_ty,
|
||||||
|
.storage = .{ .elems = elems },
|
||||||
|
} });
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Validate that `ty` is a valid ZON type, or emit a compile error.
|
||||||
|
///
|
||||||
|
/// Rules out nested optionals, error sets, etc.
|
||||||
fn checkType(self: *LowerZon, ty: Type) !void {
|
fn checkType(self: *LowerZon, ty: Type) !void {
|
||||||
var visited: std.AutoHashMapUnmanaged(InternPool.Index, void) = .empty;
|
var visited: std.AutoHashMapUnmanaged(InternPool.Index, void) = .empty;
|
||||||
try self.checkTypeInner(ty, null, &visited);
|
try self.checkTypeInner(ty, null, &visited);
|
||||||
|
|
@ -201,9 +355,9 @@ fn fail(
|
||||||
return self.sema.failWithOwnedErrorMsg(self.block, err_msg);
|
return self.sema.failWithOwnedErrorMsg(self.block, err_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lowerExpr(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) CompileError!InternPool.Index {
|
fn lowerExprKnownResTy(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) CompileError!InternPool.Index {
|
||||||
const pt = self.sema.pt;
|
const pt = self.sema.pt;
|
||||||
return self.lowerExprInner(node, res_ty) catch |err| switch (err) {
|
return self.lowerExprKnownResTyInner(node, res_ty) catch |err| switch (err) {
|
||||||
error.WrongType => return self.fail(
|
error.WrongType => return self.fail(
|
||||||
node,
|
node,
|
||||||
"expected type '{}'",
|
"expected type '{}'",
|
||||||
|
|
@ -213,7 +367,7 @@ fn lowerExpr(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) CompileError!
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lowerExprInner(
|
fn lowerExprKnownResTyInner(
|
||||||
self: *LowerZon,
|
self: *LowerZon,
|
||||||
node: Zoir.Node.Index,
|
node: Zoir.Node.Index,
|
||||||
res_ty: Type,
|
res_ty: Type,
|
||||||
|
|
@ -227,7 +381,7 @@ fn lowerExprInner(
|
||||||
break :b .none;
|
break :b .none;
|
||||||
} else b: {
|
} else b: {
|
||||||
const child_type = res_ty.optionalChild(pt.zcu);
|
const child_type = res_ty.optionalChild(pt.zcu);
|
||||||
break :b try self.lowerExprInner(node, child_type);
|
break :b try self.lowerExprKnownResTyInner(node, child_type);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
@ -239,7 +393,7 @@ fn lowerExprInner(
|
||||||
.base_addr = .{
|
.base_addr = .{
|
||||||
.uav = .{
|
.uav = .{
|
||||||
.orig_ty = res_ty.toIntern(),
|
.orig_ty = res_ty.toIntern(),
|
||||||
.val = try self.lowerExprInner(node, .fromInterned(ptr_info.child)),
|
.val = try self.lowerExprKnownResTyInner(node, .fromInterned(ptr_info.child)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.byte_offset = 0,
|
.byte_offset = 0,
|
||||||
|
|
@ -486,7 +640,7 @@ fn lowerArray(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
|
||||||
);
|
);
|
||||||
|
|
||||||
for (0..nodes.len) |i| {
|
for (0..nodes.len) |i| {
|
||||||
elems[i] = try self.lowerExpr(nodes.at(@intCast(i)), array_info.elem_type);
|
elems[i] = try self.lowerExprKnownResTy(nodes.at(@intCast(i)), array_info.elem_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array_info.sentinel) |sentinel| {
|
if (array_info.sentinel) |sentinel| {
|
||||||
|
|
@ -587,7 +741,7 @@ fn lowerTuple(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const val = try self.lowerExpr(elem_nodes.at(@intCast(i)), .fromInterned(field_types[i]));
|
const val = try self.lowerExprKnownResTy(elem_nodes.at(@intCast(i)), .fromInterned(field_types[i]));
|
||||||
|
|
||||||
if (elems[i] != .none and val != elems[i]) {
|
if (elems[i] != .none and val != elems[i]) {
|
||||||
const elem_node = elem_nodes.at(@intCast(i));
|
const elem_node = elem_nodes.at(@intCast(i));
|
||||||
|
|
@ -650,7 +804,7 @@ fn lowerStruct(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
|
||||||
};
|
};
|
||||||
|
|
||||||
const field_type: Type = .fromInterned(struct_info.field_types.get(ip)[name_index]);
|
const field_type: Type = .fromInterned(struct_info.field_types.get(ip)[name_index]);
|
||||||
field_values[name_index] = try self.lowerExpr(field_node, field_type);
|
field_values[name_index] = try self.lowerExprKnownResTy(field_node, field_type);
|
||||||
|
|
||||||
if (struct_info.comptime_bits.getBit(ip, name_index)) {
|
if (struct_info.comptime_bits.getBit(ip, name_index)) {
|
||||||
const val = ip.indexToKey(field_values[name_index]);
|
const val = ip.indexToKey(field_values[name_index]);
|
||||||
|
|
@ -715,7 +869,7 @@ fn lowerSlice(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
|
||||||
const elems = try self.sema.arena.alloc(InternPool.Index, elem_nodes.len + @intFromBool(ptr_info.sentinel != .none));
|
const elems = try self.sema.arena.alloc(InternPool.Index, elem_nodes.len + @intFromBool(ptr_info.sentinel != .none));
|
||||||
|
|
||||||
for (elems, 0..) |*elem, i| {
|
for (elems, 0..) |*elem, i| {
|
||||||
elem.* = try self.lowerExpr(elem_nodes.at(@intCast(i)), .fromInterned(ptr_info.child));
|
elem.* = try self.lowerExprKnownResTy(elem_nodes.at(@intCast(i)), .fromInterned(ptr_info.child));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr_info.sentinel != .none) {
|
if (ptr_info.sentinel != .none) {
|
||||||
|
|
@ -810,7 +964,7 @@ fn lowerUnion(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool.
|
||||||
if (field_type.toIntern() == .void_type) {
|
if (field_type.toIntern() == .void_type) {
|
||||||
return self.fail(field_node, "expected type 'void'", .{});
|
return self.fail(field_node, "expected type 'void'", .{});
|
||||||
}
|
}
|
||||||
break :b try self.lowerExpr(field_node, field_type);
|
break :b try self.lowerExprKnownResTy(field_node, field_type);
|
||||||
} else b: {
|
} else b: {
|
||||||
if (field_type.toIntern() != .void_type) {
|
if (field_type.toIntern() != .void_type) {
|
||||||
return error.WrongType;
|
return error.WrongType;
|
||||||
|
|
@ -846,7 +1000,7 @@ fn lowerVector(self: *LowerZon, node: Zoir.Node.Index, res_ty: Type) !InternPool
|
||||||
}
|
}
|
||||||
|
|
||||||
for (elems, 0..) |*elem, i| {
|
for (elems, 0..) |*elem, i| {
|
||||||
elem.* = try self.lowerExpr(elem_nodes.at(@intCast(i)), .fromInterned(vector_info.child));
|
elem.* = try self.lowerExprKnownResTy(elem_nodes.at(@intCast(i)), .fromInterned(vector_info.child));
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.sema.pt.intern(.{ .aggregate = .{
|
return self.sema.pt.intern(.{ .aggregate = .{
|
||||||
|
|
|
||||||
|
|
@ -3589,7 +3589,10 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
|
||||||
};
|
};
|
||||||
const info = tracked.resolveFull(&zcu.intern_pool) orelse return null;
|
const info = tracked.resolveFull(&zcu.intern_pool) orelse return null;
|
||||||
const file = zcu.fileByIndex(info.file);
|
const file = zcu.fileByIndex(info.file);
|
||||||
const zir = file.zir.?;
|
const zir = switch (file.getMode()) {
|
||||||
|
.zig => file.zir.?,
|
||||||
|
.zon => return 0,
|
||||||
|
};
|
||||||
const inst = zir.instructions.get(@intFromEnum(info.inst));
|
const inst = zir.instructions.get(@intFromEnum(info.inst));
|
||||||
return switch (inst.tag) {
|
return switch (inst.tag) {
|
||||||
.struct_init, .struct_init_ref => zir.extraData(Zir.Inst.StructInit, inst.data.pl_node.payload_index).data.abs_line,
|
.struct_init, .struct_init_ref => zir.extraData(Zir.Inst.StructInit, inst.data.pl_node.payload_index).data.abs_line,
|
||||||
|
|
|
||||||
|
|
@ -517,3 +517,57 @@ test "recursive" {
|
||||||
const expected: Recursive = .{ .foo = &.{ .foo = null } };
|
const expected: Recursive = .{ .foo = &.{ .foo = null } };
|
||||||
try expectEqualDeep(expected, @as(Recursive, @import("zon/recursive.zon")));
|
try expectEqualDeep(expected, @as(Recursive, @import("zon/recursive.zon")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "anon" {
|
||||||
|
const expected = .{
|
||||||
|
.{
|
||||||
|
.bool_true = true,
|
||||||
|
.bool_false = false,
|
||||||
|
.string = "foo",
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
null,
|
||||||
|
10,
|
||||||
|
36893488147419103232,
|
||||||
|
1.234,
|
||||||
|
'z',
|
||||||
|
.bar,
|
||||||
|
.{},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const actual = @import("zon/anon.zon");
|
||||||
|
try expectEqual(expected.len, actual.len);
|
||||||
|
try expectEqual(expected[1], actual[1]);
|
||||||
|
const expected_struct = expected[0];
|
||||||
|
const actual_struct = actual[0];
|
||||||
|
const expected_fields = @typeInfo(@TypeOf(expected_struct)).@"struct".fields;
|
||||||
|
const actual_fields = @typeInfo(@TypeOf(actual_struct)).@"struct".fields;
|
||||||
|
try expectEqual(expected_fields.len, actual_fields.len);
|
||||||
|
inline for (expected_fields) |field| {
|
||||||
|
try expectEqual(@field(expected_struct, field.name), @field(actual_struct, field.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test "build.zig.zon" {
|
||||||
|
const build = @import("zon/build.zig.zon");
|
||||||
|
|
||||||
|
try expectEqual(4, @typeInfo(@TypeOf(build)).@"struct".fields.len);
|
||||||
|
try expectEqualStrings("temp", build.name);
|
||||||
|
try expectEqualStrings("0.0.0", build.version);
|
||||||
|
|
||||||
|
const dependencies = build.dependencies;
|
||||||
|
try expectEqual(2, @typeInfo(@TypeOf(dependencies)).@"struct".fields.len);
|
||||||
|
|
||||||
|
const example_0 = dependencies.example_0;
|
||||||
|
try expectEqual(2, @typeInfo(@TypeOf(dependencies)).@"struct".fields.len);
|
||||||
|
try expectEqualStrings("https://example.com/foo.tar.gz", example_0.url);
|
||||||
|
try expectEqualStrings("...", example_0.hash);
|
||||||
|
|
||||||
|
const example_1 = dependencies.example_1;
|
||||||
|
try expectEqual(2, @typeInfo(@TypeOf(dependencies)).@"struct".fields.len);
|
||||||
|
try expectEqualStrings("../foo", example_1.path);
|
||||||
|
try expectEqual(false, example_1.lazy);
|
||||||
|
|
||||||
|
try expectEqual(.{ "build.zig", "build.zig.zon", "src" }, build.paths);
|
||||||
|
}
|
||||||
|
|
|
||||||
16
test/behavior/zon/anon.zon
Normal file
16
test/behavior/zon/anon.zon
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
.{
|
||||||
|
.{
|
||||||
|
.bool_true = true,
|
||||||
|
.bool_false = false,
|
||||||
|
.string = "foo",
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
null,
|
||||||
|
10,
|
||||||
|
36893488147419103232,
|
||||||
|
1.234,
|
||||||
|
'z',
|
||||||
|
.bar,
|
||||||
|
.{},
|
||||||
|
},
|
||||||
|
}
|
||||||
20
test/behavior/zon/build.zig.zon
Normal file
20
test/behavior/zon/build.zig.zon
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
.{
|
||||||
|
// Comment
|
||||||
|
.name = "temp",
|
||||||
|
.version = "0.0.0",
|
||||||
|
.dependencies = .{
|
||||||
|
.example_0 = .{
|
||||||
|
.url = "https://example.com/foo.tar.gz",
|
||||||
|
.hash = "...",
|
||||||
|
},
|
||||||
|
.example_1 = .{
|
||||||
|
.path = "../foo",
|
||||||
|
.lazy = false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.paths = .{
|
||||||
|
"build.zig",
|
||||||
|
"build.zig.zon",
|
||||||
|
"src",
|
||||||
|
},
|
||||||
|
}
|
||||||
9
test/cases/compile_errors/@import_zon_anon_inf.zig
Normal file
9
test/cases/compile_errors/@import_zon_anon_inf.zig
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
export fn entry() void {
|
||||||
|
_ = @import("zon/inf.zon");
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
// imports=zon/inf.zon
|
||||||
|
//
|
||||||
|
// inf.zon:1:1: error: infinity requires a known result type
|
||||||
|
// tmp.zig:2:17: note: imported here
|
||||||
9
test/cases/compile_errors/@import_zon_anon_nan.zig
Normal file
9
test/cases/compile_errors/@import_zon_anon_nan.zig
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
export fn entry() void {
|
||||||
|
_ = @import("zon/nan.zon");
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
// imports=zon/nan.zon
|
||||||
|
//
|
||||||
|
// nan.zon:1:1: error: NaN requires a known result type
|
||||||
|
// tmp.zig:2:17: note: imported here
|
||||||
9
test/cases/compile_errors/@import_zon_anon_neg_inf.zig
Normal file
9
test/cases/compile_errors/@import_zon_anon_neg_inf.zig
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
export fn entry() void {
|
||||||
|
_ = @import("zon/neg_inf.zon");
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
// imports=zon/neg_inf.zon
|
||||||
|
//
|
||||||
|
// neg_inf.zon:1:1: error: negative infinity requires a known result type
|
||||||
|
// tmp.zig:2:17: note: imported here
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
export fn entry() void {
|
|
||||||
const f = @import("zon/simple_union.zon");
|
|
||||||
_ = f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// error
|
|
||||||
// imports=zon/simple_union.zon
|
|
||||||
//
|
|
||||||
// tmp.zig:2:23: error: '@import' of ZON must have a known result type
|
|
||||||
Loading…
Add table
Reference in a new issue