diff --git a/src/Server.zig b/src/Server.zig index 9b94c5e0e..ca26f3064 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -1380,7 +1380,7 @@ fn resolveConfiguration( if (config.zig_lib_path) |zig_lib_path| blk: { if (zig_builtin.target.os.tag == .wasi) { - std.log.warn("The 'zig_lib_path' config option is ignored on WASI in favor of preopens.", .{}); + log.warn("The 'zig_lib_path' config option is ignored on WASI in favor of preopens.", .{}); break :blk; } if (std.fs.openDirAbsolute(zig_lib_path, .{})) |zig_lib_dir| { @@ -1409,7 +1409,7 @@ fn resolveConfiguration( if (config.global_cache_path) |global_cache_path| blk: { if (zig_builtin.target.os.tag == .wasi) { - std.log.warn("The 'global_cache_path' config option is ignored on WASI in favor of preopens.", .{}); + log.warn("The 'global_cache_path' config option is ignored on WASI in favor of preopens.", .{}); break :blk; } if (std.fs.cwd().makeOpenPath(global_cache_path, .{})) |global_cache_dir| { diff --git a/src/analysis.zig b/src/analysis.zig index c0f4289d2..d7218c817 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -2123,6 +2123,26 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, node_handle: NodeWithHandle) e return analyser.instanceStdBuiltinType("Type"); } + const type_map: std.StaticStringMap(InternPool.Index) = .initComptime(.{ + .{ "type", .type_type }, + .{ "void", .void_type }, + .{ "bool", .bool_type }, + .{ "noreturn", .noreturn_type }, + .{ "comptime_float", .comptime_float_type }, + .{ "comptime_int", .comptime_int_type }, + .{ "undefined", .undefined_type }, + .{ "null", .null_type }, + .{ "enum_literal", .enum_literal_type }, + }); + if (std.mem.eql(u8, call_name, "@Type")) { + if (params.len != 1) return null; + if (tree.nodeTag(params[0]) != .enum_literal) return null; + const name_token = tree.nodeMainToken(params[0]); + const name = offsets.identifierTokenToNameSlice(tree, name_token); + const ip_index = type_map.get(name) orelse return null; + return Type.fromIP(analyser, .type_type, ip_index); + } + if (std.mem.eql(u8, call_name, "@import")) { if (params.len == 0) return null; const import_param = params[0]; @@ -5612,6 +5632,90 @@ pub fn resolveExpressionTypeFromAncestors( const ty = try analyser.resolveTypeOfNode(.of(params[0], handle)) orelse return null; return ty.instanceTypeVal(analyser); } + + if (std.mem.eql(u8, call_name, "@branchHint")) { + if (params.len == 0) return null; + if (params[0] != node) return null; + return analyser.instanceStdBuiltinType("BranchHint"); + } + + if (std.mem.eql(u8, call_name, "@atomicLoad")) { + if (params.len <= 2) return null; + if (params[2] != node) return null; + return analyser.instanceStdBuiltinType("AtomicOrder"); + } + + if (std.mem.eql(u8, call_name, "@atomicRmw")) { + if (params.len > 2 and params[2] == node) + return analyser.instanceStdBuiltinType("AtomicRmwOp"); + if (params.len > 4 and params[4] == node) + return analyser.instanceStdBuiltinType("AtomicOrder"); + return null; + } + + if (std.mem.eql(u8, call_name, "@atomicStore")) { + if (params.len <= 3) return null; + if (params[3] != node) return null; + return analyser.instanceStdBuiltinType("AtomicOrder"); + } + + if (std.mem.eql(u8, call_name, "@cmpxchgStrong")) { + if (params.len > 4 and params[4] == node) + return analyser.instanceStdBuiltinType("AtomicOrder"); + if (params.len > 5 and params[5] == node) + return analyser.instanceStdBuiltinType("AtomicOrder"); + return null; + } + + if (std.mem.eql(u8, call_name, "@cmpxchgWeak")) { + if (params.len > 4 and params[4] == node) + return analyser.instanceStdBuiltinType("AtomicOrder"); + if (params.len > 5 and params[5] == node) + return analyser.instanceStdBuiltinType("AtomicOrder"); + return null; + } + + if (std.mem.eql(u8, call_name, "@call")) { + if (params.len == 0) return null; + if (params[0] != node) return null; + return analyser.instanceStdBuiltinType("CallModifier"); + } + + if (std.mem.eql(u8, call_name, "@export")) { + if (params.len <= 1) return null; + if (params[1] != node) return null; + return analyser.instanceStdBuiltinType("ExportOptions"); + } + + if (std.mem.eql(u8, call_name, "@extern")) { + if (params.len <= 1) return null; + if (params[1] != node) return null; + return analyser.instanceStdBuiltinType("ExternOptions"); + } + + if (std.mem.eql(u8, call_name, "@prefetch")) { + if (params.len <= 1) return null; + if (params[1] != node) return null; + return analyser.instanceStdBuiltinType("PrefetchOptions"); + } + + if (std.mem.eql(u8, call_name, "@reduce")) { + if (params.len == 0) return null; + if (params[0] != node) return null; + return analyser.instanceStdBuiltinType("ReduceOp"); + } + + if (std.mem.eql(u8, call_name, "@setFloatMode")) { + if (params.len == 0) return null; + if (params[0] != node) return null; + return analyser.instanceStdBuiltinType("FloatMode"); + } + + if (std.mem.eql(u8, call_name, "@Type")) { + if (params.len == 0) return null; + if (params[0] != node) return null; + return analyser.instanceStdBuiltinType("Type"); + } }, .@"orelse" => { diff --git a/tests/analysis/builtins.zig b/tests/analysis/builtins.zig index 7d87b47b2..592d99cc2 100644 --- a/tests/analysis/builtins.zig +++ b/tests/analysis/builtins.zig @@ -116,7 +116,58 @@ const panic = @panic("foo"); const trap = @trap(); // ^^^^ (noreturn)() +const type_type: @Type(.type) = i32; +// ^^^^^^^^^ (type)() +const type_void: @Type(.void) = {}; +// ^^^^^^^^^ (void)() +const type_bool: @Type(.bool) = false; +// ^^^^^^^^^ (bool)() +const type_noreturn: @Type(.noreturn) = @panic("foo"); +// ^^^^^^^^^^^^^ (noreturn)() +const type_comptime_float: @Type(.comptime_float) = 3.14; +// ^^^^^^^^^^^^^^^^^^^ (comptime_float)() +const type_comptime_int: @Type(.comptime_int) = 42; +// ^^^^^^^^^^^^^^^^^ (comptime_int)() +const type_undefined: @Type(.undefined) = undefined; +// ^^^^^^^^^^^^^^ (@TypeOf(undefined))() +const type_null: @Type(.null) = null; +// ^^^^^^^^^ (@TypeOf(null))() +const type_enum_literal: @Type(.enum_literal) = .foo; +// ^^^^^^^^^^^^^^^^^ (@Type(.enum_literal))() + comptime { // Use @compileLog to verify the expected type with the compiler // @compileLog(vector_builtin_13); } + +fn builtin_calls() void { + @branchHint(.none); + // ^^^^^ (BranchHint)() + @atomicLoad(undefined, undefined, .unordered); + // ^^^^^^^^^^ (AtomicOrder)() + @atomicRmw(undefined, undefined, .Xchg, undefined, .unordered); + // ^^^^^ (AtomicRmwOp)() + // ^^^^^^^^^^ (AtomicOrder)() + @atomicStore(undefined, undefined, undefined, .unordered); + // ^^^^^^^^^^ (AtomicOrder)() + @cmpxchgStrong(undefined, undefined, undefined, undefined, .unordered, .unordered); + // ^^^^^^^^^^ (AtomicOrder)() + // ^^^^^^^^^^ (AtomicOrder)() + @cmpxchgWeak(undefined, undefined, undefined, undefined, .unordered, .unordered); + // ^^^^^^^^^^ (AtomicOrder)() + // ^^^^^^^^^^ (AtomicOrder)() + @call(.always_inline, undefined, undefined); + // ^^^^^^^^^^^^^^ (CallModifier)() + @export(undefined, .{ .name = undefined }); + // ^^^^^ ([]const u8)() + @extern(undefined, .{ .name = undefined }); + // ^^^^^ ([]const u8)() + @prefetch(undefined, .{ .locality = 3 }); + // ^^^^^^^^^ (u2)() + @reduce(.And, undefined); + // ^^^^ (ReduceOp)() + @setFloatMode(.strict); + // ^^^^^^^ (FloatMode)() + @Type(.type); + // ^^^^^ (void)() +} diff --git a/tests/analysis_check.zig b/tests/analysis_check.zig index e39da90da..88669407c 100644 --- a/tests/analysis_check.zig +++ b/tests/analysis_check.zig @@ -63,6 +63,7 @@ pub fn main() Error!void { }; config.zig_exe_path = try arena.dupe(u8, zig_exe_path); } else if (std.mem.eql(u8, arg, "--zig-lib-path")) { + std.debug.assert(builtin.target.os.tag != .wasi); const zig_lib_path = arg_it.next() orelse { std.log.err("expected argument after '--zig-lib-path'.", .{}); std.process.exit(1); @@ -83,6 +84,20 @@ pub fn main() Error!void { } } + if (builtin.target.os.tag == .wasi) { + const wasi_preopens = try std.fs.wasi.preopensAlloc(gpa); + defer { + for (wasi_preopens.names[3..]) |name| gpa.free(name); + gpa.free(wasi_preopens.names); + } + + const zig_lib_dir_fd = wasi_preopens.find("/lib") orelse { + std.log.err("failed to resolve '/lib' WASI preopen", .{}); + std.process.exit(1); + }; + config.zig_lib_dir = .{ .handle = .{ .fd = zig_lib_dir_fd }, .path = "/lib" }; + } + var thread_pool: if (builtin.single_threaded) void else std.Thread.Pool = undefined; if (builtin.single_threaded) { thread_pool = {};