diff --git a/.github/workflows/artifacts.yml b/.github/workflows/artifacts.yml index af2773a08..9510e66c7 100644 --- a/.github/workflows/artifacts.yml +++ b/.github/workflows/artifacts.yml @@ -39,7 +39,7 @@ jobs: - uses: mlugg/setup-zig@v2 if: env.SKIP_DEPLOY != 'true' with: - version: master + version: 0.16.0 - name: Install APT packages if: env.SKIP_DEPLOY != 'true' diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 433d25f3c..8db43c80b 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -16,7 +16,7 @@ jobs: - uses: mlugg/setup-zig@v2 with: - version: master + version: 0.16.0 - name: Install kcov run: | diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6407ff364..1844d1f98 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,7 +20,7 @@ jobs: - uses: mlugg/setup-zig@v2 with: - version: master + version: 0.16.0 - name: Run zig fmt if: matrix.os == 'ubuntu-22.04' diff --git a/build.zig b/build.zig index 9f0dfd6fc..cfec30536 100644 --- a/build.zig +++ b/build.zig @@ -6,10 +6,10 @@ const zls_version = std.SemanticVersion.parse(@import("build.zig.zon").version) const minimum_build_zig_version = @import("build.zig.zon").minimum_zig_version; /// Specify the minimum Zig version that is usable with ZLS: -/// std.Io: move netReceive to become an Operation +/// Release 0.16.0 /// /// A breaking change to the Zig Build System should be handled by updating ZLS's build runner (see src\build_runner) -const minimum_runtime_zig_version = "0.16.0-dev.2736+3b515fbed"; +const minimum_runtime_zig_version = "0.16.0"; const release_targets = [_]std.Target.Query{ .{ .cpu_arch = .aarch64, .os_tag = .linux }, @@ -171,7 +171,7 @@ pub fn build(b: *Build) !void { artifact.* = b.addExecutable(.{ .name = "zls", .root_module = exe_module, - .max_rss = if (optimize == .Debug and target_query.os_tag == .wasi) 2_200_000_000 else 1_800_000_000, + .max_rss = if (optimize == .Debug and target_query.os_tag == .wasi) 2_600_000_000 else 2_000_000_000, .use_llvm = use_llvm, .use_lld = use_llvm, }); @@ -188,7 +188,7 @@ pub fn build(b: *Build) !void { .build_options = build_options, .version_data = version_data_module, }); - b.modules.put("zls", zls_module) catch @panic("OOM"); + b.modules.put(b.allocator, "zls", zls_module) catch @panic("OOM"); const known_folders_module = b.dependency("known_folders", .{ .target = target, @@ -498,7 +498,7 @@ fn release(b: *Build, release_artifacts: []const *Build.Step.Compile, released_z @"tar.gz", }; - var compressed_artifacts: std.StringArrayHashMapUnmanaged(std.Build.LazyPath) = .empty; + var compressed_artifacts: std.array_hash_map.String(std.Build.LazyPath) = .empty; for (release_artifacts) |exe| { const resolved_target = exe.root_module.resolved_target.?.result; diff --git a/build.zig.zon b/build.zig.zon index ab4ada332..8837ff138 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -10,21 +10,21 @@ // nix flake update --commit-lock-file // ``` // If you do not use Nix, a ZLS maintainer can take care of this. - .minimum_zig_version = "0.16.0-dev.3133+5ec8e45f3", + .minimum_zig_version = "0.16.0", // Must be kept in sync with the `deps.nix` for the Nix flake. // If you do not use Nix, a ZLS maintainer can take care of this. .dependencies = .{ .known_folders = .{ - .url = "https://github.com/ziglibs/known-folders/archive/175f5596b3d2ee3c658282bb07885580895a0e73.tar.gz", - .hash = "known_folders-0.0.0-Fy-PJk7KAAC41mQXzmFyGa0Q7tvmQjatENkREa6Gc4zu", + .url = "https://github.com/ziglibs/known-folders/archive/d6d03830968cca6b7b9f24fd97ee348346a6905d.tar.gz", + .hash = "known_folders-0.0.0-Fy-PJk3KAACzUg2us_0JvQQmod1ZA8jBt7MuoKCihq88", }, .diffz = .{ - .url = "https://github.com/ziglibs/diffz/archive/d93d5737d2c19a2fb279c8dcaa80a4ce35529a3b.tar.gz", - .hash = "diffz-0.0.1-G2tlIXvNAQCPPTvl-leqv4d5nfEdwLw2lfE11P7EGKhy", + .url = "https://github.com/ziglibs/diffz/archive/b39fe07e7fdbcf56e43ba2890b9f484f16969f90.tar.gz", + .hash = "diffz-0.0.1-G2tlISzNAQCldmOcINavGmF1zdt20NFPXeM8d07jp_68", }, .lsp_kit = .{ - .url = "https://github.com//zigtools/lsp-kit/archive/ec325a3c33d1da7708cf513355208f74d9560580.tar.gz", - .hash = "lsp_kit-0.1.0-bi_PL_kyDACVTEhLaMq2-PJx0MocqRyjXDAN0ybMUyQQ", + .url = "https://github.com/zigtools/lsp-kit/archive/b886a2b0d5cee85ecbcc3089b863f7517cc9ff7f.tar.gz", + .hash = "lsp_kit-0.1.0-bi_PL3IyDACfp1xdTnkiOHEok2YpPCCCJHuuOcNzjl1D", }, .tracy = .{ .url = "https://github.com/wolfpld/tracy/archive/refs/tags/v0.13.1.tar.gz", diff --git a/deps.nix b/deps.nix index b9b29bd5d..66b1fc35d 100644 --- a/deps.nix +++ b/deps.nix @@ -5,24 +5,24 @@ }: linkFarm "zig-packages" [ { - name = "known_folders-0.0.0-Fy-PJk7KAAC41mQXzmFyGa0Q7tvmQjatENkREa6Gc4zu"; + name = "known_folders-0.0.0-Fy-PJk3KAACzUg2us_0JvQQmod1ZA8jBt7MuoKCihq88"; path = fetchzip { - url = "https://github.com/ziglibs/known-folders/archive/4575ac4088eb7d0c8421d5b3d642f19de392d898.tar.gz"; - hash = "sha256-YE4KRNvrqzMtB7sSPnnbhwCokfNP7RqNtO1QVgwbiBc="; + url = "https://github.com/ziglibs/known-folders/archive/d6d03830968cca6b7b9f24fd97ee348346a6905d.tar.gz"; + hash = "sha256-8LlAnEwuoeQuN9V5nUuh2UwXRhS5KOwDkpm6yuOfClk="; }; } { - name = "diffz-0.0.1-G2tlIXvNAQCPPTvl-leqv4d5nfEdwLw2lfE11P7EGKhy"; + name = "diffz-0.0.1-G2tlISzNAQCldmOcINavGmF1zdt20NFPXeM8d07jp_68"; path = fetchzip { - url = "https://github.com/ziglibs/diffz/archive/d93d5737d2c19a2fb279c8dcaa80a4ce35529a3b.tar.gz"; - hash = "sha256-1IDqdr0+74IlH76eovC6m5Ww6bNMAAyHFt1ukat/UXk="; + url = "https://github.com/ziglibs/diffz/archive/b39fe07e7fdbcf56e43ba2890b9f484f16969f90.tar.gz"; + hash = "sha256-mmgaOXFpoBYMsNdVkoFa7wJKkiXtzXIbSxRUgWLdVUc="; }; } { - name = "lsp_kit-0.1.0-bi_PL_kyDACVTEhLaMq2-PJx0MocqRyjXDAN0ybMUyQQ"; + name = "lsp_kit-0.1.0-bi_PL3IyDACfp1xdTnkiOHEok2YpPCCCJHuuOcNzjl1D"; path = fetchzip { - url = "https://github.com/zigtools/lsp-kit/archive/ec325a3c33d1da7708cf513355208f74d9560580.tar.gz"; - hash = "sha256-60F2BOCrl3CreQFmpH3HAz6zzxd3VgJ3iSEkP39gtgQ="; + url = "https://github.com/zigtools/lsp-kit/archive/b886a2b0d5cee85ecbcc3089b863f7517cc9ff7f.tar.gz"; + hash = "sha256-367wPydvnpl9RYlTrXwk4bZ/ui9DbYjeY/VDYs7ZJRs="; }; } ] diff --git a/flake.lock b/flake.lock index 60812d934..16c79fb1b 100644 --- a/flake.lock +++ b/flake.lock @@ -1,28 +1,12 @@ { "nodes": { - "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, "nixpkgs": { "locked": { - "lastModified": 1775595990, - "narHash": "sha256-OEf7YqhF9IjJFYZJyuhAypgU+VsRB5lD4DuiMws5Ltc=", + "lastModified": 1776067740, + "narHash": "sha256-B35lpsqnSZwn1Lmz06BpwF7atPgFmUgw1l8KAV3zpVQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "4e92bbcdb030f3b4782be4751dc08e6b6cb6ccf2", + "rev": "7e495b747b51f95ae15e74377c5ce1fe69c1765f", "type": "github" }, "original": { @@ -35,44 +19,26 @@ "root": { "inputs": { "nixpkgs": "nixpkgs", - "zig-overlay": "zig-overlay" - } - }, - "systems": { - "flake": false, - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" + "zig-flake": "zig-flake" } }, - "zig-overlay": { + "zig-flake": { "inputs": { - "flake-compat": "flake-compat", "nixpkgs": [ "nixpkgs" - ], - "systems": "systems" + ] }, "locked": { - "lastModified": 1775651458, - "narHash": "sha256-Vin1+HI1TJvBXS4d3rcflfCWL9MmJJjjoZ2ATsPHAqg=", - "owner": "mitchellh", - "repo": "zig-overlay", - "rev": "e9ed260913d18b2973a86eabc8e46642c4e04c75", + "lastModified": 1776183664, + "narHash": "sha256-lmTMKC0Rc0L1GChNEAkn+hV/iaFMU4B2C9NkQqydumo=", + "owner": "silversquirl", + "repo": "zig-flake", + "rev": "2c9eec04c4a27ca54addd9e6c28a5a64906cba0a", "type": "github" }, "original": { - "owner": "mitchellh", - "repo": "zig-overlay", + "owner": "silversquirl", + "repo": "zig-flake", "type": "github" } } diff --git a/flake.nix b/flake.nix index 9ee4393d4..e3f2bf72f 100644 --- a/flake.nix +++ b/flake.nix @@ -2,14 +2,14 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11"; - zig-overlay.url = "github:mitchellh/zig-overlay"; - zig-overlay.inputs.nixpkgs.follows = "nixpkgs"; + zig-flake.url = "github:silversquirl/zig-flake"; + zig-flake.inputs.nixpkgs.follows = "nixpkgs"; }; outputs = { self, nixpkgs, - zig-overlay, + zig-flake, }: let lib = nixpkgs.lib; parseVersionFieldFromZon = name: @@ -18,6 +18,7 @@ (builtins.match ".*\n[[:space:]]*\\.${name}[[:space:]]=[[:space:]]\"([^\"]+)\".*") builtins.head ]; + minimum_zig_version = parseVersionFieldFromZon "minimum_zig_version"; zlsVersionShort = parseVersionFieldFromZon "version"; zlsVersionFull = zlsVersionShort @@ -33,7 +34,12 @@ system: let pkgs = nixpkgs.legacyPackages.${system}; fs = lib.fileset; - zig = zig-overlay.packages.${system}.master; + zigVersion = lib.pipe minimum_zig_version [ + builtins.splitVersion + (lib.sublist 0 5) + (lib.concatStringsSep "_") + ]; + zig = zig-flake.packages.${system}."zig_${zigVersion}"; target = builtins.replaceStrings ["darwin"] ["macos"] system; in { formatter.${system} = pkgs.alejandra; diff --git a/schema.json b/schema.json index beafb5634..c7ee96244 100644 --- a/schema.json +++ b/schema.json @@ -93,7 +93,7 @@ "default": false }, "skip_std_references": { - "description": "When true, skips searching for references in the standard library. Improves lookup speed for functions in user's code. Renaming and go-to-definition will continue to work as is", + "description": "No longer used. May be brought back to configure how symbol references in the standard library should behave", "type": "boolean", "default": false }, diff --git a/src/Config.zig b/src/Config.zig index 7268a5a80..846e0e73b 100644 --- a/src/Config.zig +++ b/src/Config.zig @@ -60,7 +60,7 @@ warn_style: bool = false, /// Whether to highlight global var declarations highlight_global_var_declarations: bool = false, -/// When true, skips searching for references in the standard library. Improves lookup speed for functions in user's code. Renaming and go-to-definition will continue to work as is +/// No longer used. May be brought back to configure how symbol references in the standard library should behave skip_std_references: bool = false, /// Favor using `zig ast-check` instead of the builtin one diff --git a/src/DiagnosticsCollection.zig b/src/DiagnosticsCollection.zig index 442f7806f..2dbbe165c 100644 --- a/src/DiagnosticsCollection.zig +++ b/src/DiagnosticsCollection.zig @@ -7,7 +7,7 @@ const Uri = @import("Uri.zig"); io: std.Io, allocator: std.mem.Allocator, mutex: std.Io.Mutex = .init, -tag_set: std.AutoArrayHashMapUnmanaged(Tag, struct { +tag_set: std.array_hash_map.Auto(Tag, struct { version: u32 = 0, error_bundle_src_base_path: ?[]const u8 = null, /// Used to store diagnostics from `pushErrorBundle` diff --git a/src/DocumentScope.zig b/src/DocumentScope.zig index 30074163c..cd3a44bec 100644 --- a/src/DocumentScope.zig +++ b/src/DocumentScope.zig @@ -16,7 +16,7 @@ extra: std.ArrayList(u32), /// Every `index` inside this `ArrayhashMap` is equivalent to a `Declaration.Index` /// This means that every declaration is only the child of a single scope -pub const DeclarationLookupMap = std.ArrayHashMapUnmanaged( +pub const DeclarationLookupMap = std.array_hash_map.Custom( DeclarationLookup, void, DeclarationLookupContext, diff --git a/src/DocumentStore.zig b/src/DocumentStore.zig index 182262e7e..e40a9881a 100644 --- a/src/DocumentStore.zig +++ b/src/DocumentStore.zig @@ -26,7 +26,7 @@ mutex: std.Io.Mutex = .init, wait_group: if (supports_build_system) std.Io.Group else void = if (supports_build_system) .init else {}, handles: Uri.ArrayHashMap(*Handle.Future) = .empty, build_files: if (supports_build_system) Uri.ArrayHashMap(*BuildFile) else void = if (supports_build_system) .empty else {}, -cimports: if (supports_build_system) std.AutoArrayHashMapUnmanaged(CImportHash, translate_c.Result) else void = if (supports_build_system) .empty else {}, +cimports: if (supports_build_system) std.array_hash_map.Auto(CImportHash, translate_c.Result) else void = if (supports_build_system) .empty else {}, diagnostics_collection: *DiagnosticsCollection, builds_in_progress: std.atomic.Value(i32) = .init(0), transport: ?*lsp.Transport = null, @@ -361,7 +361,7 @@ pub const Handle = struct { const target_index = modules.getIndex(target_root_source_file).?; // We only care about the root source file of each root module so we convert them to a set. - var root_modules: std.StringArrayHashMapUnmanaged(void) = .empty; + var root_modules: std.array_hash_map.String(void) = .empty; defer root_modules.deinit(allocator); try root_modules.ensureTotalCapacity(allocator, build_config.compilations.len); diff --git a/src/Server.zig b/src/Server.zig index 80e1366ec..b7d48eb2b 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -599,12 +599,12 @@ fn initializedHandler(server: *Server, arena: std.mem.Allocator, notification: t if (server.client_capabilities.supports_workspace_did_change_watched_files) { // `{ "watchers": [ { "globPattern": "**/*.{zig,zon}" } ] }` - var watcher: std.json.ObjectMap = .init(arena); - try watcher.putNoClobber("globPattern", .{ .string = "**/*.{zig,zon}" }); + var watcher: std.json.ObjectMap = .empty; + try watcher.putNoClobber(arena, "globPattern", .{ .string = "**/*.{zig,zon}" }); var watchers_arr: std.json.Array = try .initCapacity(arena, 1); watchers_arr.appendAssumeCapacity(.{ .object = watcher }); - var fs_watcher_obj: std.json.ObjectMap = .init(arena); - try fs_watcher_obj.putNoClobber("watchers", .{ .array = watchers_arr }); + var fs_watcher_obj: std.json.ObjectMap = .empty; + try fs_watcher_obj.putNoClobber(arena, "watchers", .{ .array = watchers_arr }); const json_val: std.json.Value = .{ .object = fs_watcher_obj }; try server.registerCapability("workspace/didChangeWatchedFiles", json_val); @@ -1894,7 +1894,7 @@ fn processMessageReportError(server: *Server, arena_state: std.heap.ArenaAllocat if (err == error.Canceled) return error.Canceled; log.err("failed to process {f}: {}", .{ fmtMessage(message), err }); if (@errorReturnTrace()) |trace| { - std.debug.dumpStackTrace(trace); + std.debug.dumpErrorReturnTrace(trace); } switch (message) { diff --git a/src/TrigramStore.zig b/src/TrigramStore.zig index 03f0c2c01..9af6114cb 100644 --- a/src/TrigramStore.zig +++ b/src/TrigramStore.zig @@ -27,7 +27,7 @@ pub const Declaration = struct { }; filter_buckets: ?[]CuckooFilter.Bucket, -trigram_to_declarations: std.AutoArrayHashMapUnmanaged(Trigram, std.ArrayList(Declaration.Index)), +trigram_to_declarations: std.array_hash_map.Auto(Trigram, std.ArrayList(Declaration.Index)), declarations: std.MultiArrayList(Declaration), pub fn init( @@ -649,7 +649,7 @@ test CuckooFilter { const element_count = 499; const filter_size = comptime CuckooFilter.capacityForCount(element_count) catch unreachable; - var entries: std.AutoArrayHashMapUnmanaged(Trigram, void) = .empty; + var entries: std.array_hash_map.Auto(Trigram, void) = .empty; defer entries.deinit(allocator); try entries.ensureTotalCapacity(allocator, element_count); diff --git a/src/Uri.zig b/src/Uri.zig index 1cd151e6d..203a3b5c1 100644 --- a/src/Uri.zig +++ b/src/Uri.zig @@ -166,7 +166,7 @@ pub const format = @compileError("Cannot format @import(\"Uri.zig\") directly!. pub const jsonStringify = @compileError("Cannot stringify @import(\"Uri.zig\") directly!. Access the underlying raw string field instead."); pub fn ArrayHashMap(comptime V: type) type { - return std.ArrayHashMapUnmanaged(Uri, V, Context, true); + return std.array_hash_map.Custom(Uri, V, Context, true); } const Context = struct { diff --git a/src/analyser/InternPool.zig b/src/analyser/InternPool.zig index d685551e4..03b372049 100644 --- a/src/analyser/InternPool.zig +++ b/src/analyser/InternPool.zig @@ -4,7 +4,7 @@ io: std.Io, gpa: Allocator, -map: std.AutoArrayHashMapUnmanaged(void, void), +map: std.array_hash_map.Auto(void, void), items: std.MultiArrayList(Item), extra: std.ArrayList(u32), string_pool: StringPool, @@ -115,11 +115,11 @@ pub const Key = union(enum) { pub const Function = struct { args: Index.Slice, /// zig only lets the first 32 arguments be `comptime` - args_is_comptime: std.StaticBitSet(32) = .initEmpty(), + args_is_comptime: std.StaticBitSet(32) = .empty, /// zig only lets the first 32 arguments be generic - args_is_generic: std.StaticBitSet(32) = .initEmpty(), + args_is_generic: std.StaticBitSet(32) = .empty, /// zig only lets the first 32 arguments be `noalias` - args_is_noalias: std.StaticBitSet(32) = .initEmpty(), + args_is_noalias: std.StaticBitSet(32) = .empty, return_type: Index, flags: Flags = .{}, @@ -990,7 +990,7 @@ pub const FieldStatus = enum { }; pub const Struct = struct { - fields: std.AutoArrayHashMapUnmanaged(String, Field), + fields: std.array_hash_map.Auto(String, Field), owner_decl: Decl.OptionalIndex, namespace: NamespaceIndex, layout: std.builtin.Type.ContainerLayout = .auto, @@ -1009,8 +1009,8 @@ pub const Struct = struct { pub const Enum = struct { tag_type: InternPool.Index, - fields: std.AutoArrayHashMapUnmanaged(String, void), - values: std.AutoArrayHashMapUnmanaged(InternPool.Index, void), + fields: std.array_hash_map.Auto(String, void), + values: std.array_hash_map.Auto(InternPool.Index, void), namespace: NamespaceIndex, tag_type_inferred: bool, @@ -1019,7 +1019,7 @@ pub const Enum = struct { pub const Union = struct { tag_type: InternPool.Index, - fields: std.AutoArrayHashMapUnmanaged(String, Field), + fields: std.array_hash_map.Auto(String, Field), namespace: NamespaceIndex, layout: std.builtin.Type.ContainerLayout = .auto, status: FieldStatus, @@ -3558,7 +3558,7 @@ pub fn errorSetMerge(ip: *InternPool, a_ty: Index, b_ty: Index) Allocator.Error! const b_names = try ip.indexToKey(b_ty).error_set_type.names.dupe(ip.gpa, ip); defer ip.gpa.free(b_names); - var set: std.AutoArrayHashMapUnmanaged(String, void) = .empty; + var set: std.array_hash_map.Auto(String, void) = .empty; defer set.deinit(ip.gpa); try set.ensureTotalCapacity(ip.gpa, a_names.len + b_names.len); @@ -4688,9 +4688,9 @@ test "function type" { .return_type = .bool_type, } }); - var args_is_comptime: std.StaticBitSet(32) = .initEmpty(); + var args_is_comptime: std.StaticBitSet(32) = .empty; args_is_comptime.set(0); - var args_is_noalias: std.StaticBitSet(32) = .initEmpty(); + var args_is_noalias: std.StaticBitSet(32) = .empty; args_is_noalias.set(1); const @"fn(comptime type, noalias i32) type" = try ip.get(.{ .function_type = .{ diff --git a/src/analysis.zig b/src/analysis.zig index d2b13b6ee..1c3d9535d 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -2229,7 +2229,7 @@ fn resolveTypeOfNodeUncached(analyser: *Analyser, options: ResolveOptions) Error .error_set_decl => { const lbrace, const rbrace = tree.nodeData(node).token_and_token; - var strings: std.AutoArrayHashMapUnmanaged(InternPool.String, void) = .empty; + var strings: std.array_hash_map.Auto(InternPool.String, void) = .empty; defer strings.deinit(analyser.gpa); var i: usize = 0; for (lbrace + 1..rbrace) |tok_i| { @@ -3852,7 +3852,7 @@ pub const Type = struct { pub const ArraySet = ArrayMap(void); pub fn ArrayMap(comptime V: type) type { - return std.ArrayHashMapUnmanaged(Type, V, ArrayMapContext, true); + return std.array_hash_map.Custom(Type, V, ArrayMapContext, true); } pub const ArrayMapContext = struct { @@ -3931,7 +3931,7 @@ pub const Type = struct { return a_ty.eql(b_ty); } }; - const Deduplicator = std.ArrayHashMapUnmanaged(Type.Data.EitherEntry, void, DeduplicatorContext, true); + const Deduplicator = std.array_hash_map.Custom(Type.Data.EitherEntry, void, DeduplicatorContext, true); var deduplicator: Deduplicator = .empty; defer deduplicator.deinit(arena); @@ -5644,7 +5644,7 @@ pub fn getPositionContext( return .empty; } -pub const TokenToTypeMap = std.ArrayHashMapUnmanaged(TokenWithHandle, Type, TokenWithHandle.Context, true); +pub const TokenToTypeMap = std.array_hash_map.Custom(TokenWithHandle, Type, TokenWithHandle.Context, true); pub const TokenWithHandle = struct { token: Ast.TokenIndex, @@ -6992,7 +6992,7 @@ pub const ReferencedType = struct { return .{ .str = str, .handle = handle, .token = token }; } - pub const Set = std.ArrayHashMapUnmanaged(ReferencedType, void, SetContext, true); + pub const Set = std.array_hash_map.Custom(ReferencedType, void, SetContext, true); const SetContext = struct { pub fn hash(self: SetContext, item: ReferencedType) u32 { diff --git a/src/build_runner/build_runner.zig b/src/build_runner/build_runner.zig index 587098f40..d5e28a04f 100644 --- a/src/build_runner/build_runner.zig +++ b/src/build_runner/build_runner.zig @@ -571,8 +571,8 @@ fn resolveStepNames( b: *std.Build, step_names: []const []const u8, check_step_only: bool, -) !std.AutoArrayHashMapUnmanaged(*Step, void) { - var starting_steps: std.AutoArrayHashMapUnmanaged(*Step, void) = .empty; +) !std.array_hash_map.Auto(*Step, void) { + var starting_steps: std.array_hash_map.Auto(*Step, void) = .empty; errdefer starting_steps.deinit(gpa); if (step_names.len == 0) { @@ -598,7 +598,7 @@ fn resolveStepNames( fn prepare( b: *std.Build, - unpopulated_step_stack: *std.AutoArrayHashMapUnmanaged(*Step, void), + unpopulated_step_stack: *std.array_hash_map.Auto(*Step, void), run: *Run, ) error{ OutOfMemory, DependencyLoopDetected }!void { const gpa = run.gpa; @@ -644,7 +644,7 @@ fn prepare( fn runSteps( b: *std.Build, - step_stack: *const std.AutoArrayHashMapUnmanaged(*Step, void), + step_stack: *const std.array_hash_map.Auto(*Step, void), parent_prog_node: std.Progress.Node, run: *Run, ) (Io.Cancelable || mem.Allocator.Error)!void { @@ -689,7 +689,7 @@ fn constructGraphAndCheckForDependencyLoop( gpa: Allocator, b: *std.Build, s: *Step, - step_stack: *std.AutoArrayHashMapUnmanaged(*Step, void), + step_stack: *std.array_hash_map.Auto(*Step, void), rand: std.Random, ) !void { switch (s.state) { @@ -738,7 +738,7 @@ fn constructGraphAndCheckForDependencyLoop( fn makeStep( group: *Io.Group, b: *std.Build, - steps_stack: *const std.AutoArrayHashMapUnmanaged(*Step, void), + steps_stack: *const std.array_hash_map.Auto(*Step, void), s: *Step, root_prog_node: std.Progress.Node, run: *Run, @@ -837,7 +837,7 @@ fn makeStep( fn stepReady( group: *Io.Group, b: *std.Build, - steps_stack: *const std.AutoArrayHashMapUnmanaged(*Step, void), + steps_stack: *const std.array_hash_map.Auto(*Step, void), s: *Step, root_prog_node: std.Progress.Node, run: *Run, @@ -903,7 +903,7 @@ fn validateSystemLibraryOptions(b: *std.Build) void { fn createModuleDependencies(b: *std.Build) Allocator.Error!void { const arena = b.graph.arena; - var all_steps: std.AutoArrayHashMapUnmanaged(*Step, void) = .empty; + var all_steps: std.array_hash_map.Auto(*Step, void) = .empty; var next_step_idx: usize = 0; try all_steps.ensureUnusedCapacity(arena, b.top_level_steps.count()); @@ -993,13 +993,13 @@ fn extractBuildInformation( run: *Run, ) !void { const helper = struct { - fn addLazyPathStepDependencies(allocator: Allocator, set: *std.AutoArrayHashMapUnmanaged(*Step, void), lazy_path: std.Build.LazyPath) !void { + fn addLazyPathStepDependencies(allocator: Allocator, set: *std.array_hash_map.Auto(*Step, void), lazy_path: std.Build.LazyPath) !void { switch (lazy_path) { .src_path, .cwd_relative, .dependency => {}, .generated => |gen| try set.put(allocator, gen.file.step, {}), } } - fn addIncludeDirStepDependencies(allocator: Allocator, set: *std.AutoArrayHashMapUnmanaged(*Step, void), include_dir: std.Build.Module.IncludeDir) !void { + fn addIncludeDirStepDependencies(allocator: Allocator, set: *std.array_hash_map.Auto(*Step, void), include_dir: std.Build.Module.IncludeDir) !void { switch (include_dir) { .path, .path_system, @@ -1022,7 +1022,7 @@ fn extractBuildInformation( } } /// Only adds the necessary dependencies to resolve the `root_source_file` and `include_dirs`. Does not include dependencies of imported modules. - fn addModuleDependencies(allocator: Allocator, set: *std.AutoArrayHashMapUnmanaged(*Step, void), module: *std.Build.Module) !void { + fn addModuleDependencies(allocator: Allocator, set: *std.array_hash_map.Auto(*Step, void), module: *std.Build.Module) !void { if (module.root_source_file) |root_source_file| { try addLazyPathStepDependencies(allocator, set, root_source_file); } @@ -1033,14 +1033,14 @@ fn extractBuildInformation( } fn processModule( allocator: Allocator, - modules: *std.StringArrayHashMapUnmanaged(shared.BuildConfig.Module), + modules: *std.array_hash_map.String(shared.BuildConfig.Module), module: *std.Build.Module, compile: ?*Step.Compile, ) !void { const root_source_file = module.root_source_file orelse return; - var include_dirs: std.StringArrayHashMapUnmanaged(void) = .empty; - var c_macros: std.StringArrayHashMapUnmanaged(void) = .empty; + var include_dirs: std.array_hash_map.String(void) = .empty; + var c_macros: std.array_hash_map.String(void) = .empty; if (compile) |exe| { try processPkgConfig(allocator, &include_dirs, &c_macros, exe); @@ -1115,7 +1115,7 @@ fn extractBuildInformation( const gpa = run.gpa; // The value tracks whether the step is a decendant of the "install" step. - var all_steps: std.AutoArrayHashMapUnmanaged(*Step, bool) = .empty; + var all_steps: std.array_hash_map.Auto(*Step, bool) = .empty; defer all_steps.deinit(gpa); // collect all steps that are decendants of the "install" step. @@ -1154,10 +1154,10 @@ fn extractBuildInformation( // Collect all steps that need to be run so that we can resolve the lazy paths we are interested in (e.g. root_source_file). { - var needed_steps: std.AutoArrayHashMapUnmanaged(*Step, void) = .empty; + var needed_steps: std.array_hash_map.Auto(*Step, void) = .empty; defer needed_steps.deinit(gpa); - var modules: std.AutoArrayHashMapUnmanaged(*std.Build.Module, void) = .empty; + var modules: std.array_hash_map.Auto(*std.Build.Module, void) = .empty; defer modules.deinit(gpa); try modules.ensureUnusedCapacity(gpa, b.modules.count()); @@ -1195,7 +1195,7 @@ fn extractBuildInformation( // - public modules (`std.Build.addModule`) // - modules that are reachable from the "install" step // - all other reachable modules - var modules: std.StringArrayHashMapUnmanaged(BuildConfig.Module) = .empty; + var modules: std.array_hash_map.String(BuildConfig.Module) = .empty; for (b.modules.values()) |root_module| { const graph = root_module.getGraph(); @@ -1242,7 +1242,7 @@ fn extractBuildInformation( // }; // Collect the dependencies from `build.zig.zon` - var root_dependencies: std.StringArrayHashMapUnmanaged([]const u8) = .empty; + var root_dependencies: std.array_hash_map.String([]const u8) = .empty; for (dependencies.root_deps) |root_dep| { inline for (comptime std.meta.declarations(dependencies.packages)) |package| blk: { if (std.mem.eql(u8, package.name, root_dep[1])) { @@ -1258,7 +1258,7 @@ fn extractBuildInformation( } } - var available_options: std.StringArrayHashMapUnmanaged(BuildConfig.AvailableOption) = .empty; + var available_options: std.array_hash_map.String(BuildConfig.AvailableOption) = .empty; try available_options.ensureTotalCapacity(arena, b.available_options_map.count()); var it = b.available_options_map.iterator(); @@ -1284,8 +1284,8 @@ fn extractBuildInformation( fn processPkgConfig( allocator: Allocator, - include_dirs: *std.StringArrayHashMapUnmanaged(void), - c_macros: *std.StringArrayHashMapUnmanaged(void), + include_dirs: *std.array_hash_map.String(void), + c_macros: *std.array_hash_map.String(void), exe: *Step.Compile, ) !void { for (exe.root_module.link_objects.items) |link_object| { diff --git a/src/features/code_actions.zig b/src/features/code_actions.zig index acd3111c2..d01ad553b 100644 --- a/src/features/code_actions.zig +++ b/src/features/code_actions.zig @@ -835,7 +835,7 @@ pub fn getImportsDecls(builder: *Builder, allocator: std.mem.Allocator) error{Ou var skip_set: std.DynamicBitSetUnmanaged = try .initEmpty(allocator, root_decls.len); defer skip_set.deinit(allocator); - var imports: std.ArrayHashMapUnmanaged(ImportDecl, void, void, true) = .empty; + var imports: std.array_hash_map.Custom(ImportDecl, void, void, true) = .empty; defer imports.deinit(allocator); // iterate until no more imports are found diff --git a/src/features/completions.zig b/src/features/completions.zig index 3cdb6c1f8..09b6a5779 100644 --- a/src/features/completions.zig +++ b/src/features/completions.zig @@ -30,7 +30,7 @@ const Builder = struct { }; pub const Completions = struct { - map: std.StringArrayHashMapUnmanaged(types.completion.Item), + map: std.array_hash_map.String(types.completion.Item), pub const empty: Completions = .{ .map = .empty }; diff --git a/src/features/diagnostics.zig b/src/features/diagnostics.zig index 0c7f2bb3c..58aac91c1 100644 --- a/src/features/diagnostics.zig +++ b/src/features/diagnostics.zig @@ -626,7 +626,7 @@ pub const BuildOnSave = struct { const stdout = multi_reader.reader(0); const stderr = multi_reader.reader(1); - var diagnostic_tags: std.AutoArrayHashMapUnmanaged(DiagnosticsCollection.Tag, void) = .empty; + var diagnostic_tags: std.array_hash_map.Auto(DiagnosticsCollection.Tag, void) = .empty; defer diagnostic_tags.deinit(allocator); defer { @@ -711,7 +711,7 @@ pub const BuildOnSave = struct { body: []u8, collection: *DiagnosticsCollection, workspace_path: []const u8, - diagnostic_tags: *std.AutoArrayHashMapUnmanaged(DiagnosticsCollection.Tag, void), + diagnostic_tags: *std.array_hash_map.Auto(DiagnosticsCollection.Tag, void), ) (error{ OutOfMemory, InvalidMessage } || std.Io.File.Writer.Error)!void { var reader: std.Io.Reader = .fixed(body); diff --git a/src/features/inlay_hints.zig b/src/features/inlay_hints.zig index c3afbd5f3..9ffef22bd 100644 --- a/src/features/inlay_hints.zig +++ b/src/features/inlay_hints.zig @@ -16,127 +16,136 @@ const data = @import("version_data"); /// don't show inlay hints for builtin functions whose parameter names carry no /// meaningful information or are trivial deductible based on the builtin name. -const excluded_builtins_set: std.StaticStringMap(void) = blk: { - @setEvalBranchQuota(2000); - break :blk .initComptime(.{ - .{"addrSpaceCast"}, - .{"addWithOverflow"}, - .{"alignCast"}, - .{"alignOf"}, - .{"as"}, - // .{"atomicLoad"}, - // .{"atomicRmw"}, - // .{"atomicStore"}, - .{"bitCast"}, - .{"bitOffsetOf"}, - .{"bitSizeOf"}, - .{"branchHint"}, - .{"breakpoint"}, // no parameters - // .{"mulAdd"}, - .{"byteSwap"}, - .{"bitReverse"}, - .{"offsetOf"}, - // .{"call"}, - .{"cDefine"}, - .{"cImport"}, - .{"cInclude"}, - .{"clz"}, - // .{"cmpxchgStrong"}, - // .{"cmpxchgWeak"}, - // .{"compileError"}, - .{"compileLog"}, // variadic - .{"constCast"}, - .{"ctz"}, - .{"cUndef"}, - // .{"cVaArg"}, - // .{"cVaCopy"}, - // .{"cVaEnd"}, - // .{"cVaStart"}, - .{"divExact"}, - .{"divFloor"}, - .{"divTrunc"}, - .{"embedFile"}, - .{"enumFromInt"}, - .{"errorFromInt"}, - .{"errorName"}, - .{"errorReturnTrace"}, // no parameters - .{"errorCast"}, - // .{"export"}, - // .{"extern"}, - // .{"field"}, - // .{"fieldParentPtr"}, - // .{"FieldType"}, - .{"floatCast"}, - .{"floatFromInt"}, - .{"frameAddress"}, // no parameters - // .{"hasDecl"}, - // .{"hasField"}, - .{"import"}, - .{"inComptime"}, // no parameters - .{"intCast"}, - .{"intFromBool"}, - .{"intFromEnum"}, - .{"intFromError"}, - .{"intFromFloat"}, - .{"intFromPtr"}, - .{"max"}, - // .{"memcpy"}, - // .{"memset"}, - .{"min"}, - // .{"wasmMemorySize"}, - // .{"wasmMemoryGrow"}, - .{"mod"}, - .{"mulWithOverflow"}, - // .{"panic"}, - .{"popCount"}, - // .{"prefetch"}, - .{"ptrCast"}, - .{"ptrFromInt"}, - .{"rem"}, - .{"returnAddress"}, // no parameters - // .{"select"}, - .{"setEvalBranchQuota"}, - .{"setFloatMode"}, - .{"setRuntimeSafety"}, - // .{"shlExact"}, - // .{"shlWithOverflow"}, - // .{"shrExact"}, - // .{"shuffle"}, - .{"sizeOf"}, - // .{"splat"}, - // .{"reduce"}, - .{"src"}, // no parameters - .{"sqrt"}, - .{"sin"}, - .{"cos"}, - .{"tan"}, - .{"exp"}, - .{"exp2"}, - .{"log"}, - .{"log2"}, - .{"log10"}, - .{"abs"}, - .{"floor"}, - .{"ceil"}, - .{"trunc"}, - .{"round"}, - .{"subWithOverflow"}, - .{"tagName"}, - .{"This"}, // no parameters - .{"trap"}, // no parameters - .{"truncate"}, - .{"Type"}, - .{"typeInfo"}, - .{"typeName"}, - .{"TypeOf"}, // variadic - // .{"unionInit"}, - // .{"Vector"}, - .{"volatileCast"}, - // .{"workGroupId"}, - // .{"workGroupSize"}, - // .{"workItemId"}, - }); -}; +const excluded_builtins_set: std.EnumArray(std.zig.BuiltinFn.Tag, bool) = .init(.{ + .add_with_overflow = true, + .addrspace_cast = true, + .align_cast = true, + .align_of = true, + .as = true, + .atomic_load = false, + .atomic_rmw = false, + .atomic_store = false, + .bit_cast = true, + .bit_offset_of = true, + .int_from_bool = true, + .bit_size_of = true, + .branch_hint = true, + .breakpoint = true, // no parameters + .disable_instrumentation = true, // no parameters + .disable_intrinsics = true, // no parameters + .mul_add = false, + .byte_swap = true, + .bit_reverse = true, + .offset_of = false, + .call = false, + .c_define = true, + .c_import = true, + .c_include = true, + .clz = true, + .cmpxchg_strong = false, + .cmpxchg_weak = false, + .compile_error = false, + .compile_log = true, // variadic + .const_cast = true, + .ctz = true, + .c_undef = true, + .c_va_arg = false, + .c_va_copy = false, + .c_va_end = false, + .c_va_start = false, + .div_exact = true, + .div_floor = true, + .div_trunc = true, + .embed_file = true, + .int_from_enum = true, + .error_name = true, + .error_return_trace = true, // no parameters + .int_from_error = true, + .error_cast = true, + .@"export" = false, + .@"extern" = false, + .field = false, + .field_parent_ptr = false, + .FieldType = false, + .float_cast = true, + .int_from_float = true, + .frame = true, + .Frame = true, + .frame_address = true, // no parameters + .has_decl = false, + .has_field = false, + .import = true, + .in_comptime = true, // no parameters + .int_cast = true, + .enum_from_int = true, + .error_from_int = true, + .float_from_int = true, + .ptr_from_int = true, + .max = true, // variadic + .memcpy = false, + .memset = false, + .memmove = false, + .min = true, // variadic + .wasm_memory_size = false, + .wasm_memory_grow = false, + .mod = true, + .mul_with_overflow = true, + .panic = false, + .pop_count = true, + .prefetch = false, + .ptr_cast = true, + .int_from_ptr = true, + .rem = true, + .return_address = true, // no parameters + .select = false, + .set_eval_branch_quota = true, + .set_float_mode = true, + .set_runtime_safety = true, + .shl_exact = false, + .shl_with_overflow = false, + .shr_exact = false, + .shuffle = false, + .size_of = true, + .splat = true, + .reduce = false, + .src = true, // no parameters + .sqrt = true, + .sin = true, + .cos = true, + .tan = true, + .exp = true, + .exp2 = true, + .log = true, + .log2 = true, + .log10 = true, + .abs = true, + .floor = true, + .ceil = true, + .trunc = true, + .round = true, + .sub_with_overflow = true, + .tag_name = true, + .This = true, // no parameters + .trap = true, // no parameters + .truncate = true, + .EnumLiteral = true, // no parameters + .Int = true, + .Tuple = true, + .Pointer = false, + .Fn = false, + .Struct = false, + .Union = false, + .Enum = false, + .type_info = true, + .type_name = true, + .TypeOf = true, // variadic + .union_init = false, + .Vector = false, + .volatile_cast = true, + .work_item_id = false, + .work_group_size = false, + .work_group_id = false, +}); pub const InlayHint = struct { index: usize, @@ -492,8 +501,9 @@ fn writeNodeInlayHint( => { if (!builder.config.inlay_hints_show_parameter_name or !builder.config.inlay_hints_show_builtin) return; - const name = tree.tokenSlice(tree.nodeMainToken(node)); - if (name.len < 2 or excluded_builtins_set.has(name[1..])) return; + const name = offsets.tokenToSlice(tree, tree.nodeMainToken(node)); + const item = std.zig.BuiltinFn.list.get(name) orelse return; + if (excluded_builtins_set.get(item.tag)) return; var buffer: [2]Ast.Node.Index = undefined; const params = tree.builtinCallParams(&buffer, node).?; diff --git a/src/features/references.zig b/src/features/references.zig index 44542d5ab..7e59ac821 100644 --- a/src/features/references.zig +++ b/src/features/references.zig @@ -757,7 +757,7 @@ pub fn referencesHandler(server: *Server, arena: std.mem.Allocator, request: Gen switch (request) { .rename => |rename| { const escaped_rename = try std.fmt.allocPrint(arena, "{f}", .{std.zig.fmtId(rename.newName)}); - var changes: std.StringArrayHashMapUnmanaged(std.ArrayList(types.TextEdit)) = .empty; + var changes: std.array_hash_map.String(std.ArrayList(types.TextEdit)) = .empty; for (locations.items) |loc| { const gop = try changes.getOrPutValue(arena, loc.uri, .empty); diff --git a/src/tools/config.json b/src/tools/config.json index e6a4f59c9..3bfd193df 100644 --- a/src/tools/config.json +++ b/src/tools/config.json @@ -103,7 +103,7 @@ }, { "name": "skip_std_references", - "description": "When true, skips searching for references in the standard library. Improves lookup speed for functions in user's code. Renaming and go-to-definition will continue to work as is", + "description": "No longer used. May be brought back to configure how symbol references in the standard library should behave", "type": "bool", "default": false }, diff --git a/src/tools/langref.html.in b/src/tools/langref.html.in index c0272124c..6f11bc006 100644 --- a/src/tools/langref.html.in +++ b/src/tools/langref.html.in @@ -128,6 +128,7 @@ } .table-wrapper { width: 100%; + margin: 1em auto; overflow-x: auto; } @@ -318,6 +319,7 @@ 0.13.0 | 0.14.1 | 0.15.2 | + 0.16.0 | master
+ Variables are never allowed to shadow {#link|Identifiers#} from an outer scope. +
+The {#syntax#}extern{#endsyntax#} keyword or {#link|@extern#} builtin function can be used to link against a variable that is exported from another object. The {#syntax#}export{#endsyntax#} keyword or {#link|@export#} builtin function can be used to make a variable available to other objects at link time. In both cases, @@ -969,22 +993,6 @@
{#see_also|Exporting a C Library#} - {#header_open|Identifiers#} -- Variable identifiers are never allowed to shadow identifiers from an outer scope. -
-- Identifiers must start with an alphabetic character or underscore and may be followed - by any number of alphanumeric characters or underscores. - They must not overlap with any keywords. See {#link|Keyword Reference#}. -
-- If a name that does not fit these requirements is needed, such as for linking with external libraries, the {#syntax#}@""{#endsyntax#} syntax may be used. -
- {#code|identifiers.zig#} - - {#header_close#} - {#header_open|Container Level Variables#}{#link|Container|Containers#} level variables have static lifetime and are order-independent and lazily analyzed. @@ -1111,8 +1119,8 @@ {#header_close#} {#header_open|Floating Point Operations#} -
By default floating point operations use {#syntax#}Strict{#endsyntax#} mode, - but you can switch to {#syntax#}Optimized{#endsyntax#} mode on a per-block basis:
+By default floating point operations use {#syntax#}.strict{#endsyntax#} mode, + but you can switch to {#syntax#}.optimized{#endsyntax#} mode on a per-block basis:
{#code|float_mode_obj.zig#}For this test we have to separate code into two object files - @@ -1367,7 +1375,7 @@ a /= b{#endsyntax#}
- In Zig, a pointer type has an alignment value. If the value is equal to the - alignment of the underlying type, it can be omitted from the type: + Pointer types may explicitly specify an alignment in bytes. If it is not + specified, the alignment is assumed to be equal to the alignment of the + underlying type.
{#code|test_variable_alignment.zig#} @@ -2461,7 +2470,8 @@ or {#header_open|Tagged union#}Unions can be declared with an enum tag type. This turns the union into a tagged union, which makes it eligible - to use with {#link|switch#} expressions. + to use with {#link|switch#} expressions. When switching on tagged unions, + the tag value can be obtained using an additional capture. Tagged unions coerce to their tag type: {#link|Type Coercion: Unions and Enums#}.
{#code|test_tagged_union.zig#} @@ -2504,6 +2514,13 @@ orA {#syntax#}packed union{#endsyntax#} has well-defined in-memory layout and is eligible to be in a {#link|packed struct#}.
All fields in a packed union must have the same {#link|@bitSizeOf#}.
+ ++ Equating packed unions results in a comparison of the backing integer, + and only works for the {#syntax#}=={#endsyntax#} and {#syntax#}!={#endsyntax#} {#link|Operators#}. +
+ {#code|test_packed_union_equality.zig#} + {#header_close#} {#header_open|Anonymous Union Literals#} @@ -2594,6 +2611,13 @@ or {#header_close#} + {#header_open|Switching on Errors#} ++ When switching on errors, some special cases are allowed to simplify generic programming patterns: +
+ {#code|test_switch_on_errors.zig#} + {#header_close#} + {#header_open|Labeled switch#}When a switch statement is labeled, it can be referenced from a @@ -2659,12 +2683,13 @@ or {#code|test_inline_else.zig#}
- When using an inline prong switching on an union an additional - capture can be used to obtain the union's enum tag value. + When using an inline prong switching on an union an additional capture + can be used to obtain the union's enum tag value at comptime, even though + its payload might only be known at runtime.
{#code|test_inline_switch_union_tag.zig#} - {#see_also|inline while|inline for#} + {#see_also|inline while|inline for|Tagged union#} {#header_close#} {#header_close#} @@ -3239,7 +3264,7 @@ fn createFoo(param: i32) !Foo {@@ -3449,6 +3474,52 @@ void do_a_thing(struct Foo *foo) {
{#code|test_integer_widening.zig#} + {#header_close#} + {#header_open|Type Coercion: Int to Float#} ++ {#link|Integers#} coerce to {#link|Floats#} if every possible integer value can be stored in the float + without rounding (i.e. the integer's precision does not exceed the float's significand precision). + Larger integer types that cannot be safely coerced must be explicitly casted with {#link|@floatFromInt#}. +
+| Float Type | +Largest Integer Types | +
|---|---|
| {#syntax#}f16{#endsyntax#} | +{#syntax#}i12{#endsyntax#} and {#syntax#}u11{#endsyntax#} | +
| {#syntax#}f32{#endsyntax#} | +{#syntax#}i25{#endsyntax#} and {#syntax#}u24{#endsyntax#} | +
| {#syntax#}f64{#endsyntax#} | +{#syntax#}i54{#endsyntax#} and {#syntax#}u53{#endsyntax#} | +
| {#syntax#}f80{#endsyntax#} | +{#syntax#}i65{#endsyntax#} and {#syntax#}u64{#endsyntax#} | +
| {#syntax#}f128{#endsyntax#} | +{#syntax#}i114{#endsyntax#} and {#syntax#}u113{#endsyntax#} | +
| {#syntax#}c_longdouble{#endsyntax#} | +Varies by target | +
@@ -3512,12 +3583,10 @@ void do_a_thing(struct Foo *foo) { {#header_close#} {#header_open|Explicit Casts#} -
- Explicit casts are performed via {#link|Builtin Functions#}. - Some explicit casts are safe; some are not. - Some explicit casts perform language-level assertions; some do not. - Some explicit casts are no-ops at runtime; some are not. -
+Explicit casts are performed via {#link|Builtin Functions#}.
+Some explicit casts can violate type safety when used incorrectly.
+Some explicit casts perform language-level assertions.
+Some explicit casts are no-ops at runtime.
{#syntax#}@errorFromInt(value: std.meta.Int(.unsigned, @bitSizeOf(anyerror))) anyerror{#endsyntax#}
+ {#syntax#}@errorFromInt(value: @Int(.unsigned, @bitSizeOf(anyerror))) anyerror{#endsyntax#}
Converts from the integer representation of an error into {#link|The Global Error Set#} type.
@@ -4924,8 +4993,9 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val{#syntax#}@floatFromInt(int: anytype) anytype{#endsyntax#}
Converts an integer to the closest floating point representation. The return type is the inferred result type. - To convert the other way, use {#link|@intFromFloat#}. This operation is legal - for all values of all integer types. + To convert the other way, use {#link|@round#}, {#link|@floor#}, + {#link|@ceil#}, or {#link|@trunc#}. This operation is legal for all + values of all integer types.
{#header_close#} @@ -5044,7 +5114,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val {#header_close#} {#header_open|@intFromError#} -{#syntax#}@intFromError(err: anytype) std.meta.Int(.unsigned, @bitSizeOf(anyerror)){#endsyntax#}
+ {#syntax#}@intFromError(err: anytype) @Int(.unsigned, @bitSizeOf(anyerror)){#endsyntax#}
Supports the following types:
@@ -5065,14 +5135,8 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val {#header_open|@intFromFloat#}{#syntax#}@intFromFloat(float: anytype) anytype{#endsyntax#}
- - Converts the integer part of a floating point number to the inferred result type. -
-- If the integer part of the floating point number cannot fit in the destination type, - it invokes safety-checked {#link|Illegal Behavior#}. -
- {#see_also|@floatFromInt#} +Deprecated. Equivalent to {#link|@trunc#}.
+ {#see_also|@floatFromInt|@round|@floor|@ceil|@trunc#} {#header_close#} {#header_open|@intFromPtr#} @@ -5353,10 +5417,10 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_valChanges the current scope's rules about how floating point operations are defined.
{#syntax#}@floor(value: anytype) @TypeOf(value){#endsyntax#}
- - Returns the largest integral value not greater than the given floating point number. - Uses a dedicated hardware instruction when available. -
-- Supports {#link|Floats#} and {#link|Vectors#} of floats. -
+Returns the largest integral value not greater than the given floating point number. + Uses a dedicated hardware instruction when available.
+Supports {#link|Floats#} and {#link|Vectors#} of floats.
+When the inferred result type is an {#link|integer|Integers#}, + the integer part is extracted from the floored result. If that value + cannot fit in the destination type, it invokes safety-checked + {#link|Illegal Behavior#}.
{#header_close#} + {#header_open|@ceil#}{#syntax#}@ceil(value: anytype) @TypeOf(value){#endsyntax#}
- - Returns the smallest integral value not less than the given floating point number. - Uses a dedicated hardware instruction when available. -
-- Supports {#link|Floats#} and {#link|Vectors#} of floats. -
+Returns the smallest integral value not less than the given floating point number. + Uses a dedicated hardware instruction when available.
+Supports {#link|Floats#} and {#link|Vectors#} of floats.
+When the inferred result type is an {#link|integer|Integers#}, + the integer part is extracted from the ceiled result. If that value + cannot fit in the destination type, it invokes safety-checked + {#link|Illegal Behavior#}.
{#header_close#} + {#header_open|@trunc#}{#syntax#}@trunc(value: anytype) @TypeOf(value){#endsyntax#}
- - Rounds the given floating point number to an integer, towards zero. - Uses a dedicated hardware instruction when available. -
-- Supports {#link|Floats#} and {#link|Vectors#} of floats. -
+Rounds the given floating point number to an integer, towards zero. + Uses a dedicated hardware instruction when available.
+Supports {#link|Floats#} and {#link|Vectors#} of float parameters.
+When the inferred result type is an {#link|integer|Integers#}, + the integer part is extracted from the truncated result. If that value + cannot fit in the destination type, it invokes safety-checked + {#link|Illegal Behavior#}.
{#header_close#} + {#header_open|@round#}{#syntax#}@round(value: anytype) @TypeOf(value){#endsyntax#}
- - Rounds the given floating point number to the nearest integer. If two integers are equally close, rounds away from zero. - Uses a dedicated hardware instruction when available. -
+Rounds the given floating point number to the nearest integer. If two + integers are equally close, rounds away from zero. Uses a dedicated + hardware instruction when available.
{#code|test_round_builtin.zig#} - -- Supports {#link|Floats#} and {#link|Vectors#} of floats. -
+Supports {#link|Floats#} and {#link|Vectors#} of floats.
+When the inferred result type is an {#link|integer|Integers#}, + the integer part is extracted from the rounded result. If that value + cannot fit in the destination type, it invokes safety-checked + {#link|Illegal Behavior#}.
{#header_close#} {#header_open|@subWithOverflow#} @@ -6305,7 +6373,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_valZig has a general purpose allocator available to be imported - with {#syntax#}std.heap.GeneralPurposeAllocator{#endsyntax#}. However, it is still recommended to + with {#syntax#}std.heap.DebugAllocator{#endsyntax#}. However, it is still recommended to follow the {#link|Choosing an Allocator#} guide.
@@ -7027,8 +7095,7 @@ WebAssembly.instantiate(typedArray, { The result is 3{#end_shell_samp#} {#header_close#} {#header_open|WASI#} -Zig's support for WebAssembly System Interface (WASI) is under active development. - Example of using the standard library and reading command line arguments:
+Zig standard library has first-class support for WebAssembly System Interface.
{#code|wasi_args.zig#} {#shell_samp#}$ wasmtime wasi_args.wasm 123 hello @@ -7090,6 +7157,7 @@ coding style.Everything is a value, all types are data, everything is context, all logic manages state. @@ -7115,6 +7183,31 @@ coding style. cannot be any more specific without being incorrect.
{#header_close#} + {#header_open|Refrain from Underscore Prefixes#} +In some programming languages, it is common to prefix identifiers with + underscores {#syntax#}_like_this{#endsyntax#} to avoid keyword + collisions, name collisions, or indicate additional metadata associated with usage of the + identifier, such as: privacy, existence of complex data invariants, exclusion from + semantic versioning, or context-specific type reflection meaning. +
+In Zig, there are no private fields, and this style guide recommends + against pretending otherwise. Instead, fields should be named carefully + based on their semantics and documentation should indicate how to use + fields without violating data invariants. If a field is not subject to + the same semantic versioning rules as everything else, the exception + should be noted in the {#link|Doc Comments#}. +
+As for {#link|type reflection|@typeInfo#}, it is less error prone and + more maintainable to use the type system than to make field names + meaningful.
+Regarding name collisions, an underscore is insufficient to explain + the difference between the two otherwise identical names. If there's no + danger in getting them mixed up, then this guide recommends more verbose + names at outer scopes and more abbreviated names at inner scopes.
+Finally, keyword collisions are better avoided via + {#link|String Identifier Syntax#}.
+ {#header_close#} + {#header_open|Whitespace#}